diff options
author | Robin Watts <robin.watts@artifex.com> | 2013-01-25 19:24:49 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-02-06 19:24:12 +0000 |
commit | d3aa37962470253083714b5092a1ba759f674d47 (patch) | |
tree | ec60a0857cd3d44d3db5bc0c95aa69335b6b2d47 /draw/draw_device.c | |
parent | c42dac496e0994c4253eb50ce67ceaec864ed379 (diff) | |
download | mupdf-d3aa37962470253083714b5092a1ba759f674d47.tar.xz |
Change to pass structures by reference rather than value.
This is faster on ARM in particular. The primary changes involve
fz_matrix, fz_rect and fz_bbox.
Rather than passing 'fz_rect r' into a function, we now consistently
pass 'const fz_rect *r'. Where a rect is passed in and modified, we
miss the 'const' off. Where possible, we return the pointer to the
modified structure to allow 'chaining' of expressions.
The basic upshot of this work is that we do far fewer copies of
rectangle/matrix structures, and all the copies we do are explicit.
This has opened the way to other optimisations, also performed in
this commit.
Rather than using expressions like:
fz_concat(fz_scale(sx, sy), fz_translate(tx, ty))
we now have fz_pre_{scale,translate,rotate} functions. These
can be implemented much more efficiently than doing the fully
fledged matrix multiplication that fz_concat requires.
We add fz_rect_{min,max} functions to return pointers to the
min/max points of a rect. These can be used to in transformations
to directly manipulate values.
With a little casting in the path transformation code we can avoid
more needless copying.
We rename fz_widget_bbox to the more consistent fz_bound_widget.
Diffstat (limited to 'draw/draw_device.c')
-rw-r--r-- | draw/draw_device.c | 353 |
1 files changed, 188 insertions, 165 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c index e631e472..21fe71db 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -137,9 +137,9 @@ fz_knockout_begin(fz_draw_device *dev) state = push_stack(dev); - bbox = fz_pixmap_bbox(dev->ctx, state->dest); - bbox = fz_intersect_bbox(bbox, state->scissor); - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox); + fz_pixmap_bbox(dev->ctx, state->dest, &bbox); + fz_intersect_bbox(&bbox, &state->scissor); + dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); if (isolated) { @@ -157,7 +157,7 @@ fz_knockout_begin(fz_draw_device *dev) break; } if (prev) - fz_copy_pixmap_rect(ctx, dest, prev, bbox); + fz_copy_pixmap_rect(ctx, dest, prev, &bbox); else fz_clear_pixmap(ctx, dest); } @@ -170,7 +170,7 @@ fz_knockout_begin(fz_draw_device *dev) } else { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } #ifdef DUMP_GROUP_BLENDS @@ -238,7 +238,7 @@ static void fz_knockout_end(fz_draw_device *dev) } static void -fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm, +fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = devp->user; @@ -254,14 +254,13 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm, if (model == NULL) model = fz_device_gray; - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); fz_flatten_fill_path(dev->gel, path, ctm, flatness); fz_sort_gel(dev->gel); - bbox = fz_bound_gel(dev->gel); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_intersect_bbox(fz_bound_gel(dev->gel, &bbox), &state->scissor); - if (fz_is_empty_rect(bbox)) + if (fz_is_empty_rect(&bbox)) return; if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -272,15 +271,15 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm, colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scan_convert(dev->gel, even_odd, bbox, state->dest, colorbv); + fz_scan_convert(dev->gel, even_odd, &bbox, state->dest, colorbv); if (state->shape) { - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); fz_flatten_fill_path(dev->gel, path, ctm, flatness); fz_sort_gel(dev->gel); colorbv[0] = alpha * 255; - fz_scan_convert(dev->gel, even_odd, bbox, state->shape, colorbv); + fz_scan_convert(dev->gel, even_odd, &bbox, state->shape, colorbv); } if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -288,7 +287,7 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm, } static void -fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, +fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = devp->user; @@ -308,17 +307,16 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_ if (linewidth * expansion < 0.1f) linewidth = 1 / expansion; - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); if (stroke->dash_len > 0) fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); else fz_flatten_stroke_path(dev->gel, path, stroke, ctm, flatness, linewidth); fz_sort_gel(dev->gel); - bbox = fz_bound_gel(dev->gel); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_intersect_bbox(fz_bound_gel(dev->gel, &bbox), &state->scissor); - if (fz_is_empty_rect(bbox)) + if (fz_is_empty_rect(&bbox)) return; if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -329,10 +327,10 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_ colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scan_convert(dev->gel, 0, bbox, state->dest, colorbv); + fz_scan_convert(dev->gel, 0, &bbox, state->dest, colorbv); if (state->shape) { - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); if (stroke->dash_len > 0) fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); else @@ -340,7 +338,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_ fz_sort_gel(dev->gel); colorbv[0] = 255; - fz_scan_convert(dev->gel, 0, bbox, state->shape, colorbv); + fz_scan_convert(dev->gel, 0, &bbox, state->shape, colorbv); } if (state->blendmode & FZ_BLEND_KNOCKOUT) @@ -348,7 +346,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_ } static void -fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz_matrix ctm) +fz_draw_clip_path(fz_device *devp, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm) { fz_draw_device *dev = devp->user; float expansion = fz_matrix_expansion(ctm); @@ -358,18 +356,21 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz fz_colorspace *model; fz_context *ctx = dev->ctx; - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); fz_flatten_fill_path(dev->gel, path, ctm, flatness); fz_sort_gel(dev->gel); state = push_stack(dev); model = state->dest->colorspace; - bbox = fz_bound_gel(dev->gel); - bbox = fz_intersect_bbox(bbox, state->scissor); - bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(rect)); + fz_intersect_bbox(fz_bound_gel(dev->gel, &bbox), &state->scissor); + if (rect) + { + fz_bbox bbox2; + fz_intersect_bbox(&bbox, fz_bbox_from_rect(&bbox2, rect)); + } - if (fz_is_empty_rect(bbox) || fz_is_rect_gel(dev->gel)) + if (fz_is_empty_rect(&bbox) || fz_is_rect_gel(dev->gel)) { state[1].scissor = bbox; state[1].mask = NULL; @@ -381,17 +382,17 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, state[1].mask); - state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(dev->ctx, state[1].dest); if (state[1].shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, state[1].shape); } - fz_scan_convert(dev->gel, even_odd, bbox, state[1].mask, NULL); + fz_scan_convert(dev->gel, even_odd, &bbox, state[1].mask, NULL); state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; @@ -406,7 +407,7 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz } static void -fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke_state *stroke, fz_matrix ctm) +fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm) { fz_draw_device *dev = devp->user; float expansion = fz_matrix_expansion(ctm); @@ -420,7 +421,7 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke if (linewidth * expansion < 0.1f) linewidth = 1 / expansion; - fz_reset_gel(dev->gel, state->scissor); + fz_reset_gel(dev->gel, &state->scissor); if (stroke->dash_len > 0) fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); else @@ -430,24 +431,27 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke state = push_stack(dev); model = state->dest->colorspace; - bbox = fz_bound_gel(dev->gel); - bbox = fz_intersect_bbox(bbox, state->scissor); - bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(rect)); + fz_intersect_bbox(fz_bound_gel(dev->gel, &bbox), &state->scissor); + if (rect) + { + fz_bbox bbox2; + fz_intersect_bbox(&bbox, fz_bbox_from_rect(&bbox2, rect)); + } fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, state[1].mask); - state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(dev->ctx, state[1].dest); if (state->shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, state[1].shape); } - if (!fz_is_empty_rect(bbox)) - fz_scan_convert(dev->gel, 0, bbox, state[1].mask, NULL); + if (!fz_is_empty_rect(&bbox)) + fz_scan_convert(dev->gel, 0, &bbox, state[1].mask, NULL); state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; @@ -463,15 +467,15 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke static void draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk, - int xorig, int yorig, fz_bbox scissor) + int xorig, int yorig, const fz_bbox *scissor) { unsigned char *dp, *mp; fz_bbox bbox; int x, y, w, h; - bbox = fz_pixmap_bbox_no_ctx(msk); - bbox = fz_translate_bbox(bbox, xorig, yorig); - bbox = fz_intersect_bbox(bbox, scissor); /* scissor < dst */ + fz_pixmap_bbox_no_ctx(msk, &bbox); + fz_translate_bbox(&bbox, xorig, yorig); + fz_intersect_bbox(&bbox, scissor); /* scissor < dst */ x = bbox.x0; y = bbox.y0; w = bbox.x1 - bbox.x0; @@ -494,7 +498,7 @@ draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk, } static void -fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, +fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = devp->user; @@ -527,7 +531,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, tm.e = text->items[i].x; tm.f = text->items[i].y; - trm = fz_concat(tm, ctm); + fz_concat(&trm, &tm, ctm); x = floorf(trm.e); y = floorf(trm.f); @@ -538,28 +542,28 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, scissor.x0 -= x; scissor.x1 -= x; scissor.y0 -= y; scissor.y1 -= y; - glyph = fz_render_glyph(dev->ctx, text->font, gid, trunc_trm, model, scissor); + glyph = fz_render_glyph(dev->ctx, text->font, gid, &trunc_trm, model, scissor); if (glyph) { if (glyph->n == 1) { - draw_glyph(colorbv, state->dest, glyph, x, y, state->scissor); + draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor); if (state->shape) - draw_glyph(&shapebv, state->shape, glyph, x, y, state->scissor); + draw_glyph(&shapebv, state->shape, glyph, x, y, &state->scissor); } else { - fz_matrix ctm = {glyph->w, 0.0, 0.0, glyph->h, x + glyph->x, y + glyph->y}; - fz_paint_image(state->dest, state->scissor, state->shape, glyph, ctm, alpha * 255); + fz_matrix tm = {glyph->w, 0.0, 0.0, glyph->h, x + glyph->x, y + glyph->y}; + fz_paint_image(state->dest, &state->scissor, state->shape, glyph, &tm, alpha * 255); } fz_drop_pixmap(dev->ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm); + fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &trm); if (path) { - fz_draw_fill_path(devp, path, 0, fz_identity, colorspace, color, alpha); + fz_draw_fill_path(devp, path, 0, &fz_identity, colorspace, color, alpha); fz_free_path(dev->ctx, path); } else @@ -574,8 +578,9 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, } static void -fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, - fz_colorspace *colorspace, float *color, float alpha) +fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, + const fz_matrix *ctm, fz_colorspace *colorspace, + float *color, float alpha) { fz_draw_device *dev = devp->user; unsigned char colorbv[FZ_MAX_COLORS + 1]; @@ -605,7 +610,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_ tm.e = text->items[i].x; tm.f = text->items[i].y; - trm = fz_concat(tm, ctm); + fz_concat(&trm, &tm, ctm); x = floorf(trm.e); y = floorf(trm.f); @@ -616,20 +621,20 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_ scissor.x0 -= x; scissor.x1 -= x; scissor.y0 -= y; scissor.y1 -= y; - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trunc_trm, ctm, stroke, scissor); + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trunc_trm, ctm, stroke, scissor); if (glyph) { - draw_glyph(colorbv, state->dest, glyph, x, y, state->scissor); + draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor); if (state->shape) - draw_glyph(colorbv, state->shape, glyph, x, y, state->scissor); + draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor); fz_drop_pixmap(dev->ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm); + fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &trm); if (path) { - fz_draw_stroke_path(devp, path, stroke, fz_identity, colorspace, color, alpha); + fz_draw_stroke_path(devp, path, stroke, &fz_identity, colorspace, color, alpha); fz_free_path(dev->ctx, path); } else @@ -644,7 +649,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_ } static void -fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) +fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accumulate) { fz_draw_device *dev = devp->user; fz_context *ctx = dev->ctx; @@ -666,8 +671,10 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) if (accumulate == 0) { /* make the mask the exact size needed */ - bbox = fz_bbox_from_rect(fz_bound_text(dev->ctx, text, ctm)); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_rect rect; + + fz_bbox_from_rect(&bbox, fz_bound_text(dev->ctx, text, ctm, &rect)); + fz_intersect_bbox(&bbox, &state->scissor); } else { @@ -679,13 +686,13 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) { if (accumulate == 0 || accumulate == 1) { - mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, mask); - dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(dev->ctx, dest); if (state->shape) { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } else @@ -706,7 +713,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) dev->top--; } - if (!fz_is_empty_rect(bbox) && mask) + if (!fz_is_empty_rect(&bbox) && mask) { tm = text->trm; @@ -718,7 +725,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) tm.e = text->items[i].x; tm.f = text->items[i].y; - trm = fz_concat(tm, ctm); + fz_concat(&trm, &tm, ctm); x = floorf(trm.e); y = floorf(trm.f); @@ -726,17 +733,17 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_glyph(dev->ctx, text->font, gid, trunc_trm, model, bbox); + glyph = fz_render_glyph(dev->ctx, text->font, gid, &trunc_trm, model, bbox); if (glyph) { - draw_glyph(NULL, mask, glyph, x, y, bbox); + draw_glyph(NULL, mask, glyph, x, y, &bbox); if (state[1].shape) - draw_glyph(NULL, state[1].shape, glyph, x, y, bbox); + draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox); fz_drop_pixmap(dev->ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm); + fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &trm); if (path) { fz_pixmap *old_dest; @@ -748,7 +755,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) state[0].mask = NULL; fz_try(ctx) { - fz_draw_fill_path(devp, path, 0, fz_identity, fz_device_gray, &white, 1); + fz_draw_fill_path(devp, path, 0, &fz_identity, fz_device_gray, &white, 1); } fz_always(ctx) { @@ -778,7 +785,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate) } static void -fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm) +fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm) { fz_draw_device *dev = devp->user; fz_context *ctx = dev->ctx; @@ -789,20 +796,21 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke int i, x, y, gid; fz_draw_state *state = push_stack(dev); fz_colorspace *model = state->dest->colorspace; + fz_rect rect; /* make the mask the exact size needed */ - bbox = fz_bbox_from_rect(fz_bound_text(dev->ctx, text, ctm)); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_bbox_from_rect(&bbox, fz_bound_text(dev->ctx, text, ctm, &rect)); + fz_intersect_bbox(&bbox, &state->scissor); fz_try(ctx) { - state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, mask); - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(dev->ctx, dest); if (state->shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } else @@ -814,7 +822,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke dump_spaces(dev->top-1, "Clip (stroke text) begin\n"); #endif - if (!fz_is_empty_rect(bbox)) + if (!fz_is_empty_rect(&bbox)) { tm = text->trm; @@ -826,7 +834,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke tm.e = text->items[i].x; tm.f = text->items[i].y; - trm = fz_concat(tm, ctm); + fz_concat(&trm, &tm, ctm); x = floorf(trm.e); y = floorf(trm.f); @@ -834,17 +842,17 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX); trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX); - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trunc_trm, ctm, stroke, bbox); + glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trunc_trm, ctm, stroke, bbox); if (glyph) { - draw_glyph(NULL, mask, glyph, x, y, bbox); + draw_glyph(NULL, mask, glyph, x, y, &bbox); if (shape) - draw_glyph(NULL, shape, glyph, x, y, bbox); + draw_glyph(NULL, shape, glyph, x, y, &bbox); fz_drop_pixmap(dev->ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm); + fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &trm); if (path) { fz_pixmap *old_dest; @@ -856,7 +864,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke state[0].mask = NULL; fz_try(ctx) { - fz_draw_stroke_path(devp, path, stroke, fz_identity, fz_device_gray, &white, 1); + fz_draw_stroke_path(devp, path, stroke, &fz_identity, fz_device_gray, &white, 1); } fz_always(ctx) { @@ -884,12 +892,12 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke } static void -fz_draw_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm) +fz_draw_ignore_text(fz_device *dev, fz_text *text, const fz_matrix *ctm) { } static void -fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) +fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float alpha) { fz_draw_device *dev = devp->user; fz_rect bounds; @@ -900,11 +908,11 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - bounds = fz_bound_shade(dev->ctx, shade, ctm); + fz_bound_shade(dev->ctx, shade, ctm, &bounds); scissor = state->scissor; - bbox = fz_intersect_bbox(fz_bbox_from_rect(bounds), scissor); + fz_intersect_bbox(fz_bbox_from_rect(&bbox, &bounds), &scissor); - if (fz_is_empty_rect(bbox)) + if (fz_is_empty_rect(&bbox)) return; if (!model) @@ -921,11 +929,11 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) if (alpha < 1) { - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox); + dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); fz_clear_pixmap(dev->ctx, dest); if (shape) { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } } @@ -962,9 +970,9 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) } } - fz_paint_shade(dev->ctx, shade, ctm, dest, bbox); + fz_paint_shade(dev->ctx, shade, ctm, dest, &bbox); if (shape) - fz_clear_pixmap_rect_with_value(dev->ctx, shape, 255, bbox); + fz_clear_pixmap_rect_with_value(dev->ctx, shape, 255, &bbox); if (alpha < 1) { @@ -982,7 +990,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) } static fz_pixmap * -fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, fz_bbox *clip) +fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, const fz_bbox *clip) { fz_pixmap *scaled; fz_context *ctx = dev->ctx; @@ -992,7 +1000,7 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x /* Unrotated or X-flip or Y-flip or XY-flip */ fz_matrix m = *ctm; if (gridfit) - m = fz_gridfit_matrix(m); + fz_gridfit_matrix(&m); scaled = fz_scale_pixmap_cached(ctx, image, m.e, m.f, m.a, m.d, clip, dev->cache_x, dev->cache_y); if (!scaled) return NULL; @@ -1009,7 +1017,7 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x fz_matrix m = *ctm; fz_bbox rclip; if (gridfit) - m = fz_gridfit_matrix(m); + fz_gridfit_matrix(&m); if (clip) { rclip.x0 = clip->y0; @@ -1017,7 +1025,7 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x rclip.x1 = clip->y1; rclip.y1 = clip->x1; } - scaled = fz_scale_pixmap_cached(ctx, image, m.f, m.e, m.b, m.c, (clip ? &rclip : 0), dev->cache_x, dev->cache_y); + scaled = fz_scale_pixmap_cached(ctx, image, m.f, m.e, m.b, m.c, (clip ? &rclip : NULL), dev->cache_x, dev->cache_y); if (!scaled) return NULL; ctm->b = scaled->w; @@ -1038,7 +1046,7 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x } static void -fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) +fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float alpha) { fz_draw_device *dev = devp->user; fz_pixmap *converted = NULL; @@ -1050,9 +1058,10 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_bbox clip = fz_pixmap_bbox(ctx, state->dest); + fz_bbox clip; + fz_matrix local_ctm = *ctm; - clip = fz_intersect_bbox(clip, state->scissor); + fz_intersect_bbox(fz_pixmap_bbox(ctx, state->dest, &clip), &state->scissor); fz_var(scaled); @@ -1065,8 +1074,8 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) if (image->w == 0 || image->h == 0) return; - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); + dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b); + dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d); pixmap = fz_image_to_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; @@ -1086,7 +1095,9 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) if (pixmap->colorspace != model && !after) { - converted = fz_new_pixmap_with_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap)); + fz_bbox bbox; + fz_pixmap_bbox(ctx, pixmap, &bbox); + converted = fz_new_pixmap_with_bbox(ctx, model, &bbox); fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } @@ -1094,7 +1105,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) if (dx < pixmap->w && dy < pixmap->h) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) @@ -1116,13 +1127,15 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) } else { - converted = fz_new_pixmap_with_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap)); + fz_bbox bbox; + fz_pixmap_bbox(ctx, pixmap, &bbox); + converted = fz_new_pixmap_with_bbox(ctx, model, &bbox); fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } } - fz_paint_image(state->dest, state->scissor, state->shape, pixmap, ctm, alpha * 255); + fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, alpha * 255); if (state->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_end(dev); @@ -1140,7 +1153,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) } static void -fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, +fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = devp->user; @@ -1154,15 +1167,17 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_bbox clip = fz_pixmap_bbox(ctx, state->dest); + fz_bbox clip; + fz_matrix local_ctm = *ctm; - clip = fz_intersect_bbox(clip, state->scissor); + fz_pixmap_bbox(ctx, state->dest, &clip); + fz_intersect_bbox(&clip, &state->scissor); if (image->w == 0 || image->h == 0) return; - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); + dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b); + dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d); pixmap = fz_image_to_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; @@ -1174,7 +1189,7 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, if (dx < pixmap->w && dy < pixmap->h) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) @@ -1192,7 +1207,7 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_paint_image_with_color(state->dest, state->scissor, state->shape, pixmap, ctm, colorbv); + fz_paint_image_with_color(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, colorbv); if (scaled) fz_drop_pixmap(dev->ctx, scaled); @@ -1211,7 +1226,7 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, } static void -fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matrix ctm) +fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, const fz_matrix *ctm) { fz_draw_device *dev = devp->user; fz_context *ctx = dev->ctx; @@ -1225,9 +1240,12 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri int dx, dy; fz_draw_state *state = push_stack(dev); fz_colorspace *model = state->dest->colorspace; - fz_bbox clip = fz_pixmap_bbox(ctx, state->dest); + fz_bbox clip; + fz_matrix local_ctm = *ctm; + fz_rect urect; - clip = fz_intersect_bbox(clip, state->scissor); + fz_pixmap_bbox(ctx, state->dest, &clip); + fz_intersect_bbox(&clip, &state->scissor); fz_var(mask); fz_var(dest); @@ -1249,26 +1267,31 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri dump_spaces(dev->top-1, "Clip (image mask) begin\n"); #endif - bbox = fz_bbox_from_rect(fz_transform_rect(ctm, fz_unit_rect)); - bbox = fz_intersect_bbox(bbox, state->scissor); - bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(rect)); + urect = fz_unit_rect; + fz_bbox_from_rect(&bbox, fz_transform_rect(&urect, &local_ctm)); + fz_intersect_bbox(&bbox, &state->scissor); + if (rect) + { + fz_bbox bbox2; + fz_intersect_bbox(&bbox, fz_bbox_from_rect(&bbox2, rect)); + } - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); + dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b); + dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d); fz_try(ctx) { pixmap = fz_image_to_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; - state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, mask); - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(dev->ctx, dest); if (state->shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } @@ -1278,7 +1301,7 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri if (dx < pixmap->w && dy < pixmap->h) { int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) @@ -1290,7 +1313,7 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect rect, fz_matri if (scaled) pixmap = scaled; } - fz_paint_image(mask, bbox, state->shape, pixmap, ctm, 255); + fz_paint_image(mask, &bbox, state->shape, pixmap, &local_ctm, 255); } fz_always(ctx) { @@ -1356,7 +1379,7 @@ fz_draw_pop_clip(fz_device *devp) } static void -fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace *colorspace, float *colorfv) +fz_draw_begin_mask(fz_device *devp, const fz_rect *rect, int luminosity, fz_colorspace *colorspace, float *colorfv) { fz_draw_device *dev = devp->user; fz_pixmap *dest; @@ -1365,12 +1388,11 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace fz_pixmap *shape = state->shape; fz_context *ctx = dev->ctx; - bbox = fz_bbox_from_rect(rect); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_intersect_bbox(fz_bbox_from_rect(&bbox, rect), &state->scissor); fz_try(ctx) { - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, fz_device_gray, bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, fz_device_gray, &bbox); if (state->shape) { /* FIXME: If we ever want to support AIS true, then @@ -1446,8 +1468,8 @@ fz_draw_end_mask(fz_device *devp) state[1].mask = NULL; /* create new dest scratch buffer */ - bbox = fz_pixmap_bbox(ctx, temp); - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox); + fz_pixmap_bbox(ctx, temp, &bbox); + dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); fz_clear_pixmap(dev->ctx, dest); /* push soft mask as clip mask */ @@ -1458,14 +1480,14 @@ fz_draw_end_mask(fz_device *devp) * clip mask when we pop. So create a new shape now. */ if (state[0].shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, state[1].shape); } state[1].scissor = bbox; } static void -fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, int blendmode, float alpha) +fz_draw_begin_group(fz_device *devp, const fz_rect *rect, int isolated, int knockout, int blendmode, float alpha) { fz_draw_device *dev = devp->user; fz_bbox bbox; @@ -1478,12 +1500,11 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i fz_knockout_begin(dev); state = push_stack(dev); - bbox = fz_bbox_from_rect(rect); - bbox = fz_intersect_bbox(bbox, state->scissor); + fz_intersect_bbox(fz_bbox_from_rect(&bbox, rect), &state->scissor); fz_try(ctx) { - state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); #ifndef ATTEMPT_KNOCKOUT_AND_ISOLATED knockout = 0; @@ -1496,7 +1517,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i } else { - fz_copy_pixmap_rect(dev->ctx, dest, state[0].dest, bbox); + fz_copy_pixmap_rect(dev->ctx, dest, state[0].dest, &bbox); } if (blendmode == 0 && alpha == 1.0 && isolated) @@ -1507,7 +1528,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i } else { - state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, bbox); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); fz_clear_pixmap(dev->ctx, shape); } @@ -1586,7 +1607,7 @@ fz_draw_end_group(fz_device *devp) } static void -fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm) +fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm) { fz_draw_device *dev = devp->user; fz_pixmap *dest = NULL; @@ -1595,6 +1616,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; + fz_rect local_view = *view; /* area, view, xstep, ystep are in pattern space */ /* ctm maps from pattern space to device space */ @@ -1603,7 +1625,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo fz_knockout_begin(dev); state = push_stack(dev); - bbox = fz_bbox_from_rect(fz_transform_rect(ctm, view)); + fz_bbox_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 @@ -1613,19 +1635,19 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo */ fz_try(ctx) { - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); fz_clear_pixmap(ctx, dest); shape = state[0].shape; if (shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox); + state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); fz_clear_pixmap(ctx, shape); } state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].xstep = xstep; state[1].ystep = ystep; - state[1].area = fz_bbox_from_rect(area); - state[1].ctm = ctm; + fz_bbox_from_rect(&state[1].area, area); + state[1].ctm = *ctm; #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Tile begin\n"); #endif @@ -1665,12 +1687,11 @@ fz_draw_end_tile(fz_device *devp) /* Fudge the scissor bbox a little to allow for inaccuracies in the * matrix inversion. */ - scissor_tmp = fz_rect_from_bbox(state[0].scissor); - scissor_tmp = fz_expand_rect(scissor_tmp, 1); - scissor_tmp = fz_transform_rect(fz_invert_matrix(ctm), scissor_tmp); - scissor = fz_bbox_from_rect(scissor_tmp); - area = fz_intersect_bbox(area, scissor); + fz_rect_from_bbox(&scissor_tmp, &state[0].scissor); + fz_transform_rect(fz_expand_rect(&scissor_tmp, 1), fz_invert_matrix(&ttm, &ctm)); + fz_intersect_bbox(&area, fz_bbox_from_rect(&scissor, &scissor_tmp)); + /* FIXME: area is a bbox, so FP not appropriate here */ x0 = floorf(area.x0 / xstep); y0 = floorf(area.y0 / ystep); x1 = ceilf(area.x1 / xstep); @@ -1699,7 +1720,8 @@ fz_draw_end_tile(fz_device *devp) { for (x = x0; x < x1; x++) { - ttm = fz_concat(fz_translate(x * xstep, y * ystep), ctm); + ttm = ctm; + fz_pre_translate(&ttm, x * xstep, y * ystep); state[1].dest->x = ttm.e; state[1].dest->y = ttm.f; if (state[1].dest->x > 0 && state[1].dest->x + state[1].dest->w < 0) @@ -1709,7 +1731,8 @@ fz_draw_end_tile(fz_device *devp) fz_paint_pixmap_with_bbox(state[0].dest, state[1].dest, 255, state[0].scissor); if (state[1].shape) { - ttm = fz_concat(fz_translate(x * xstep, y * ystep), shapectm); + ttm = shapectm; + fz_pre_translate(&ttm, x * xstep, y * ystep); state[1].shape->x = ttm.e; state[1].shape->y = ttm.f; fz_paint_pixmap_with_bbox(state[0].shape, state[1].shape, 255, state[0].scissor); @@ -1829,19 +1852,19 @@ fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) } fz_device * -fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, fz_bbox clip) +fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, const fz_bbox *clip) { fz_device *dev = fz_new_draw_device(ctx, dest); fz_draw_device *ddev = dev->user; - if (clip.x0 > ddev->stack[0].scissor.x0) - ddev->stack[0].scissor.x0 = clip.x0; - if (clip.x1 < ddev->stack[0].scissor.x1) - ddev->stack[0].scissor.x1 = clip.x1; - if (clip.y0 > ddev->stack[0].scissor.y0) - ddev->stack[0].scissor.y0 = clip.y0; - if (clip.y1 < ddev->stack[0].scissor.y1) - ddev->stack[0].scissor.y1 = clip.y1; + if (clip->x0 > ddev->stack[0].scissor.x0) + ddev->stack[0].scissor.x0 = clip->x0; + if (clip->x1 < ddev->stack[0].scissor.x1) + ddev->stack[0].scissor.x1 = clip->x1; + if (clip->y0 > ddev->stack[0].scissor.y0) + ddev->stack[0].scissor.y0 = clip->y0; + if (clip->y1 < ddev->stack[0].scissor.y1) + ddev->stack[0].scissor.y1 = clip->y1; return dev; } |