diff options
-rw-r--r-- | docs/examples/bbox-device.js | 91 | ||||
-rw-r--r-- | source/tools/murun.c | 36 |
2 files changed, 119 insertions, 8 deletions
diff --git a/docs/examples/bbox-device.js b/docs/examples/bbox-device.js new file mode 100644 index 00000000..52d2cb4a --- /dev/null +++ b/docs/examples/bbox-device.js @@ -0,0 +1,91 @@ +function BBoxDevice(bbox) { + function extend(x,y) { + if (x < bbox[0]) bbox[0] = x; + if (x > bbox[2]) bbox[2] = x; + if (y < bbox[1]) bbox[1] = y; + if (y > bbox[3]) bbox[3] = y; + } + function extendPoint(m, px, py) { + var x = px * m[0] + py * m[2] + m[4]; + var y = px * m[1] + py * m[3] + m[5]; + extend(x, y); + } + function extendRect(m, r) { + var x0 = r[0], y0 = r[1]; + var x1 = r[2], y1 = r[3]; + extendPoint(m, x0, y0); + extendPoint(m, x1, y0); + extendPoint(m, x0, y1); + extendPoint(m, x1, y1); + } + function PathBounder(ctm) { + return { + moveTo: function (x,y) { extendPoint(ctm, x, y) }, + lineTo: function (x,y) { extendPoint(ctm, x, y) }, + curveTo: function (x1,y1,x2,y2,x3,y3) { + extendPoint(ctm, x1, y1); + extendPoint(ctm, x2, y2); + extendPoint(ctm, x3, y3); + }, + }; + } + function TextBounder(ctm) { + return { + showGlyph: function (font,trm,gid,ucs,wmode,bidi) { + var bbox = [ 0, -0.2, font.advanceGlyph(gid, 0), 0.8 ]; + extendRect(Concat(trm, ctm), bbox); + }, + }; + } + return { + fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) { + path.walk(new PathBounder(ctm)); + }, + clipPath: function (path, evenOdd, ctm) { + path.walk(new PathBounder(ctm)); + }, + strokePath: function (path, stroke, ctm, colorSpace, color, alpha) { + path.walk(new PathBounder(ctm)); + }, + clipStrokePath: function (path, stroke, ctm) { + path.walk(new PathBounder(ctm)); + }, + fillText: function (text, ctm, colorSpace, color, alpha) { + text.walk(new TextBounder(ctm)); + }, + clipText: function (text, ctm) { + text.walk(new TextBounder(ctm)); + }, + strokeText: function (text, stroke, ctm, colorSpace, color, alpha) { + text.walk(new TextBounder(ctm)); + }, + clipStrokeText: function (text, stroke, ctm) { + text.walk(new TextBounder(ctm)); + }, + ignoreText: function (text, ctm) { + text.walk(new TextBounder(ctm)); + }, + fillShade: function (shade, ctm, alpha) { + var bbox = shade.bound(ctm); + extend(bbox[0], bbox[1]); + extend(bbox[2], bbox[3]); + }, + fillImage: function (image, ctm, alpha) { + extendRect(ctm, [0,0,1,1]); + }, + fillImageMask: function (image, ctm, colorSpace, color, alpha) { + extendRect(ctm, [0,0,1,1]); + }, + }; +} + +if (argv.length != 3) + print("usage: mutool run bbox-device.js document.pdf pageNumber") +else { + var doc = new Document(argv[1]); + var page = doc.loadPage(parseInt(argv[2])-1); + var bbox = [Infinity, Infinity, -Infinity, -Infinity]; + page.run(new BBoxDevice(bbox), Identity); + print("original bbox:", page.bound()); + print("computed bbox:", bbox.map(function (x) { return Math.round(x); })); +} diff --git a/source/tools/murun.c b/source/tools/murun.c index 6b2df126..3ed840fb 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -437,14 +437,18 @@ struct color { static fz_matrix ffi_tomatrix(js_State *J, int idx) { - fz_matrix matrix; - js_getindex(J, idx, 0); matrix.a = js_tonumber(J, -1); js_pop(J, 1); - js_getindex(J, idx, 1); matrix.b = js_tonumber(J, -1); js_pop(J, 1); - js_getindex(J, idx, 2); matrix.c = js_tonumber(J, -1); js_pop(J, 1); - js_getindex(J, idx, 3); matrix.d = js_tonumber(J, -1); js_pop(J, 1); - js_getindex(J, idx, 4); matrix.e = js_tonumber(J, -1); js_pop(J, 1); - js_getindex(J, idx, 5); matrix.f = js_tonumber(J, -1); js_pop(J, 1); - return matrix; + if (js_iscoercible(J, idx)) + { + fz_matrix matrix; + js_getindex(J, idx, 0); matrix.a = js_tonumber(J, -1); js_pop(J, 1); + js_getindex(J, idx, 1); matrix.b = js_tonumber(J, -1); js_pop(J, 1); + js_getindex(J, idx, 2); matrix.c = js_tonumber(J, -1); js_pop(J, 1); + js_getindex(J, idx, 3); matrix.d = js_tonumber(J, -1); js_pop(J, 1); + js_getindex(J, idx, 4); matrix.e = js_tonumber(J, -1); js_pop(J, 1); + js_getindex(J, idx, 5); matrix.f = js_tonumber(J, -1); js_pop(J, 1); + return matrix; + } + return fz_identity; } static void ffi_pushmatrix(js_State *J, fz_matrix matrix) @@ -2314,6 +2318,21 @@ static void ffi_Image_toPixmap(js_State *J) js_newuserdata(J, "fz_pixmap", pixmap, ffi_gc_fz_pixmap); } +static void ffi_Shade_bound(js_State *J) +{ + fz_context *ctx = js_getcontext(J); + fz_shade *shade = js_touserdata(J, 0, "fz_shade"); + fz_matrix ctm = ffi_tomatrix(J, 1); + fz_rect bounds; + + fz_try(ctx) + fz_bound_shade(ctx, shade, &ctm, &bounds); + fz_catch(ctx) + rethrow(J); + + ffi_pushrect(J, bounds); +} + static void ffi_new_Font(js_State *J) { fz_context *ctx = js_getcontext(J); @@ -4575,6 +4594,7 @@ int murun_main(int argc, char **argv) js_newobject(J); { + jsB_propfun(J, "Shade.bound", ffi_Shade_bound, 1); } js_setregistry(J, "fz_shade"); |