summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/pdfapp.c2
-rw-r--r--apps/pdfdraw.c8
-rw-r--r--draw/blendmodes.c2
-rw-r--r--fitz/dev_draw.c23
-rw-r--r--fitz/dev_list.c9
-rw-r--r--fitz/dev_null.c2
-rw-r--r--fitz/dev_trace.c2
-rw-r--r--fitz/fitz.h6
-rw-r--r--fitz/res_font.c6
-rw-r--r--mupdf/mupdf.h4
-rw-r--r--mupdf/pdf_build.c8
-rw-r--r--mupdf/pdf_interpret.c71
-rw-r--r--mupdf/pdf_page.c95
-rw-r--r--mupdf/pdf_type3.c2
14 files changed, 178 insertions, 62 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 145f49db..c5930129 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -265,7 +265,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
/* Create display list */
app->page->list = fz_newdisplaylist();
mdev = fz_newlistdevice(app->page->list);
- error = pdf_runcontentstream(mdev, fz_identity, app->xref, app->page->resources, app->page->contents);
+ error = pdf_runpage(app->xref, app->page, mdev, fz_identity);
if (error)
{
error = fz_rethrow(error, "cannot draw page %d in '%s'", app->pageno, app->doctitle);
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index 3fb5f3c4..3ec51631 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -212,7 +212,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *
fprintf(stdout, "creating display list for banded rendering\n");
list = fz_newdisplaylist();
dev = fz_newlistdevice(list);
- error = pdf_runcontentstream(dev, fz_identity, xref, drawpage->resources, drawpage->contents);
+ error = pdf_runpage(xref, drawpage, dev, fz_identity);
if (error)
die(fz_rethrow(error, "cannot draw page %d in PDF file '%s'", pagenum, basename));
fz_freedevice(dev);
@@ -231,7 +231,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *
}
else
{
- error = pdf_runcontentstream(dev, ctm, xref, drawpage->resources, drawpage->contents);
+ error = pdf_runpage(xref, drawpage, dev, ctm);
if (error)
die(fz_rethrow(error, "cannot draw page %d in PDF file '%s'", pagenum, basename));
}
@@ -342,7 +342,7 @@ static void drawtxt(int pagenum, struct benchmark *loadtimes)
text = fz_newtextspan();
dev = fz_newtextdevice(text);
- error = pdf_runcontentstream(dev, ctm, xref, drawpage->resources, drawpage->contents);
+ error = pdf_runpage(xref, drawpage, dev, ctm);
if (error)
die(fz_rethrow(error, "cannot extract text from page %d in PDF file '%s'", pagenum, basename));
@@ -375,7 +375,7 @@ static void drawxml(int pagenum)
printf("<?xml version=\"1.0\"?>\n");
printf("<page number=\"%d\">\n", pagenum);
- error = pdf_runcontentstream(dev, ctm, xref, drawpage->resources, drawpage->contents);
+ error = pdf_runpage(xref, drawpage, dev, ctm);
if (error)
die(fz_rethrow(error, "cannot display page %d in PDF file '%s' as XML", pagenum, basename));
diff --git a/draw/blendmodes.c b/draw/blendmodes.c
index 5a7530ec..11cb627f 100644
--- a/draw/blendmodes.c
+++ b/draw/blendmodes.c
@@ -282,7 +282,7 @@ fz_blendnonseparable(byte * restrict sp, byte * restrict bp, int w, fz_blendmode
saba = fz_mul255(sa, ba);
- /* ugh, bivision to get non-premul components */
+ /* ugh, division to get non-premul components */
if (sa) {
sr = sr * 255 / sa;
sg = sg * 255 / sa;
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index 86ef1846..28550174 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -24,8 +24,10 @@ struct fz_drawdevice_s
} clipstack[MAXCLIP];
int cliptop;
- fz_blendmode blendmode;
- fz_pixmap *groupstack[MAXCLIP];
+ struct {
+ fz_pixmap *dest;
+ fz_blendmode blendmode;
+ } groupstack[MAXCLIP];
int grouptop;
};
@@ -819,14 +821,12 @@ fz_drawendmask(void *user)
}
static void
-fz_drawbegingroup(void *user, fz_rect rect, fz_colorspace *colorspace, int isolated, int knockout, fz_blendmode blendmode)
+fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode)
{
fz_drawdevice *dev = user;
fz_bbox bbox;
fz_pixmap *dest;
- fz_warn("fz_drawbegingroup");
-
if (dev->cliptop == MAXCLIP)
{
fz_warn("assert: too many clip masks on stack");
@@ -839,8 +839,9 @@ fz_drawbegingroup(void *user, fz_rect rect, fz_colorspace *colorspace, int isola
fz_clearpixmap(dest, 0);
- dev->blendmode = blendmode;
- dev->groupstack[dev->grouptop++] = dev->dest;
+ dev->groupstack[dev->grouptop].blendmode = blendmode;
+ dev->groupstack[dev->grouptop].dest = dev->dest;
+ dev->grouptop++;
dev->dest = dest;
}
@@ -849,14 +850,14 @@ fz_drawendgroup(void *user)
{
fz_drawdevice *dev = user;
fz_pixmap *group = dev->dest;
-
- fz_warn("fz_drawendgroup");
+ fz_blendmode blendmode;
if (dev->grouptop > 0)
{
dev->grouptop--;
- dev->dest = dev->groupstack[dev->grouptop];
- fz_blendpixmaps(group, dev->dest, dev->blendmode);
+ dev->dest = dev->groupstack[dev->grouptop].dest;
+ blendmode = dev->groupstack[dev->grouptop].blendmode;
+ fz_blendpixmaps(group, dev->dest, blendmode);
}
fz_droppixmap(group);
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index f3e7c750..c5c65017 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -269,10 +269,10 @@ fz_listendmask(void *user)
}
static void
-fz_listbegingroup(void *user, fz_rect rect, fz_colorspace *colorspace, int isolated, int knockout, fz_blendmode blendmode)
+fz_listbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode)
{
fz_displaynode *node;
- node = fz_newdisplaynode(FZ_CMDBEGINGROUP, fz_identity, colorspace, nil, 0);
+ node = fz_newdisplaynode(FZ_CMDBEGINGROUP, fz_identity, nil, nil, 0);
node->rect = rect;
node->item.blendmode = blendmode;
node->flag |= isolated ? ISOLATED : 0;
@@ -406,8 +406,9 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
break;
case FZ_CMDBEGINGROUP:
bbox = fz_transformrect(topctm, node->rect);
- dev->begingroup(dev->user, bbox, node->colorspace,
- node->flag & ISOLATED, node->flag & KNOCKOUT, node->item.blendmode);
+ dev->begingroup(dev->user, bbox,
+ node->flag & ISOLATED, node->flag & KNOCKOUT,
+ node->item.blendmode);
break;
case FZ_CMDENDGROUP:
dev->endgroup(dev->user);
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index 223275aa..90737e63 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -17,7 +17,7 @@ static void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz
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, fz_colorspace *cs, int isolated, int knockout, fz_blendmode blendmode) {}
+static void fz_nullbegingroup(void *user, fz_rect r, int isolated, int knockout, fz_blendmode blendmode) {}
static void fz_nullendgroup(void *user) {}
fz_device *
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index b51015f8..6941ec40 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -244,7 +244,7 @@ fz_traceendmask(void *user)
}
static void
-fz_tracebegingroup(void *user, fz_rect bbox, fz_colorspace *colorspace, int isolated, int knockout, fz_blendmode blendmode)
+fz_tracebegingroup(void *user, fz_rect bbox, int isolated, int knockout, fz_blendmode blendmode)
{
printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%d\">\n",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
diff --git a/fitz/fitz.h b/fitz/fitz.h
index e8fb9efe..38b26619 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -759,8 +759,8 @@ struct fz_font_s
fz_buffer **t3procs; /* has 256 entries if used */
float *t3widths; /* has 256 entries if used */
void *t3xref; /* a pdf_xref for the callback */
- fz_error (*t3runcontentstream)(struct fz_device_s *dev, fz_matrix ctm,
- struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents);
+ fz_error (*t3run)(struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents,
+ struct fz_device_s *dev, fz_matrix ctm);
fz_rect bbox;
@@ -1016,7 +1016,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, fz_colorspace *, int isolated, int knockout, fz_blendmode blendmode);
+ void (*begingroup)(void *, fz_rect, int isolated, int knockout, fz_blendmode blendmode);
void (*endgroup)(void *);
};
diff --git a/fitz/res_font.c b/fitz/res_font.c
index aca58c0b..368c4919 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -24,7 +24,7 @@ fz_newfont(void)
font->t3procs = nil;
font->t3widths = nil;
font->t3xref = nil;
- font->t3runcontentstream = nil;
+ font->t3run = nil;
font->bbox.x0 = 0;
font->bbox.y0 = 0;
@@ -466,7 +466,7 @@ fz_rendert3glyph(fz_font *font, int gid, fz_matrix trm)
ctm = fz_concat(font->t3matrix, trm);
dev = fz_newbboxdevice(&bbox);
- error = font->t3runcontentstream(dev, ctm, font->t3xref, font->t3resources, contents);
+ error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm);
if (error)
fz_catch(error, "cannot draw type3 glyph");
fz_freedevice(dev);
@@ -476,7 +476,7 @@ fz_rendert3glyph(fz_font *font, int gid, fz_matrix trm)
cache = fz_newglyphcache();
dev = fz_newdrawdevice(cache, glyph);
- error = font->t3runcontentstream(dev, ctm, font->t3xref, font->t3resources, contents);
+ error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm);
if (error)
fz_catch(error, "cannot draw type3 glyph");
fz_freedevice(dev);
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index eea518d5..24cf2f3d 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -523,6 +523,7 @@ struct pdf_page_s
{
fz_rect mediabox;
int rotate;
+ int transparency;
fz_obj *resources;
fz_buffer *contents;
fz_displaylist *list;
@@ -642,7 +643,8 @@ void pdf_showshade(pdf_csi*, fz_shade *shd);
void pdf_gsave(pdf_csi *csi);
void pdf_grestore(pdf_csi *csi);
fz_error pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents);
-fz_error pdf_runcontentstream(fz_device *dev, fz_matrix ctm, pdf_xref *xref, fz_obj *resources, fz_buffer *contents);
+fz_error pdf_runcontents(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm);
+fz_error pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm);
pdf_material * pdf_keepmaterial(pdf_material *mat);
pdf_material * pdf_dropmaterial(pdf_material *mat);
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index ae408bf3..fe6cc301 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -225,7 +225,7 @@ pdf_showshade(pdf_csi *csi, fz_shade *shd)
if (gstate->blendmode != FZ_BNORMAL)
{
fz_rect bbox = fz_boundshade(shd, gstate->ctm);
- csi->dev->begingroup(csi->dev->user, bbox, nil, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
}
csi->dev->fillshade(csi->dev->user, shd, gstate->ctm);
@@ -250,7 +250,7 @@ pdf_showimage(pdf_csi *csi, pdf_image *image)
if (gstate->blendmode != FZ_BNORMAL)
{
fz_rect bbox = fz_transformrect(gstate->ctm, fz_unitrect);
- csi->dev->begingroup(csi->dev->user, bbox, nil, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
}
tile = pdf_loadtile(image);
@@ -327,7 +327,7 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
bbox = fz_boundpath(path, &gstate->strokestate, gstate->ctm);
else
bbox = fz_boundpath(path, nil, gstate->ctm);
- csi->dev->begingroup(csi->dev->user, bbox, nil, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
}
if (dofill)
@@ -462,7 +462,7 @@ pdf_flushtext(pdf_csi *csi)
if (gstate->blendmode != FZ_BNORMAL)
{
fz_rect bbox = fz_boundtext(text, gstate->ctm);
- csi->dev->begingroup(csi->dev->user, bbox, nil, 0, 0, gstate->blendmode);
+ csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode);
}
if (dofill)
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 8a901468..f89f9acc 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -2,13 +2,13 @@
#include "mupdf.h"
static pdf_csi *
-pdf_newcsi(fz_device *dev, pdf_xref *xref, fz_matrix ctm)
+pdf_newcsi(pdf_xref *xref, fz_device *dev, fz_matrix ctm)
{
pdf_csi *csi;
csi = fz_malloc(sizeof(pdf_csi));
- csi->dev = dev;
csi->xref = xref;
+ csi->dev = dev;
csi->top = 0;
csi->xbalance = 0;
@@ -156,24 +156,21 @@ pdf_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj)
gstate->stroke.parentalpha = gstate->stroke.alpha;
gstate->fill.parentalpha = gstate->fill.alpha;
+ /* apply xobject's transform matrix */
+ gstate->ctm = fz_concat(xobj->matrix, gstate->ctm);
+
/* reset alpha to 1.0 when starting a new Transparency group */
if (xobj->transparency)
{
+ csi->dev->begingroup(csi->dev->user,
+ fz_transformrect(gstate->ctm, xobj->bbox),
+ xobj->isolated, xobj->knockout, gstate->blendmode);
+
gstate->blendmode = FZ_BNORMAL;
gstate->stroke.alpha = gstate->stroke.parentalpha;
gstate->fill.alpha = gstate->fill.parentalpha;
}
- /* apply xobject's transform matrix */
- gstate->ctm = fz_concat(xobj->matrix, gstate->ctm);
-
- if (xobj->isolated || xobj->knockout)
- {
- /* The xobject's contents ought to be blended properly,
- but for now, just do over and hope for something */
- // TODO: push, pop and blend buffers
- }
-
/* clip to the bounds */
fz_moveto(csi->path, xobj->bbox.x0, xobj->bbox.y0);
@@ -196,6 +193,9 @@ pdf_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj)
if (error)
return fz_rethrow(error, "cannot interpret XObject stream");
+ if (xobj->transparency)
+ csi->dev->endgroup(csi->dev->user);
+
csi->topctm = oldtopctm;
while (oldtop < csi->gtop)
@@ -247,7 +247,7 @@ pdf_runinlineimage(pdf_csi *csi, fz_obj *rdb, fz_stream *file, fz_obj *dict)
*/
static fz_error
-pdf_runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *rdb, fz_obj *extgstate)
+pdf_runextgstate(pdf_csi *csi, pdf_gstate *gstate, fz_obj *rdb, fz_obj *extgstate)
{
int i, k;
@@ -270,7 +270,7 @@ pdf_runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *rdb, fz_obj *extgst
gstate->font = nil;
}
- error = pdf_loadfont(&gstate->font, xref, rdb, font);
+ error = pdf_loadfont(&gstate->font, csi->xref, rdb, font);
if (error)
return fz_rethrow(error, "cannot load font (%d %d R)", fz_tonum(font), fz_togen(font));
if (!gstate->font)
@@ -335,16 +335,14 @@ pdf_runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *rdb, fz_obj *extgst
return fz_throw("malformed BM");
gstate->blendmode = FZ_BNORMAL;
-#if 1
- for (k = 0; k < nelem(bm); k++) {
- if (!strcmp(bm[k].name, n)) {
+ for (k = 0; k < nelem(bm); k++)
+ {
+ if (!strcmp(bm[k].name, n))
+ {
gstate->blendmode = bm[k].mode;
- if (gstate->blendmode != FZ_BNORMAL)
- fz_warn("ignoring blend mode %s", n);
break;
}
}
-#endif
}
else if (!strcmp(s, "SMask"))
@@ -364,14 +362,14 @@ pdf_runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *rdb, fz_obj *extgst
if (!strcmp(fz_toname(subtype), "Form"))
{
- error = pdf_loadxobject(&xobj, xref, g);
+ error = pdf_loadxobject(&xobj, csi->xref, g);
if (error)
return fz_rethrow(error, "cannot load xobject (%d %d R)", fz_tonum(val), fz_togen(val));
}
else if (!strcmp(fz_toname(subtype), "Image"))
{
- error = pdf_loadimage(&img, xref, g);
+ error = pdf_loadimage(&img, csi->xref, g);
if (error)
return fz_rethrow(error, "cannot load xobject (%d %d R)", fz_tonum(val), fz_togen(val));
}
@@ -1100,7 +1098,7 @@ Lsetcolor:
if (!obj)
return fz_throw("cannot find extgstate resource /%s", fz_toname(csi->stack[0]));
- error = pdf_runextgstate(gstate, csi->xref, rdb, obj);
+ error = pdf_runextgstate(csi, gstate, rdb, obj);
if (error)
return fz_rethrow(error, "cannot set ExtGState (%d %d R)", fz_tonum(obj), fz_togen(obj));
break;
@@ -1497,7 +1495,6 @@ pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
{
fz_stream *file;
fz_error error;
-
contents->rp = contents->bp;
file = fz_openbuffer(contents);
error = pdf_runcsifile(csi, rdb, file, csi->xref->scratch, sizeof csi->xref->scratch);
@@ -1509,13 +1506,33 @@ pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
}
fz_error
-pdf_runcontentstream(fz_device *dev, fz_matrix ctm,
- pdf_xref *xref, fz_obj *resources, fz_buffer *contents)
+pdf_runcontents(pdf_xref *xref, fz_obj *resources, fz_buffer *contents,
+ fz_device *dev, fz_matrix ctm)
{
- pdf_csi *csi = pdf_newcsi(dev, xref, ctm);
+ pdf_csi *csi = pdf_newcsi(xref, dev, ctm);
fz_error error = pdf_runcsibuffer(csi, resources, contents);
pdf_freecsi(csi);
if (error)
return fz_rethrow(error, "cannot parse content stream");
return fz_okay;
}
+
+fz_error
+pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
+{
+ fz_error error;
+
+ if (page->transparency)
+ dev->begingroup(dev->user,
+ fz_transformrect(ctm, page->mediabox),
+ 0, 0, FZ_BNORMAL);
+
+ error = pdf_runcontents(xref, page->resources, page->contents, dev, ctm);
+ if (error)
+ return fz_rethrow(error, "cannot parse page content stream");
+
+ if (page->transparency)
+ dev->endgroup(dev->user);
+
+ return fz_okay;
+}
diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c
index d39fad83..794e50b1 100644
--- a/mupdf/pdf_page.c
+++ b/mupdf/pdf_page.c
@@ -2,6 +2,7 @@
#include "mupdf.h"
/* we need to combine all sub-streams into one for the content stream interpreter */
+
static fz_error
pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
{
@@ -64,6 +65,96 @@ pdf_loadpagecontents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj)
return fz_okay;
}
+/* We need to know whether to install a page-level transparency group */
+
+static int pdf_resourcesusetransparency(fz_obj *rdb);
+
+static int
+pdf_extgstateusestransparency(fz_obj *dict)
+{
+ fz_obj *obj;
+
+ obj = fz_dictgets(dict, "BM");
+ if (fz_isname(obj) && strcmp(fz_toname(obj), "Normal"))
+ return 1;
+
+ obj = fz_dictgets(dict, "SMask");
+ if (fz_isname(obj) && strcmp(fz_toname(obj), "None"))
+ return 1;
+
+ obj = fz_dictgets(dict, "ca");
+ if (obj && fz_toreal(obj) < 1)
+ return 1;
+
+ obj = fz_dictgets(dict, "CA");
+ if (obj && fz_toreal(obj) < 1)
+ return 1;
+
+ return 0;
+}
+
+static int
+pdf_patternusestransparency(fz_obj *dict)
+{
+ fz_obj *obj;
+
+ obj = fz_dictgets(dict, "Resources");
+ if (pdf_resourcesusetransparency(obj))
+ return 1;
+
+ obj = fz_dictgets(dict, "ExtGState");
+ if (pdf_resourcesusetransparency(obj))
+ return 1;
+
+ return 0;
+}
+
+static int
+pdf_xobjectusestransparency(fz_obj *dict)
+{
+ fz_obj *obj;
+
+ obj = fz_dictgets(dict, "SMask");
+ if (fz_isname(obj) && strcmp(fz_toname(obj), "None"))
+ return 1;
+
+ obj = fz_dictgets(dict, "Resources");
+ if (pdf_resourcesusetransparency(obj))
+ return 1;
+
+ return 0;
+}
+
+static int
+pdf_resourcesusetransparency(fz_obj *rdb)
+{
+ fz_obj *dict;
+ int i;
+
+ /* stop on cyclic resource dependencies */
+ if (fz_dictgets(rdb, ".seen"))
+ return 0;
+
+ fz_dictputs(rdb, ".seen", fz_newnull());
+
+ dict = fz_dictgets(rdb, "ExtGState");
+ for (i = 0; i < fz_dictlen(dict); i++)
+ if (pdf_extgstateusestransparency(fz_dictgetval(dict, i)))
+ return 1;
+
+ dict = fz_dictgets(rdb, "Pattern");
+ for (i = 0; i < fz_dictlen(dict); i++)
+ if (pdf_patternusestransparency(fz_dictgetval(dict, i)))
+ return 1;
+
+ dict = fz_dictgets(rdb, "XObject");
+ for (i = 0; i < fz_dictlen(dict); i++)
+ if (pdf_xobjectusestransparency(fz_dictgetval(dict, i)))
+ return 1;
+
+ return 0;
+}
+
fz_error
pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
{
@@ -82,6 +173,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page = fz_malloc(sizeof(pdf_page));
page->resources = nil;
page->contents = nil;
+ page->transparency = 0;
page->list = nil;
page->text = nil;
page->links = nil;
@@ -127,6 +219,9 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
return fz_rethrow(error, "cannot load page contents (%d %d R)", fz_tonum(obj), fz_togen(obj));
}
+ if (pdf_resourcesusetransparency(page->resources))
+ page->transparency = 1;
+
pdf_logpage("} %p\n", page);
*pagep = page;
diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c
index c45e3ff6..ddcf0258 100644
--- a/mupdf/pdf_type3.c
+++ b/mupdf/pdf_type3.c
@@ -135,7 +135,7 @@ pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj
fz_warn("no resource dictionary for type 3 font!");
fontdesc->font->t3xref = xref;
- fontdesc->font->t3runcontentstream = pdf_runcontentstream;
+ fontdesc->font->t3run = pdf_runcontents;
/*
* CharProcs