diff options
Diffstat (limited to 'base/gxblend.c')
-rw-r--r-- | base/gxblend.c | 873 |
1 files changed, 472 insertions, 401 deletions
diff --git a/base/gxblend.c b/base/gxblend.c index 59d0deaf..8e806888 100644 --- a/base/gxblend.c +++ b/base/gxblend.c @@ -745,7 +745,7 @@ art_blend_saturation_rgb_16(int n_chan, uint16_t *gs_restrict dst, const uint16_ int mins, maxs; int y; int64_t scale; - int r, g, b; + int64_t r, g, b; minb = rb < gb ? rb : gb; minb = minb < bb ? minb : bb; @@ -764,15 +764,19 @@ art_blend_saturation_rgb_16(int n_chan, uint16_t *gs_restrict dst, const uint16_ maxs = rs > gs ? rs : gs; maxs = maxs > bs ? maxs : bs; + /* -65535 <= maxs - mins <= 65535 i.e. 17 bits */ + /* -65535 <= maxb - minb <= 65535 i.e. 17 bits */ + /* worst case, maxb - minb == +/- 1, so scale would be 33 bits. */ scale = (((int64_t)(maxs - mins)) << 16) / (maxb - minb); + /* 0 <= y <= 65535 */ y = (rb * 77 + gb * 151 + bb * 28 + 0x80) >> 8; r = y + ((((rb - y) * scale) + 0x8000) >> 16); g = y + ((((gb - y) * scale) + 0x8000) >> 16); b = y + ((((bb - y) * scale) + 0x8000) >> 16); - if ((r | g | b) & 0x10000) { + if ((r | g | b) & (int64_t)~0xffff) { int64_t scalemin, scalemax; - int min, max; + int64_t min, max; min = r < g ? r : g; min = min < b ? min : b; @@ -780,7 +784,7 @@ art_blend_saturation_rgb_16(int n_chan, uint16_t *gs_restrict dst, const uint16_ max = max > b ? max : b; if (min < 0) - scalemin = ((int64_t)(y << 16)) / (y - min); + scalemin = (((int64_t)y) << 16) / (y - min); else scalemin = 0x10000; @@ -1207,7 +1211,10 @@ art_blend_pixel_8_inline(byte *gs_restrict dst, const byte *gs_restrict backdrop * PDF specification */ case BLEND_MODE_CompatibleOverprint: { - gx_color_index drawn_comps = p14dev->drawn_comps; + gx_color_index drawn_comps = p14dev->op_state == PDF14_OP_STATE_FILL ? + p14dev->drawn_comps_fill : p14dev->drawn_comps_stroke; + bool opm = p14dev->op_state == PDF14_OP_STATE_FILL ? + p14dev->effective_overprint_mode : p14dev->stroke_effective_op_mode; gx_color_index comps; /* If overprint mode is true and the current color space and * the group color space are CMYK (or CMYK and spots), then @@ -1266,12 +1273,14 @@ art_blend_pixel_8_inline(byte *gs_restrict dst, const byte *gs_restrict backdrop the mixing of the source with the blend result. Essentially replacing that mixing with the color we have here. */ - if (p14dev->effective_overprint_mode && p14dev->color_info.num_components > 3 + if (opm && p14dev->color_info.num_components > 3 && !(p14dev->ctx->additive)) { - for (i = 0; i < 4; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = s < 0xff ? s : b; /* Subtractive zero */ + for (i = 0, comps = drawn_comps; i < 4; i++, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst[i] = src[i]; + } else { + dst[i] = backdrop[i]; + } } for (i = 4; i < n_chan; i++) { dst[i] = backdrop[i]; @@ -1462,7 +1471,10 @@ art_blend_pixel_16_inline(uint16_t *gs_restrict dst, const uint16_t *gs_restrict * PDF specification */ case BLEND_MODE_CompatibleOverprint: { - gx_color_index drawn_comps = p14dev->drawn_comps; + gx_color_index drawn_comps = p14dev->op_state == PDF14_OP_STATE_FILL ? + p14dev->drawn_comps_fill : p14dev->drawn_comps_stroke; + bool opm = p14dev->op_state == PDF14_OP_STATE_FILL ? + p14dev->effective_overprint_mode : p14dev->stroke_effective_op_mode; gx_color_index comps; /* If overprint mode is true and the current color space and * the group color space are CMYK (or CMYK and spots), then @@ -1472,12 +1484,14 @@ art_blend_pixel_16_inline(uint16_t *gs_restrict dst, const uint16_t *gs_restrict * the CMYK colorants (see gx_put_blended_image_cmykspot). * that way we don't have to worry about where the process colors * are. */ - if (p14dev->effective_overprint_mode && p14dev->color_info.num_components > 3 + if (opm && p14dev->color_info.num_components > 3 && !(p14dev->ctx->additive)) { - for (i = 0; i < 4; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = s < 0xffff ? s : b; /* Subtractive zero */ + for (i = 0, comps = drawn_comps; i < 4; i++, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst[i] = src[i]; + } else { + dst[i] = backdrop[i]; + } } for (i = 4; i < n_chan; i++) { dst[i] = backdrop[i]; @@ -1527,9 +1541,10 @@ art_pdf_union_8(byte alpha1, byte alpha2) } #endif -static void -art_pdf_knockout_composite_pixel_alpha_8(byte *gs_restrict backdrop, byte tos_shape, byte *gs_restrict dst, - const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, +static byte* +art_pdf_knockout_composite_pixel_alpha_8(byte *gs_restrict backdrop, byte tos_shape, + byte *gs_restrict dst, byte *gs_restrict src, int n_chan, + gs_blend_mode_t blend_mode, const pdf14_nonseparable_blending_procs_t * pblend_procs, pdf14_device *p14dev) { @@ -1546,16 +1561,15 @@ art_pdf_knockout_composite_pixel_alpha_8(byte *gs_restrict backdrop, byte tos_sh /* source alpha is zero, if we have a src shape value there then copy the backdrop, else leave it alone */ if (tos_shape) - memcpy(dst, backdrop, n_chan + 1); - return; + return backdrop; + return NULL; } /* In this case a_s is not zero */ if (a_b == 0) { /* backdrop alpha is zero but not source alpha, just copy source pixels and avoid computation. */ - memcpy(dst, src, n_chan + 1); - return; + return src; } /* Result alpha is Union of backdrop and source alpha */ @@ -1594,11 +1608,12 @@ art_pdf_knockout_composite_pixel_alpha_8(byte *gs_restrict backdrop, byte tos_sh } } dst[n_chan] = a_r; + return dst; } -static void +static forceinline uint16_t* art_pdf_knockout_composite_pixel_alpha_16(uint16_t *gs_restrict backdrop, uint16_t tos_shape, uint16_t *gs_restrict dst, - const uint16_t *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, + uint16_t *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, const pdf14_nonseparable_blending_procs_t * pblend_procs, pdf14_device *p14dev) { @@ -1615,16 +1630,15 @@ art_pdf_knockout_composite_pixel_alpha_16(uint16_t *gs_restrict backdrop, uint16 /* source alpha is zero, if we have a src shape value there then copy the backdrop, else leave it alone */ if (tos_shape) - memcpy(dst, backdrop, 2*(n_chan + 1)); - return; + return backdrop; + return NULL; } /* In this case a_s is not zero */ if (a_b == 0) { /* backdrop alpha is zero but not source alpha, just copy source pixels and avoid computation. */ - memcpy(dst, src, 2*(n_chan + 1)); - return; + return src; } /* Result alpha is Union of backdrop and source alpha */ @@ -1666,6 +1680,7 @@ art_pdf_knockout_composite_pixel_alpha_16(uint16_t *gs_restrict backdrop, uint16 } } dst[n_chan] = a_r; + return dst; } void @@ -2073,9 +2088,6 @@ art_pdf_composite_pixel_alpha_16_fast_mono(uint16_t *gs_restrict dst, const uint * @alpha: Alpha mask value. * @src_alpha_g: alpha_g value associated with @src. * @blend_mode: Blend mode for compositing. - * @first_blend_spot: The first component for which Normal blending should be used. - * @pblend_procs: Procs for handling non separable blending modes. - * @p14dev: pdf14 device * * Note: this is only for non-isolated groups. This covers only the * single-alpha case. A separate function is needed for dual-alpha, @@ -2094,9 +2106,7 @@ art_pdf_composite_pixel_alpha_16_fast_mono(uint16_t *gs_restrict dst, const uint static forceinline int art_pdf_recomposite_group_8(byte *gs_restrict *dstp, byte *gs_restrict dst_alpha_g, byte *gs_restrict src, byte src_alpha_g, int n_chan, - byte alpha, gs_blend_mode_t blend_mode, int first_blend_spot, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - pdf14_device *p14dev) + byte alpha, gs_blend_mode_t blend_mode) { byte dst_alpha; int i; @@ -2157,16 +2167,32 @@ art_pdf_recomposite_group_8(byte *gs_restrict *dstp, byte *gs_restrict dst_alpha } static forceinline int +art_pdf_ko_recomposite_group_8(byte tos_shape, + byte src_alpha_g, byte* gs_restrict* dstp, + byte* gs_restrict dst_alpha_g, byte* gs_restrict src, + int n_chan, byte alpha, gs_blend_mode_t blend_mode, bool has_mask) +{ + byte* gs_restrict dst = *dstp; + + if (tos_shape == 0 || src_alpha_g == 0) { + /* If a softmask was present pass it along Bug 693548 */ + if (has_mask) + dst[n_chan] = alpha; + return 0; + } + + return art_pdf_recomposite_group_8(dstp, dst_alpha_g, src, src_alpha_g, + n_chan, alpha, blend_mode); +} + +static forceinline int art_pdf_recomposite_group_16(uint16_t *gs_restrict *dstp, uint16_t *gs_restrict dst_alpha_g, uint16_t *gs_restrict src, uint16_t src_alpha_g, int n_chan, - uint16_t alpha, gs_blend_mode_t blend_mode, int first_blend_spot, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - pdf14_device *p14dev) + uint16_t alpha, gs_blend_mode_t blend_mode) { uint16_t dst_alpha; int i; - int tmp; - int scale; + uint32_t tmp; uint16_t *gs_restrict dst = *dstp; if (src_alpha_g == 0) @@ -2192,25 +2218,24 @@ art_pdf_recomposite_group_16(uint16_t *gs_restrict *dstp, uint16_t *gs_restrict if (src_alpha_g != 65535 && dst_alpha != 0) { /* Uncomposite the color. In other words, solve "src = (src, src_alpha_g) over dst" for src */ - scale = ((unsigned int)(dst_alpha * 65535 + (src_alpha_g>>1))) / src_alpha_g - + uint32_t scale = ((unsigned int)(dst_alpha * 65535 + (src_alpha_g>>1))) / src_alpha_g - dst_alpha; /* scale is NOT in 16.16 form here. I've seen values of 0xfefe01, for example. */ for (i = 0; i < n_chan; i++) { int si, di; int64_t tmp64; + int t; si = src[i]; di = dst[i]; /* RJW: Nasty that we have to resort to 64bit here, but we'll live with it. */ - tmp64 = (si - di) * (int64_t)scale + 0x8000; - tmp = si + (tmp64 >> 16); - - /* todo: it should be possible to optimize these cond branches */ - if (tmp < 0) - tmp = 0; - if (tmp > 65535) - tmp = 65535; - src[i] = tmp; + tmp64 = (si - di) * (uint64_t)scale + 0x8000; + t = si + (tmp64 >> 16); + if (t < 0) + t = 0; + else if (t > 65535) + t = 65535; + src[i] = t; } } @@ -2218,7 +2243,7 @@ art_pdf_recomposite_group_16(uint16_t *gs_restrict *dstp, uint16_t *gs_restrict tmp = (src_alpha_g * tmp + 0x8000)>>16; src[n_chan] = tmp; if (dst_alpha_g != NULL) { - int d = *dst_alpha_g; + uint32_t d = *dst_alpha_g; d += d>>15; tmp = (0x10000 - d) * (0xffff - tmp) + 0x8000; *dst_alpha_g = 0xffff - (tmp >> 16); @@ -2228,95 +2253,25 @@ art_pdf_recomposite_group_16(uint16_t *gs_restrict *dstp, uint16_t *gs_restrict /* todo: optimize BLEND_MODE_Normal buf alpha != 255 case */ } -/** - * art_pdf_composite_knockout_group_8: Composite group pixel. - * @backdrop: Backdrop of original parent group. - * @tos_shape: So that we know to copy the backdrop or not even if a_s is zero - * @dst: Where to store pixel. - * @dst_alpha_g: Optional pointer to alpha g value. - * @alpha: Alpha mask value. - * @blend_mode: Blend mode for compositing. - * @pblend_procs: Procs for handling non separable blending modes. - * @p14dev: PDF14 device - * @has_mask: needed for knowing to pass back the soft mask value if shape = 0 - * - * Note: this is only for knockout nonisolated groups. - * - * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. - * - * @NOTE: This function may corrupt src. - **/ -static forceinline void -art_pdf_composite_knockout_group_8(byte *gs_restrict backdrop, byte tos_shape, byte *gs_restrict dst, - byte *gs_restrict dst_alpha_g, byte *gs_restrict src, int n_chan, byte alpha, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - pdf14_device *p14dev, bool has_mask) -{ - byte src_alpha; /* $\alpha g_n$ */ - int tmp; - - if (tos_shape == 0) { - /* If a softmask was present pass it along Bug 693548 */ - if (has_mask) - dst[n_chan] = alpha; - return; - } - - if (alpha != 255) { - if (tos_shape != 255) return; - src_alpha = src[n_chan]; - if (src_alpha == 0) - return; - tmp = src_alpha * alpha + 0x80; - src[n_chan] = (tmp + (tmp >> 8)) >> 8; - } - - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } - art_pdf_knockout_composite_pixel_alpha_8(backdrop, tos_shape, dst, src, - n_chan, blend_mode, pblend_procs, - p14dev); -} - -static forceinline void -art_pdf_composite_knockout_group_16(uint16_t *gs_restrict backdrop, uint16_t tos_shape, uint16_t *gs_restrict dst, - uint16_t *gs_restrict dst_alpha_g, uint16_t *gs_restrict src, int n_chan, uint16_t alpha, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - pdf14_device *p14dev, bool has_mask) +static forceinline int +art_pdf_ko_recomposite_group_16(uint16_t tos_shape, + uint16_t src_alpha_g, uint16_t* gs_restrict* dstp, + uint16_t* gs_restrict dst_alpha_g, uint16_t* gs_restrict src, + int n_chan, uint16_t alpha, gs_blend_mode_t blend_mode, + bool has_mask) { - int src_alpha; /* $\alpha g_n$ */ - int tmp; + uint16_t* gs_restrict dst = *dstp; - if (tos_shape == 0) { + if (tos_shape == 0 || src_alpha_g == 0) { /* If a softmask was present pass it along Bug 693548 */ if (has_mask) dst[n_chan] = alpha; - return; - } - - if (alpha != 65535) { - if (tos_shape != 65535) return; - src_alpha = src[n_chan]; - if (src_alpha == 0) - return; - src_alpha += src_alpha>>15; - tmp = src_alpha * alpha + 0x8000; - src[n_chan] = tmp >> 16; + return 0; } - if (dst_alpha_g != NULL) { - tmp = *dst_alpha_g; - tmp += tmp>>15; - tmp = (0x10000 - tmp) * (0xffff - src[n_chan]) + 0x8000; - *dst_alpha_g = 0xffff - (tmp >> 16); - } - art_pdf_knockout_composite_pixel_alpha_16(backdrop, tos_shape, dst, src, - n_chan, blend_mode, pblend_procs, - p14dev); + return art_pdf_recomposite_group_16(dstp, dst_alpha_g, src, + src_alpha_g, n_chan, alpha, + blend_mode); } /** @@ -2363,6 +2318,39 @@ art_pdf_composite_group_8(byte *gs_restrict dst, byte *gs_restrict dst_alpha_g, } static forceinline int +art_pdf_ko_composite_group_8(byte tos_shape, + byte* gs_restrict src_alpha_g, byte* gs_restrict dst, + byte* gs_restrict dst_alpha_g, byte* gs_restrict src, + int n_chan, byte alpha, bool has_mask) +{ + byte src_alpha; /* $\alpha g_n$ */ + int tmp; + + if (tos_shape == 0 || (src_alpha_g != NULL && *src_alpha_g == 0)) { + /* If a softmask was present pass it along Bug 693548 */ + if (has_mask) + dst[n_chan] = alpha; + return 0; + } + + if (alpha != 255) { + if (tos_shape != 255) + return 0; + src_alpha = src[n_chan]; + if (src_alpha == 0) + return 0; + tmp = src_alpha * alpha + 0x80; + src[n_chan] = (tmp + (tmp >> 8)) >> 8; + } + + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } + return 1; +} + +static forceinline int art_pdf_composite_group_16(uint16_t *gs_restrict dst, uint16_t *gs_restrict dst_alpha_g, uint16_t *gs_restrict src, int n_chan, uint16_t alpha) { @@ -2386,6 +2374,41 @@ art_pdf_composite_group_16(uint16_t *gs_restrict dst, uint16_t *gs_restrict dst_ return 1; } +static forceinline int +art_pdf_ko_composite_group_16(uint16_t tos_shape, + uint16_t* gs_restrict src_alpha_g, uint16_t* gs_restrict dst, + uint16_t* gs_restrict dst_alpha_g, uint16_t* gs_restrict src, + int n_chan, uint16_t alpha, bool has_mask) +{ + uint16_t src_alpha; + int tmp; + + if (tos_shape == 0 || (src_alpha_g != NULL && *src_alpha_g == 0)) { + /* If a softmask was present pass it along Bug 693548 */ + if (has_mask) + dst[n_chan] = alpha; + return 0; + } + + if (alpha != 65535) { + if (tos_shape != 65535) + return 0; + src_alpha = src[n_chan]; + if (src_alpha == 0) + return 0; + tmp = alpha + (alpha >> 15); + src[n_chan] = (src_alpha * tmp + 0x8000) >> 16; + } + + if (dst_alpha_g != NULL) { + tmp = *dst_alpha_g; + tmp += tmp >> 15; + tmp = (0x10000 - tmp) * (0xffff - src[n_chan]) + 0x8000; + *dst_alpha_g = 0xffff - (tmp >> 16); + } + return 1; +} + /* A very simple case. Knockout isolated group going to a parent that is not a knockout. Simply copy over everwhere where we have a non-zero alpha value */ void @@ -2486,7 +2509,9 @@ art_pdf_composite_knockout_8(byte *gs_restrict dst, inner loop is a single interpolation */ tmp = dst[i] * dst_alpha * (255 - src_shape) + ((int)src[i]) * 255 * src_shape + (result_alpha << 7); - dst[i] = tmp / (result_alpha * 255); + tmp = tmp / (result_alpha * 255); + if (tmp > 255) tmp = 255; + dst[i] = tmp; } dst[n_chan] = result_alpha; } @@ -2504,23 +2529,24 @@ art_pdf_composite_knockout_8(byte *gs_restrict dst, /* Result alpha is Union of backdrop and source alpha */ tmp = (0xff - a_b) * (0xff - a_s) + 0x80; a_r = 0xff - (((tmp >> 8) + tmp) >> 8); - /* todo: verify that a_r is nonzero in all cases */ - /* Compute a_s / a_r in 16.16 format */ - src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + if (a_r != 0) { + /* Compute a_s / a_r in 16.16 format */ + src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs, p14dev); - for (i = 0; i < n_chan; i++) { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ + art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs, p14dev); + for (i = 0; i < n_chan; i++) { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ - c_s = src[i]; - c_b = dst[i]; - c_bl = blend[i]; - tmp = a_b * (c_bl - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; - dst[i] = tmp >> 16; + c_s = src[i]; + c_b = dst[i]; + c_bl = blend[i]; + tmp = a_b * (c_bl - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } dst[n_chan] = a_r; } @@ -2562,7 +2588,10 @@ art_pdf_composite_knockout_16(uint16_t *gs_restrict dst, tmp = dst[i] * dst_alpha; tmp = (tmp>>16) * (65535 - src_shape) + src[i] * src_shape + (result_alpha>>1); - dst[i] = tmp / result_alpha; + tmp = tmp / result_alpha; + if (tmp > 65535) tmp = 65535; + dst[i] = tmp; + } } dst[n_chan] = result_alpha; @@ -2581,26 +2610,27 @@ art_pdf_composite_knockout_16(uint16_t *gs_restrict dst, /* Result alpha is Union of backdrop and source alpha */ tmp = (0xffff - a_b) * (0xffff - a_s) + 0x8000; a_r = 0xffff - (((tmp >> 16) + tmp) >> 16); - /* todo: verify that a_r is nonzero in all cases */ - /* Compute a_s / a_r in 16.16 format */ - src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + if (a_r != 0) { + /* Compute a_s / a_r in 16.16 format */ + src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - src_scale >>= 1; /* Lose a bit to avoid overflow */ - a_b >>= 1; /* Lose a bit to avoid overflow */ - art_blend_pixel_16(blend, dst, src, n_chan, blend_mode, pblend_procs, p14dev); - for (i = 0; i < n_chan; i++) { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - int stmp; + src_scale >>= 1; /* Lose a bit to avoid overflow */ + a_b >>= 1; /* Lose a bit to avoid overflow */ + art_blend_pixel_16(blend, dst, src, n_chan, blend_mode, pblend_procs, p14dev); + for (i = 0; i < n_chan; i++) { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + int stmp; - c_s = src[i]; - c_b = dst[i]; - c_bl = blend[i]; - stmp = a_b * (c_bl - ((int)c_s)) + 0x4000; - c_mix = c_s + (((stmp >> 16) + stmp) >> 15); - tmp = src_scale * (c_mix - c_b) + 0x4000; - dst[i] = c_b + (tmp >> 15); + c_s = src[i]; + c_b = dst[i]; + c_bl = blend[i]; + stmp = a_b * (c_bl - ((int)c_s)) + 0x4000; + c_mix = c_s + (((stmp >> 16) + stmp) >> 15); + tmp = src_scale * (c_mix - c_b) + 0x4000; + dst[i] = c_b + (tmp >> 15); + } } dst[n_chan] = a_r; } @@ -2785,7 +2815,7 @@ dump_raw_buffer_be(const gs_memory_t *mem, int num_rows, int width, int n_chan, typedef void (*art_pdf_compose_group_fn)(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, + byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, byte *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, @@ -2798,7 +2828,8 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, - bool tos_has_tag, byte *gs_restrict nos_ptr, + bool tos_has_tag, byte *gs_restrict tos_alpha_g_ptr, + byte *gs_restrict nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *gs_restrict nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, @@ -2819,7 +2850,6 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, byte tos_pixel[PDF14_MAX_PLANES]; byte nos_pixel[PDF14_MAX_PLANES]; byte back_drop[PDF14_MAX_PLANES]; - gx_color_index comps; bool in_mask_rect_y; bool in_mask_rect; byte pix_alpha; @@ -2955,27 +2985,33 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, /* alpha */ back_drop[n_chan] = backdrop_ptr[n_chan * nos_planestride]; } - art_pdf_composite_knockout_group_8(back_drop, tos_shape, - nos_pixel, nos_alpha_g_ptr, - tos_pixel, n_chan, pix_alpha, - blend_mode, pblend_procs, - pdev, has_mask2); + if (tos_isolated ? + art_pdf_ko_composite_group_8(tos_shape, tos_alpha_g_ptr, + nos_pixel, nos_alpha_g_ptr, + tos_pixel, n_chan, pix_alpha, + has_mask2) : + art_pdf_ko_recomposite_group_8(tos_shape, has_alpha ? tos_ptr[tos_alpha_g_offset] : 255, + &dst, nos_alpha_g_ptr, tos_pixel, n_chan, pix_alpha, + blend_mode, has_mask2)) + dst = art_pdf_knockout_composite_pixel_alpha_8(back_drop, tos_shape, + nos_pixel, tos_pixel, + n_chan, blend_mode, + pblend_procs, pdev); } else if (tos_isolated ? art_pdf_composite_group_8(nos_pixel, nos_alpha_g_ptr, tos_pixel, n_chan, pix_alpha) : art_pdf_recomposite_group_8(&dst, nos_alpha_g_ptr, tos_pixel, has_alpha ? tos_ptr[tos_alpha_g_offset] : 255, n_chan, - pix_alpha, blend_mode, first_blend_spot, - pblend_procs, pdev)) { + pix_alpha, blend_mode)) { dst = art_pdf_composite_pixel_alpha_8_inline(nos_pixel, tos_pixel, n_chan, blend_mode, first_blend_spot, pblend_procs, pdev); } if (nos_shape_offset && pix_alpha != 0) { nos_ptr[nos_shape_offset] = - art_pdf_union_mul_8 (nos_ptr[nos_shape_offset], - has_alpha ? tos_ptr[tos_shape_offset] : global_shape, - shape); + art_pdf_union_mul_8(nos_ptr[nos_shape_offset], + has_alpha ? tos_ptr[tos_shape_offset] : global_shape, + shape); } if (dst) { @@ -2992,24 +3028,8 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, } } else { /* Pure subtractive */ - /* If we were running in the compatible overprint blend mode - * and popping the group, we don't need to fool with the - * drawn components as that should have already have been - * handled during the blending within our special non-isolated - * group. So in other words, if the blend mode is normal - * (or compatible) and we are doing overprint, the overprint - * has NOT been handled by compatible overprint mode and we - * need to take care of it now */ - if (overprint) { - for (i = 0, comps = drawn_comps; comps != 0; ++i, comps >>= 1) { - if ((comps & 0x1) != 0) { - nos_ptr[i * nos_planestride] = 255 - dst[i]; - } - } - } else { - for (i = 0; i < n_chan; ++i) - nos_ptr[i * nos_planestride] = 255 - dst[i]; - } + for (i = 0; i < n_chan; ++i) + nos_ptr[i * nos_planestride] = 255 - dst[i]; } /* alpha */ nos_ptr[n_chan * nos_planestride] = dst[n_chan]; @@ -3021,6 +3041,8 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, if (nos_alpha_g_ptr != NULL) ++nos_alpha_g_ptr; + if (tos_alpha_g_ptr != NULL) + ++tos_alpha_g_ptr; if (backdrop_ptr != NULL) ++backdrop_ptr; ++tos_ptr; @@ -3028,6 +3050,8 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, } tos_ptr += tos_rowstride - width; nos_ptr += nos_rowstride - width; + if (tos_alpha_g_ptr != NULL) + tos_alpha_g_ptr += tos_rowstride - width; if (nos_alpha_g_ptr != NULL) nos_alpha_g_ptr += nos_rowstride - width; if (mask_row_ptr != NULL) @@ -3039,7 +3063,7 @@ template_compose_group(byte *gs_restrict tos_ptr, bool tos_isolated, static void compose_group_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3048,7 +3072,7 @@ compose_group_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, in const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3056,7 +3080,7 @@ compose_group_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, in static void compose_group_nonknockout_blend(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3065,7 +3089,7 @@ compose_group_nonknockout_blend(byte *tos_ptr, bool tos_isolated, int tos_planes const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3073,7 +3097,7 @@ compose_group_nonknockout_blend(byte *tos_ptr, bool tos_isolated, int tos_planes static void compose_group_nonknockout_nonblend_isolated_allmask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3138,7 +3162,7 @@ compose_group_nonknockout_nonblend_isolated_allmask_common(byte *tos_ptr, bool t static void compose_group_nonknockout_nonblend_isolated_mask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3228,7 +3252,7 @@ compose_group_nonknockout_nonblend_isolated_mask_common(byte *tos_ptr, bool tos_ static void compose_group_nonknockout_nonblend_isolated_nomask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3237,7 +3261,7 @@ compose_group_nonknockout_nonblend_isolated_nomask_common(byte *tos_ptr, bool to const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, /*tos_isolated*/1, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3245,7 +3269,7 @@ compose_group_nonknockout_nonblend_isolated_nomask_common(byte *tos_ptr, bool to static void compose_group_nonknockout_nonblend_nonisolated_mask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3254,7 +3278,7 @@ compose_group_nonknockout_nonblend_nonisolated_mask_common(byte *tos_ptr, bool t const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3262,7 +3286,7 @@ compose_group_nonknockout_nonblend_nonisolated_mask_common(byte *tos_ptr, bool t static void compose_group_nonknockout_nonblend_nonisolated_nomask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3271,7 +3295,7 @@ compose_group_nonknockout_nonblend_nonisolated_nomask_common(byte *tos_ptr, bool const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3279,7 +3303,7 @@ compose_group_nonknockout_nonblend_nonisolated_nomask_common(byte *tos_ptr, bool static void compose_group_nonknockout_noblend_general(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3288,7 +3312,7 @@ compose_group_nonknockout_noblend_general(byte *tos_ptr, bool tos_isolated, int const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); @@ -3296,7 +3320,7 @@ compose_group_nonknockout_noblend_general(byte *tos_ptr, bool tos_isolated, int static void compose_group_alphaless_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3305,7 +3329,7 @@ compose_group_alphaless_knockout(byte *tos_ptr, bool tos_isolated, int tos_plane const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0); @@ -3313,7 +3337,7 @@ compose_group_alphaless_knockout(byte *tos_ptr, bool tos_isolated, int tos_plane static void compose_group_alphaless_nonknockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, - int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, byte *tos_alpha_g_ptr, byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, const byte *mask_tr_fn, @@ -3322,7 +3346,7 @@ compose_group_alphaless_nonknockout(byte *tos_ptr, bool tos_isolated, int tos_pl const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0); @@ -3351,6 +3375,7 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, bool nos_isolated = nos->isolated; bool nos_knockout = nos->knockout; byte *nos_alpha_g_ptr; + byte *tos_alpha_g_ptr; int tos_shape_offset = n_chan * tos_planestride; int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); bool tos_has_tag = tos->has_tags; @@ -3390,6 +3415,10 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, nos_alpha_g_ptr = nos_ptr + nos_alpha_g_offset; } else nos_alpha_g_ptr = NULL; + if (tos->has_alpha_g) { + tos_alpha_g_ptr = tos_ptr + tos_alpha_g_offset; + } else + tos_alpha_g_ptr = NULL; if (nos->backdrop != NULL) { backdrop_ptr = nos->backdrop + x0 - nos->rect.p.x + (y0 - nos->rect.p.y) * nos->rowstride; @@ -3473,10 +3502,10 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, fn = &compose_group_nonknockout_blend; /* Small %ages, nothing more than 2% */ else if (tos->has_shape == 0 && tos_has_tag == 0 && nos_isolated == 0 && nos_alpha_g_ptr == NULL && nos_shape_offset == 0 && nos_tag_offset == 0 && backdrop_ptr == NULL && has_matte == 0 && num_spots == 0 && - overprint == 0) { + overprint == 0 && tos_alpha_g_ptr == NULL) { /* Additive vs Subtractive makes no difference in normal blend mode with no spots */ if (tos_isolated) { - if (has_mask || maskbuf) {/* 7% */ + if (has_mask && maskbuf) {/* 7% */ /* AirPrint test case hits this */ if (maskbuf && maskbuf->rect.p.x <= x0 && maskbuf->rect.p.y <= y0 && maskbuf->rect.q.x >= x1 && maskbuf->rect.q.y >= y1) { @@ -3495,8 +3524,12 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, } } else fn = &compose_group_nonknockout_nonblend_isolated_mask_common; - } else /* 14% */ - fn = &compose_group_nonknockout_nonblend_isolated_nomask_common; + } else + if (maskbuf) { + /* Outside mask */ + fn = &compose_group_nonknockout_nonblend_isolated_mask_common; + } else + fn = &compose_group_nonknockout_nonblend_isolated_nomask_common; } else { if (has_mask || maskbuf) /* 4% */ fn = &compose_group_nonknockout_nonblend_nonisolated_mask_common; @@ -3508,7 +3541,7 @@ do_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, fn(tos_ptr, tos_isolated, tos_planestride, tos->rowstride, alpha, shape, blend_mode, tos->has_shape, tos_shape_offset, tos_alpha_g_offset, - tos_tag_offset, tos_has_tag, nos_ptr, nos_isolated, nos_planestride, + tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos->rowstride, nos_alpha_g_ptr, nos_knockout, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, @@ -3534,6 +3567,7 @@ interp16(const uint16_t *table, uint16_t idx) typedef void (*art_pdf_compose_group16_fn)(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, @@ -3547,7 +3581,8 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, - bool tos_has_tag, uint16_t *gs_restrict nos_ptr, + bool tos_has_tag, uint16_t *gs_restrict tos_alpha_g_ptr, + uint16_t *gs_restrict nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *gs_restrict nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, @@ -3568,7 +3603,6 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, uint16_t tos_pixel[PDF14_MAX_PLANES]; uint16_t nos_pixel[PDF14_MAX_PLANES]; uint16_t back_drop[PDF14_MAX_PLANES]; - gx_color_index comps; bool in_mask_rect_y; bool in_mask_rect; uint16_t pix_alpha; @@ -3713,11 +3747,18 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, /* alpha */ back_drop[n_chan] = backdrop_ptr[n_chan * nos_planestride]; } - art_pdf_composite_knockout_group_16(back_drop, tos_shape, - nos_pixel, nos_alpha_g_ptr, - tos_pixel, n_chan, pix_alpha, - blend_mode, pblend_procs, - pdev, has_mask2); + + if (tos_isolated ? + art_pdf_ko_composite_group_16(tos_shape, tos_alpha_g_ptr, + nos_pixel, nos_alpha_g_ptr, + tos_pixel, n_chan, pix_alpha, + has_mask2) : + art_pdf_ko_recomposite_group_16(tos_shape, has_alpha ? tos_ptr[tos_alpha_g_offset] : 65535, + &dst, nos_alpha_g_ptr, tos_pixel, n_chan, pix_alpha, + blend_mode, has_mask2)) { + dst = art_pdf_knockout_composite_pixel_alpha_16(back_drop, tos_shape, nos_pixel, tos_pixel, + n_chan, blend_mode, pblend_procs, pdev); + } } else if (tos_isolated ? art_pdf_composite_group_16(nos_pixel, nos_alpha_g_ptr, @@ -3726,8 +3767,7 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, tos_pixel, has_alpha ? GET16_2NATIVE(tos_is_be, tos_ptr[tos_alpha_g_offset]) : 65535, n_chan, - pix_alpha, blend_mode, first_blend_spot, - pblend_procs, pdev)) { + pix_alpha, blend_mode)) { dst = art_pdf_composite_pixel_alpha_16_inline(nos_pixel, tos_pixel, n_chan, blend_mode, first_blend_spot, pblend_procs, pdev); @@ -3753,24 +3793,8 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, } } else { /* Pure subtractive */ - /* If we were running in the compatible overprint blend mode - * and popping the group, we don't need to fool with the - * drawn components as that should have already have been - * handled during the blending within our special non-isolated - * group. So in other words, if the blend mode is normal - * (or compatible) and we are doing overprint, the overprint - * has NOT been handled by compatible overprint mode and we - * need to take care of it now */ - if (overprint) { - for (i = 0, comps = drawn_comps; comps != 0; ++i, comps >>= 1) { - if ((comps & 0x1) != 0) { - nos_ptr[i * nos_planestride] = 65535 - dst[i]; - } - } - } else { - for (i = 0; i < n_chan; ++i) - nos_ptr[i * nos_planestride] = 65535 - dst[i]; - } + for (i = 0; i < n_chan; ++i) + nos_ptr[i * nos_planestride] = 65535 - dst[i]; } /* alpha */ nos_ptr[n_chan * nos_planestride] = dst[n_chan]; @@ -3782,6 +3806,8 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, if (nos_alpha_g_ptr != NULL) ++nos_alpha_g_ptr; + if (tos_alpha_g_ptr != NULL) + ++tos_alpha_g_ptr; if (backdrop_ptr != NULL) ++backdrop_ptr; ++tos_ptr; @@ -3789,6 +3815,8 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, } tos_ptr += tos_rowstride - width; nos_ptr += nos_rowstride - width; + if (tos_alpha_g_ptr != NULL) + tos_alpha_g_ptr += tos_rowstride - width; if (nos_alpha_g_ptr != NULL) nos_alpha_g_ptr += nos_rowstride - width; if (mask_row_ptr != NULL) @@ -3799,8 +3827,9 @@ template_compose_group16(uint16_t *gs_restrict tos_ptr, bool tos_isolated, } static void -compose_group16_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, - bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, +compose_group16_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, + int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, @@ -3809,36 +3838,35 @@ compose_group16_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestri const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_nonknockout_blend(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, - gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, +compose_group16_nonknockout_blend(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { - template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, + template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, + alpha, shape, blend_mode, tos_has_shape, tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, - nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, + tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_nonknockout_nonblend_isolated_allmask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, - uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, +compose_group16_nonknockout_nonblend_isolated_allmask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { @@ -3904,12 +3932,11 @@ compose_group16_nonknockout_nonblend_isolated_allmask_common(uint16_t *tos_ptr, } static void -compose_group16_nonknockout_nonblend_isolated_mask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, - gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, +compose_group16_nonknockout_nonblend_isolated_mask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { @@ -3999,103 +4026,102 @@ compose_group16_nonknockout_nonblend_isolated_mask_common(uint16_t *tos_ptr, boo } static void -compose_group16_nonknockout_nonblend_isolated_nomask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, - uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, +compose_group16_nonknockout_nonblend_isolated_nomask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group16(tos_ptr, /*tos_isolated*/1, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/ 0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_nonknockout_nonblend_nonisolated_mask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, - uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, +compose_group16_nonknockout_nonblend_nonisolated_mask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group16(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_nonknockout_nonblend_nonisolated_nomask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, - uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, +compose_group16_nonknockout_nonblend_nonisolated_nomask_common(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group16(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, /*tos_alpha_g_ptr*/0, nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_nonknockout_noblend_general(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, - gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, - uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, - uint16_t *backdrop_ptr, - bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, +compose_group16_nonknockout_noblend_general(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, + int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, + bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, + uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, + bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1, 0); } static void -compose_group16_alphaless_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, - gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, +compose_group16_alphaless_knockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, + int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, + bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { - template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, + alpha, shape, blend_mode, tos_has_shape, tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0, 1); } static void -compose_group16_alphaless_nonknockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, uint16_t alpha, uint16_t shape, - gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, - uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, - int nos_shape_offset, int nos_tag_offset, +compose_group16_alphaless_nonknockout(uint16_t *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + uint16_t alpha, uint16_t shape, gs_blend_mode_t blend_mode, bool tos_has_shape, int tos_shape_offset, int tos_alpha_g_offset, + int tos_tag_offset, bool tos_has_tag, uint16_t *tos_alpha_g_ptr, uint16_t *nos_ptr, bool nos_isolated, int nos_planestride, + int nos_rowstride, uint16_t *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, uint16_t *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, uint16_t mask_bg_alpha, const uint16_t *mask_tr_fn, uint16_t *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) { - template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, - nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, + template_compose_group16(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, + alpha, shape, blend_mode, tos_has_shape, tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0, 1); } @@ -4125,6 +4151,7 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, bool nos_isolated = nos->isolated; bool nos_knockout = nos->knockout; uint16_t *nos_alpha_g_ptr; + uint16_t *tos_alpha_g_ptr; int tos_shape_offset = n_chan * tos_planestride; int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); bool tos_has_tag = tos->has_tags; @@ -4161,6 +4188,10 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, nos_alpha_g_ptr = nos_ptr + (nos_alpha_g_offset>>1); } else nos_alpha_g_ptr = NULL; + if (tos->has_alpha_g) { + tos_alpha_g_ptr = tos_ptr + (tos_alpha_g_offset>>1); + } else + tos_alpha_g_ptr = NULL; if (nos->backdrop != NULL) { backdrop_ptr = (uint16_t *)(void *)(nos->backdrop + (x0 - nos->rect.p.x)*2 + @@ -4243,18 +4274,23 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, fn = &compose_group16_nonknockout_blend; /* Small %ages, nothing more than 2% */ else if (tos->has_shape == 0 && tos_has_tag == 0 && nos_isolated == 0 && nos_alpha_g_ptr == NULL && nos_shape_offset == 0 && nos_tag_offset == 0 && backdrop_ptr == NULL && has_matte == 0 && num_spots == 0 && - overprint == 0) { + overprint == 0 && tos_alpha_g_ptr == NULL) { /* Additive vs Subtractive makes no difference in normal blend mode with no spots */ if (tos_isolated) { - if (has_mask || maskbuf) {/* 7% */ + if (has_mask && maskbuf) {/* 7% */ /* AirPrint test case hits this */ if (maskbuf && maskbuf->rect.p.x <= x0 && maskbuf->rect.p.y <= y0 && maskbuf->rect.q.x >= x1 && maskbuf->rect.q.y >= y1) fn = &compose_group16_nonknockout_nonblend_isolated_allmask_common; else fn = &compose_group16_nonknockout_nonblend_isolated_mask_common; - } else /* 14% */ - fn = &compose_group16_nonknockout_nonblend_isolated_nomask_common; + } else + if (maskbuf) { + /* Outside mask data but still has mask */ + fn = &compose_group16_nonknockout_nonblend_isolated_mask_common; + } else { + fn = &compose_group16_nonknockout_nonblend_isolated_nomask_common; + } } else { if (has_mask || maskbuf) /* 4% */ fn = &compose_group16_nonknockout_nonblend_nonisolated_mask_common; @@ -4273,7 +4309,7 @@ do_compose_group16(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, nos_tag_offset >>= 1; fn(tos_ptr, tos_isolated, tos_planestride, tos->rowstride>>1, alpha, shape, blend_mode, tos->has_shape, tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, - nos_ptr, nos_isolated, nos_planestride, nos->rowstride>>1, nos_alpha_g_ptr, nos_knockout, + tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos->rowstride>>1, nos_alpha_g_ptr, nos_knockout, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, backdrop_ptr, @@ -4310,9 +4346,10 @@ do_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, gs_memory_t *memory, gx_device *dev) { pdf14_device *pdev = (pdf14_device *)dev; - bool overprint = pdev->overprint; + bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint; bool additive = pdev->ctx->additive; - gx_color_index drawn_comps = pdev->drawn_comps; + gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ? + pdev->drawn_comps_fill : pdev->drawn_comps_stroke; int n_chan = nos->n_chan; int num_spots = tos->num_spots; byte alpha = tos->alpha>>8; @@ -4329,7 +4366,7 @@ do_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, bool tos_isolated = false; bool nos_isolated = nos->isolated; bool nos_knockout = nos->knockout; - byte *nos_alpha_g_ptr; + byte *nos_alpha_g_ptr, *tos_alpha_g_ptr; int tos_shape_offset = n_chan * tos_planestride; int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); bool tos_has_tag = tos->has_tags; @@ -4365,6 +4402,10 @@ do_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, nos_alpha_g_ptr = nos_ptr + nos_alpha_g_offset; } else nos_alpha_g_ptr = NULL; + if (tos->has_alpha_g) { + tos_alpha_g_ptr = tos_ptr + tos_alpha_g_offset; + } else + tos_alpha_g_ptr = NULL; if (nos->backdrop != NULL) { backdrop_ptr = nos->backdrop + x0 - nos->rect.p.x + (y0 - nos->rect.p.y) * nos->rowstride; @@ -4419,7 +4460,7 @@ do_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, fn = &compose_group_alphaless_nonknockout; fn(tos_ptr, tos_isolated, tos_planestride, tos->rowstride, alpha, shape, blend_mode, tos->has_shape, - tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride, nos->rowstride, nos_alpha_g_ptr, nos_knockout, nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, /* maskbuf */ NULL, mask_bg_alpha, mask_tr_fn, @@ -4440,9 +4481,10 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos, gs_memory_t *memory, gx_device *dev) { pdf14_device *pdev = (pdf14_device *)dev; - bool overprint = pdev->overprint; + bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint; bool additive = pdev->ctx->additive; - gx_color_index drawn_comps = pdev->drawn_comps; + gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ? + pdev->drawn_comps_fill : pdev->drawn_comps_stroke; int n_chan = nos->n_chan; int num_spots = tos->num_spots; uint16_t alpha = tos->alpha; @@ -4462,6 +4504,7 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos, bool nos_isolated = nos->isolated; bool nos_knockout = nos->knockout; uint16_t *nos_alpha_g_ptr; + uint16_t *tos_alpha_g_ptr; int tos_shape_offset = n_chan * tos_planestride; int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); bool tos_has_tag = tos->has_tags; @@ -4496,6 +4539,11 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos, nos_alpha_g_ptr = nos_ptr + (nos_alpha_g_offset>>1); } else nos_alpha_g_ptr = NULL; + if (tos->has_alpha_g) { + tos_alpha_g_ptr = tos_ptr + (tos_alpha_g_offset>>1); + } else + tos_alpha_g_ptr = NULL; + if (nos->backdrop != NULL) { backdrop_ptr = (uint16_t *)(void *)(nos->backdrop + (x0 - nos->rect.p.x)*2 + @@ -4551,7 +4599,7 @@ do_compose_alphaless_group16(pdf14_buf *tos, pdf14_buf *nos, fn = &compose_group16_alphaless_nonknockout; fn(tos_ptr, tos_isolated, tos_planestride>>1, tos->rowstride>>1, alpha, shape, blend_mode, tos->has_shape, - tos_shape_offset>>1, tos_alpha_g_offset>>1, tos_tag_offset>>1, tos_has_tag, + tos_shape_offset>>1, tos_alpha_g_offset>>1, tos_tag_offset>>1, tos_has_tag, tos_alpha_g_ptr, nos_ptr, nos_isolated, nos_planestride>>1, nos->rowstride>>1, nos_alpha_g_ptr, nos_knockout, nos_shape_offset>>1, nos_tag_offset>>1, mask_row_ptr, has_mask, /* maskbuf */ NULL, mask_bg_alpha, NULL, @@ -4580,16 +4628,15 @@ pdf14_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, typedef void (*pdf14_mark_fill_rect_fn)(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated); + int alpha_g_off, int shape_off, byte shape); static forceinline void template_mark_fill_rect(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i, j, k; - gx_color_index comps; byte dst[PDF14_MAX_PLANES] = { 0 }; byte dest_alpha; bool tag_blend = blend_mode == BLEND_MODE_Normal || @@ -4638,45 +4685,49 @@ template_mark_fill_rect(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restri dest_alpha = dst[num_comp]; pdst = art_pdf_composite_pixel_alpha_8_inline(dst, src, num_comp, blend_mode, first_blend_spot, pdev->blend_procs, pdev); - /* Until I see otherwise in AR or the spec, do not fool - with spot overprinting while we are in an RGB or Gray - blend color space. */ - if (!additive && overprint) { + /* Post blend complement for subtractive and handling of drawncomps + if overprint. We will have already done the compatible overprint + mode in the above composition */ + if (!additive && !overprint) { + /* Pure subtractive */ + for (k = 0; k < num_comp; ++k) + dst_ptr[k * planestride] = 255 - pdst[k]; + } else if (!additive && overprint) { + int comps; /* If this is an overprint case, and alpha_r is different than alpha_d then we will need to adjust the colors of the non-drawn components here too */ - for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { - if ((comps & 0x1) != 0) { - dst_ptr[k * planestride] = 255 - pdst[k]; - } else if (dest_alpha != pdst[num_comp]) { - /* We need val_new = (val_old * old_alpha) / new_alpha */ - if (pdst[num_comp] != 0) { - int val = (int)floor(((float)dest_alpha / (float)pdst[num_comp]) * (255 - pdst[k]) + 0.5); - if (val < 0) - val = 0; - else if (val > 255) + if (dest_alpha != pdst[num_comp] && pdst[num_comp] != 0) { + /* dest_alpha > pdst[num_comp], and dst[num_comp] != 0. + * Therefore dest_alpha / pdst[num_comp] <= 255 */ + uint32_t scale = 256 * dest_alpha / pdst[num_comp]; + for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 255 - pdst[k]; + } else { + /* We need val_new = (val_old * old_alpha) / new_alpha */ + uint32_t val = (scale * (255 - pdst[k]) + 128)>>8; + if (val > 255) val = 255; dst_ptr[k * planestride] = val; } } - } - } else { - /* Post blend complement for subtractive */ - if (!additive) { - /* Pure subtractive */ - for (k = 0; k < num_comp; ++k) - dst_ptr[k * planestride] = 255 - pdst[k]; - } else { - /* Hybrid case, additive with subtractive spots */ - for (k = 0; k < (num_comp - num_spots); k++) { - dst_ptr[k * planestride] = pdst[k]; - } - for (k = 0; k < num_spots; k++) { - dst_ptr[(k + num_comp - num_spots) * planestride] = - 255 - pdst[k + num_comp - num_spots]; + for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 255 - pdst[k]; + } } } + } else { + /* Hybrid case, additive with subtractive spots */ + for (k = 0; k < (num_comp - num_spots); k++) { + dst_ptr[k * planestride] = pdst[k]; + } + for (k = 0; k < num_spots; k++) { + dst_ptr[(k + num_comp - num_spots) * planestride] = + 255 - pdst[k + num_comp - num_spots]; + } } /* The alpha channel */ dst_ptr[num_comp * planestride] = pdst[num_comp]; @@ -4708,7 +4759,7 @@ static void mark_fill_rect_alpha0(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i, j; @@ -4732,19 +4783,19 @@ static void mark_fill_rect(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { template_mark_fill_rect(w, h, dst_ptr, src, num_comp, num_spots, first_blend_spot, src_alpha, rowstride, planestride, additive, pdev, blend_mode, overprint, drawn_comps, tag_off, curr_tag, - alpha_g_off, shape_off, shape, isolated); + alpha_g_off, shape_off, shape); } static void mark_fill_rect_sub4_fast(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i, j, k; @@ -4788,43 +4839,43 @@ static void mark_fill_rect_add_nospots(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, first_blend_spot, src_alpha, rowstride, planestride, /*additive*/1, pdev, blend_mode, /*overprint*/0, /*drawn_comps*/0, tag_off, curr_tag, - alpha_g_off, shape_off, shape, /*isolated*/ 0); + alpha_g_off, shape_off, shape); } static void mark_fill_rect_add_nospots_common(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, /*first_blend_spot*/0, src_alpha, rowstride, planestride, /*additive*/1, pdev, /*blend_mode*/BLEND_MODE_Normal, /*overprint*/0, /*drawn_comps*/0, /*tag_off*/0, curr_tag, - alpha_g_off, /*shape_off*/0, shape, /*isolated*/ 0); + alpha_g_off, /*shape_off*/0, shape); } static void mark_fill_rect_add_nospots_common_no_alpha_g(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, /*first_blend_spot*/0, src_alpha, rowstride, planestride, /*additive*/1, pdev, /*blend_mode*/BLEND_MODE_Normal, /*overprint*/0, /*drawn_comps*/0, /*tag_off*/0, curr_tag, - /*alpha_g_off*/0, /*shape_off*/0, shape, /*isolated*/ 0); + /*alpha_g_off*/0, /*shape_off*/0, shape); } static void mark_fill_rect_add3_common(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i, j, k; @@ -4868,7 +4919,7 @@ static void mark_fill_rect_add1_no_spots(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i; bool tag_blend = blend_mode == BLEND_MODE_Normal || @@ -4914,7 +4965,7 @@ static void mark_fill_rect_add1_no_spots_normal(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i; @@ -4968,7 +5019,7 @@ static void mark_fill_rect_add1_no_spots_fast(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, - int alpha_g_off, int shape_off, byte shape, bool isolated) + int alpha_g_off, int shape_off, byte shape) { int i; @@ -5024,8 +5075,9 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, int shape_off = num_chan * planestride; int alpha_g_off = shape_off + (has_shape ? planestride : 0); int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0); - bool overprint = pdev->overprint; - gx_color_index drawn_comps = pdev->drawn_comps; + bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint; + gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ? + pdev->drawn_comps_fill : pdev->drawn_comps_stroke; byte shape = 0; /* Quiet compiler. */ byte src_alpha; const gx_color_index mask = ((gx_color_index)1 << 8) - 1; @@ -5033,7 +5085,6 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, int num_spots = buf->num_spots; int first_blend_spot = num_comp; pdf14_mark_fill_rect_fn fn; - bool isolated = buf->isolated; if (num_spots > 0 && !blend_valid_for_spot(blend_mode)) first_blend_spot = num_comp - num_spots; @@ -5139,7 +5190,7 @@ do_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, fn(w, h, dst_ptr, src, num_comp, num_spots, first_blend_spot, src_alpha, rowstride, planestride, additive, pdev, blend_mode, overprint, - drawn_comps, tag_off, curr_tag, alpha_g_off, shape_off, shape, isolated); + drawn_comps, tag_off, curr_tag, alpha_g_off, shape_off, shape); #if 0 /* #if RAW_DUMP */ @@ -5170,8 +5221,8 @@ template_mark_fill_rect16(int w, int h, uint16_t *gs_restrict dst_ptr, uint16_t int alpha_g_off, int shape_off, uint16_t shape_) { int i, j, k; - gx_color_index comps; uint16_t dst[PDF14_MAX_PLANES] = { 0 }; + uint16_t dest_alpha; /* Expand src_alpha and shape to be 0...0x10000 rather than 0...0xffff */ int src_alpha = src_alpha_ + (src_alpha_>>15); int shape = shape_ + (shape_>>15); @@ -5218,34 +5269,52 @@ template_mark_fill_rect16(int w, int h, uint16_t *gs_restrict dst_ptr, uint16_t } } dst[num_comp] = dst_ptr[num_comp * planestride]; + dest_alpha = dst[num_comp]; pdst = art_pdf_composite_pixel_alpha_16_inline(dst, src, num_comp, blend_mode, first_blend_spot, pdev->blend_procs, pdev); - /* Until I see otherwise in AR or the spec, do not fool - with spot overprinting while we are in an RGB or Gray - blend color space. */ - if (!additive && overprint) { - for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { - if ((comps & 0x1) != 0) { - dst_ptr[k * planestride] = 65535 - pdst[k]; + /* Post blend complement for subtractive and handling of drawncomps + if overprint. We will have already done the compatible overprint + mode in the above composition */ + if (!additive && !overprint) { + /* Pure subtractive */ + for (k = 0; k < num_comp; ++k) + dst_ptr[k * planestride] = 65535 - pdst[k]; + } else if (!additive && overprint) { + int comps; + /* If this is an overprint case, and alpha_r is different + than alpha_d then we will need to adjust + the colors of the non-drawn components here too */ + if (dest_alpha != pdst[num_comp] && pdst[num_comp] != 0) { + /* dest_alpha > pdst[num_comp], and dst[num_comp] != 0. + * Therefore dest_alpha / pdst[num_comp] <= 65535 */ + uint64_t scale = (uint64_t)65536 * dest_alpha / pdst[num_comp]; + for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 65535 - pdst[k]; + } else { + /* We need val_new = (val_old * old_alpha) / new_alpha */ + uint64_t val = (scale * (65535 - pdst[k]) + 32768)>>16; + if (val > 65535) + val = 65535; + dst_ptr[k * planestride] = val; + } } - } - } else { - /* Post blend complement for subtractive */ - if (!additive) { - /* Pure subtractive */ - for (k = 0; k < num_comp; ++k) - dst_ptr[k * planestride] = 65535 - pdst[k]; - } else { - /* Hybrid case, additive with subtractive spots */ - for (k = 0; k < (num_comp - num_spots); k++) { - dst_ptr[k * planestride] = pdst[k]; - } - for (k = 0; k < num_spots; k++) { - dst_ptr[(k + num_comp - num_spots) * planestride] = - 65535 - pdst[k + num_comp - num_spots]; + for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 65535 - pdst[k]; + } } } + } else { + /* Hybrid case, additive with subtractive spots */ + for (k = 0; k < (num_comp - num_spots); k++) { + dst_ptr[k * planestride] = pdst[k]; + } + for (k = 0; k < num_spots; k++) { + dst_ptr[(k + num_comp - num_spots) * planestride] = + 65535 - pdst[k + num_comp - num_spots]; + } } /* The alpha channel */ dst_ptr[num_comp * planestride] = pdst[num_comp]; @@ -5335,7 +5404,7 @@ mark_fill_rect16_sub4_fast(int w, int h, uint16_t *gs_restrict dst_ptr, uint16_t dst_ptr[4 * planestride] = a_s; } else if (a_s != 0) { /* Result alpha is Union of backdrop and source alpha */ - int tmp, src_scale; + unsigned int tmp, src_scale; unsigned int a_r; a_b += a_b>>15; @@ -5418,9 +5487,8 @@ mark_fill_rect16_add3_common(int w, int h, uint16_t *gs_restrict dst_ptr, uint16 /* alpha */ dst_ptr[3 * planestride] = a_s; } else if (a_s != 0) { - int tmp; + unsigned int tmp, src_scale; unsigned int a_r; - int src_scale; a_b += a_b >> 15; /* Result alpha is Union of backdrop and source alpha */ @@ -5521,8 +5589,9 @@ mark_fill_rect16_add1_no_spots_normal(int w, int h, uint16_t *gs_restrict dst_pt dst_ptr[planestride] = a_s; } else { /* Result alpha is Union of backdrop and source alpha */ - int tmp, src_scale, c_s, c_b; + unsigned int tmp, src_scale; unsigned int a_r; + int c_s, c_b; a_b += a_b>>15; tmp = (0x10000 - a_b) * (0xffff - a_s) + 0x8000; @@ -5580,8 +5649,9 @@ mark_fill_rect16_add1_no_spots_fast(int w, int h, uint16_t *gs_restrict dst_ptr, dst_ptr[planestride] = a_s; } else if (a_s != 0) { /* Result alpha is Union of backdrop and source alpha */ - int tmp, src_scale, c_s, c_b; + unsigned int tmp, src_scale; unsigned int a_r; + int c_s, c_b; a_b += a_b>>15; tmp = (0x10000 - a_b) * (0xffff - a_s) + 0x8000; @@ -5627,8 +5697,9 @@ do_mark_fill_rectangle16(gx_device * dev, int x, int y, int w, int h, int shape_off = num_chan * planestride; int alpha_g_off = shape_off + (has_shape ? planestride : 0); int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0); - bool overprint = pdev->overprint; - gx_color_index drawn_comps = pdev->drawn_comps; + bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint; + gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ? + pdev->drawn_comps_fill : pdev->drawn_comps_stroke; uint16_t shape = 0; /* Quiet compiler. */ uint16_t src_alpha; int num_spots = buf->num_spots; |