summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/examples/bbox-device.js91
-rw-r--r--source/tools/murun.c36
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");