summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-08-02 12:11:03 +0100
committerRobin Watts <robin.watts@artifex.com>2017-10-24 15:16:35 +0100
commit5ca92b5a7166cb0304f9d30d0989b5379c7fa532 (patch)
tree13e8cd576815154304b34ed51f30f15bc4c02ab6
parent874cd7a3b8b803702f1d6ccb8c674e8662002e9b (diff)
downloadmupdf-5ca92b5a7166cb0304f9d30d0989b5379c7fa532.tar.xz
Fix overprint with shadings.
-rw-r--r--include/mupdf/fitz/pixmap.h1
-rw-r--r--include/mupdf/fitz/shade.h4
-rw-r--r--source/fitz/draw-device.c48
-rw-r--r--source/fitz/draw-imp.h5
-rw-r--r--source/fitz/draw-mesh.c8
-rw-r--r--source/fitz/draw-paint.c48
-rw-r--r--source/fitz/stext-device.c2
-rw-r--r--source/fitz/svg-device.c2
8 files changed, 101 insertions, 17 deletions
diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h
index 4fc84b48..a555a046 100644
--- a/include/mupdf/fitz/pixmap.h
+++ b/include/mupdf/fitz/pixmap.h
@@ -16,6 +16,7 @@
*/
typedef struct fz_pixmap_s fz_pixmap;
+typedef struct fz_overprint_s fz_overprint;
/*
fz_pixmap_bbox: Return the bounding box for a pixmap.
diff --git a/include/mupdf/fitz/shade.h b/include/mupdf/fitz/shade.h
index f95a4afc..1a9a174d 100644
--- a/include/mupdf/fitz/shade.h
+++ b/include/mupdf/fitz/shade.h
@@ -132,8 +132,10 @@ fz_rect *fz_bound_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm,
bbox: Pointer to a bounding box to limit the rendering
of the shade.
+
+ op: NULL, or pointer to overprint bitmap.
*/
-void fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, fz_colorspace *prf, const fz_color_params *color_params, const fz_irect *bbox);
+void fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, fz_colorspace *prf, const fz_color_params *color_params, const fz_irect *bbox, const fz_overprint *op);
/*
* Handy routine for processing mesh based shades
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 6ba5a4cf..a26e5986 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -1296,17 +1296,43 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m
{
unsigned char *s;
int x, y, n, i;
+ fz_color_params local_cp;
+ fz_color_params *cp = NULL;
- eop = resolve_color(ctx, &op, shade->background, fz_default_colorspace(ctx, dev->default_cs, shade->colorspace), alpha, color_params, colorbv, state->dest, prf);
+ /* Disable OPM */
+ if (color_params)
+ {
+ local_cp = *color_params;
+ local_cp.opm = 0;
+ cp = &local_cp;
+ }
+
+ eop = resolve_color(ctx, &op, shade->background, fz_default_colorspace(ctx, dev->default_cs, shade->colorspace), alpha, cp, colorbv, state->dest, prf);
n = dest->n;
- for (y = scissor.y0; y < scissor.y1; y++)
+ if (eop)
{
- s = dest->samples + (unsigned int)((y - dest->y) * dest->stride + (scissor.x0 - dest->x) * n);
- for (x = scissor.x0; x < scissor.x1; x++)
+ for (y = scissor.y0; y < scissor.y1; y++)
{
- for (i = 0; i < n; i++)
- *s++ = colorbv[i];
+ s = dest->samples + (unsigned int)((y - dest->y) * dest->stride + (scissor.x0 - dest->x) * n);
+ for (x = scissor.x0; x < scissor.x1; x++)
+ {
+ for (i = 0; i < n; i++)
+ if (fz_overprint_component(eop, i))
+ *s++ = colorbv[i];
+ }
+ }
+ }
+ else
+ {
+ for (y = scissor.y0; y < scissor.y1; y++)
+ {
+ s = dest->samples + (unsigned int)((y - dest->y) * dest->stride + (scissor.x0 - dest->x) * n);
+ for (x = scissor.x0; x < scissor.x1; x++)
+ {
+ for (i = 0; i < n; i++)
+ *s++ = colorbv[i];
+ }
}
}
if (shape)
@@ -1322,7 +1348,15 @@ fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_m
}
}
- fz_paint_shade(ctx, shade, &ctm, dest, prf, color_params, &bbox);
+ if (color_params->op)
+ {
+ eop = &op;
+ set_op_from_spaces(ctx, eop, dest, shade->colorspace, 0);
+ }
+ else
+ eop = NULL;
+
+ fz_paint_shade(ctx, shade, &ctm, dest, prf, color_params, &bbox, eop);
if (shape)
fz_clear_pixmap_rect_with_value(ctx, shape, 255, &bbox);
diff --git a/source/fitz/draw-imp.h b/source/fitz/draw-imp.h
index 8d1c3ef6..47a429d1 100644
--- a/source/fitz/draw-imp.h
+++ b/source/fitz/draw-imp.h
@@ -110,11 +110,11 @@ struct fz_aa_context_s
/* Overprint bitmap */
-typedef struct
+struct fz_overprint_s
{
/* Bit i set -> never alter this color */
uint32_t mask[(FZ_MAX_COLORS+31)/32];
-} fz_overprint;
+};
static void inline fz_set_overprint(fz_overprint *op, int i)
{
@@ -446,6 +446,7 @@ void fz_paint_image_with_color(fz_pixmap * restrict dst, const fz_irect * restri
void fz_paint_pixmap(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int alpha);
void fz_paint_pixmap_with_mask(fz_pixmap * restrict dst, const fz_pixmap * restrict src, const fz_pixmap * restrict msk);
void fz_paint_pixmap_with_bbox(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int alpha, fz_irect bbox);
+void fz_paint_pixmap_with_overprint(fz_pixmap * restrict dst, const fz_pixmap * restrict src, const fz_overprint *op);
void fz_blend_pixmap(fz_context *ctx, fz_pixmap * restrict dst, fz_pixmap * restrict src, int alpha, int blendmode, int isolated, const fz_pixmap * restrict shape);
diff --git a/source/fitz/draw-mesh.c b/source/fitz/draw-mesh.c
index b914a275..cd88d996 100644
--- a/source/fitz/draw-mesh.c
+++ b/source/fitz/draw-mesh.c
@@ -211,7 +211,7 @@ do_paint_tri(fz_context *ctx, void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex
}
void
-fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, fz_colorspace *prf, const fz_color_params *color_params, const fz_irect *bbox)
+fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, fz_colorspace *prf, const fz_color_params *color_params, const fz_irect *bbox, const fz_overprint *op)
{
unsigned char clut[256][FZ_MAX_COLORS];
fz_pixmap *temp = NULL;
@@ -293,8 +293,6 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap
/* Now Change from our device_n colorspace into the target colorspace/spots. */
conv = fz_clone_pixmap_area_with_different_seps(ctx, temp, NULL, dest->colorspace, dest->seps, color_params, prf, NULL);
- fz_paint_pixmap(dest, conv, 255);
- fz_drop_pixmap(ctx, conv);
}
else
{
@@ -340,9 +338,9 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap
d += conv->stride - conv->w * conv->n;
s += temp->stride - temp->w * temp->n;
}
- fz_paint_pixmap(dest, conv, 255);
- fz_drop_pixmap(ctx, conv);
}
+ fz_paint_pixmap_with_overprint(dest, conv, op);
+ fz_drop_pixmap(ctx, conv);
}
}
fz_always(ctx)
diff --git a/source/fitz/draw-paint.c b/source/fitz/draw-paint.c
index 3eb1c174..581c2ff9 100644
--- a/source/fitz/draw-paint.c
+++ b/source/fitz/draw-paint.c
@@ -2257,6 +2257,54 @@ fz_paint_pixmap(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int al
}
void
+fz_paint_pixmap_with_overprint(fz_pixmap * restrict dst, const fz_pixmap * restrict src, const fz_overprint *op)
+{
+ const unsigned char *sp;
+ unsigned char *dp;
+ fz_irect bbox;
+ fz_irect bbox2;
+ int x, y, w, h, n, da, sa;
+ fz_span_painter_t *fn;
+
+ if (dst->n - dst->alpha != src->n - src->alpha)
+ {
+ fprintf(stderr, "fz_paint_pixmap_with_overprint - FIXME\n");
+ return;
+ }
+ assert(dst->n - dst->alpha == src->n - src->alpha);
+
+ fz_pixmap_bbox_no_ctx(dst, &bbox);
+ fz_pixmap_bbox_no_ctx(src, &bbox2);
+ fz_intersect_irect(&bbox, &bbox2);
+
+ x = bbox.x0;
+ y = bbox.y0;
+ w = bbox.x1 - bbox.x0;
+ h = bbox.y1 - bbox.y0;
+ if (w == 0 || h == 0)
+ return;
+
+ n = src->n;
+ sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
+ sa = src->alpha;
+ dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
+ da = dst->alpha;
+
+ n -= sa;
+ fn = fz_get_span_painter(da, sa, n, 255, op);
+ assert(fn);
+ if (fn == NULL)
+ return;
+
+ while (h--)
+ {
+ (*fn)(dp, da, sp, sa, n, w, 255, op);
+ sp += src->stride;
+ dp += dst->stride;
+ }
+}
+
+void
fz_paint_pixmap_with_mask(fz_pixmap * restrict dst, const fz_pixmap * restrict src, const fz_pixmap * restrict msk)
{
const unsigned char *sp, *mp;
diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c
index f693c115..03369940 100644
--- a/source/fitz/stext-device.c
+++ b/source/fitz/stext-device.c
@@ -603,7 +603,7 @@ fz_new_image_from_shade(fz_context *ctx, fz_shade *shade, fz_matrix *in_out_ctm,
fz_fill_pixmap_with_color(ctx, pix, shade->colorspace, shade->background, color_params);
else
fz_clear_pixmap(ctx, pix);
- fz_paint_shade(ctx, shade, &ctm, pix, NULL, color_params, &bbox);
+ fz_paint_shade(ctx, shade, &ctm, pix, NULL, color_params, &bbox, NULL);
img = fz_new_image_from_pixmap(ctx, pix, NULL);
}
fz_always(ctx)
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 7098e0a0..d7b144ed 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -921,7 +921,7 @@ svg_dev_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_ma
fz_try(ctx)
{
- fz_paint_shade(ctx, shade, ctm, pix, NULL, color_params, &bbox);
+ fz_paint_shade(ctx, shade, ctm, pix, NULL, color_params, &bbox, NULL);
buf = fz_new_buffer_from_pixmap_as_png(ctx, pix, color_params);
if (alpha != 1.0f)
fz_write_printf(ctx, out, "<g opacity=\"%g\">\n", alpha);