diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-07-23 18:26:01 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-07-23 18:26:01 +0000 |
commit | 0da7075063e13032b2f11ca39fc9624f3c91e3c7 (patch) | |
tree | 956117fa67ca63f118a2e4e966f0cf3049ea1acb /fitz/dev_draw.c | |
parent | 84b1d89a5cd68182175c0761431707294798aed5 (diff) | |
download | mupdf-0da7075063e13032b2f11ca39fc9624f3c91e3c7.tar.xz |
Support constant alpha for shadings, images and transparency groups.
Diffstat (limited to 'fitz/dev_draw.c')
-rw-r--r-- | fitz/dev_draw.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index 95d479ab..1947af4f 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -488,7 +488,7 @@ fz_drawignoretext(void *user, fz_text *text, fz_matrix ctm) } static void -fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm) +fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; @@ -517,6 +517,12 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm) return; } + if (alpha < 1) + { + dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox); + fz_clearpixmap(dest, 0); + } + if (shade->usebackground) { unsigned char *s; @@ -538,7 +544,13 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm) } } - fz_rendershade(shade, ctm, dev->dest, bbox); + fz_rendershade(shade, ctm, dest, bbox); + + if (alpha < 1) + { + fz_blendpixmapswithalpha(dev->dest, dest, alpha); + fz_droppixmap(dest); + } } static int @@ -552,7 +564,7 @@ fz_calcimagescale(fz_pixmap *image, fz_matrix ctm, int *dx, int *dy) } static void -fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) +fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; @@ -592,7 +604,21 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) } #endif - fz_blendimage(dev->dest, dev->scissor, image, ctm); + if (alpha < 1) + { + fz_pixmap *temp; + fz_bbox bbox; + bbox = fz_roundrect(fz_transformrect(ctm, fz_unitrect)); + bbox = fz_intersectbbox(bbox, dev->scissor); + temp = fz_newpixmapwithrect(dev->dest->colorspace, bbox); + fz_blendimage(temp, bbox, image, ctm); + fz_blendpixmapswithalpha(dev->dest, temp, alpha); + fz_droppixmap(temp); + } + else + { + fz_blendimage(dev->dest, dev->scissor, image, ctm); + } if (scaled) fz_droppixmap(scaled); @@ -812,7 +838,7 @@ fz_drawendmask(void *user) } static void -fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode) +fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode, float alpha) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; @@ -831,6 +857,7 @@ fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blend fz_clearpixmap(dest, 0); + dev->stack[dev->top].alpha = alpha; dev->stack[dev->top].blendmode = blendmode; dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].dest = dev->dest; @@ -846,14 +873,40 @@ fz_drawendgroup(void *user) fz_drawdevice *dev = user; fz_pixmap *group = dev->dest; fz_blendmode blendmode; + float alpha; if (dev->top > 0) { dev->top--; + alpha = dev->stack[dev->top].alpha; blendmode = dev->stack[dev->top].blendmode; dev->dest = dev->stack[dev->top].dest; dev->scissor = dev->stack[dev->top].scissor; - fz_blendpixmapswithmode(dev->dest, group, blendmode); + + /* TODO: blend mode + constant alpha */ + if (blendmode == FZ_BNORMAL) + { + if (alpha < 1) + fz_blendpixmapswithalpha(dev->dest, group, alpha); + else + fz_blendpixmaps(dev->dest, group); + } + else + { + if (alpha < 1) + { + unsigned char *p = group->samples; + int n = group->w * group->h * group->n; + int a = alpha * 255; + while (n--) + { + *p = fz_mul255(*p, a); + p++; + } + } + fz_blendpixmapswithmode(dev->dest, group, blendmode); + } + fz_droppixmap(group); } } |