diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-08-03 13:22:38 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-10-24 15:16:35 +0100 |
commit | cdf1bf6dcac8fec399355f21772bd89785ef8599 (patch) | |
tree | 3a60280224c878aa1f267061b2196205298367b7 /source/fitz/draw-device.c | |
parent | cbdb9dc747ff7e7c9e187e056c4077edae629729 (diff) | |
download | mupdf-cdf1bf6dcac8fec399355f21772bd89785ef8599.tar.xz |
Fix overprint color component detection.
If a colorant is not an explicit separation, then it will be
mapped down to process colorants. These cannot be protected
from overprint.
Incorporates a fix for a problem with shades seen on page 8 of.
Altona_Technical_v20_x4. This shows a problem where we were failing
to correctly overprint a grey gradient with a spot color one.
The overprint setup code was checking for 'Orange' being one of
the process colours, and not finding it. Consequently it was deciding
that Orange would have to be mapped to a process color, and so the
process colors could not be protected from overprint.
The code should have spotted that 'Orange' was one of the spot
colors. With this added, it works correctly.
Diffstat (limited to 'source/fitz/draw-device.c')
-rw-r--r-- | source/fitz/draw-device.c | 136 |
1 files changed, 91 insertions, 45 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 7274200f..72c0ab74 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -360,22 +360,63 @@ set_op_from_spaces(fz_context *ctx, fz_overprint *op, const fz_pixmap *dest, con dn = dest->n - dest->alpha; dc = dn - dest->s; - for (i = 0; i < dc; i++) - { - const char *name = fz_colorspace_colorant(ctx, dest->colorspace, i); - - for (j = 0; j < sn; j++) + /* If a source colorant is not mentioned in the destination + * colorants (either process or spots), then it will be mapped + * to process colorants. In this case, the process colorants + * can never be protected. + */ + for (j = 0; j < sn; j++) + { + const char *sname = fz_colorspace_colorant(ctx, src, j); + if (!sname) + continue; + if (!strcmp(sname, "All")) + break; + for (i = 0; i < dc; i++) { - const char *sname = fz_colorspace_colorant(ctx, src, j); - if (!name || !sname) + const char *name = fz_colorspace_colorant(ctx, dest->colorspace, i); + if (!name) continue; if (!strcmp(name, sname)) break; - if (!strcmp(sname, "All")) + } + if (i != dc) + continue; + for (; i < dn; i++) + { + const char *name = fz_separation_name(ctx, dest->seps, i - dc); + if (!name) + continue; + if (!strcmp(name, sname)) break; } - if (j == sn) - fz_set_overprint(op, i); + if (i == dn) + { + /* This source colorant wasn't mentioned */ + break; + } + } + if (j == sn) + { + /* We did not find any source colorants that weren't mentioned, so + * process colorants might not be touched... */ + for (i = 0; i < dc; i++) + { + const char *name = fz_colorspace_colorant(ctx, dest->colorspace, i); + + for (j = 0; j < sn; j++) + { + const char *sname = fz_colorspace_colorant(ctx, src, j); + if (!name || !sname) + continue; + if (!strcmp(name, sname)) + break; + if (!strcmp(sname, "All")) + break; + } + if (j == sn) + fz_set_overprint(op, i); + } } for (i = dc; i < dn; i++) { @@ -1443,6 +1484,44 @@ fz_default_image_scale(void *arg, int dst_w, int dst_h, int src_w, int src_h) return dst_w < src_w && dst_h < src_h; } +static fz_pixmap * +convert_pixmap_for_painting(fz_context *ctx, fz_pixmap *pixmap, fz_colorspace *model, fz_colorspace *src_cs, fz_pixmap *dest, const fz_color_params *color_params, fz_draw_device *dev, fz_overprint **eop) +{ + fz_pixmap *converted; + + if (fz_colorspace_is_device_n(ctx, src_cs) && dest->seps) + { + converted = fz_clone_pixmap_area_with_different_seps(ctx, pixmap, NULL, model, dest->seps, color_params, dev->default_cs); + set_op_from_spaces(ctx, *eop, dest, src_cs, 0); + } + else + { + converted = fz_convert_pixmap(ctx, pixmap, model, NULL, dev->default_cs, color_params, 1); + if (*eop) + { + if (fz_colorspace_n(ctx, model) != 4) + { + /* Can only overprint to CMYK based spaces */ + *eop = NULL; + } + else if (!fz_colorspace_is_device_n(ctx, pixmap->colorspace)) + { + int i; + int n = dest->n - dest->alpha; + for (i = 4; i < n; i++) + fz_set_overprint(*eop, i); + } + else + { + set_op_from_spaces(ctx, *eop, dest, src_cs, 0); + } + } + } + fz_drop_pixmap(ctx, pixmap); + + return converted; +} + static void fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *in_ctm, float alpha, const fz_color_params *color_params) { @@ -1536,20 +1615,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m after = 1; if (conversion_required && !after) - { - fz_pixmap *converted; - /* If we have a spotty image, and we are going to spotty output, - * then we can't lose the spots during color conversion. */ - if (fz_colorspace_is_device_n(ctx, src_cs) && state->dest->seps) - { - converted = fz_clone_pixmap_area_with_different_seps(ctx, pixmap, NULL, model, state->dest->seps, color_params, dev->default_cs); - set_op_from_spaces(ctx, eop, state->dest, src_cs, color_params->opm); - } - else - converted = fz_convert_pixmap(ctx, pixmap, model, NULL, dev->default_cs, color_params, 1); - fz_drop_pixmap(ctx, pixmap); - pixmap = converted; - } + pixmap = convert_pixmap_for_painting(ctx, pixmap, model, src_cs, state->dest, color_params, dev, &eop); if (!(devp->hints & FZ_DONT_INTERPOLATE_IMAGES) && ctx->tuning->image_scale(ctx->tuning->image_scale_arg, dx, dy, pixmap->w, pixmap->h)) { @@ -1581,27 +1647,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m } else #endif - { - fz_pixmap *converted; - if (fz_colorspace_is_device_n(ctx, src_cs) && state->dest->seps) - { - converted = fz_clone_pixmap_area_with_different_seps(ctx, pixmap, NULL, model, state->dest->seps, color_params, dev->default_cs); - set_op_from_spaces(ctx, eop, state->dest, src_cs, color_params->opm); - } - else - { - converted = fz_convert_pixmap(ctx, pixmap, model, NULL, dev->default_cs, color_params, 1); - if (eop && !fz_colorspace_is_device_n(ctx, pixmap->colorspace) && fz_colorspace_n(ctx, model) == 4) - { - int i; - int n = state->dest->n - state->dest->alpha; - for (i = 4; i < n; i++) - fz_set_overprint(eop, i); - } - } - fz_drop_pixmap(ctx, pixmap); - pixmap = converted; - } + pixmap = convert_pixmap_for_painting(ctx, pixmap, model, src_cs, state->dest, color_params, dev, &eop); } fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES), devp->flags & FZ_DEVFLAG_GRIDFIT_AS_TILED, eop); |