diff options
-rw-r--r-- | Jamfile | 1 | ||||
-rw-r--r-- | include/fitz/image.h | 2 | ||||
-rw-r--r-- | include/fitz/object.h | 1 | ||||
-rw-r--r-- | include/mupdf/rsrc.h | 3 | ||||
-rw-r--r-- | include/mupdf/xref.h | 1 | ||||
-rw-r--r-- | mupdf/build.c | 26 | ||||
-rw-r--r-- | mupdf/colorspace.c | 21 | ||||
-rw-r--r-- | mupdf/image.c | 157 | ||||
-rw-r--r-- | mupdf/interpret.c | 143 | ||||
-rw-r--r-- | mupdf/parse.c | 4 | ||||
-rw-r--r-- | mupdf/resources.c | 113 | ||||
-rw-r--r-- | mupdf/stream.c | 31 | ||||
-rw-r--r-- | mupdf/xobject.c | 65 | ||||
-rw-r--r-- | object/dict.c | 10 | ||||
-rw-r--r-- | render/render.c | 4 |
15 files changed, 440 insertions, 142 deletions
@@ -111,6 +111,7 @@ Library libmupdf : mupdf/fontfile.c mupdf/colorspace.c mupdf/image.c + mupdf/xobject.c mupdf/resources.c mupdf/page.c mupdf/build.c diff --git a/include/fitz/image.h b/include/fitz/image.h index 13d4d096..cfbba169 100644 --- a/include/fitz/image.h +++ b/include/fitz/image.h @@ -10,3 +10,5 @@ struct fz_image_s int w, h, n, a; }; +void fz_dropimage(fz_image *img); + diff --git a/include/fitz/object.h b/include/fitz/object.h index 520fa27f..e275074b 100644 --- a/include/fitz/object.h +++ b/include/fitz/object.h @@ -106,6 +106,7 @@ fz_obj *fz_dictgetkey(fz_obj *dict, int idx); fz_obj *fz_dictgetval(fz_obj *dict, int idx); fz_obj *fz_dictget(fz_obj *dict, fz_obj *key); fz_obj *fz_dictgets(fz_obj *dict, char *key); +fz_obj *fz_dictgetsa(fz_obj *dict, char *key, char *abbrev); fz_error *fz_dictput(fz_obj *dict, fz_obj *key, fz_obj *val); fz_error *fz_dictputs(fz_obj *dict, char *key, fz_obj *val); fz_error *fz_dictdel(fz_obj *dict, fz_obj *key); diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h index 8277c5cc..9dc12acd 100644 --- a/include/mupdf/rsrc.h +++ b/include/mupdf/rsrc.h @@ -58,7 +58,7 @@ struct pdf_xobject_s fz_buffer *contents; }; -fz_error *pdf_loadxobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj); +fz_error *pdf_loadxobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); void pdf_dropxobject(pdf_xobject *xobj); /* @@ -78,6 +78,7 @@ struct pdf_image_s fz_buffer *samples; }; +fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_file *file); fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *stm); /* diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h index d7d2e156..ac01ca9d 100644 --- a/include/mupdf/xref.h +++ b/include/mupdf/xref.h @@ -57,6 +57,7 @@ fz_error *pdf_loadobject(fz_obj **objp, pdf_xref *, int oid, int gen); fz_error *pdf_loadindirect(fz_obj **objp, pdf_xref *, fz_obj *ref); fz_error *pdf_resolve(fz_obj **reforobj, pdf_xref *); +fz_error *pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj); int pdf_isstream(pdf_xref *xref, int oid, int gen); fz_error *pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); fz_error *pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); diff --git a/mupdf/build.c b/mupdf/build.c index 448d2db4..7c52ccab 100644 --- a/mupdf/build.c +++ b/mupdf/build.c @@ -236,24 +236,38 @@ fz_error * pdf_showimage(pdf_csi *csi, pdf_image *img) { fz_error *error; - fz_node *node; + fz_node *mask; + fz_node *color; + fz_node *shape; - error = fz_newimagenode(&node, (fz_image*)img); + error = fz_newimagenode(&color, (fz_image*)img); if (error) return error; if (img->super.n == 0 && img->super.a == 1) { - error = pdf_addfillshape(csi->gstate + csi->gtop, node); + error = pdf_addfillshape(csi->gstate + csi->gtop, color); if (error) { - fz_dropnode(node); + fz_dropnode(color); return error; } } else { - /* TODO image mask sub-image */ - fz_insertnode(csi->gstate[csi->gtop].head, node); + if (img->mask) + { + error = fz_newimagenode(&shape, (fz_image*)img->mask); + if (error) return error; + error = fz_newmasknode(&mask); + if (error) return error; + fz_insertnode(mask, shape); + fz_insertnode(mask, color); + fz_insertnode(csi->gstate[csi->gtop].head, mask); + } + else + { + fz_insertnode(csi->gstate[csi->gtop].head, color); + } } return nil; diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c index 5c2ae10f..28c34692 100644 --- a/mupdf/colorspace.c +++ b/mupdf/colorspace.c @@ -707,6 +707,24 @@ printf("\n"); *csp = pdf_devicecmyk; return nil; } + + if (!strcmp(fz_toname(obj), "G")) + { + *csp = pdf_devicegray; + return nil; + } + + if (!strcmp(fz_toname(obj), "RGB")) + { + *csp = pdf_devicergb; + return nil; + } + + if (!strcmp(fz_toname(obj), "CMYK")) + { + *csp = pdf_devicecmyk; + return nil; + } } else if (fz_isarray(obj)) @@ -736,6 +754,9 @@ printf("\n"); if (!strcmp(fz_toname(name), "Indexed")) return loadindexed(csp, xref, obj); + if (!strcmp(fz_toname(name), "I")) + return loadindexed(csp, xref, obj); + if (!strcmp(fz_toname(name), "Separation")) return loadseparation(csp, xref, obj); diff --git a/mupdf/image.c b/mupdf/image.c index c30fb780..044307eb 100644 --- a/mupdf/image.c +++ b/mupdf/image.c @@ -1,6 +1,14 @@ #include <fitz.h> #include <mupdf.h> +void pdf_dropimage(fz_image *fzimg) +{ + pdf_image *img = (pdf_image*)fzimg; + fz_dropbuffer(img->samples); + if (img->mask) + fz_dropimage(img->mask); +} + static inline int getbit(const unsigned char *buf, int x) { return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1; @@ -95,10 +103,6 @@ printf(" decode bpc=%d skip=%d n=%d twon=%g\n", bpc, skip, pix->n, twon); } } -// for (i = 0; i < 256; i++) -// for (k = 0; k < 32; k++) -// table[k][i] = i; - for (y = 0; y < pix->h; y++) { for (x = 0; x < pix->w; x++) @@ -143,6 +147,7 @@ loadtile(fz_image *img, fz_pixmap *tile) return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc); } +printf(" unpack n=%d\n", tile->n); for (y = 0; y < tile->h; y++) { for (x = 0; x < tile->w; x++) @@ -194,12 +199,116 @@ loadtile(fz_image *img, fz_pixmap *tile) return nil; } +fz_error * +pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_file *file) +{ + fz_error *error; + pdf_image *img; + fz_filter *filter; + fz_obj *cs; + fz_obj *d; + int ismask; + int i; + + img = *imgp = fz_malloc(sizeof(pdf_image)); + if (!img) + return fz_outofmem; + +printf("inline image ");fz_debugobj(dict);printf("\n"); + + img->super.loadtile = loadtile; + img->super.drop = pdf_dropimage; + img->super.n = 0; + img->super.a = 0; + img->indexed = nil; + + img->super.w = fz_toint(fz_dictgetsa(dict, "Width", "W")); + img->super.h = fz_toint(fz_dictgetsa(dict, "Height", "H")); + img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); + ismask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); + d = fz_dictgetsa(dict, "Decode", "D"); + cs = fz_dictgetsa(dict, "ColorSpace", "CS"); + + if (ismask) + { + img->super.n = 0; + img->super.a = 1; + img->bpc = 1; + } + + if (cs) + { + error = pdf_loadcolorspace(&img->super.cs, xref, cs); + if (error) + return error; + img->super.n = img->super.cs->n; + img->super.a = 0; + if (!strcmp(img->super.cs->name, "Indexed")) + { +printf(" indexed!\n"); + img->indexed = (pdf_indexed*)img->super.cs; + img->super.cs = img->indexed->base; + } + } + + if (fz_isarray(d)) + { +printf(" decode array!\n"); + if (img->indexed) + for (i = 0; i < 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(d, i)); + else + for (i = 0; i < (img->super.n + img->super.a) * 2; i++) + img->decode[i] = fz_toreal(fz_arrayget(d, i)); + } + else + { + if (img->indexed) + for (i = 0; i < 2; i++) + img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0; + else + for (i = 0; i < (img->super.n + img->super.a) * 2; i++) + img->decode[i] = i & 1; + } + + if (img->indexed) + img->stride = (img->super.w * img->bpc + 7) / 8; + else + img->stride = (img->super.w * (img->super.n + img->super.a) * img->bpc + 7) / 8; + + /* load image data */ + error = pdf_decodefilter(&filter, dict); + if (error) + return error; + + error = fz_pushfilter(file, filter); + if (error) + return error; + + error = fz_readfile(&img->samples, file); + if (error) + return error; + + fz_popfilter(file); + + /* 0 means opaque and 1 means transparent, so we invert to get alpha */ + if (ismask) + { + unsigned char *p; + for (p = img->samples->bp; p < img->samples->ep; p++) + *p = ~*p; + } + + return nil; +} + /* TODO error cleanup */ fz_error * pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) { fz_error *error; pdf_image *img; + pdf_image *mask; int ismask; fz_obj *obj; fz_obj *sub; @@ -246,7 +355,6 @@ printf(" indexed!\n"); indexed = (pdf_indexed*)cs; cs = indexed->base; } - n = cs->n; a = 0; @@ -257,6 +365,8 @@ printf(" indexed!\n"); * ImageMask, Mask and SoftMask */ + mask = nil; + ismask = fz_tobool(fz_dictgets(dict, "ImageMask")); if (ismask) { @@ -269,7 +379,23 @@ printf(" image mask!\n"); obj = fz_dictgets(dict, "SMask"); if (fz_isindirect(obj)) { - // sub-image mask + puts(" smask"); + error = pdf_loadindirect(&sub, xref, obj); + if (error) + return error; + + error = pdf_loadimage(&mask, xref, sub, obj); + if (error) + return error; + + if (mask->super.cs != pdf_devicegray) + return fz_throw("syntaxerror: SMask must be DeviceGray"); + + mask->super.cs = 0; + mask->super.n = 0; + mask->super.a = 1; + + fz_dropobj(sub); } obj = fz_dictgets(dict, "Mask"); @@ -280,17 +406,20 @@ printf(" image mask!\n"); return error; if (fz_isarray(sub)) { - // color key masking + puts(" mask / color key"); } else { - // sub-image mask + puts(" mask"); + error = pdf_loadimage(&mask, xref, sub, obj); + if (error) + return error; } fz_dropobj(sub); } else if (fz_isarray(obj)) { - // color key masking + puts(" mask / color key"); } /* @@ -312,7 +441,7 @@ printf(" decode array!\n"); { if (indexed) for (i = 0; i < 2; i++) - img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0; + img->decode[i] = i & 1 ? (1 << bpc) - 1 : 0; else for (i = 0; i < (n + a) * 2; i++) img->decode[i] = i & 1; @@ -351,18 +480,23 @@ printf(" decode array!\n"); *p = ~*p; } +if (indexed) +printf(" decode [ %g %g ]\n", img->decode[0], img->decode[1]); +else +{ printf(" decode [ "); for (i = 0; i < (n + a) * 2; i++) printf("%g ", img->decode[i]); printf("]\n"); printf("\n"); +} /* * Create image object */ img->super.loadtile = loadtile; - img->super.drop = nil; + img->super.drop = pdf_dropimage; img->super.cs = cs; img->super.w = w; img->super.h = h; @@ -371,6 +505,7 @@ printf("\n"); img->indexed = indexed; img->stride = stride; img->bpc = bpc; + img->mask = (fz_image*)mask; *imgp = img; diff --git a/mupdf/interpret.c b/mupdf/interpret.c index 374f23bc..dfe7d36d 100644 --- a/mupdf/interpret.c +++ b/mupdf/interpret.c @@ -68,6 +68,99 @@ pdf_dropcsi(pdf_csi *csi) fz_free(csi); } +/* + * Do some magic to call the xobject subroutine. + * Push gstate, set transform, clip, run, pop gstate. + */ + +static fz_error * +runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj) +{ + fz_error *error; + fz_node *transform; + fz_file *file; + +puts("run xobject"); + + /* gsave */ + if (csi->gtop == 31) + return fz_throw("gstate overflow in content stream"); + memcpy(&csi->gstate[csi->gtop + 1], + &csi->gstate[csi->gtop], + sizeof (pdf_gstate)); + csi->gtop ++; + + /* push transform */ + + error = fz_newtransformnode(&transform, xobj->matrix); + if (error) + return error; + + error = pdf_addtransform(csi->gstate + csi->gtop, transform); + if (error) + { + fz_dropnode(transform); + return error; + } + + /* run contents */ + + xobj->contents->rp = xobj->contents->bp; + + error = fz_openbuffer(&file, xobj->contents, FZ_READ); + if (error) + return error; + + error = pdf_runcsi(csi, xref, xobj->resources, file); + + fz_closefile(file); + + if (error) + return error; + + /* grestore */ + if (csi->gtop == 0) + return fz_throw("gstate underflow in content stream"); + csi->gtop --; + + return nil; +} + +/* + * Decode inline image and insert into page. + */ + +static fz_error * +runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_file *file, fz_obj *dict) +{ + fz_error *error; + pdf_image *img; + char buf[256]; + int token; + int len; + + error = pdf_loadinlineimage(&img, xref, dict, file); + if (error) + return error; + + token = pdf_lex(file, buf, sizeof buf, &len); + if (token != PDF_TKEYWORD || strcmp("EI", buf)) + return fz_throw("syntaxerror: corrupt inline image"); + + error = pdf_showimage(csi, img); + if (error) + { + fz_dropimage((fz_image*)img); + return error; + } + + return nil; +} + +/* + * Set gstate params from an ExtGState dictionary. + */ + static fz_error * runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate) { @@ -119,6 +212,10 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate) return nil; } +/* + * The meat of the interpreter... + */ + static fz_error * runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf) { @@ -552,28 +649,42 @@ Lsetcolorspace: fz_obj *dict; fz_obj *obj; pdf_image *img; + pdf_xobject *xobj; if (csi->top != 1) goto syntaxerror; dict = fz_dictgets(rdb, "XObject"); if (!dict) +{ +fz_debugobj(rdb); return fz_throw("syntaxerror: missing xobject resource"); +} obj = fz_dictget(dict, csi->stack[0]); if (!obj) return fz_throw("syntaxerror: missing xobject resource"); img = pdf_findresource(xref->rimage, obj); - if (!img) + xobj = pdf_findresource(xref->rxobject, obj); + + if (!img && !xobj) + return fz_throw("syntaxerror: missing xobject resource"); + + if (img) { -fprintf(stderr, "syntaxerror: missing image resource"); -return nil; + error = pdf_showimage(csi, img); + if (error) + return error; } - error = pdf_showimage(csi, img); - if (error) - return error; + if (xobj) + { + clearstack(csi); + error = runxobject(csi, xref, xobj); + if (error) + return error; + } } else @@ -922,9 +1033,23 @@ pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file) break; case PDF_TKEYWORD: - error = runkeyword(csi, xref, rdb, buf); - if (error) return error; - clearstack(csi); + if (!strcmp(buf, "BI")) + { + fz_obj *obj; + error = pdf_parsedict(&obj, file, buf, sizeof buf); + if (error) + return error; + error = runinlineimage(csi, xref, file, obj); + fz_dropobj(obj); + if (error) + return error; + } + else + { + error = runkeyword(csi, xref, rdb, buf); + if (error) return error; + clearstack(csi); + } break; default: diff --git a/mupdf/parse.c b/mupdf/parse.c index ef6e93a3..3bf1e00f 100644 --- a/mupdf/parse.c +++ b/mupdf/parse.c @@ -122,6 +122,10 @@ skip: if (tok == PDF_TCDICT) return nil; + /* for BI .. ID .. EI in content streams */ + if (tok == PDF_TKEYWORD && !strcmp(buf, "ID")) + return nil; + if (tok != PDF_TNAME) goto cleanup; diff --git a/mupdf/resources.c b/mupdf/resources.c index 068de99b..7051c04d 100644 --- a/mupdf/resources.c +++ b/mupdf/resources.c @@ -109,7 +109,7 @@ preloadxobject(pdf_xref *xref, fz_obj *ref) if (!strcmp(fz_toname(subtype), "Form")) { -// error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj); + error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj, ref); fz_dropobj(obj); if (error) { fz_free(rsrc); @@ -341,114 +341,3 @@ cleanup: return error; } -#if 0 - -static fz_error * -loadcolorspaces(pdf_resources *rdb, pdf_xref *xref, fz_obj *dict) -{ - fz_error *err; - fz_colorspace *colorspace; - fz_obj *key, *val; - fz_obj *ptr; - int i; - - for (i = 0; i < fz_dictlen(dict); i++) - { - colorspace = nil; - ptr = nil; - - key = fz_dictgetkey(dict, i); - val = fz_dictgetval(dict, i); - - err = pdf_resolve(&val, xref); - if (err) return err; - - err = pdf_loadcolorspace(&colorspace, xref, val); - if (err) goto cleanup; - -printf(" -> %s\n", colorspace->name); - - err = fz_newpointer(&ptr, colorspace); - if (err) goto cleanup; - - err = fz_dictput(rdb->colorspace, key, ptr); - if (err) goto cleanup; - - fz_dropobj(ptr); - fz_dropobj(val); - colorspace = nil; - } - - return nil; - -cleanup: - if (colorspace) fz_dropcolorspace(colorspace); - if (ptr) fz_dropobj(ptr); - fz_dropobj(val); - return err; -} - -fz_error * -pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *topdict) -{ - fz_error *err; - pdf_resources *rdb; - fz_obj *subdict; - - rdb = *rdbp = fz_malloc(sizeof (pdf_resources)); - if (!rdb) - return fz_outofmem; - - rdb->extgstate = nil; - rdb->font = nil; - rdb->colorspace = nil; - rdb->ximage = nil; - rdb->xform = nil; - - err = fz_newdict(&rdb->extgstate, 5); - if (err) { pdf_dropresources(rdb); return err; } - - subdict = fz_dictgets(topdict, "ExtGState"); - if (subdict) - { - err = pdf_resolve(&subdict, xref); - if (err) { pdf_dropresources(rdb); return err; } - err = loadextgstates(rdb, xref, subdict); - fz_dropobj(subdict); - if (err) { pdf_dropresources(rdb); return err; } - } - - err = fz_newdict(&rdb->font, 15); - if (err) { pdf_dropresources(rdb); return err; } - - err = loadextgstatefonts(rdb, xref); - if (err) { pdf_dropresources(rdb); return err; } - - subdict = fz_dictgets(topdict, "Font"); - if (subdict) - { - err = pdf_resolve(&subdict, xref); - if (err) { pdf_dropresources(rdb); return err; } - err = loadfonts(rdb, xref, subdict); - fz_dropobj(subdict); - if (err) { pdf_dropresources(rdb); return err; } - } - - err = fz_newdict(&rdb->colorspace, 5); - if (err) { pdf_dropresources(rdb); return err; } - - subdict = fz_dictgets(topdict, "ColorSpace"); - if (subdict) - { - err = pdf_resolve(&subdict, xref); - if (err) { pdf_dropresources(rdb); return err; } - err = loadcolorspaces(rdb, xref, subdict); - fz_dropobj(subdict); - if (err) { pdf_dropresources(rdb); return err; } - } - - return nil; -} - -#endif - diff --git a/mupdf/stream.c b/mupdf/stream.c index 5d39436f..9b108a2b 100644 --- a/mupdf/stream.c +++ b/mupdf/stream.c @@ -87,7 +87,10 @@ buildfilters(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps) p = nil; error = buildonefilter(&tail, f, p); - error = fz_newpipeline(&head, head, tail); + if (head) + error = fz_newpipeline(&head, head, tail); + else + head = tail; } *filterp = head; @@ -118,6 +121,28 @@ makerawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int return nil; } +fz_error * +pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj) +{ + fz_obj *filters; + fz_obj *params; + + filters = fz_dictgetsa(stmobj, "Filter", "F"); + params = fz_dictgetsa(stmobj, "DecodeParms", "DP"); + + if (filters) + { + if (fz_isname(filters)) + return buildonefilter(filterp, filters, params); + else + return buildfilters(filterp, nil, filters, params); + } + else + return fz_newnullfilter(filterp, -1); + + return nil; +} + static fz_error * makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) { @@ -128,8 +153,8 @@ makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, i error = makerawfilter(&pipe, xref, stmobj, oid, gen); - filters = fz_dictgets(stmobj, "Filter"); - params = fz_dictgets(stmobj, "DecodeParms"); + filters = fz_dictgetsa(stmobj, "Filter", "F"); + params = fz_dictgetsa(stmobj, "DecodeParms", "DP"); if (filters) { diff --git a/mupdf/xobject.c b/mupdf/xobject.c new file mode 100644 index 00000000..1340bc5c --- /dev/null +++ b/mupdf/xobject.c @@ -0,0 +1,65 @@ +#include <fitz.h> +#include <mupdf.h> + +fz_error * +pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_error *error; + pdf_xobject *form; + fz_obj *obj; + + form = fz_malloc(sizeof(pdf_xobject)); + if (!form) + return fz_outofmem; + +printf("loading xobject ");fz_debugobj(dict);printf("\n"); + + obj = fz_dictgets(dict, "BBox"); + form->bbox.min.x = fz_toreal(fz_arrayget(obj, 0)); + form->bbox.min.y = fz_toreal(fz_arrayget(obj, 1)); + form->bbox.max.x = fz_toreal(fz_arrayget(obj, 2)); + form->bbox.max.y = fz_toreal(fz_arrayget(obj, 3)); + + obj = fz_dictgets(dict, "Matrix"); + form->matrix.a = fz_toreal(fz_arrayget(obj, 0)); + form->matrix.b = fz_toreal(fz_arrayget(obj, 1)); + form->matrix.c = fz_toreal(fz_arrayget(obj, 2)); + form->matrix.d = fz_toreal(fz_arrayget(obj, 3)); + form->matrix.e = fz_toreal(fz_arrayget(obj, 4)); + form->matrix.f = fz_toreal(fz_arrayget(obj, 5)); + + form->resources = nil; + obj = fz_dictgets(dict, "Resources"); + if (obj) + { + error = pdf_resolve(&obj, xref); + if (error) + { + fz_free(form); + return error; + } + + error = pdf_loadresources(&form->resources, xref, obj); + if (error) + { + fz_dropobj(obj); + fz_free(form); + return error; + } + + fz_dropobj(obj); + } + + error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref)); + if (error) + { + fz_dropobj(form->resources); + fz_free(form); + return error; + } + + *formp = form; + return nil; +} + + diff --git a/object/dict.c b/object/dict.c index 61e55bc4..fda48dc3 100644 --- a/object/dict.c +++ b/object/dict.c @@ -169,6 +169,16 @@ fz_dictget(fz_obj *obj, fz_obj *key) return fz_dictgets(obj, fz_toname(key)); } +fz_obj * +fz_dictgetsa(fz_obj *obj, char *key, char *abbrev) +{ + fz_obj *v; + v = fz_dictgets(obj, key); + if (v) + return v; + return fz_dictgets(obj, abbrev); +} + fz_error * fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val) { diff --git a/render/render.c b/render/render.c index 6b2d5e29..fd3e0620 100644 --- a/render/render.c +++ b/render/render.c @@ -183,6 +183,7 @@ fz_error * fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm) { fz_error *error; + fz_pixmap *oldacc; fz_pixmap *colorpix; fz_pixmap *shapepix; fz_node *color; @@ -202,7 +203,9 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm) printf("begin mask\n"); + oldacc = gc->acc; oldmode = gc->mode; + gc->acc = nil; gc->mode = FZ_RMASK; gc->tmp = nil; @@ -232,6 +235,7 @@ if (!shapepix) return nil; fz_droppixmap(shapepix); fz_droppixmap(colorpix); + gc->acc = oldacc; gc->mode = oldmode; printf("end mask\n"); |