From 634fa34f946fb3d48736917102a1e5be583a3fc8 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Mon, 2 Jan 2012 18:25:10 +0000 Subject: Fix bug 692593 - solve crash due to inappropriately sized shape plane. When starting to tile, create a shape plane if one exists. When finishing tiling, plot the shape plane back too. This solves the SEGVs. Something isn't quite right with the blending colours on part of this file though. --- draw/draw_device.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'draw') diff --git a/draw/draw_device.c b/draw/draw_device.c index 2634c4f8..5583c30e 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -1461,8 +1461,10 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo { fz_draw_device *dev = devp->user; fz_colorspace *model = dev->dest->colorspace; - fz_pixmap *dest; + fz_pixmap *dest = NULL; + fz_pixmap *shape = dev->shape; fz_bbox bbox; + fz_context *ctx = dev->ctx; /* area, view, xstep, ystep are in pattern space */ /* ctm maps from pattern space to device space */ @@ -1482,7 +1484,20 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox); /* FIXME: See note #1 */ fz_clear_pixmap(dest); - + if (shape) + { + fz_var(shape); + fz_try(ctx) + { + shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox); + fz_clear_pixmap(shape); + } + fz_catch(ctx) + { + fz_drop_pixmap(ctx, dest); + fz_rethrow(ctx); + } + } dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].dest = dev->dest; dev->stack[dev->top].shape = dev->shape; @@ -1499,6 +1514,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo dev->scissor = bbox; dev->dest = dest; + dev->shape = shape; } static void @@ -1506,26 +1522,24 @@ fz_draw_end_tile(fz_device *devp) { fz_draw_device *dev = devp->user; fz_pixmap *tile = dev->dest; + fz_pixmap *tileshape = dev->shape; float xstep, ystep; - fz_matrix ctm, ttm; + fz_matrix ctm, ttm, shapectm; fz_rect area; int x0, y0, x1, y1, x, y; if (dev->top > 0) { dev->top--; -#ifdef DUMP_GROUP_BLENDS - dump_spaces(dev->top, "Tile end\n"); -#endif xstep = dev->stack[dev->top].xstep; ystep = dev->stack[dev->top].ystep; area = dev->stack[dev->top].area; ctm = dev->stack[dev->top].ctm; dev->scissor = dev->stack[dev->top].scissor; dev->dest = dev->stack[dev->top].dest; + dev->shape = dev->stack[dev->top].shape; dev->blendmode = dev->stack[dev->top].blendmode; - x0 = floorf(area.x0 / xstep); y0 = floorf(area.y0 / ystep); x1 = ceilf(area.x1 / xstep); @@ -1533,6 +1547,22 @@ fz_draw_end_tile(fz_device *devp) ctm.e = tile->x; ctm.f = tile->y; + if (tileshape) + { + shapectm = ctm; + shapectm.e = tileshape->x; + shapectm.f = tileshape->y; + } + +#ifdef DUMP_GROUP_BLENDS + dump_spaces(dev->top, ""); + fz_dump_blend(dev->ctx, tile, "Tiling "); + if (tileshape) + fz_dump_blend(dev->ctx, tileshape, "/"); + fz_dump_blend(dev->ctx, dev->dest, " onto "); + if (dev->shape) + fz_dump_blend(dev->ctx, dev->shape, "/"); +#endif for (y = y0; y < y1; y++) { @@ -1542,10 +1572,24 @@ fz_draw_end_tile(fz_device *devp) tile->x = ttm.e; tile->y = ttm.f; fz_paint_pixmap_with_rect(dev->dest, tile, 255, dev->scissor); + if (tileshape) + { + ttm = fz_concat(fz_translate(x * xstep, y * ystep), shapectm); + tileshape->x = ttm.e; + tileshape->y = ttm.f; + fz_paint_pixmap_with_rect(dev->shape, tileshape, 255, dev->scissor); + } } } fz_drop_pixmap(dev->ctx, tile); + fz_drop_pixmap(dev->ctx, tileshape); +#ifdef DUMP_GROUP_BLENDS + fz_dump_blend(dev->ctx, dev->dest, " to get "); + if (dev->shape) + fz_dump_blend(dev->ctx, dev->shape, "/"); + printf("\n"); +#endif } if (dev->blendmode & FZ_BLEND_KNOCKOUT) @@ -1557,7 +1601,7 @@ fz_draw_free_user(fz_device *devp) { fz_draw_device *dev = devp->user; fz_context *ctx = dev->ctx; - /* TODO: pop and free the stacks */ + /* pop and free the stacks */ if (dev->top > 0) { fz_warn(ctx, "items left on stack in draw device: %d", dev->top); -- cgit v1.2.3