From ccaf716d6c3f20731aaed277653cf3b1be4e218b Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 16 Jun 2016 16:32:08 +0200 Subject: Add device space transform state to draw device. Allows us to remove the out parameter 'transform' from fz_begin_page. --- docs/mutool/run.html | 10 ++-- include/mupdf/fitz/device.h | 16 +++-- include/mupdf/fitz/writer.h | 4 +- platform/x11/pdfapp.c | 4 +- source/fitz/draw-device.c | 143 +++++++++++++++++++++++++------------------- source/fitz/font.c | 2 +- source/fitz/image.c | 4 +- source/fitz/output-cbz.c | 4 +- source/fitz/output-png.c | 4 +- source/fitz/util.c | 16 ++--- source/fitz/writer.c | 4 +- source/pdf/pdf-write.c | 3 +- source/tools/muconvert.c | 5 +- source/tools/mudraw.c | 4 +- source/tools/murun.c | 24 ++------ 15 files changed, 129 insertions(+), 118 deletions(-) diff --git a/docs/mutool/run.html b/docs/mutool/run.html index 3d8f2753..44eedec0 100644 --- a/docs/mutool/run.html +++ b/docs/mutool/run.html @@ -119,6 +119,9 @@ only store bytes. Matrices and Rectangles +

+All dimensions are in points unless otherwise specified. +

Matrices are simply 6-element arrays representing a 3-by-3 transformation matrix as @@ -183,6 +186,7 @@ MuPDF can open many document types (PDF, XPS, CBZ, EPUB, FB2 and a handful of im

Page#run(device, transform)
Calls device functions for all the contents on the page, using the specified transform matrix. The device can be one of the built-in devices or a JavaScript object with methods for the device calls. +The transform maps from user space points to device space pixels.
Page#toPixmap(transform, colorspace)
Render the page into a Pixmap, using the transform and colorspace.
Page#toDisplayList() @@ -251,7 +255,7 @@ DrawDevice The DrawDevice can be used to render to a Pixmap; either by running a Page with it or by calling its methods directly.
-
new DrawDevice(pixmap) +
new DrawDevice(transform, pixmap)
Create a device for drawing into a pixmap. The pixmap bounds used should match the transformed page bounds, or you can adjust them to only draw a part of the page.
@@ -481,10 +485,8 @@ Document writer objects are used to create new documents in several formats.
Create a new document writer to create a document with the specified format and output options. If format is null it is inferred from the filename suffix. The options argument is a comma separated list of flags and key-value pairs. See below for more details. -
DocumentWriter#beginPage(mediabox, transform) +
DocumentWriter#beginPage(mediabox)
Begin rendering a new page. Returns a Device that can be used to render the page graphics. -The transform argument must be an empty array which is set to the transform matrix to be -used with the device functions.
DocumentWriter#endPage(device)
Finish the page rendering. The argument must be the same device object that was returned by the beginPage method. diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h index 02f20ef6..99588075 100644 --- a/include/mupdf/fitz/device.h +++ b/include/mupdf/fitz/device.h @@ -338,8 +338,10 @@ enum draw device, see fz_clear_pixmap* for how to clear it prior to calling fz_new_draw_device. Free the device by calling fz_drop_device. + + transform: Transform from user space in points to device space in pixels. */ -fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest); +fz_device *fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest); /* fz_new_draw_device_with_bbox: Create a device to draw on a pixmap. @@ -350,12 +352,14 @@ fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest); calling fz_new_draw_device. Free the device by calling fz_drop_device. + transform: Transform from user space in points to device space in pixels. + clip: Bounding box to restrict any marking operations of the draw device. */ -fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, const fz_irect *clip); +fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip); -fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest); +fz_device *fz_new_draw_device_type3(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest); /* struct fz_draw_options: Options for creating a pixmap and draw device. @@ -382,10 +386,10 @@ fz_draw_options *fz_parse_draw_options(fz_context *ctx, fz_draw_options *options /* fz_new_draw_device_with_options: Create a new pixmap and draw device, using the specified options. - mediabox: An in parameter containing the size of the page. + options: Options to configure the draw device, and choose the resolution and colorspace. + mediabox: The bounds of the page in points. pixmap: An out parameter containing the newly created pixmap. - transform: An out parameter containing the transform to be used when running the page. */ -fz_device *fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, const fz_rect *mediabox, fz_matrix *transform, fz_pixmap **pixmap); +fz_device *fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *options, const fz_rect *mediabox, fz_pixmap **pixmap); #endif diff --git a/include/mupdf/fitz/writer.h b/include/mupdf/fitz/writer.h index 98b0824a..6f0f47be 100644 --- a/include/mupdf/fitz/writer.h +++ b/include/mupdf/fitz/writer.h @@ -11,7 +11,7 @@ typedef struct fz_document_writer_s fz_document_writer; struct fz_document_writer_s { - fz_device *(*begin_page)(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox, fz_matrix *ctm); + fz_device *(*begin_page)(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox); void (*end_page)(fz_context *ctx, fz_document_writer *wri, fz_device *dev); void (*close)(fz_context *ctx, fz_document_writer *wri); }; @@ -20,7 +20,7 @@ int fz_has_option(fz_context *ctx, const char *opts, const char *key, const char fz_document_writer *fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options); -fz_device *fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox, fz_matrix *ctm); +fz_device *fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox); void fz_end_page(fz_context *ctx, fz_document_writer *wri, fz_device *dev); void fz_close_document_writer(fz_context *ctx, fz_document_writer *wri); void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri); diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 55d5b5e3..2b650442 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -793,7 +793,7 @@ static void pdfapp_updatepage(pdfapp_t *app) fz_transform_rect(fz_bound_annot(app->ctx, annot, &bounds), &ctm); fz_rect_from_irect(&bounds, fz_round_rect(&ibounds, &bounds)); fz_clear_pixmap_rect_with_value(app->ctx, app->image, 255, &ibounds); - idev = fz_new_draw_device_with_bbox(app->ctx, app->image, &ibounds); + idev = fz_new_draw_device_with_bbox(app->ctx, NULL, app->image, &ibounds); pdfapp_runpage(app, idev, &ctm, &bounds, NULL); fz_drop_device(app->ctx, idev); } @@ -895,7 +895,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai fz_clear_pixmap_with_value(app->ctx, app->image, 255); if (app->page_list || app->annotations_list) { - idev = fz_new_draw_device(app->ctx, app->image); + idev = fz_new_draw_device(app->ctx, NULL, app->image); pdfapp_runpage(app, idev, &ctm, &bounds, &cookie); fz_drop_device(app->ctx, idev); } diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index bdfa1085..44d0bfaf 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -62,19 +62,19 @@ fz_parse_draw_options(fz_context *ctx, fz_draw_options *opts, const char *args) } fz_device * -fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, const fz_rect *mediabox, - fz_matrix *transform, fz_pixmap **pixmap) +fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, const fz_rect *mediabox, fz_pixmap **pixmap) { float zoom = opts->resolution / 72.0f; int w = opts->width; int h = opts->height; fz_rect bounds; fz_irect ibounds; + fz_matrix transform; fz_device *dev; - fz_pre_scale(fz_rotate(transform, opts->rotate), zoom, zoom); + fz_pre_scale(fz_rotate(&transform, opts->rotate), zoom, zoom); bounds = *mediabox; - fz_round_rect(&ibounds, fz_transform_rect(&bounds, transform)); + fz_round_rect(&ibounds, fz_transform_rect(&bounds, &transform)); /* If width or height are set, we may need to adjust the transform */ if (w || h) @@ -98,9 +98,9 @@ fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, co } if (scalex != 1 || scaley != 1) { - fz_pre_scale(transform, scalex, scaley); + fz_pre_scale(&transform, scalex, scaley); bounds = *mediabox; - fz_round_rect(&ibounds, fz_transform_rect(&bounds, transform)); + fz_round_rect(&ibounds, fz_transform_rect(&bounds, &transform)); } } @@ -112,7 +112,7 @@ fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *opts, co else fz_clear_pixmap_with_value(ctx, *pixmap, 255); - dev = fz_new_draw_device(ctx, *pixmap); + dev = fz_new_draw_device(ctx, &transform, *pixmap); } fz_catch(ctx) { @@ -160,6 +160,7 @@ struct fz_draw_state_s { struct fz_draw_device_s { fz_device super; + fz_matrix transform; fz_gel *gel; int flags; int top; @@ -386,14 +387,22 @@ static void fz_knockout_end(fz_context *ctx, fz_draw_device *dev) #endif } +static inline fz_matrix concat(const fz_matrix *one, const fz_matrix *two) +{ + fz_matrix ctm; + fz_concat(&ctm, one, two); + return ctm; +} + static void -fz_draw_fill_path(fz_context *ctx, fz_device *devp, const fz_path *path, int even_odd, const fz_matrix *ctm, +fz_draw_fill_path(fz_context *ctx, fz_device *devp, const fz_path *path, int even_odd, const fz_matrix *in_ctm, fz_colorspace *colorspace, const float *color, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_gel *gel = dev->gel; - float expansion = fz_matrix_expansion(ctm); + float expansion = fz_matrix_expansion(&ctm); float flatness = 0.3f / expansion; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; @@ -406,7 +415,7 @@ fz_draw_fill_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve flatness = 0.001f; fz_reset_gel(ctx, gel, &state->scissor); - fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_flatten_fill_path(ctx, gel, path, &ctm, flatness); fz_sort_gel(ctx, gel); fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); @@ -427,7 +436,7 @@ fz_draw_fill_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve if (state->shape) { fz_reset_gel(ctx, gel, &state->scissor); - fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_flatten_fill_path(ctx, gel, path, &ctm, flatness); fz_sort_gel(ctx, gel); colorbv[0] = alpha * 255; @@ -439,13 +448,14 @@ fz_draw_fill_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve } static void -fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, +fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *in_ctm, fz_colorspace *colorspace, const float *color, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_gel *gel = dev->gel; - float expansion = fz_matrix_expansion(ctm); + float expansion = fz_matrix_expansion(&ctm); float flatness = 0.3f / expansion; float linewidth = stroke->linewidth; unsigned char colorbv[FZ_MAX_COLORS + 1]; @@ -463,9 +473,9 @@ fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); else - fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_stroke_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); fz_sort_gel(ctx, gel); fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); @@ -494,9 +504,9 @@ fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const { fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); else - fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_stroke_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); fz_sort_gel(ctx, gel); colorbv[0] = 255; @@ -515,12 +525,13 @@ fz_draw_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const } static void -fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int even_odd, const fz_matrix *ctm, const fz_rect *scissor) +fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int even_odd, const fz_matrix *in_ctm, const fz_rect *scissor) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_gel *gel = dev->gel; - float expansion = fz_matrix_expansion(ctm); + float expansion = fz_matrix_expansion(&ctm); float flatness = 0.3f / expansion; fz_irect bbox; fz_draw_state *state = &dev->stack[dev->top]; @@ -530,7 +541,7 @@ fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve flatness = 0.001f; fz_reset_gel(ctx, gel, &state->scissor); - fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_flatten_fill_path(ctx, gel, path, &ctm, flatness); fz_sort_gel(ctx, gel); state = push_stack(ctx, dev); @@ -588,12 +599,13 @@ fz_draw_clip_path(fz_context *ctx, fz_device *devp, const fz_path *path, int eve } static void -fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor) +fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *in_ctm, const fz_rect *scissor) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_gel *gel = dev->gel; - float expansion = fz_matrix_expansion(ctm); + float expansion = fz_matrix_expansion(&ctm); float flatness = 0.3f / expansion; float linewidth = stroke->linewidth; fz_irect bbox; @@ -608,9 +620,9 @@ fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, const fz_path *path, fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); else - fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_stroke_path(ctx, gel, path, stroke, &ctm, flatness, linewidth); fz_sort_gel(ctx, gel); state = push_stack(ctx, dev); @@ -728,10 +740,11 @@ draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_glyph *glyph, } static void -fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *ctm, +fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *in_ctm, fz_colorspace *colorspace, const float *color, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; unsigned char colorbv[FZ_MAX_COLORS + 1]; @@ -766,7 +779,7 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f tm.e = span->items[i].x; tm.f = span->items[i].y; - fz_concat(&trm, &tm, ctm); + fz_concat(&trm, &tm, &ctm); glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state->dest->alpha); if (glyph) @@ -794,7 +807,7 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm); if (path) { - fz_draw_fill_path(ctx, devp, path, 0, ctm, colorspace, color, alpha); + fz_draw_fill_path(ctx, devp, path, 0, &ctm, colorspace, color, alpha); fz_drop_path(ctx, path); } else @@ -811,10 +824,11 @@ fz_draw_fill_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f static void fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_stroke_state *stroke, - const fz_matrix *ctm, fz_colorspace *colorspace, + const fz_matrix *in_ctm, fz_colorspace *colorspace, const float *color, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; unsigned char colorbv[FZ_MAX_COLORS + 1]; @@ -847,9 +861,9 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const tm.e = span->items[i].x; tm.f = span->items[i].y; - fz_concat(&trm, &tm, ctm); + fz_concat(&trm, &tm, &ctm); - glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, ctm, stroke, &state->scissor); + glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor); if (glyph) { int x = (int)trm.e; @@ -864,7 +878,7 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_path *path = fz_outline_glyph(ctx, span->font, gid, &tm); if (path) { - fz_draw_stroke_path(ctx, devp, path, stroke, ctm, colorspace, color, alpha); + fz_draw_stroke_path(ctx, devp, path, stroke, &ctm, colorspace, color, alpha); fz_drop_path(ctx, path); } else @@ -880,9 +894,10 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const } static void -fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor) +fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *in_ctm, const fz_rect *scissor) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_irect bbox; fz_pixmap *mask, *dest, *shape; fz_matrix tm, trm; @@ -898,7 +913,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f model = state->dest->colorspace; /* make the mask the exact size needed */ - fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, NULL, ctm, &rect)); + fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, NULL, &ctm, &rect)); fz_intersect_irect(&bbox, &state->scissor); if (scissor) { @@ -950,7 +965,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f tm.e = span->items[i].x; tm.f = span->items[i].y; - fz_concat(&trm, &tm, ctm); + fz_concat(&trm, &tm, &ctm); glyph = fz_render_glyph(ctx, span->font, gid, &trm, model, &state->scissor, state[1].dest->alpha); if (glyph) @@ -975,7 +990,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f state[1].mask = NULL; fz_try(ctx) { - fz_draw_fill_path(ctx, devp, path, 0, ctm, fz_device_gray(ctx), &white, 1); + fz_draw_fill_path(ctx, devp, path, 0, &ctm, fz_device_gray(ctx), &white, 1); } fz_always(ctx) { @@ -1005,9 +1020,10 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f } static void -fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor) +fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *in_ctm, const fz_rect *scissor) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_irect bbox; fz_pixmap *mask, *dest, *shape; fz_matrix tm, trm; @@ -1020,7 +1036,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, STACK_PUSHED("clip stroke text"); /* make the mask the exact size needed */ - fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, stroke, ctm, &rect)); + fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, stroke, &ctm, &rect)); fz_intersect_irect(&bbox, &state->scissor); if (scissor) { @@ -1069,9 +1085,9 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, tm.e = span->items[i].x; tm.f = span->items[i].y; - fz_concat(&trm, &tm, ctm); + fz_concat(&trm, &tm, &ctm); - glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, ctm, stroke, &state->scissor); + glyph = fz_render_stroked_glyph(ctx, span->font, gid, &trm, &ctm, stroke, &state->scissor); if (glyph) { int x = (int)trm.e; @@ -1095,7 +1111,7 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, state[0].mask = NULL; fz_try(ctx) { - fz_draw_stroke_path(ctx, devp, path, stroke, ctm, fz_device_gray(ctx), &white, 1); + fz_draw_stroke_path(ctx, devp, path, stroke, &ctm, fz_device_gray(ctx), &white, 1); } fz_always(ctx) { @@ -1129,9 +1145,10 @@ fz_draw_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, const } static void -fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float alpha) +fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_matrix *in_ctm, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_rect bounds; fz_irect bbox, scissor; fz_pixmap *dest, *shape; @@ -1140,7 +1157,7 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_bound_shade(ctx, shade, ctm, &bounds); + fz_bound_shade(ctx, shade, &ctm, &bounds); scissor = state->scissor; fz_intersect_irect(fz_irect_from_rect(&bbox, &bounds), &scissor); @@ -1200,7 +1217,7 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m } } - fz_paint_shade(ctx, shade, ctm, dest, &bbox); + fz_paint_shade(ctx, shade, &ctm, dest, &bbox); if (shape) fz_clear_pixmap_rect_with_value(ctx, shape, 255, &bbox); @@ -1292,9 +1309,10 @@ fz_default_image_scale(void *arg, int dst_w, int dst_h, int src_w, int src_h) } static void -fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, float alpha) +fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *in_ctm, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix local_ctm = concat(in_ctm, &dev->transform); fz_pixmap *converted = NULL; fz_pixmap *scaled = NULL; fz_pixmap *pixmap; @@ -1304,7 +1322,6 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_irect clip; - fz_matrix local_ctm = *ctm; fz_matrix inverse; fz_irect src_area; @@ -1428,10 +1445,11 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m } static void -fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, +fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *in_ctm, fz_colorspace *colorspace, const float *color, float alpha) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix local_ctm = concat(in_ctm, &dev->transform); unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; @@ -1442,7 +1460,6 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_irect clip; - fz_matrix local_ctm = *ctm; fz_matrix inverse; fz_irect src_area; @@ -1536,9 +1553,10 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const } static void -fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, const fz_rect *scissor) +fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *in_ctm, const fz_rect *scissor) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix local_ctm = concat(in_ctm, &dev->transform); fz_irect bbox; fz_pixmap *mask = NULL; fz_pixmap *dest = NULL; @@ -1550,7 +1568,6 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_draw_state *state = push_stack(ctx, dev); fz_colorspace *model = state->dest->colorspace; fz_irect clip; - fz_matrix local_ctm = *ctm; fz_rect urect; STACK_PUSHED("clip image mask"); @@ -2067,9 +2084,10 @@ fz_tile_size(fz_context *ctx, tile_record *tile) } static int -fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id) +fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *in_ctm, int id) { fz_draw_device *dev = (fz_draw_device*)devp; + fz_matrix ctm = concat(in_ctm, &dev->transform); fz_pixmap *dest = NULL; fz_pixmap *shape; fz_irect bbox; @@ -2085,7 +2103,7 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const state = push_stack(ctx, dev); STACK_PUSHED("tile"); - fz_irect_from_rect(&bbox, fz_transform_rect(&local_view, ctm)); + fz_irect_from_rect(&bbox, fz_transform_rect(&local_view, &ctm)); /* We should never have a bbox that entirely covers our destination. * If we do, then the check for only 1 tile being visible above has * failed. Actually, this *can* fail due to the round_rect, at extreme @@ -2099,10 +2117,10 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const { tile_key tk; tile_record *tile; - tk.ctm[0] = ctm->a; - tk.ctm[1] = ctm->b; - tk.ctm[2] = ctm->c; - tk.ctm[3] = ctm->d; + tk.ctm[0] = ctm.a; + tk.ctm[1] = ctm.b; + tk.ctm[2] = ctm.c; + tk.ctm[3] = ctm.d; tk.id = id; tile = fz_find_item(ctx, fz_drop_tile_record_imp, &tk, &fz_tile_store_type); @@ -2115,7 +2133,7 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const state[1].ystep = ystep; state[1].id = id; fz_irect_from_rect(&state[1].area, area); - state[1].ctm = *ctm; + state[1].ctm = ctm; #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Tile begin (cached)\n"); #endif @@ -2142,7 +2160,7 @@ fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const state[1].ystep = ystep; state[1].id = id; fz_irect_from_rect(&state[1].area, area); - state[1].ctm = *ctm; + state[1].ctm = ctm; #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Tile begin\n"); #endif @@ -2354,7 +2372,7 @@ fz_draw_render_flags(fz_context *ctx, fz_device *devp, int set, int clear) } fz_device * -fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) +fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest) { fz_draw_device *dev = fz_new_device(ctx, sizeof *dev); @@ -2388,6 +2406,7 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) dev->super.render_flags = fz_draw_render_flags; + dev->transform = transform ? *transform : fz_identity; dev->flags = 0; dev->top = 0; dev->stack = &dev->init_stack[0]; @@ -2417,9 +2436,9 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) } fz_device * -fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, const fz_irect *clip) +fz_new_draw_device_with_bbox(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest, const fz_irect *clip) { - fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, dest); + fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, transform, dest); if (clip->x0 > dev->stack[0].scissor.x0) dev->stack[0].scissor.x0 = clip->x0; @@ -2434,9 +2453,9 @@ fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, const fz_irect *c } fz_device * -fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest) +fz_new_draw_device_type3(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest) { - fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, dest); + fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, transform, dest); dev->flags |= FZ_DRAWDEV_FLAGS_TYPE3; return (fz_device*)dev; } diff --git a/source/fitz/font.c b/source/fitz/font.c index cebccf03..d534212c 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -1248,7 +1248,7 @@ fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matr glyph = fz_new_pixmap_with_bbox(ctx, model, &bbox, 1); fz_clear_pixmap(ctx, glyph); - dev = fz_new_draw_device_type3(ctx, glyph); + dev = fz_new_draw_device_type3(ctx, NULL, glyph); fz_try(ctx) { fz_run_t3_glyph(ctx, font, gid, trm, dev); diff --git a/source/fitz/image.c b/source/fitz/image.c index 6f840c38..a027b902 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -1057,8 +1057,8 @@ display_list_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subar fz_pre_scale(&ctm, w, h); fz_clear_pixmap(ctx, pix); /* clear to transparent */ - dev = fz_new_draw_device(ctx, pix); - fz_run_display_list(ctx, image->list, dev, &ctm, NULL, NULL); + dev = fz_new_draw_device(ctx, &ctm, pix); + fz_run_display_list(ctx, image->list, dev, &fz_identity, NULL, NULL); fz_drop_device(ctx, dev); /* Never do more subsampling, cos we've already given them the right size */ diff --git a/source/fitz/output-cbz.c b/source/fitz/output-cbz.c index ba7ca196..80ef287c 100644 --- a/source/fitz/output-cbz.c +++ b/source/fitz/output-cbz.c @@ -16,10 +16,10 @@ struct fz_cbz_writer_s const char *fz_cbz_write_options_usage = ""; static fz_device * -cbz_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox, fz_matrix *transform) +cbz_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) { fz_cbz_writer *wri = (fz_cbz_writer*)wri_; - return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, transform, &wri->pixmap); + return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, &wri->pixmap); } static void diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c index 00eaeee8..5bd0737e 100644 --- a/source/fitz/output-png.c +++ b/source/fitz/output-png.c @@ -312,10 +312,10 @@ struct fz_png_writer_s const char *fz_png_write_options_usage = ""; static fz_device * -png_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox, fz_matrix *transform) +png_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) { fz_png_writer *wri = (fz_png_writer*)wri_; - return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, transform, &wri->pixmap); + return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, &wri->pixmap); } static void diff --git a/source/fitz/util.c b/source/fitz/util.c index 01e52e91..425d2181 100644 --- a/source/fitz/util.c +++ b/source/fitz/util.c @@ -62,8 +62,8 @@ fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, const fz fz_try(ctx) { - dev = fz_new_draw_device(ctx, pix); - fz_run_display_list(ctx, list, dev, ctm, NULL, NULL); + dev = fz_new_draw_device(ctx, ctm, pix); + fz_run_display_list(ctx, list, dev, &fz_identity, NULL, NULL); } fz_always(ctx) { @@ -95,8 +95,8 @@ fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, const fz_matrix fz_try(ctx) { - dev = fz_new_draw_device(ctx, pix); - fz_run_page_contents(ctx, page, dev, ctm, NULL); + dev = fz_new_draw_device(ctx, ctm, pix); + fz_run_page_contents(ctx, page, dev, &fz_identity, NULL); } fz_always(ctx) { @@ -128,8 +128,8 @@ fz_new_pixmap_from_annot(fz_context *ctx, fz_annot *annot, const fz_matrix *ctm, fz_try(ctx) { - dev = fz_new_draw_device(ctx, pix); - fz_run_annot(ctx, annot, dev, ctm, NULL); + dev = fz_new_draw_device(ctx, ctm, pix); + fz_run_annot(ctx, annot, dev, &fz_identity, NULL); } fz_always(ctx) { @@ -161,8 +161,8 @@ fz_new_pixmap_from_page(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz fz_try(ctx) { - dev = fz_new_draw_device(ctx, pix); - fz_run_page(ctx, page, dev, ctm, NULL); + dev = fz_new_draw_device(ctx, ctm, pix); + fz_run_page(ctx, page, dev, &fz_identity, NULL); } fz_always(ctx) { diff --git a/source/fitz/writer.c b/source/fitz/writer.c index 5c82b1d7..556e01a8 100644 --- a/source/fitz/writer.c +++ b/source/fitz/writer.c @@ -81,9 +81,9 @@ fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri) } fz_device * -fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox, fz_matrix *ctm) +fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox) { - return wri->begin_page(ctx, wri, mediabox, ctm); + return wri->begin_page(ctx, wri, mediabox); } void diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index 8d0f6f58..1dce7235 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -3204,11 +3204,10 @@ struct pdf_writer_s }; static fz_device * -pdf_writer_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox, fz_matrix *ctm) +pdf_writer_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) { pdf_writer *wri = (pdf_writer*)wri_; wri->mediabox = *mediabox; - *ctm = fz_identity; return pdf_page_write(ctx, wri->pdf, &wri->mediabox, &wri->resources, &wri->contents); } diff --git a/source/tools/muconvert.c b/source/tools/muconvert.c index 3fd97cfd..95f01c4a 100644 --- a/source/tools/muconvert.c +++ b/source/tools/muconvert.c @@ -54,15 +54,14 @@ static void usage(void) static void runpage(int number) { - fz_matrix ctm; fz_rect mediabox; fz_page *page; fz_device *dev; page = fz_load_page(ctx, doc, number - 1); fz_bound_page(ctx, page, &mediabox); - dev = fz_begin_page(ctx, out, &mediabox, &ctm); - fz_run_page(ctx, page, dev, &ctm, NULL); + dev = fz_begin_page(ctx, out, &mediabox); + fz_run_page(ctx, page, dev, &fz_identity, NULL); fz_end_page(ctx, out, dev); fz_drop_page(ctx, page); } diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 6c27fc28..20a6524d 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -545,13 +545,13 @@ static void drawband(fz_context *ctx, fz_page *page, fz_display_list *list, cons else fz_clear_pixmap_with_value(ctx, pix, 255); - dev = fz_new_draw_device(ctx, pix); + dev = fz_new_draw_device(ctx, ctm, pix); if (lowmemory) fz_enable_device_hints(ctx, dev, FZ_NO_CACHE); if (alphabits_graphics == 0) fz_enable_device_hints(ctx, dev, FZ_DONT_INTERPOLATE_IMAGES); if (list) - fz_run_display_list(ctx, list, dev, ctm, tbounds, cookie); + fz_run_display_list(ctx, list, dev, &fz_identity, tbounds, cookie); else fz_run_page(ctx, page, dev, ctm, cookie); fz_drop_device(ctx, dev); diff --git a/source/tools/murun.c b/source/tools/murun.c index 6d14f99f..e9d66742 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -306,16 +306,6 @@ static void ffi_pushmatrix(js_State *J, fz_matrix matrix) js_pushnumber(J, matrix.f); js_setindex(J, -2, 5); } -static void ffi_setmatrix(js_State *J, int idx, fz_matrix matrix) -{ - js_pushnumber(J, matrix.a); js_setindex(J, idx, 0); - js_pushnumber(J, matrix.b); js_setindex(J, idx, 1); - js_pushnumber(J, matrix.c); js_setindex(J, idx, 2); - js_pushnumber(J, matrix.d); js_setindex(J, idx, 3); - js_pushnumber(J, matrix.e); js_setindex(J, idx, 4); - js_pushnumber(J, matrix.f); js_setindex(J, idx, 5); -} - static fz_rect ffi_torect(js_State *J, int idx) { fz_rect rect; @@ -2117,11 +2107,12 @@ static void ffi_new_DisplayListDevice(js_State *J) static void ffi_new_DrawDevice(js_State *J) { fz_context *ctx = js_getcontext(J); - fz_pixmap *pixmap = js_touserdata(J, 1, "fz_pixmap"); + fz_matrix transform = ffi_tomatrix(J, 1); + fz_pixmap *pixmap = js_touserdata(J, 2, "fz_pixmap"); fz_device *device; fz_try(ctx) - device = fz_new_draw_device(ctx, pixmap); + device = fz_new_draw_device(ctx, &transform, pixmap); fz_catch(ctx) rethrow(J); @@ -2151,16 +2142,13 @@ static void ffi_DocumentWriter_beginPage(js_State *J) fz_context *ctx = js_getcontext(J); fz_document_writer *wri = js_touserdata(J, 0, "fz_document_writer"); fz_rect mediabox = ffi_torect(J, 1); - fz_matrix ctm = fz_identity; fz_device *device; fz_try(ctx) - device = fz_begin_page(ctx, wri, &mediabox, &ctm); + device = fz_begin_page(ctx, wri, &mediabox); fz_catch(ctx) rethrow(J); - ffi_setmatrix(J, 2, ctm); - js_getregistry(J, "fz_device"); js_newuserdata(J, "fz_device", fz_keep_device(ctx, device), ffi_gc_fz_device); } @@ -3253,7 +3241,7 @@ int murun_main(int argc, char **argv) js_newobject(J); { - jsB_propfun(J, "DocumentWriter.beginPage", ffi_DocumentWriter_beginPage, 2); + jsB_propfun(J, "DocumentWriter.beginPage", ffi_DocumentWriter_beginPage, 1); jsB_propfun(J, "DocumentWriter.endPage", ffi_DocumentWriter_endPage, 1); jsB_propfun(J, "DocumentWriter.close", ffi_DocumentWriter_close, 1); } @@ -3335,7 +3323,7 @@ int murun_main(int argc, char **argv) jsB_propcon(J, "fz_text", "Text", ffi_new_Text, 0); jsB_propcon(J, "fz_path", "Path", ffi_new_Path, 0); jsB_propcon(J, "fz_display_list", "DisplayList", ffi_new_DisplayList, 0); - jsB_propcon(J, "fz_device", "DrawDevice", ffi_new_DrawDevice, 1); + jsB_propcon(J, "fz_device", "DrawDevice", ffi_new_DrawDevice, 2); jsB_propcon(J, "fz_device", "DisplayListDevice", ffi_new_DisplayListDevice, 1); jsB_propcon(J, "fz_document_writer", "DocumentWriter", ffi_new_DocumentWriter, 3); -- cgit v1.2.3