diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-10-10 15:43:27 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-10-10 15:57:46 +0100 |
commit | ed7fdb2a8926fa946926281450150eab0de13700 (patch) | |
tree | bfdd451110418d3ef09c5d1578687ae8f1beacc7 /source | |
parent | f22be2b82fe1afe733dd0e6c3ab9d26a39acd39b (diff) | |
download | mupdf-ed7fdb2a8926fa946926281450150eab0de13700.tar.xz |
Bug 697075: Fix tile repeat calculations.
When calculating how many repeats of tiles are required, we
need to allow for the fact that the bbox of the tile can be
larger than the repeat step in PDF.
The calculation to do this before was incorrectly being done
using the scissor bbox, when it should have been the tile
bbox.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/draw-device.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index e40b61db..4a021542 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -2254,9 +2254,9 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp) fz_draw_device *dev = (fz_draw_device*)devp; float xstep, ystep; fz_matrix ttm, ctm, shapectm; - fz_irect area, scissor; - fz_rect scissor_tmp; - int x0, y0, x1, y1, x, y; + fz_irect area, scissor, tile_bbox; + fz_rect scissor_tmp, tile_tmp, tile_rect; + int x0, y0, x1, y1, x, y, extra_x, extra_y; fz_draw_state *state; tile_record *tile; tile_key *key; @@ -2280,22 +2280,29 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp) fz_transform_rect(fz_expand_rect(&scissor_tmp, 1), fz_invert_matrix(&ttm, &ctm)); fz_intersect_irect(&area, fz_irect_from_rect(&scissor, &scissor_tmp)); + tile_bbox.x0 = state[1].dest->x; + tile_bbox.y0 = state[1].dest->y; + tile_bbox.x1 = state[1].dest->w + tile_bbox.x0; + tile_bbox.y1 = state[1].dest->h + tile_bbox.y0; + fz_rect_from_irect(&tile_tmp, &tile_bbox); + fz_transform_rect(fz_expand_rect(&tile_tmp, 1), &ttm); + /* FIXME: area is a bbox, so FP not appropriate here */ /* In PDF files xstep/ystep can be smaller than view (the area of a * single tile) (see fts_15_1506.pdf for an example). This means that * we have to bias the left hand/bottom edge calculations by the * difference between the step and the width/height of the tile. */ /* scissor, xstep and area are all in pattern space. */ - x0 = xstep - scissor.x1 + scissor.x0; - if (x0 > 0) - x0 = 0; - y0 = ystep - scissor.y1 + scissor.y0; - if (y0 > 0) - y0 = 0; - x0 = floorf((area.x0 + x0) / xstep); - y0 = floorf((area.y0 + y0) / ystep); - x1 = ceilf(area.x1 / xstep); - y1 = ceilf(area.y1 / ystep); + extra_x = tile_tmp.x1 - tile_tmp.x0 - xstep; + if (extra_x < 0) + extra_x = 0; + extra_y = tile_tmp.y1 - tile_tmp.y0 - ystep; + if (extra_y < 0) + extra_y = 0; + x0 = floorf((area.x0 - tile_tmp.x0 - extra_x) / xstep); + y0 = floorf((area.y0 - tile_tmp.y0 - extra_y) / ystep); + x1 = ceilf((area.x1 - tile_tmp.x0 + extra_x) / xstep); + y1 = ceilf((area.y1 - tile_tmp.y0 + extra_y) / ystep); ctm.e = state[1].dest->x; ctm.f = state[1].dest->y; @@ -2324,6 +2331,7 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp) fz_pre_translate(&ttm, x * xstep, y * ystep); state[1].dest->x = ttm.e; state[1].dest->y = ttm.f; + /* Check for overflow due to float -> int conversions */ if (state[1].dest->x > 0 && state[1].dest->x + state[1].dest->w < 0) continue; if (state[1].dest->y > 0 && state[1].dest->y + state[1].dest->h < 0) |