static void fz_draw_fill_image_mask(fz_context *ctx, void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = user; fz_colorspace *model = dev->dest->colorspace; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; int dx, dy; int i; if (image->w == 0 || image->h == 0) return; if (dev->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_begin(ctx, 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) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit); if (scaled == NULL) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy); } if (scaled != NULL) image = scaled; } fz_convert_color(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(dev->dest, dev->scissor, dev->shape, image, ctm, colorbv); if (scaled) fz_drop_pixmap(ctx, scaled); if (dev->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_begin(ctx, dev); }
static void fz_draw_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_draw_device *dev = user; fz_colorspace *model = dev->dest->colorspace; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; int dx, dy; int i; 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); if (dx < image->w && dy < image->h) { scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy); if (scaled == NULL) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; scaled = fz_scale_pixmap(image, image->x, image->y, dx, dy); } if (scaled != NULL) image = scaled; } fz_convert_color(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(dev->dest, dev->scissor, image, ctm, colorbv); if (scaled) fz_drop_pixmap(scaled); }
static void fz_draw_fill_image(fz_context *ctx, void *user, fz_pixmap *image, fz_matrix ctm, float alpha) { fz_draw_device *dev = user; fz_colorspace *model = dev->dest->colorspace; fz_pixmap *converted = NULL; fz_pixmap *scaled = NULL; int after; int dx, dy; if (!model) { fz_warn(ctx, "cannot render image directly to an alpha mask"); return; } if (image->w == 0 || image->h == 0) return; /* 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 (dev->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_begin(ctx, dev); after = 0; if (image->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; } 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) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit); if (scaled == NULL) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy); } if (scaled != NULL) image = scaled; } if (image->colorspace != model) { if ((image->colorspace == fz_device_gray && model == fz_device_rgb) || (image->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; } } fz_paint_image(dev->dest, dev->scissor, dev->shape, image, ctm, alpha * 255); if (scaled) fz_drop_pixmap(ctx, scaled); if (converted) fz_drop_pixmap(ctx, converted); if (dev->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_end(ctx, dev); }
static void fz_draw_clip_image_mask(fz_context *ctx, void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm) { fz_draw_device *dev = user; fz_colorspace *model = dev->dest->colorspace; fz_bbox bbox; fz_pixmap *mask, *dest, *shape; fz_pixmap *scaled = NULL; int dx, dy; if (dev->top == dev->stack_max) fz_grow_stack(dev); #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, "Clip (image mask) begin\n"); #endif if (image->w == 0 || image->h == 0) { dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = NULL; dev->stack[dev->top].dest = NULL; dev->stack[dev->top].blendmode = dev->blendmode; dev->scissor = fz_empty_bbox; dev->top++; return; } bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect)); bbox = fz_intersect_bbox(bbox, dev->scissor); if (rect) bbox = fz_intersect_bbox(bbox, fz_round_rect(*rect)); mask = fz_new_pixmap_with_rect(ctx, NULL, bbox); fz_clear_pixmap(mask); dest = fz_new_pixmap_with_rect(ctx, model, bbox); /* FIXME: See note #1 */ fz_clear_pixmap(dest); if (dev->shape) { shape = fz_new_pixmap_with_rect(ctx, NULL, bbox); fz_clear_pixmap(shape); } else shape = NULL; 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) { int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit); if (scaled == NULL) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy); } if (scaled != NULL) image = scaled; } fz_paint_image(mask, bbox, dev->shape, image, ctm, 255); if (scaled) fz_drop_pixmap(ctx, scaled); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; dev->stack[dev->top].dest = dev->dest; dev->stack[dev->top].shape = dev->shape; /* FIXME: See note #1 */ dev->stack[dev->top].blendmode = dev->blendmode | FZ_BLEND_ISOLATED; dev->scissor = bbox; dev->dest = dest; dev->shape = shape; dev->top++; }
static void 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; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_bbox clip = fz_pixmap_bbox(ctx, state->dest); clip = fz_intersect_bbox(clip, state->scissor); fz_var(scaled); if (!model) { fz_warn(dev->ctx, "cannot render image directly to an alpha mask"); return; } 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 */ fz_try(ctx) { if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); after = 0; if (pixmap->colorspace == fz_device_gray) after = 1; if (pixmap->colorspace != model && !after) { converted = fz_new_pixmap_with_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap)); fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } if (dx < pixmap->w && dy < pixmap->h) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); 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, pixmap, pixmap->x, pixmap->y, dx, dy, NULL); } if (scaled) pixmap = scaled; } if (pixmap->colorspace != model) { 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_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap)); fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } } fz_paint_image(state->dest, state->scissor, state->shape, pixmap, ctm, alpha * 255); if (state->blendmode & FZ_BLEND_KNOCKOUT) fz_knockout_end(dev); } 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); } }
static void 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; fz_bbox bbox; fz_pixmap *mask = NULL; 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; fz_bbox clip = fz_pixmap_bbox(ctx, state->dest); clip = fz_intersect_bbox(clip, state->scissor); fz_var(mask); fz_var(dest); fz_var(shape); if (image->w == 0 || image->h == 0) { #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Clip (image mask) (empty) begin\n"); #endif state[1].scissor = fz_empty_bbox; state[1].mask = NULL; return; } #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Clip (image mask) begin\n"); #endif bbox = fz_bbox_covering_rect(fz_transform_rect(ctm, fz_unit_rect)); bbox = fz_intersect_bbox(bbox, state->scissor); if (rect) bbox = fz_intersect_bbox(bbox, fz_bbox_covering_rect(*rect)); 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_bbox(dev->ctx, NULL, bbox); fz_clear_pixmap(dev->ctx, mask); 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); fz_clear_pixmap(dev->ctx, shape); } if (dx < pixmap->w && dy < pixmap->h) { int gridfit = !(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; } 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) { fz_drop_pixmap(ctx, shape); fz_drop_pixmap(ctx, dest); fz_drop_pixmap(ctx, mask); fz_rethrow(ctx); } state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; state[1].dest = dest; state[1].shape = shape; state[1].mask = mask; }
static void 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_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); pixmap = fz_image_to_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; fz_try(ctx) { if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); if (dx < pixmap->w && dy < pixmap->h) { 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; } fz_convert_color(dev->ctx, model, colorfv, colorspace, color); 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, pixmap, ctm, colorbv); if (scaled) fz_drop_pixmap(dev->ctx, scaled); 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(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm) { fz_draw_device *dev = user; fz_colorspace *model = dev->dest->colorspace; fz_bbox bbox; fz_pixmap *mask, *dest; fz_pixmap *scaled = NULL; int dx, dy; if (dev->top == STACK_SIZE) { fz_warn("assert: too many buffers on stack"); return; } if (image->w == 0 || image->h == 0) { dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = NULL; dev->stack[dev->top].dest = NULL; dev->scissor = fz_empty_bbox; dev->top++; return; } bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect)); bbox = fz_intersect_bbox(bbox, dev->scissor); if (rect) bbox = fz_intersect_bbox(bbox, fz_round_rect(*rect)); mask = fz_new_pixmap_with_rect(NULL, bbox); dest = fz_new_pixmap_with_rect(model, bbox); fz_clear_pixmap(mask); fz_clear_pixmap(dest); 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) { scaled = fz_transform_pixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy); if (scaled == NULL) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; scaled = fz_scale_pixmap(image, image->x, image->y, dx, dy); } if (scaled != NULL) image = scaled; } fz_paint_image(mask, bbox, image, ctm, 255); if (scaled) fz_drop_pixmap(scaled); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; dev->stack[dev->top].dest = dev->dest; dev->scissor = bbox; dev->dest = dest; dev->top++; }