summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fitz/dev_draw.c65
-rw-r--r--fitz/dev_list.c18
-rw-r--r--fitz/dev_null.c6
-rw-r--r--fitz/dev_trace.c14
-rw-r--r--fitz/fitz.h6
-rw-r--r--mupdf/pdf_build.c28
-rw-r--r--mupdf/pdf_interpret.c7
7 files changed, 94 insertions, 50 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);
}
}
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index 65c2c731..4dcd1470 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -210,20 +210,20 @@ fz_listpopclip(void *user)
}
static void
-fz_listfillshade(void *user, fz_shade *shade, fz_matrix ctm)
+fz_listfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
fz_displaynode *node;
- node = fz_newdisplaynode(FZ_CMDFILLSHADE, ctm, nil, nil, 0);
+ node = fz_newdisplaynode(FZ_CMDFILLSHADE, ctm, nil, nil, alpha);
node->rect = fz_boundshade(shade, ctm);
node->item.shade = fz_keepshade(shade);
fz_appenddisplaynode(user, node);
}
static void
-fz_listfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
+fz_listfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
fz_displaynode *node;
- node = fz_newdisplaynode(FZ_CMDFILLIMAGE, ctm, nil, nil, 0);
+ node = fz_newdisplaynode(FZ_CMDFILLIMAGE, ctm, nil, nil, alpha);
node->rect = fz_transformrect(ctm, fz_unitrect);
node->item.image = fz_keeppixmap(image);
fz_appenddisplaynode(user, node);
@@ -269,10 +269,10 @@ fz_listendmask(void *user)
}
static void
-fz_listbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode)
+fz_listbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode, float alpha)
{
fz_displaynode *node;
- node = fz_newdisplaynode(FZ_CMDBEGINGROUP, fz_identity, nil, nil, 0);
+ node = fz_newdisplaynode(FZ_CMDBEGINGROUP, fz_identity, nil, nil, alpha);
node->rect = rect;
node->item.blendmode = blendmode;
node->flag |= isolated ? ISOLATED : 0;
@@ -383,10 +383,10 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
dev->ignoretext(dev->user, node->item.text, ctm);
break;
case FZ_CMDFILLSHADE:
- dev->fillshade(dev->user, node->item.shade, ctm);
+ dev->fillshade(dev->user, node->item.shade, ctm, node->alpha);
break;
case FZ_CMDFILLIMAGE:
- dev->fillimage(dev->user, node->item.image, ctm);
+ dev->fillimage(dev->user, node->item.image, ctm, node->alpha);
break;
case FZ_CMDFILLIMAGEMASK:
dev->fillimagemask(dev->user, node->item.image, ctm,
@@ -409,7 +409,7 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
bbox = fz_transformrect(topctm, node->rect);
dev->begingroup(dev->user, bbox,
node->flag & ISOLATED, node->flag & KNOCKOUT,
- node->item.blendmode);
+ node->item.blendmode, node->alpha);
break;
case FZ_CMDENDGROUP:
dev->endgroup(dev->user);
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index 336d2e8d..c48cc2aa 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -11,13 +11,13 @@ static void fz_nullcliptext(void *user, fz_text *text, fz_matrix ctm, int accumu
static void fz_nullclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm) {}
static void fz_nullignoretext(void *user, fz_text *text, fz_matrix ctm) {}
static void fz_nullpopclip(void *user) {}
-static void fz_nullfillshade(void *user, fz_shade *shade, fz_matrix ctm) {}
-static void fz_nullfillimage(void *user, fz_pixmap *image, fz_matrix ctm) {}
+static void fz_nullfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha) {}
+static void fz_nullfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha) {}
static void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
static void fz_nullclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) {}
static void fz_nullbeginmask(void *user, fz_rect r, int luminosity, fz_colorspace *cs, float *bc) {}
static void fz_nullendmask(void *user) {}
-static void fz_nullbegingroup(void *user, fz_rect r, int isolated, int knockout, fz_blendmode blendmode) {}
+static void fz_nullbegingroup(void *user, fz_rect r, int isolated, int knockout, fz_blendmode blendmode, float alpha) {}
static void fz_nullendgroup(void *user) {}
fz_device *
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index cdd71135..b6b73fd7 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -187,17 +187,17 @@ fz_traceignoretext(void *user, fz_text *text, fz_matrix ctm)
}
static void
-fz_tracefillimage(void *user, fz_pixmap *image, fz_matrix ctm)
+fz_tracefillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
- printf("<fillimage ");
+ printf("<fillimage alpha=\"%g\" ", alpha);
fz_tracematrix(ctm);
printf("/>\n");
}
static void
-fz_tracefillshade(void *user, fz_shade *shade, fz_matrix ctm)
+fz_tracefillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
- printf("<fillshade ");
+ printf("<fillshade alpha=\"%g\" ", alpha);
fz_tracematrix(ctm);
printf("/>\n");
}
@@ -245,11 +245,11 @@ fz_traceendmask(void *user)
}
static void
-fz_tracebegingroup(void *user, fz_rect bbox, int isolated, int knockout, fz_blendmode blendmode)
+fz_tracebegingroup(void *user, fz_rect bbox, int isolated, int knockout, fz_blendmode blendmode, float alpha)
{
- printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\">\n",
+ printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\" alpha=\"%g\">\n",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
- isolated, knockout, fz_blendnames[blendmode]);
+ isolated, knockout, fz_blendnames[blendmode], alpha);
}
static void
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 140f2f60..bff0ce70 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -1014,8 +1014,8 @@ struct fz_device_s
void (*clipstroketext)(void *, fz_text *, fz_strokestate *, fz_matrix);
void (*ignoretext)(void *, fz_text *, fz_matrix);
- void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm);
- void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm);
+ void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm, float alpha);
+ void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm, float alpha);
void (*fillimagemask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
void (*clipimagemask)(void *, fz_pixmap *img, fz_matrix ctm);
@@ -1023,7 +1023,7 @@ struct fz_device_s
void (*beginmask)(void *, fz_rect, int luminosity, fz_colorspace *cs, float *bc);
void (*endmask)(void *);
- void (*begingroup)(void *, fz_rect, int isolated, int knockout, fz_blendmode blendmode);
+ void (*begingroup)(void *, fz_rect, int isolated, int knockout, fz_blendmode blendmode, float alpha);
void (*endgroup)(void *);
};
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 13c16372..b34e1548 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -224,15 +224,12 @@ pdf_showshade(pdf_csi *csi, fz_shade *shd)
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_rect bbox;
- if (gstate->fill.alpha < 1)
- fz_warn("ignoring ca for shading: %g", gstate->fill.alpha);
-
bbox = fz_boundshade(shd, gstate->ctm);
if (gstate->blendmode != FZ_BNORMAL)
- csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);
- csi->dev->fillshade(csi->dev->user, shd, gstate->ctm);
+ csi->dev->fillshade(csi->dev->user, shd, gstate->ctm, gstate->fill.alpha);
if (gstate->blendmode != FZ_BNORMAL)
csi->dev->endgroup(csi->dev->user);
@@ -245,13 +242,10 @@ pdf_showimage(pdf_csi *csi, pdf_image *image)
fz_pixmap *tile, *mask;
fz_rect bbox;
- if (gstate->fill.alpha < 1)
- fz_warn("ignoring ca for image: %g", gstate->fill.alpha);
-
bbox = fz_transformrect(gstate->ctm, fz_unitrect);
if (gstate->blendmode != FZ_BNORMAL)
- csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);
if (image->mask)
{
@@ -285,7 +279,7 @@ pdf_showimage(pdf_csi *csi, pdf_image *image)
if (gstate->fill.shade)
{
csi->dev->clipimagemask(csi->dev->user, tile, gstate->ctm);
- csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm);
+ csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm, gstate->fill.alpha);
csi->dev->popclip(csi->dev->user);
}
break;
@@ -293,7 +287,7 @@ pdf_showimage(pdf_csi *csi, pdf_image *image)
}
else
{
- csi->dev->fillimage(csi->dev->user, tile, gstate->ctm);
+ csi->dev->fillimage(csi->dev->user, tile, gstate->ctm, gstate->fill.alpha);
}
if (image->mask)
@@ -331,7 +325,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
bbox = fz_boundpath(path, nil, gstate->ctm);
if (gstate->blendmode != FZ_BNORMAL)
- csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);
if (dofill)
{
@@ -355,7 +349,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
if (gstate->fill.shade)
{
csi->dev->clippath(csi->dev->user, path, evenodd, gstate->ctm);
- csi->dev->fillshade(csi->dev->user, gstate->fill.shade, csi->topctm);
+ csi->dev->fillshade(csi->dev->user, gstate->fill.shade, csi->topctm, gstate->fill.alpha);
csi->dev->popclip(csi->dev->user);
}
break;
@@ -384,7 +378,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
if (gstate->stroke.shade)
{
csi->dev->clipstrokepath(csi->dev->user, path, &gstate->strokestate, gstate->ctm);
- csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, csi->topctm);
+ csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, csi->topctm, gstate->stroke.alpha);
csi->dev->popclip(csi->dev->user);
}
break;
@@ -429,7 +423,7 @@ pdf_flushtext(pdf_csi *csi)
bbox = fz_boundtext(text, gstate->ctm);
if (gstate->blendmode != FZ_BNORMAL)
- csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);
if (doinvisible)
csi->dev->ignoretext(csi->dev->user, text, gstate->ctm);
@@ -463,7 +457,7 @@ pdf_flushtext(pdf_csi *csi)
if (gstate->fill.shade)
{
csi->dev->cliptext(csi->dev->user, text, gstate->ctm, 0);
- csi->dev->fillshade(csi->dev->user, gstate->fill.shade, csi->topctm);
+ csi->dev->fillshade(csi->dev->user, gstate->fill.shade, csi->topctm, gstate->fill.alpha);
csi->dev->popclip(csi->dev->user);
}
break;
@@ -492,7 +486,7 @@ pdf_flushtext(pdf_csi *csi)
if (gstate->stroke.shade)
{
csi->dev->clipstroketext(csi->dev->user, text, &gstate->strokestate, gstate->ctm);
- csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, csi->topctm);
+ csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, csi->topctm, gstate->stroke.alpha);
csi->dev->popclip(csi->dev->user);
}
break;
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index a9392765..90abe657 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -175,12 +175,9 @@ pdf_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj)
pdf_dropxobject(softmask);
}
- if (gstate->fill.alpha < 1)
- fz_warn("ignoring ca for xobject: %g", gstate->fill.alpha);
-
csi->dev->begingroup(csi->dev->user,
fz_transformrect(gstate->ctm, xobj->bbox),
- xobj->isolated, xobj->knockout, gstate->blendmode);
+ xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
gstate->blendmode = FZ_BNORMAL;
gstate->stroke.alpha = 1;
@@ -1513,7 +1510,7 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
if (page->transparency)
dev->begingroup(dev->user,
fz_transformrect(ctm, page->mediabox),
- 0, 0, FZ_BNORMAL);
+ 0, 0, FZ_BNORMAL, 1);
error = pdf_runcontents(xref, page->resources, page->contents, dev, ctm);
if (error)