diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-08-26 14:59:40 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-08-26 14:59:40 +0000 |
commit | 89e4f36476393a52d1c16feacea4d1f495b9d12c (patch) | |
tree | 037a8cb3e5db2854f81d6ee67dad18d5c6d2aa38 | |
parent | f943c91e68893a2e9f7a2b42cea56daa73fd169d (diff) | |
download | mupdf-89e4f36476393a52d1c16feacea4d1f495b9d12c.tar.xz |
Load and draw annotations with appearance streams.
-rw-r--r-- | mupdf/mupdf.h | 23 | ||||
-rw-r--r-- | mupdf/pdf_annot.c | 86 | ||||
-rw-r--r-- | mupdf/pdf_interpret.c | 41 | ||||
-rw-r--r-- | mupdf/pdf_page.c | 8 | ||||
-rw-r--r-- | mupdf/pdf_type3.c | 2 |
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 */ |