summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-04 02:04:18 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-04 02:04:18 +0200
commita287d03f33f05a842fdd725f1ab95dbeafa9fe5b (patch)
tree0f8cc52179f1da6ab37cf1be1ac94733951ae459
parentfda7116fc12ea7e125ff8fc9851e3ca9280459b9 (diff)
downloadmupdf-a287d03f33f05a842fdd725f1ab95dbeafa9fe5b.tar.xz
pdf: Respect OCG target state visibility flags.
-rw-r--r--mupdf/mupdf.h5
-rw-r--r--mupdf/pdf_interpret.c42
2 files changed, 42 insertions, 5 deletions
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index f82bf9bb..4184a59f 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -598,6 +598,10 @@ struct pdf_csi_s
fz_device *dev;
pdf_xref *xref;
+ /* usage mode for optional content groups */
+ char *target; /* "View", "Print", "Export" */
+
+ /* interpreter stack */
fz_obj *obj;
char name[256];
unsigned char string[256];
@@ -646,6 +650,7 @@ 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_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform);
+fz_error pdf_runpagewithtarget(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *target);
fz_error pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm);
fz_error pdf_runglyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm);
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 6de24e74..dbeeb997 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -2,13 +2,14 @@
#include "mupdf.h"
static pdf_csi *
-pdf_newcsi(pdf_xref *xref, fz_device *dev, fz_matrix ctm)
+pdf_newcsi(pdf_xref *xref, fz_device *dev, fz_matrix ctm, char *target)
{
pdf_csi *csi;
csi = fz_malloc(sizeof(pdf_csi));
csi->xref = xref;
csi->dev = dev;
+ csi->target = target;
csi->top = 0;
csi->obj = nil;
@@ -154,6 +155,25 @@ pdf_freecsi(pdf_csi *csi)
fz_free(csi);
}
+static int
+pdf_ishiddenocg(pdf_csi *csi, fz_obj *xobj)
+{
+ char target_state[16];
+ fz_obj *obj;
+
+ fz_strlcpy(target_state, csi->target, sizeof target_state);
+ fz_strlcat(target_state, "State", sizeof target_state);
+
+ obj = fz_dictgets(xobj, "OC");
+ obj = fz_dictgets(obj, "OCGs");
+ if (fz_isarray(obj))
+ obj = fz_arrayget(obj, 0);
+ obj = fz_dictgets(obj, "Usage");
+ obj = fz_dictgets(obj, csi->target);
+ obj = fz_dictgets(obj, target_state);
+ return !strcmp(fz_toname(obj), "OFF");
+}
+
fz_error
pdf_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform)
{
@@ -547,6 +567,9 @@ static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
if (!fz_isname(subtype))
return fz_throw("no XObject subtype specified");
+ if (pdf_ishiddenocg(csi, obj))
+ return fz_okay;
+
if (!strcmp(fz_toname(subtype), "Form") && fz_dictgets(obj, "Subtype2"))
subtype = fz_dictgets(obj, "Subtype2");
@@ -1377,7 +1400,7 @@ pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
}
fz_error
-pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
+pdf_runpagewithtarget(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *target)
{
pdf_csi *csi;
fz_error error;
@@ -1389,7 +1412,7 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
fz_transformrect(ctm, page->mediabox),
0, 0, FZ_BNORMAL, 1);
- csi = pdf_newcsi(xref, dev, ctm);
+ csi = pdf_newcsi(xref, dev, ctm, target);
error = pdf_runcsibuffer(csi, page->resources, page->contents);
pdf_freecsi(csi);
if (error)
@@ -1407,7 +1430,10 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
if (flags & (1 << 5)) /* NoView */
continue;
- csi = pdf_newcsi(xref, dev, ctm);
+ if (pdf_ishiddenocg(csi, annot->obj))
+ continue;
+
+ csi = pdf_newcsi(xref, dev, ctm, target);
error = pdf_runxobject(csi, page->resources, annot->ap, annot->matrix);
pdf_freecsi(csi);
if (error)
@@ -1421,9 +1447,15 @@ pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
}
fz_error
+pdf_runpage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm)
+{
+ return pdf_runpagewithtarget(xref, page, dev, ctm, "View");
+}
+
+fz_error
pdf_runglyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm)
{
- pdf_csi *csi = pdf_newcsi(xref, dev, ctm);
+ pdf_csi *csi = pdf_newcsi(xref, dev, ctm, "View");
fz_error error = pdf_runcsibuffer(csi, resources, contents);
pdf_freecsi(csi);
if (error)