summaryrefslogtreecommitdiff
path: root/source/fitz/draw-device.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-08-03 13:22:38 +0100
committerRobin Watts <robin.watts@artifex.com>2017-10-24 15:16:35 +0100
commitcdf1bf6dcac8fec399355f21772bd89785ef8599 (patch)
tree3a60280224c878aa1f267061b2196205298367b7 /source/fitz/draw-device.c
parentcbdb9dc747ff7e7c9e187e056c4077edae629729 (diff)
downloadmupdf-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.c136
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);