diff options
Diffstat (limited to 'draw/draw_device.c')
-rw-r--r-- | draw/draw_device.c | 180 |
1 files changed, 105 insertions, 75 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c index 279ef64d..65ee5a39 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -878,11 +878,13 @@ fz_transform_pixmap(fz_context *ctx, fz_pixmap *image, fz_matrix *ctm, int x, in } static void -fz_draw_fill_image(fz_device *devp, fz_pixmap *image, fz_matrix ctm, float alpha) +fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) { fz_draw_device *dev = devp->user; fz_pixmap *converted = NULL; fz_pixmap *scaled = NULL; + fz_pixmap *pixmap; + fz_pixmap *orig_pixmap; int after; int dx, dy; fz_context *ctx = dev->ctx; @@ -903,87 +905,93 @@ fz_draw_fill_image(fz_device *devp, fz_pixmap *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); + + pixmap = fz_image_to_pixmap(ctx, image, dx, dy); + orig_pixmap = pixmap; + /* convert images with more components (cmyk->rgb) before scaling */ /* convert images with fewer components (gray->rgb after scaling */ /* convert images with expensive colorspace transforms after scaling */ - if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + fz_try(ctx) + { + if (state->blendmode & FZ_BLEND_KNOCKOUT) + state = fz_knockout_begin(dev); - after = 0; - if (image->colorspace == fz_device_gray) - after = 1; + after = 0; + if (pixmap->colorspace == fz_device_gray) + after = 1; - if (image->colorspace != model && !after) - { - converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image)); - fz_convert_pixmap(ctx, image, converted); - image = converted; - } + if (pixmap->colorspace != model && !after) + { + converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(pixmap)); + fz_convert_pixmap(ctx, pixmap, converted); + pixmap = converted; + } - fz_try(ctx) - { - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); - if (dx < image->w && dy < image->h) + if (dx < pixmap->w && dy < pixmap->h) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; - scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy, NULL); + scaled = fz_scale_pixmap(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL); } if (scaled) - image = scaled; + pixmap = scaled; } - if (image->colorspace != model) + if (pixmap->colorspace != model) { - if ((image->colorspace == fz_device_gray && model == fz_device_rgb) || - (image->colorspace == fz_device_gray && model == fz_device_bgr)) + if ((pixmap->colorspace == fz_device_gray && model == fz_device_rgb) || + (pixmap->colorspace == fz_device_gray && model == fz_device_bgr)) { /* We have special case rendering code for gray -> rgb/bgr */ } else { - converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image)); - fz_convert_pixmap(ctx, image, converted); - image = converted; + converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(pixmap)); + fz_convert_pixmap(ctx, pixmap, converted); + pixmap = converted; } } - fz_paint_image(state->dest, state->scissor, state->shape, image, ctm, alpha * 255); + fz_paint_image(state->dest, state->scissor, state->shape, pixmap, ctm, alpha * 255); + + if (state->blendmode & FZ_BLEND_KNOCKOUT) + fz_knockout_end(dev); } - fz_catch(ctx) + fz_always(ctx) { fz_drop_pixmap(ctx, scaled); fz_drop_pixmap(ctx, converted); + fz_drop_pixmap(ctx, orig_pixmap); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - - if (scaled) - fz_drop_pixmap(ctx, scaled); - if (converted) - fz_drop_pixmap(ctx, converted); - - if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); } static void -fz_draw_fill_image_mask(fz_device *devp, fz_pixmap *image, fz_matrix ctm, +fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = devp->user; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; + fz_pixmap *pixmap; + fz_pixmap *orig_pixmap; int dx, dy; int i; + fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_bbox clip = fz_bound_pixmap(state->dest); @@ -993,43 +1001,57 @@ fz_draw_fill_image_mask(fz_device *devp, fz_pixmap *image, fz_matrix ctm, if (image->w == 0 || image->h == 0) return; - if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); - if (dx < image->w && dy < image->h) + pixmap = fz_image_to_pixmap(ctx, image, dx, dy); + orig_pixmap = pixmap; + + fz_try(ctx) { - int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev->ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); - if (!scaled) + if (state->blendmode & FZ_BLEND_KNOCKOUT) + state = fz_knockout_begin(dev); + + if (dx < pixmap->w && dy < pixmap->h) { - if (dx < 1) - dx = 1; - if (dy < 1) - dy = 1; - scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy, NULL); + int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); + scaled = fz_transform_pixmap(dev->ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + if (!scaled) + { + if (dx < 1) + dx = 1; + if (dy < 1) + dy = 1; + scaled = fz_scale_pixmap(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL); + } + if (scaled) + pixmap = scaled; } - if (scaled) - image = scaled; - } - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); - for (i = 0; i < model->n; i++) - colorbv[i] = colorfv[i] * 255; - colorbv[i] = alpha * 255; + fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + for (i = 0; i < model->n; i++) + colorbv[i] = colorfv[i] * 255; + colorbv[i] = alpha * 255; - fz_paint_image_with_color(state->dest, state->scissor, state->shape, image, ctm, colorbv); + fz_paint_image_with_color(state->dest, state->scissor, state->shape, pixmap, ctm, colorbv); - if (scaled) - fz_drop_pixmap(dev->ctx, scaled); + if (scaled) + fz_drop_pixmap(dev->ctx, scaled); - if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + if (state->blendmode & FZ_BLEND_KNOCKOUT) + fz_knockout_end(dev); + } + fz_always(ctx) + { + fz_drop_pixmap(dev->ctx, orig_pixmap); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } } static void -fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_matrix ctm) +fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect *rect, fz_matrix ctm) { fz_draw_device *dev = devp->user; fz_context *ctx = dev->ctx; @@ -1038,6 +1060,8 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat fz_pixmap *dest = NULL; fz_pixmap *shape = NULL; fz_pixmap *scaled = NULL; + fz_pixmap *pixmap; + fz_pixmap *orig_pixmap; int dx, dy; fz_draw_state *state = push_stack(dev); fz_colorspace *model = state->dest->colorspace; @@ -1068,10 +1092,16 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat if (rect) bbox = fz_intersect_bbox(bbox, fz_round_rect(*rect)); - mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox); - fz_clear_pixmap(dev->ctx, mask); + dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); + dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); + pixmap = fz_image_to_pixmap(ctx, image, dx, dy); + orig_pixmap = pixmap; + fz_try(ctx) { + mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox); + fz_clear_pixmap(dev->ctx, mask); + dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox); fz_clear_pixmap(dev->ctx, dest); if (state->shape) @@ -1080,23 +1110,28 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat fz_clear_pixmap(dev->ctx, shape); } - dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); - if (dx < image->w && dy < image->h) + if (dx < pixmap->w && dy < pixmap->h) { int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev->ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(dev->ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; - scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy, NULL); + scaled = fz_scale_pixmap(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL); } if (scaled) - image = scaled; + pixmap = scaled; } + fz_paint_image(mask, bbox, state->shape, pixmap, ctm, 255); + + } + fz_always(ctx) + { + fz_drop_pixmap(ctx, scaled); + fz_drop_pixmap(ctx, orig_pixmap); } fz_catch(ctx) { @@ -1106,11 +1141,6 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat fz_rethrow(ctx); } - fz_paint_image(mask, bbox, state->shape, image, ctm, 255); - - if (scaled) - fz_drop_pixmap(dev->ctx, scaled); - state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; state[1].dest = dest; |