summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-08-26 14:59:40 +0000
committerTor Andersson <tor@ghostscript.com>2010-08-26 14:59:40 +0000
commit89e4f36476393a52d1c16feacea4d1f495b9d12c (patch)
tree037a8cb3e5db2854f81d6ee67dad18d5c6d2aa38
parentf943c91e68893a2e9f7a2b42cea56daa73fd169d (diff)
downloadmupdf-89e4f36476393a52d1c16feacea4d1f495b9d12c.tar.xz
Load and draw annotations with appearance streams.
-rw-r--r--mupdf/mupdf.h23
-rw-r--r--mupdf/pdf_annot.c86
-rw-r--r--mupdf/pdf_interpret.c41
-rw-r--r--mupdf/pdf_page.c8
-rw-r--r--mupdf/pdf_type3.c2
5 files changed, 124 insertions, 36 deletions
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index a62ccc6c..359e01fd 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -441,6 +441,7 @@ void pdf_debugfont(pdf_fontdesc *fontdesc);
*/
typedef struct pdf_link_s pdf_link;
+typedef struct pdf_annot_s pdf_annot;
typedef struct pdf_outline_s pdf_outline;
typedef enum pdf_linkkind_e
@@ -457,6 +458,14 @@ struct pdf_link_s
pdf_link *next;
};
+struct pdf_annot_s
+{
+ fz_obj *obj;
+ fz_rect rect;
+ pdf_xobject *ap;
+ pdf_annot *next;
+};
+
struct pdf_outline_s
{
char *title;
@@ -468,15 +477,16 @@ struct pdf_outline_s
fz_obj *pdf_lookupdest(pdf_xref *xref, fz_obj *nameddest);
-pdf_link *pdf_newlink(pdf_linkkind kind, fz_rect rect, fz_obj *dest);
-pdf_link *pdf_loadlink(pdf_xref *xref, fz_obj *dict);
-void pdf_freelink(pdf_link *link);
-
pdf_outline *pdf_loadoutline(pdf_xref *xref);
void pdf_debugoutline(pdf_outline *outline, int level);
void pdf_freeoutline(pdf_outline *outline);
-void pdf_loadannots(pdf_link **, pdf_xref *, fz_obj *annots);
+pdf_link *pdf_loadlink(pdf_xref *xref, fz_obj *dict);
+void pdf_loadlinks(pdf_link **, pdf_xref *, fz_obj *annots);
+void pdf_freelink(pdf_link *link);
+
+void pdf_loadannots(pdf_annot **, pdf_xref *, fz_obj *annots);
+void pdf_freeannot(pdf_annot *link);
/*
* Page tree, pages and related objects
@@ -494,6 +504,7 @@ struct pdf_page_s
fz_displaylist *list;
fz_textspan *text;
pdf_link *links;
+ pdf_annot *annots;
};
/* pagetree.c */
@@ -613,8 +624,8 @@ 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_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);
+fz_error pdf_runglyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, 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_annot.c b/mupdf/pdf_annot.c
index 9050ca24..0af7fa18 100644
--- a/mupdf/pdf_annot.c
+++ b/mupdf/pdf_annot.c
@@ -1,17 +1,6 @@
#include "fitz.h"
#include "mupdf.h"
-pdf_link *
-pdf_newlink(pdf_linkkind kind, fz_rect bbox, fz_obj *dest)
-{
- pdf_link *link = fz_malloc(sizeof(pdf_link));
- link->kind = kind;
- link->rect = bbox;
- link->dest = fz_keepobj(dest);
- link->next = nil;
- return link;
-}
-
void
pdf_freelink(pdf_link *link)
{
@@ -107,14 +96,19 @@ pdf_loadlink(pdf_xref *xref, fz_obj *dict)
if (dest)
{
- return pdf_newlink(kind, bbox, dest);
+ pdf_link *link = fz_malloc(sizeof(pdf_link));
+ link->kind = kind;
+ link->rect = bbox;
+ link->dest = fz_keepobj(dest);
+ link->next = nil;
+ return link;
}
return nil;
}
void
-pdf_loadannots(pdf_link **lp, pdf_xref *xref, fz_obj *annots)
+pdf_loadlinks(pdf_link **linkp, pdf_xref *xref, fz_obj *annots)
{
pdf_link *link;
fz_obj *subtype;
@@ -123,7 +117,7 @@ pdf_loadannots(pdf_link **lp, pdf_xref *xref, fz_obj *annots)
link = nil;
- pdf_logpage("load annotations {\n");
+ pdf_logpage("load link annotations {\n");
for (i = 0; i < fz_arraylen(annots); i++)
{
@@ -143,5 +137,67 @@ pdf_loadannots(pdf_link **lp, pdf_xref *xref, fz_obj *annots)
pdf_logpage("}\n");
- *lp = link;
+ *linkp = link;
+}
+
+void
+pdf_freeannot(pdf_annot *annot)
+{
+ if (annot->next)
+ pdf_freeannot(annot->next);
+ if (annot->ap)
+ pdf_dropxobject(annot->ap);
+ if (annot->obj)
+ fz_dropobj(annot->obj);
+ fz_free(annot);
+}
+
+void
+pdf_loadannots(pdf_annot **headp, pdf_xref *xref, fz_obj *annots)
+{
+ pdf_annot *head, *annot;
+ fz_obj *obj, *ap, *as, *n, *rect;
+ pdf_xobject *form;
+ fz_error error;
+ int i;
+
+ head = nil;
+
+ pdf_logpage("load appearance annotations {\n");
+
+ for (i = 0; i < fz_arraylen(annots); i++)
+ {
+ obj = fz_arrayget(annots, i);
+
+ rect = fz_dictgets(obj, "Rect");
+ ap = fz_dictgets(obj, "AP");
+ as = fz_dictgets(obj, "AS");
+ if (fz_isdict(ap))
+ {
+ n = fz_dictgets(ap, "N"); /* normal state */
+ if (fz_isindirect(n) && !pdf_isstream(xref, fz_tonum(n), fz_togen(n)))
+ n = fz_dictget(n, as);
+
+ if (fz_isindirect(n) && pdf_isstream(xref, fz_tonum(n), fz_togen(n)))
+ {
+ error = pdf_loadxobject(&form, xref, n);
+ if (error)
+ {
+ fz_catch(error, "ignoring broken annotation");
+ continue;
+ }
+
+ annot = fz_malloc(sizeof (pdf_annot));
+ annot->obj = fz_keepobj(obj);
+ annot->rect = pdf_torect(rect);
+ annot->ap = form;
+ annot->next = head;
+ head = annot;
+ }
+ }
+ }
+
+ pdf_logpage("}\n");
+
+ *headp = head;
}
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index e8cdf20d..77aa7465 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -1486,33 +1486,48 @@ pdf_runcsibuffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
}
fz_error
-pdf_runcontents(pdf_xref *xref, fz_obj *resources, fz_buffer *contents,
- fz_device *dev, fz_matrix 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)
{
+ pdf_csi *csi;
fz_error error;
+ pdf_annot *annot;
+ fz_matrix atm;
if (page->transparency)
dev->begingroup(dev->user,
fz_transformrect(ctm, page->mediabox),
0, 0, FZ_BNORMAL, 1);
- error = pdf_runcontents(xref, page->resources, page->contents, dev, ctm);
+ csi = pdf_newcsi(xref, dev, ctm);
+ error = pdf_runcsibuffer(csi, page->resources, page->contents);
+ pdf_freecsi(csi);
if (error)
return fz_rethrow(error, "cannot parse page content stream");
if (page->transparency)
dev->endgroup(dev->user);
+ for (annot = page->annots; annot; annot = annot->next)
+ {
+ atm = fz_concat(ctm, fz_translate(annot->rect.x0, annot->rect.y0));
+ csi = pdf_newcsi(xref, dev, atm);
+ error = pdf_runxobject(csi, page->resources, annot->ap);
+ pdf_freecsi(csi);
+ if (error)
+ return fz_rethrow(error, "cannot parse annotation appearance stream");
+ }
+
+ return fz_okay;
+}
+
+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);
+ fz_error error = pdf_runcsibuffer(csi, resources, contents);
+ pdf_freecsi(csi);
+ if (error)
+ return fz_rethrow(error, "cannot parse glyph content stream");
return fz_okay;
}
diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c
index 949abd4e..eed1526b 100644
--- a/mupdf/pdf_page.c
+++ b/mupdf/pdf_page.c
@@ -171,6 +171,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page->list = nil;
page->text = nil;
page->links = nil;
+ page->annots = nil;
obj = fz_dictgets(dict, "MediaBox");
if (!fz_isarray(obj))
@@ -199,7 +200,10 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
obj = fz_dictgets(dict, "Annots");
if (obj)
- pdf_loadannots(&page->links, xref, obj);
+ {
+ pdf_loadlinks(&page->links, xref, obj);
+ pdf_loadannots(&page->annots, xref, obj);
+ }
page->resources = fz_dictgets(dict, "Resources");
if (page->resources)
@@ -236,5 +240,7 @@ pdf_freepage(pdf_page *page)
fz_freetextspan(page->text);
if (page->links)
pdf_freelink(page->links);
+ if (page->annots)
+ pdf_freeannot(page->annots);
fz_free(page);
}
diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c
index 4d127921..9cc15596 100644
--- a/mupdf/pdf_type3.c
+++ b/mupdf/pdf_type3.c
@@ -129,7 +129,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->t3run = pdf_runcontents;
+ fontdesc->font->t3run = pdf_runglyph;
/* CharProcs */