diff options
-rw-r--r-- | source/fitz/draw-device.c | 24 | ||||
-rw-r--r-- | source/fitz/draw-imp.h | 1 | ||||
-rw-r--r-- | source/fitz/draw-paint.c | 81 |
3 files changed, 94 insertions, 12 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 85c0b7e3..27229108 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -2119,12 +2119,8 @@ fz_draw_begin_group(fz_context *ctx, fz_device *devp, const fz_rect *rect, fz_co fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox, dev->default_cs); } - if (blendmode == 0 && alpha == 1.0f && isolated) - { - /* We can render direct to any existing shape plane. - * If there isn't one, we don't need to make one. */ - state[1].shape = state[0].shape; - } + if (isolated) + state[1].shape = NULL; else { state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox, NULL, 1); @@ -2212,17 +2208,21 @@ fz_draw_end_group(fz_context *ctx, fz_device *devp) else fz_blend_pixmap(ctx, state[0].dest, state[1].dest, alpha * 255, blendmode, isolated, state[1].shape); + assert(state[0].shape == NULL || state[0].shape != state[1].shape); + if (state[0].shape && state[0].shape != state[1].shape) + { + if (state[1].shape) + fz_paint_pixmap(state[0].shape, state[1].shape, alpha * 255); + else + fz_paint_pixmap_alpha(state[0].shape, state[1].dest, alpha * 255); + } + fz_drop_pixmap(ctx, state[1].shape); /* The following test should not be required, but just occasionally * errors can cause the stack to get out of sync, and this might save * our bacon. */ + assert(state[0].dest != state[1].dest); if (state[0].dest != state[1].dest) fz_drop_pixmap(ctx, state[1].dest); - if (state[0].shape != state[1].shape) - { - if (state[0].shape) - fz_paint_pixmap(state[0].shape, state[1].shape, alpha * 255); - fz_drop_pixmap(ctx, state[1].shape); - } #ifdef DUMP_GROUP_BLENDS fz_dump_blend(ctx, " to get ", state[0].dest); if (state[0].shape) diff --git a/source/fitz/draw-imp.h b/source/fitz/draw-imp.h index c14947c8..d2d50d2e 100644 --- a/source/fitz/draw-imp.h +++ b/source/fitz/draw-imp.h @@ -458,6 +458,7 @@ void fz_paint_image(fz_pixmap * restrict dst, const fz_irect * restrict scissor, void fz_paint_image_with_color(fz_pixmap * restrict dst, const fz_irect * restrict scissor, fz_pixmap *restrict shape, const fz_pixmap * restrict img, const fz_matrix * restrict ctm, const unsigned char * restrict colorbv, int lerp_allowed, int gridfit_as_tiled, const fz_overprint * restrict eop); void fz_paint_pixmap(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int alpha); +void fz_paint_pixmap_alpha(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); diff --git a/source/fitz/draw-paint.c b/source/fitz/draw-paint.c index aaa1c890..0a58fd58 100644 --- a/source/fitz/draw-paint.c +++ b/source/fitz/draw-paint.c @@ -2256,6 +2256,87 @@ fz_paint_pixmap(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int al } } +static inline void +paint_span_alpha_solid(byte * restrict dp, const byte * restrict sp, int n, int w) +{ + TRACK_FN(); + sp += n-1; + do + { + int s = *sp; + int t = FZ_EXPAND(255 - s); + sp += n; + *dp = s + FZ_COMBINE(*dp, t); + dp ++; + } + while (--w); +} + +static inline void +paint_span_alpha_not_solid(byte * restrict dp, const byte * restrict sp, int n, int w, int alpha) +{ + TRACK_FN(); + sp += n-1; + alpha = FZ_EXPAND(alpha); + do + { + int masa = FZ_COMBINE(sp[0], alpha); + sp += n; + *dp = FZ_BLEND(*sp, *dp, masa); + dp++; + } + while (--w); +} + +void +fz_paint_pixmap_alpha(fz_pixmap * restrict dst, const fz_pixmap * restrict src, int alpha) +{ + const unsigned char *sp; + unsigned char *dp; + fz_irect bbox; + fz_irect bbox2; + int x, y, w, h, n; + + if (alpha == 0) + return; + + assert(dst->n == 1 && dst->alpha == 1 && src->n >= 1 && src->alpha == 1); + + 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); + dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n); + + if (alpha == 255) + { + while (h--) + { + paint_span_alpha_solid(dp, sp, n, w); + sp += src->stride; + dp += dst->stride; + } + } + else + { + while (h--) + { + paint_span_alpha_not_solid(dp, sp, n, w, alpha); + sp += src->stride; + dp += dst->stride; + } + } +} + void fz_paint_pixmap_with_overprint(fz_pixmap * restrict dst, const fz_pixmap * restrict src, const fz_overprint *op) { |