diff options
author | Tor Andersson <tor@ghostscript.com> | 2009-12-03 01:17:53 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2009-12-03 01:17:53 +0100 |
commit | 573ec2157b5bcc4c7798ebd7ef6e7d85612df949 (patch) | |
tree | 1cb2e1a71b4ec948ffb5c55d563e04f0e32a9c25 | |
parent | efba335f3383e10d9eb79278a74ed1fbad720d45 (diff) | |
download | mupdf-573ec2157b5bcc4c7798ebd7ef6e7d85612df949.tar.xz |
Load content stream buffers instead of parsing into a display tree in xobjects, patterns, type 3 fonts and pages.
-rw-r--r-- | fitz/fitz_res.h | 3 | ||||
-rw-r--r-- | fitz/res_font.c | 5 | ||||
-rw-r--r-- | mupdf/mupdf.h | 5 | ||||
-rw-r--r-- | mupdf/pdf_page.c | 187 | ||||
-rw-r--r-- | mupdf/pdf_pattern.c | 109 | ||||
-rw-r--r-- | mupdf/pdf_type3.c | 61 | ||||
-rw-r--r-- | mupdf/pdf_xobject.c | 18 |
7 files changed, 97 insertions, 291 deletions
diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h index fbb780ff..6064a317 100644 --- a/fitz/fitz_res.h +++ b/fitz/fitz_res.h @@ -195,7 +195,8 @@ struct fz_font_s int fthint; /* ... force hinting for DynaLab fonts */ fz_matrix t3matrix; - struct fz_tree_s **t3procs; /* has 256 entries if used */ + fz_obj *t3resources; + fz_buffer **t3procs; /* has 256 entries if used */ float *t3widths; /* has 256 entries if used */ fz_irect bbox; diff --git a/fitz/res_font.c b/fitz/res_font.c index 64ba5730..b06c4e4f 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -22,6 +22,7 @@ fz_newfont(void) font->fthint = 0; font->t3matrix = fz_identity(); + font->t3resources = nil; font->t3procs = nil; font->t3widths = nil; @@ -50,9 +51,11 @@ fz_dropfont(fz_font *font) { if (font->t3procs) { + if (font->t3resources) + fz_dropobj(font->t3resources); for (i = 0; i < 256; i++) if (font->t3procs[i]) - ; // XXX fz_droptree(font->t3procs[i]); + fz_dropbuffer(font->t3procs[i]); fz_free(font->t3procs); fz_free(font->t3widths); } diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index cbb9c287..555b935d 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -249,7 +249,8 @@ struct pdf_pattern_s float ystep; fz_matrix matrix; fz_rect bbox; -// XXX fz_tree *tree; + fz_obj *resources; + fz_buffer *contents; }; fz_error pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *obj); @@ -577,7 +578,7 @@ struct pdf_page_s fz_rect mediabox; int rotate; fz_obj *resources; -// XXX fz_tree *tree; + fz_buffer *contents; pdf_comment *comments; pdf_link *links; }; diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c index 31b0f4de..012e57cb 100644 --- a/mupdf/pdf_page.c +++ b/mupdf/pdf_page.c @@ -1,44 +1,13 @@ #include "fitz.h" #include "mupdf.h" -#if 0 // XXX +/* we need to combine all sub-streams into one for the content stream interpreter */ static fz_error -runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) +pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list) { fz_error error; - fz_stream *stm; - fz_buffer *buf; - - pdf_logpage("simple content stream\n"); - - error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); - if (error) - return fz_rethrow(error, "cannot load content stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref)); - - stm = fz_openrbuffer(buf); - - error = pdf_runcsi(csi, xref, rdb, stm); - - fz_dropstream(stm); - fz_dropbuffer(buf); - - if (error) - return fz_rethrow(error, "cannot interpret content stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref)); - - return fz_okay; -} - -/* we need to combine all sub-streams into one for pdf_runcsi - * to deal with split dictionaries etc. - */ -static fz_error -runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) -{ - fz_error error; - fz_stream *file; fz_buffer *big; fz_buffer *one; - fz_obj *stm; int i, n; pdf_logpage("multiple content streams: %d\n", fz_arraylen(list)); @@ -47,7 +16,7 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) for (i = 0; i < fz_arraylen(list); i++) { - stm = fz_arrayget(list, i); + fz_obj *stm = fz_arrayget(list, i); error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm)); if (error) { @@ -56,89 +25,66 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) } n = one->wp - one->rp; - while (big->wp + n + 1 > big->ep) - { fz_growbuffer(big); - } - memcpy(big->wp, one->rp, n); - big->wp += n; *big->wp++ = ' '; fz_dropbuffer(one); } - file = fz_openrbuffer(big); - - error = pdf_runcsi(csi, xref, rdb, file); - if (error) - { - fz_dropbuffer(big); - fz_dropstream(file); - return fz_rethrow(error, "cannot interpret content buffer"); - } - - fz_dropstream(file); - fz_dropbuffer(big); + *bigbufp = big; return fz_okay; } static fz_error -loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *obj) +pdf_loadpagecontents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj) { - fz_error error = fz_okay; - pdf_csi *csi; - - error = pdf_newcsi(&csi, 0); - if (error) - return fz_rethrow(error, "cannot create interpreter"); + fz_error error; if (fz_isarray(obj)) { - if (fz_arraylen(obj) == 1) - error = runone(csi, xref, rdb, fz_arrayget(obj, 0)); - else - error = runmany(csi, xref, rdb, obj); + error = pdf_loadpagecontentsarray(bufp, xref, obj); + if (error) + return fz_rethrow(error, "cannot load content stream array"); } else if (pdf_isstream(xref, fz_tonum(obj), fz_togen(obj))) - error = runone(csi, xref, rdb, obj); + { + error = pdf_loadstream(bufp, xref, fz_tonum(obj), fz_togen(obj)); + if (error) + return fz_rethrow(error, "cannot load content stream"); + } else - fz_warn("page contents missing, leaving page blank"); - - if (obj && error) { - pdf_dropcsi(csi); - return fz_rethrow(error, "cannot interpret page contents (%d %d R)", fz_tonum(obj), fz_togen(obj)); + fz_warn("page contents missing, leaving page blank"); + *bufp = fz_newbuffer(0); } - *treep = csi->tree; - csi->tree = nil; - - pdf_dropcsi(csi); - return fz_okay; } -#endif fz_error pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict) { fz_error error; - fz_obj *obj; pdf_page *page; - fz_obj *rdb; - pdf_comment *comments = nil; - pdf_link *links = nil; + fz_obj *obj; fz_rect bbox; int rotate; pdf_logpage("load page {\n"); - /* - * Sort out page media - */ + // TODO: move this to a more appropriate place + /* Ensure that we have a store for resource objects */ + if (!xref->store) + xref->store = pdf_newstore(); + + page = fz_malloc(sizeof(pdf_page)); + page->resources = nil; + page->contents = nil; + page->comments = nil; + page->links = nil; obj = fz_dictgets(dict, "CropBox"); if (!obj) @@ -146,82 +92,33 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict) if (!fz_isarray(obj)) return fz_throw("cannot find page bounds"); bbox = pdf_torect(obj); - - pdf_logpage("bbox [%g %g %g %g]\n", - bbox.x0, bbox.y0, bbox.x1, bbox.y1); - if (bbox.x1 - bbox.x0 < 1 || bbox.y1 - bbox.y0 < 1) return fz_throw("invalid page size"); - obj = fz_dictgets(dict, "Rotate"); - if (fz_isint(obj)) - rotate = fz_toint(obj); - else - rotate = 0; + page->mediabox.x0 = MIN(bbox.x0, bbox.x1); + page->mediabox.y0 = MIN(bbox.y0, bbox.y1); + page->mediabox.x1 = MAX(bbox.x0, bbox.x1); + page->mediabox.y1 = MAX(bbox.y0, bbox.y1); + page->rotate = fz_toint(fz_dictgets(dict, "Rotate")); + pdf_logpage("bbox [%g %g %g %g]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); pdf_logpage("rotate %d\n", rotate); - /* - * Load annotations - */ - obj = fz_dictgets(dict, "Annots"); if (obj) - { - pdf_loadannots(&comments, &links, xref, obj); - } - - /* - * Create store for resource objects - */ + pdf_loadannots(&page->comments, &page->links, xref, obj); - if (!xref->store) - { - xref->store = pdf_newstore(); - } - - /* - * Locate resources - */ - - rdb = fz_dictgets(dict, "Resources"); - if (rdb) - rdb = fz_keepobj(rdb); - else - { - fz_warn("cannot find page resources, proceeding anyway."); - rdb = fz_newdict(0); - } - - /* - * Interpret content stream to build display tree - */ + page->resources = fz_dictgets(dict, "Resources"); + if (page->resources) + fz_keepobj(page->resources); obj = fz_dictgets(dict, "Contents"); -#if 0 // XXX - error = loadpagecontents(&tree, xref, rdb, obj); + error = pdf_loadpagecontents(&page->contents, xref, obj); if (error) { - fz_dropobj(rdb); + pdf_droppage(page); return fz_rethrow(error, "cannot load page contents"); } -#endif - - /* - * Create page object - */ - - page = fz_malloc(sizeof(pdf_page)); - page->mediabox.x0 = MIN(bbox.x0, bbox.x1); - page->mediabox.y0 = MIN(bbox.y0, bbox.y1); - page->mediabox.x1 = MAX(bbox.x0, bbox.x1); - page->mediabox.y1 = MAX(bbox.y0, bbox.y1); - page->rotate = rotate; - page->resources = rdb; /* we have already kept or created it */ -// page->tree = tree; - - page->comments = comments; - page->links = links; pdf_logpage("} %p\n", page); @@ -233,11 +130,13 @@ void pdf_droppage(pdf_page *page) { pdf_logpage("drop page %p\n", page); - /* if (page->comments) pdf_dropcomment(page->comments); */ if (page->resources) fz_dropobj(page->resources); + if (page->contents) + fz_dropbuffer(page->contents); if (page->links) pdf_droplink(page->links); +// if (page->comments) +// pdf_dropcomment(page->comments); fz_free(page); } - diff --git a/mupdf/pdf_pattern.c b/mupdf/pdf_pattern.c index 3c62d813..0997a849 100644 --- a/mupdf/pdf_pattern.c +++ b/mupdf/pdf_pattern.c @@ -1,33 +1,12 @@ #include "fitz.h" #include "mupdf.h" -pdf_pattern * -pdf_keeppattern(pdf_pattern *pat) -{ - pat->refs ++; - return pat; -} - -void -pdf_droppattern(pdf_pattern *pat) -{ - if (pat && --pat->refs == 0) - { -//XXX if (pat->tree) -//XXX fz_droptree(pat->tree); - fz_free(pat); - } -} - fz_error pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict) { fz_error error; pdf_pattern *pat; - fz_stream *stm; - fz_obj *resources; fz_obj *obj; - pdf_csi *csi; if ((*patp = pdf_finditem(xref->store, PDF_KPATTERN, dict))) { @@ -39,6 +18,12 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict) pat = fz_malloc(sizeof(pdf_pattern)); pat->refs = 1; + pat->resources = nil; + pat->contents = nil; + + /* Store pattern now, to avoid possible recursion if objects refer back to this one */ + pdf_storeitem(xref->store, PDF_KPATTERN, dict, pat); + pat->ismask = fz_toint(fz_dictgets(dict, "PaintType")) == 2; pat->xstep = fz_toreal(fz_dictgets(dict, "XStep")); pat->ystep = fz_toreal(fz_dictgets(dict, "YStep")); @@ -65,70 +50,38 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict) pat->matrix.c, pat->matrix.d, pat->matrix.e, pat->matrix.f); - /* Store pattern now, to avoid possible recursion if objects refer back to this one */ - pdf_storeitem(xref->store, PDF_KPATTERN, dict, pat); - - /* - * Locate resources - */ - - resources = fz_dictgets(dict, "Resources"); - if (!resources) - { - error = fz_throw("cannot find Resources dictionary"); - goto cleanup; - } - - /* - * Content stream - */ + pat->resources = fz_dictgets(dict, "Resources"); + if (pat->resources) + fz_keepobj(pat->resources); - pdf_logrsrc("content stream\n"); -#if 0 // XXX - - error = pdf_newcsi(&csi, pat->ismask); - if (error) - { - error = fz_rethrow(error, "cannot create interpreter"); - goto cleanup; - } - - error = pdf_openstream(&stm, xref, fz_tonum(dict), fz_togen(dict)); - if (error) - { - pdf_dropcsi(csi); - error = fz_rethrow(error, "cannot open pattern stream (%d %d R)", fz_tonum(dict), fz_togen(dict)); - goto cleanup; - } - - error = pdf_runcsi(csi, xref, resources, stm); + error = pdf_loadstream(&pat->contents, xref, fz_tonum(dict), fz_togen(dict)); if (error) { - fz_dropstream(stm); - pdf_dropcsi(csi); - error = fz_rethrow(error, "cannot interpret pattern stream (%d %d R)", fz_tonum(dict), fz_togen(dict)); - goto cleanup; + pdf_removeitem(xref->store, PDF_KPATTERN, dict); + pdf_droppattern(pat); + return fz_rethrow(error, "cannot load pattern stream (%d %d R)", fz_tonum(dict), fz_togen(dict)); } - /* - * Move display list to pattern struct - */ - - pat->tree = csi->tree; - csi->tree = nil; - - fz_dropstream(stm); - pdf_dropcsi(csi); -#endif - - pdf_logrsrc("}\n"); - *patp = pat; return fz_okay; +} -cleanup: - pdf_removeitem(xref->store, PDF_KPATTERN, dict); - pdf_droppattern(pat); - return error; /* already rethrown */ +pdf_pattern * +pdf_keeppattern(pdf_pattern *pat) +{ + pat->refs ++; + return pat; } +void +pdf_droppattern(pdf_pattern *pat) +{ + if (pat && --pat->refs == 0) + { + if (pat->resources) + fz_dropobj(pat->resources); + if (pat->contents) + fz_dropbuffer(pat->contents); + fz_free(pat); + } +} diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c index 4313ac9d..7ea2b35a 100644 --- a/mupdf/pdf_type3.c +++ b/mupdf/pdf_type3.c @@ -1,42 +1,6 @@ #include "fitz.h" #include "mupdf.h" -#if 0 // XXX -static fz_error -loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) -{ - fz_error error; - pdf_csi *csi; - fz_stream *stm; - - error = pdf_newcsi(&csi, 1); - if (error) - return fz_rethrow(error, "cannot create interpreter"); - - error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); - if (error) - { - pdf_dropcsi(csi); - return fz_rethrow(error, "cannot open glyph content stream"); - } - - error = pdf_runcsi(csi, xref, rdb, stm); - if (error) - { - fz_dropstream(stm); - pdf_dropcsi(csi); - return fz_rethrow(error, "cannot interpret glyph content stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref)); - } - - *treep = csi->tree; - csi->tree = nil; - - fz_dropstream(stm); - pdf_dropcsi(csi); - return fz_okay; -} -#endif - fz_error pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { @@ -46,7 +10,6 @@ pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj pdf_fontdesc *fontdesc; fz_obj *encoding; fz_obj *widths; - fz_obj *resources; fz_obj *charprocs; fz_obj *obj; int first, last; @@ -166,15 +129,15 @@ pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj pdf_endhmtx(fontdesc); /* - * Resources + * Resources -- inherit page resources if the font doesn't have its own */ - resources = fz_dictgets(dict, "Resources"); - - /* Inherit page's resource dict if type3 font does not have one */ - if (!resources && rdb) - resources = rdb; - else if (!resources && !rdb) + fontdesc->font->t3resources = fz_dictgets(dict, "Resources"); + if (!fontdesc->font->t3resources) + fontdesc->font->t3resources = rdb; + if (fontdesc->font->t3resources) + fz_keepobj(fontdesc->font->t3resources); + if (!fontdesc->font->t3resources) fz_warn("no resource dictionary for type 3 font!"); /* @@ -195,18 +158,14 @@ pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj obj = fz_dictgets(charprocs, estrings[i]); if (obj) { - pdf_logfont("load charproc %s {\n", estrings[i]); -// XXX error = loadcharproc(&fontdesc->font->t3procs[i], xref, resources, obj); -// XXX if (error) -// XXX goto cleanup; - + error = pdf_loadstream(&fontdesc->font->t3procs[i], xref, fz_tonum(obj), fz_togen(obj)); + if (error) + goto cleanup; pdf_logfont("}\n"); } } } - pdf_logfont("}\n"); - *fontdescp = fontdesc; return fz_okay; diff --git a/mupdf/pdf_xobject.c b/mupdf/pdf_xobject.c index 62cebb35..edde7bfe 100644 --- a/mupdf/pdf_xobject.c +++ b/mupdf/pdf_xobject.c @@ -19,8 +19,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) form->resources = nil; form->contents = nil; - /* Store item immediately, to avoid infinite recursion if contained - objects refer again to this xobject */ + /* Store item immediately, to avoid possible recursion if objects refer back to this one */ pdf_storeitem(xref->store, PDF_KXOBJECT, dict, form); pdf_logrsrc("load xobject (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), form); @@ -65,27 +64,20 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) pdf_logrsrc("transparency %d\n", form->transparency); form->resources = fz_dictgets(dict, "Resources"); - if (form->resources) - form->resources = fz_keepobj(form->resources); error = pdf_loadstream(&form->contents, xref, fz_tonum(dict), fz_togen(dict)); if (error) { - error = fz_rethrow(error, "cannot load xobject content stream"); - goto cleanup; + pdf_removeitem(xref->store, PDF_KXOBJECT, dict); + pdf_dropxobject(form); + return fz_rethrow(error, "cannot load xobject content stream (%d %d R)", fz_tonum(dict), fz_togen(dict)); } pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp); - pdf_logrsrc("}\n"); *formp = form; return fz_okay; - -cleanup: - pdf_removeitem(xref->store, PDF_KXOBJECT, dict); - pdf_dropxobject(form); - return error; } pdf_xobject * @@ -100,9 +92,7 @@ pdf_dropxobject(pdf_xobject *xobj) { if (xobj && --xobj->refs == 0) { - if (xobj->resources) fz_dropobj(xobj->resources); if (xobj->contents) fz_dropbuffer(xobj->contents); fz_free(xobj); } } - |