summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fitz/fitz_res.h3
-rw-r--r--fitz/res_font.c5
-rw-r--r--mupdf/mupdf.h5
-rw-r--r--mupdf/pdf_page.c187
-rw-r--r--mupdf/pdf_pattern.c109
-rw-r--r--mupdf/pdf_type3.c61
-rw-r--r--mupdf/pdf_xobject.c18
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);
}
}
-