summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile4
-rw-r--r--include/fitz.h4
-rw-r--r--include/fitz/image.h10
-rw-r--r--include/fitz/scanconv.h2
-rw-r--r--include/fitz/tree.h11
-rw-r--r--mupdf/build.c58
-rw-r--r--mupdf/colorspace.c6
-rw-r--r--mupdf/font.c1
-rw-r--r--mupdf/image.c54
-rw-r--r--mupdf/interpret.c131
-rw-r--r--mupdf/open.c3
-rw-r--r--mupdf/page.c22
-rw-r--r--mupdf/repair.c3
-rw-r--r--mupdf/resources.c376
-rw-r--r--mupdf/xref.c3
-rw-r--r--render/render.c14
-rw-r--r--render/renderimage.c59
-rw-r--r--render/renderpath.c53
-rw-r--r--render/rendertext.c8
-rw-r--r--render/scanconv.c30
-rw-r--r--test/pdfrip.c15
-rw-r--r--tree/debug.c5
-rw-r--r--tree/font.c1
-rw-r--r--tree/node2.c24
-rw-r--r--tree/text.c64
25 files changed, 740 insertions, 221 deletions
diff --git a/Jamfile b/Jamfile
index 80219171..3ce33eab 100644
--- a/Jamfile
+++ b/Jamfile
@@ -82,8 +82,9 @@ Library libfitz :
render/fill.c
render/stroke.c
render/render.c
- render/renderpath.c
render/rendertext.c
+ render/renderpath.c
+ render/renderimage.c
;
Library libmupdf :
@@ -103,6 +104,7 @@ Library libmupdf :
mupdf/font.c
mupdf/fontfile.c
mupdf/colorspace.c
+ mupdf/image.c
mupdf/resources.c
mupdf/page.c
mupdf/pagetree.c
diff --git a/include/fitz.h b/include/fitz.h
index 85ac8118..48754391 100644
--- a/include/fitz.h
+++ b/include/fitz.h
@@ -18,13 +18,15 @@
#include "fitz/cmap.h"
#include "fitz/font.h"
+
#include "fitz/colorspace.h"
+#include "fitz/pixmap.h"
+#include "fitz/image.h"
#include "fitz/tree.h"
#include "fitz/path.h"
#include "fitz/text.h"
-#include "fitz/pixmap.h"
#include "fitz/scanconv.h"
#include "fitz/render.h"
diff --git a/include/fitz/image.h b/include/fitz/image.h
new file mode 100644
index 00000000..0ff954c5
--- /dev/null
+++ b/include/fitz/image.h
@@ -0,0 +1,10 @@
+typedef struct fz_image_s fz_image;
+
+struct fz_image_s
+{
+ fz_error* (*loadtile)(fz_image*,fz_pixmap*);
+ void (*free)(fz_image*);
+ fz_colorspace *cs;
+ int w, h, n, a;
+};
+
diff --git a/include/fitz/scanconv.h b/include/fitz/scanconv.h
index 794b9ba2..057153c4 100644
--- a/include/fitz/scanconv.h
+++ b/include/fitz/scanconv.h
@@ -39,7 +39,7 @@ void fz_advanceael(fz_ael *ael);
void fz_freeael(fz_ael *ael);
fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
- void (*blitfunc)(int,int,int,short*,void*), void *blitdata);
+ void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata);
fz_error *fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
fz_error *fz_strokepath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
diff --git a/include/fitz/tree.h b/include/fitz/tree.h
index 6578ab51..7181ac9b 100644
--- a/include/fitz/tree.h
+++ b/include/fitz/tree.h
@@ -125,15 +125,14 @@ struct fz_linknode_s
struct fz_metanode_s
{
fz_node super;
- fz_obj *info;
+ fz_obj *name;
+ fz_obj *dict;
};
struct fz_imagenode_s
{
fz_node super;
- fz_colorspace *cs;
- int w, h, n, a;
- // XXX fz_image *image;
+ fz_image *image;
};
/* common to all nodes */
@@ -142,7 +141,7 @@ fz_rect fz_boundnode(fz_node *node, fz_matrix ctm);
void fz_freenode(fz_node *node);
/* branch nodes */
-fz_error *fz_newmetanode(fz_node **nodep, fz_obj *info);
+fz_error *fz_newmetanode(fz_node **nodep, fz_obj *name, fz_obj *dict);
fz_error *fz_newovernode(fz_node **nodep);
fz_error *fz_newmasknode(fz_node **nodep);
fz_error *fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i);
@@ -157,7 +156,7 @@ int fz_ismetanode(fz_node *node);
/* leaf nodes */
fz_error *fz_newlinknode(fz_node **nodep, fz_tree *subtree);
fz_error *fz_newcolornode(fz_node **nodep, fz_colorspace *cs, int n, float *v);
-fz_error *fz_newimagenode(fz_node **nodep, fz_colorspace *cs, int w, int h, int n, int a);
+fz_error *fz_newimagenode(fz_node **nodep, fz_image *image);
int fz_islinknode(fz_node *node);
int fz_iscolornode(fz_node *node);
diff --git a/mupdf/build.c b/mupdf/build.c
index 5747b962..d235c9bc 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -1,8 +1,6 @@
#include <fitz.h>
#include <mupdf.h>
-extern int FT_Get_Char_Index(void*, int);
-
void
pdf_initgstate(pdf_gstate *gs)
{
@@ -137,6 +135,62 @@ pdf_addtransform(pdf_gstate *gs, fz_node *transform)
return nil;
}
+#if 0
+
+BMC ... EMC object nesting can be completely fucked up
+and out of sync with graphics object nesting.
+
+fz_error *
+pdf_beginmarkedcontent(pdf_gstate *gs, fz_node *meta)
+{
+ fz_error *error;
+ fz_node *over;
+
+ error = fz_newovernode(&over);
+ if (error) return error;
+
+ fz_insertnode(gs->head, meta);
+ fz_insertnode(meta, over);
+ gs->head = over;
+
+printf("begin mc meta=%p over=%p\n", meta, over);
+{
+fz_node *node = gs->head;
+ while (node)
+ {
+printf(" node=%p ismeta=%d\n", node, fz_ismetanode(node));
+ node = node->parent;
+ }
+printf("okay.\n");
+}
+
+ return nil;
+}
+
+fz_error *
+pdf_endmarkedcontent(pdf_gstate *gs)
+{
+ fz_node *node = gs->head;
+
+printf("end mc\n");
+printf(" node=%p ismeta=%d\n", node, fz_ismetanode(node));
+
+ while (node && !fz_ismetanode(node))
+ {
+printf(" node=%p ismeta=%d\n", node, fz_ismetanode(node));
+ node = node->parent;
+ }
+
+ if (node == nil)
+ return fz_throw("syntaxerror: unbalanced marked content");
+
+ gs->head = node->parent;
+
+ return nil;
+}
+
+#endif
+
fz_error *
pdf_showpath(pdf_csi *csi,
int doclose, int dofill, int dostroke, int evenodd)
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index 05a4535c..3511dc91 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -530,6 +530,12 @@ printf("\n");
{
return loadiccbased(csp, xref, fz_arrayget(obj, 1));
}
+
+ if (!strcmp(fz_toname(name), "Separation"))
+ {
+ *csp = pdf_devicegray;
+ return nil;
+ }
}
}
diff --git a/mupdf/font.c b/mupdf/font.c
index c7ff3eb9..562eb5ba 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -94,6 +94,7 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
FT_Set_Transform(face, &m, &v);
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
+ //fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP);
if (fterr)
return fz_throw("freetype failed to load glyph: 0x%x", fterr);
diff --git a/mupdf/image.c b/mupdf/image.c
new file mode 100644
index 00000000..00e6171b
--- /dev/null
+++ b/mupdf/image.c
@@ -0,0 +1,54 @@
+#include <fitz.h>
+#include <mupdf.h>
+
+static fz_error *loadtile(fz_image *fzimg, fz_pixmap *tile)
+{
+ return nil;
+}
+
+fz_error *
+pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict)
+{
+ fz_error *error;
+ pdf_image *img;
+ fz_colorspace *cs;
+ int ismask;
+ fz_obj *obj;
+
+ img = fz_malloc(sizeof(pdf_image));
+ if (!img)
+ return fz_outofmem;
+
+ img->super.loadtile = loadtile;
+ img->super.free = nil;
+ img->super.cs = nil;
+
+ img->super.w = fz_toint(fz_dictgets(dict, "Width"));
+ img->super.h = fz_toint(fz_dictgets(dict, "Height"));
+ img->bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent"));
+
+ cs = nil;
+ obj = fz_dictgets(dict, "ColorSpace");
+ if (obj)
+ error = pdf_loadcolorspace(&cs, xref, obj);
+
+ ismask = fz_tobool(fz_dictgets(dict, "ImageMask"));
+
+ if (!ismask)
+ {
+ img->super.cs = cs;
+ img->super.n = cs->n;
+ img->super.a = 0;
+ }
+ else
+ {
+ img->super.cs = nil;
+ img->super.n = 0;
+ img->super.a = 1;
+ }
+
+ *imgp = img;
+
+ return nil;
+}
+
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index fdf367b5..f9179792 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -1,20 +1,6 @@
#include <fitz.h>
#include <mupdf.h>
-void pdf_initgstate(pdf_gstate *gs);
-
-fz_error *pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path);
-fz_error *pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int evenodd);
-
-fz_error *pdf_addfillshape(pdf_gstate *gs, fz_node *shape);
-fz_error *pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape);
-fz_error *pdf_addclipmask(pdf_gstate *gs, fz_node *shape);
-fz_error *pdf_addtransform(pdf_gstate *gs, fz_node *transform);
-
-fz_error *pdf_showpath(pdf_csi *, int doclose, int dofill, int dostroke, int evenodd);
-fz_error *pdf_showtext(pdf_csi *, fz_obj *text);
-fz_error *pdf_flushtext(pdf_csi *);
-
fz_error *
pdf_newcsi(pdf_csi **csip)
{
@@ -51,8 +37,8 @@ pdf_newcsi(pdf_csi **csip)
csi->tree->root = node;
csi->gstate[0].head = node;
- error = fz_newcolornode(&node, pdf_devicegray, 1, &white);
- fz_insertnode(csi->tree->root, node);
+// error = fz_newcolornode(&node, pdf_devicegray, 1, &white);
+// fz_insertnode(csi->tree->root, node);
csi->clip = nil;
@@ -83,9 +69,8 @@ pdf_freecsi(pdf_csi *csi)
}
static fz_error *
-runextgstate(pdf_gstate *gstate, pdf_resources *rdb, fz_obj *extgstate)
+runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
{
- char name[64];
int i, k;
for (i = 0; i < fz_dictlen(extgstate); i++)
@@ -98,13 +83,9 @@ runextgstate(pdf_gstate *gstate, pdf_resources *rdb, fz_obj *extgstate)
{
if (fz_isarray(val) && fz_arraylen(val) == 2)
{
- fz_obj *ref, *obj;
- ref = fz_arrayget(val, 0);
- sprintf(name, "$f.%d.%d", fz_tonum(ref), fz_togen(ref));
- obj = fz_dictgets(rdb->font, name);
- if (!obj)
- return fz_throw("syntaxerror: missing resource");
- gstate->font = fz_topointer(obj);
+ gstate->font = pdf_findresource(xref->rfont, fz_arrayget(val, 0));
+ if (!gstate->font)
+ return fz_throw("syntaxerror: missing font resource");
gstate->size = fz_toreal(fz_arrayget(val, 1));
}
else
@@ -139,7 +120,7 @@ runextgstate(pdf_gstate *gstate, pdf_resources *rdb, fz_obj *extgstate)
}
static fz_error *
-runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
+runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_error *error;
@@ -169,7 +150,7 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
fz_node *meta;
if (csi->top != 1)
goto syntaxerror;
- error = fz_newmetanode(&meta, csi->stack[0]);
+ error = fz_newmetanode(&meta, csi->stack[0], nil);
if (error) return error;
fz_insertnode(gstate->head, meta);
}
@@ -177,18 +158,43 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
else if (!strcmp(buf, "DP"))
{
fz_node *meta;
- fz_obj *info;
if (csi->top != 2)
goto syntaxerror;
- error = fz_packobj(&info, "<< %o %o >>",
- csi->stack[0], csi->stack[1]);
+ error = fz_newmetanode(&meta, csi->stack[0], csi->stack[1]);
if (error) return error;
- error = fz_newmetanode(&meta, info);
- fz_dropobj(info);
+ fz_insertnode(gstate->head, meta);
+ }
+
+ else if (!strcmp(buf, "BMC"))
+ {
+ fz_node *meta;
+ if (csi->top != 1)
+ goto syntaxerror;
+ error = fz_newmetanode(&meta, csi->stack[0], nil);
if (error) return error;
+ // error = pdf_beginmarkedcontent(gstate, meta);
+ // if (error) { fz_freenode(meta); return error; };
fz_insertnode(gstate->head, meta);
}
+ else if (!strcmp(buf, "BDC"))
+ {
+ fz_node *meta;
+ if (csi->top != 2)
+ goto syntaxerror;
+ error = fz_newmetanode(&meta, csi->stack[0], csi->stack[1]);
+ if (error) return error;
+ // error = pdf_beginmarkedcontent(gstate, meta);
+ // if (error) { fz_freenode(meta); return error; };
+ fz_insertnode(gstate->head, meta);
+ }
+
+ else if (!strcmp(buf, "EMC"))
+ {
+ // error = pdf_endmarkedcontent(gstate);
+ // if (error) return error;
+ }
+
else if (!strcmp(buf, "cm"))
{
fz_matrix m;
@@ -218,16 +224,21 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
else if (!strcmp(buf, "gs"))
{
+ fz_obj *dict;
fz_obj *obj;
if (csi->top != 1)
goto syntaxerror;
- obj = fz_dictget(rdb->extgstate, csi->stack[0]);
+ dict = fz_dictgets(rdb, "ExtGState");
+ if (!dict)
+ return fz_throw("syntaxerror: missing extgstate resource");
+
+ obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
- return fz_throw("syntaxerror: missing resource");
-
- runextgstate(gstate, rdb, obj);
+ return fz_throw("syntaxerror: missing extgstate resource");
+
+ runextgstate(gstate, xref, obj);
}
else if (!strcmp(buf, "re"))
@@ -286,6 +297,7 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
else if (!strcmp(buf, "cs"))
{
+ fz_obj *dict;
fz_obj *obj;
if (csi->top != 1)
@@ -301,15 +313,24 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
gstate->fillcs = pdf_devicecmyk;
else
{
- obj = fz_dictget(rdb->colorspace, obj);
+ dict = fz_dictgets(rdb, "ColorSpace");
+ if (!dict)
+ return fz_throw("syntaxerror: missing colorspace resource");
+ obj = fz_dictget(dict, obj);
if (!obj)
- return fz_throw("syntaxerror: missing resource");
- gstate->fillcs = fz_topointer(obj);
+ return fz_throw("syntaxerror: missing colorspace resource");
+ if (fz_isindirect(obj))
+ gstate->fillcs = pdf_findresource(xref->rcolorspace, obj);
+ else
+ return fz_throw("syntaxerror: inline colorspace in dict");
+ if (!gstate->fillcs)
+ return fz_throw("syntaxerror: missing colorspace resource");
}
}
else if (!strcmp(buf, "CS"))
{
+ fz_obj *dict;
fz_obj *obj;
if (csi->top != 1)
@@ -325,10 +346,18 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
gstate->strokecs = pdf_devicecmyk;
else
{
- obj = fz_dictget(rdb->colorspace, obj);
+ dict = fz_dictgets(rdb, "ColorSpace");
+ if (!dict)
+ return fz_throw("syntaxerror: missing colorspace resource");
+ obj = fz_dictget(dict, obj);
if (!obj)
- return fz_throw("syntaxerror: missing resource");
- gstate->strokecs = fz_topointer(obj);
+ return fz_throw("syntaxerror: missing colorspace resource");
+ if (fz_isindirect(obj))
+ gstate->strokecs = pdf_findresource(xref->rcolorspace, obj);
+ else
+ return fz_throw("syntaxerror: inline colorspace in dict");
+ if (!gstate->strokecs)
+ return fz_throw("syntaxerror: missing colorspace resource");
}
}
@@ -419,16 +448,24 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
else if (!strcmp(buf, "Tf"))
{
+ fz_obj *dict;
fz_obj *obj;
if (csi->top != 2)
goto syntaxerror;
- obj = fz_dictget(rdb->font, csi->stack[0]);
+ dict = fz_dictgets(rdb, "Font");
+ if (!dict)
+ return fz_throw("syntaxerror: missing font resource");
+
+ obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
- return fz_throw("syntaxerror: missing resource");
+ return fz_throw("syntaxerror: missing font resource");
+
+ gstate->font = pdf_findresource(xref->rfont, obj);
+ if (!gstate->font)
+ return fz_throw("syntaxerror: missing font resource");
- gstate->font = fz_topointer(obj);
gstate->size = fz_toreal(csi->stack[1]);
}
@@ -754,7 +791,7 @@ syntaxerror:
}
fz_error *
-pdf_runcsi(pdf_csi *csi, pdf_resources *rdb, fz_file *file)
+pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file)
{
fz_error *error;
unsigned char buf[65536];
@@ -835,7 +872,7 @@ pdf_runcsi(pdf_csi *csi, pdf_resources *rdb, fz_file *file)
break;
case PDF_TKEYWORD:
- error = runkeyword(csi, rdb, buf);
+ error = runkeyword(csi, xref, rdb, buf);
if (error) return error;
clearstack(csi);
break;
diff --git a/mupdf/open.c b/mupdf/open.c
index 529872a8..19320d43 100644
--- a/mupdf/open.c
+++ b/mupdf/open.c
@@ -460,9 +460,10 @@ pdf_openpdf(pdf_xref **xrefp, char *filename)
unsigned char buf[65536]; /* yeowch! */
- xref = fz_malloc(sizeof (pdf_xref));
+ xref = fz_malloc(sizeof(pdf_xref));
if (!xref)
return fz_outofmem;
+ memset(xref, 0, sizeof(pdf_xref));
xref->file = nil;
xref->version = 1.0;
diff --git a/mupdf/page.c b/mupdf/page.c
index 4450ae8d..48e8af77 100644
--- a/mupdf/page.c
+++ b/mupdf/page.c
@@ -2,7 +2,7 @@
#include <mupdf.h>
static fz_error *
-runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref)
+runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
{
fz_error *error;
@@ -10,7 +10,7 @@ runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref)
if (error)
return error;
- error = pdf_runcsi(csi, rdb, xref->stream);
+ error = pdf_runcsi(csi, xref, rdb, xref->stream);
pdf_closestream(xref);
@@ -18,7 +18,7 @@ runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref)
}
static fz_error *
-loadpagecontents(fz_tree **treep, pdf_xref *xref, pdf_resources *rdb, fz_obj *ref)
+loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
{
fz_error *error;
fz_obj *obj;
@@ -39,7 +39,7 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, pdf_resources *rdb, fz_obj *re
{
for (i = 0; i < fz_arraylen(obj); i++)
{
- error = runcsi(xref, csi, rdb, fz_arrayget(obj, i));
+ error = runcsi(csi, xref, rdb, fz_arrayget(obj, i));
if (error) {
fz_dropobj(obj);
goto cleanup;
@@ -48,7 +48,7 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, pdf_resources *rdb, fz_obj *re
}
else
{
- error = runcsi(xref, csi, rdb, ref);
+ error = runcsi(csi, xref, rdb, ref);
if (error) {
fz_dropobj(obj);
goto cleanup;
@@ -62,7 +62,7 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, pdf_resources *rdb, fz_obj *re
{
for (i = 0; i < fz_arraylen(ref); i++)
{
- error = runcsi(xref, csi, rdb, fz_arrayget(ref, i));
+ error = runcsi(csi, xref, rdb, fz_arrayget(ref, i));
if (error)
goto cleanup;
}
@@ -83,7 +83,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
fz_error *error;
fz_obj *obj;
pdf_page *page;
- pdf_resources *rdb;
+ fz_obj *rdb;
fz_tree *tree;
fz_rect bbox;
int rotate;
@@ -123,7 +123,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
error = loadpagecontents(&tree, xref, rdb, obj);
if (error) {
- pdf_freeresources(rdb);
+ fz_dropobj(rdb);
return error;
}
@@ -134,7 +134,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page = *pagep = fz_malloc(sizeof(pdf_page));
if (!page) {
fz_droptree(tree);
- pdf_freeresources(rdb);
+ fz_dropobj(rdb);
return fz_outofmem;
}
@@ -143,7 +143,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page->mediabox.max.x = MAX(bbox.min.x, bbox.max.x);
page->mediabox.max.y = MAX(bbox.min.y, bbox.max.y);
page->rotate = rotate;
- page->rdb = rdb;
+ page->resources = rdb;
page->tree = tree;
return nil;
@@ -152,7 +152,7 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
void
pdf_freepage(pdf_page *page)
{
- pdf_freeresources(page->rdb);
+ fz_dropobj(page->resources);
fz_droptree(page->tree);
fz_free(page);
}
diff --git a/mupdf/repair.c b/mupdf/repair.c
index 8742d15f..5f4a139e 100644
--- a/mupdf/repair.c
+++ b/mupdf/repair.c
@@ -124,9 +124,10 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename)
int next;
int i;
- xref = fz_malloc(sizeof (pdf_xref));
+ xref = fz_malloc(sizeof(pdf_xref));
if (!xref)
return fz_outofmem;
+ memset(xref, 0, sizeof(pdf_xref));
xref->file = nil;
xref->version = 0.0;
diff --git a/mupdf/resources.c b/mupdf/resources.c
index ef2515a2..f859566f 100644
--- a/mupdf/resources.c
+++ b/mupdf/resources.c
@@ -1,126 +1,348 @@
#include <fitz.h>
#include <mupdf.h>
+void *
+pdf_findresource(pdf_rsrc *rsrc, fz_obj *ref)
+{
+ while (rsrc)
+ {
+ if (rsrc->oid == fz_tonum(ref) && rsrc->gen == fz_togen(ref))
+ return rsrc->val;
+ rsrc = rsrc->next;
+ }
+ return nil;
+}
+
+/*
+Load resources:
+
+Go through resource dictionary and resolve some levels of
+indirect references so we end up with a stylized structure:
+
+<<
+ /Font <<
+ /F0 1 0 R
+ /F1 2 0 R
+ /F2 3 0 R
+ >>
+ /ExtGState <<
+ /Gs0 << ... /Font 1 0 R ... >>
+ /Gs1 << ... >>
+ >>
+ /ColorSpace <<
+ /Cs0 5 0 R
+ /Cs1 [ /ICCBased 5 0 R ] % /Cs1 -1 0 R ???
+ /Cs2 [ /CalRGB << ... >> ] % /Cs2 -2 0 R ???
+ >>
+ /XObject <<
+ /Im0 10 0 R
+ /Fm0 11 0 R
+ >>
+>>
+
+Then all references to actual resources will get
+parsed and inserted into the pdf_xref resource
+lists, indexed by their object number.
+
+TODO: inline colorspaces -> fake objects || refcount ?
+TODO: inline images -> fake objects || refcount?
+
+*/
+
static fz_error *
-loadextgstatefonts(pdf_resources *rdb, pdf_xref *xref)
+preloadcolorspace(pdf_xref *xref, fz_obj *ref)
{
- fz_error *err;
- char name[64];
- pdf_font *font;
- fz_obj *extgstate;
+ fz_error *error;
+ fz_colorspace *colorspace;
+ pdf_rsrc *rsrc;
fz_obj *obj;
- fz_obj *ptr;
- fz_obj *ref;
- int i;
- for (i = 0; i < fz_dictlen(rdb->extgstate); i++)
- {
- extgstate = fz_dictgetval(rdb->extgstate, i);
+ if (pdf_findresource(xref->rcolorspace, ref))
+ return nil;
- obj = fz_dictgets(extgstate, "Font");
- if (obj)
- {
- font = nil;
- ptr = nil;
+ rsrc = fz_malloc(sizeof(pdf_rsrc));
+ if (!rsrc)
+ return fz_outofmem;
+ rsrc->oid = fz_tonum(ref);
+ rsrc->gen = fz_togen(ref);
+
+ error = pdf_loadindirect(&obj, xref, ref);
+ if (error)
+ return error;
+ error = pdf_loadcolorspace(&colorspace, xref, obj);
+ fz_dropobj(obj);
+ if (error) {
+ fz_free(rsrc);
+ return error;
+ }
- if (!fz_isarray(obj) || fz_arraylen(obj) != 2)
- return fz_throw("syntaxerror in ExtGState/Font");
+ rsrc->val = colorspace;
+ rsrc->next = xref->rcolorspace;
+ xref->rcolorspace = rsrc;
+ return nil;
+}
- ref = fz_arrayget(obj, 0);
- sprintf(name, "$f.%d.%d", fz_tonum(ref), fz_togen(ref));
+static fz_error *
+preloadxobject(pdf_xref *xref, fz_obj *ref)
+{
+ fz_error *error;
+ pdf_rsrc *rsrc;
+ fz_obj *obj;
+ fz_obj *subtype;
- err = pdf_resolve(&ref, xref);
- if (err) return err;
+ if (pdf_findresource(xref->rxobject, ref))
+ return nil;
+ if (pdf_findresource(xref->rimage, ref))
+ return nil;
- err = pdf_loadfont(&font, xref, ref);
- if (err) goto cleanup;
+ rsrc = fz_malloc(sizeof(pdf_rsrc));
+ if (!rsrc)
+ return fz_outofmem;
+ rsrc->oid = fz_tonum(ref);
+ rsrc->gen = fz_togen(ref);
- err = fz_newpointer(&ptr, font);
- if (err) goto cleanup;
+ error = pdf_loadindirect(&obj, xref, ref);
+ if (error)
+ return error;
- err = fz_dictputs(rdb->font, name, ptr);
- if (err) goto cleanup;
+ subtype = fz_dictgets(obj, "Subtype");
- fz_dropobj(ptr);
- fz_dropobj(ref);
+ if (!strcmp(fz_toname(subtype), "Form"))
+ {
+// error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj);
+ fz_dropobj(obj);
+ if (error) {
+ fz_free(rsrc);
+ return error;
}
+ rsrc->next = xref->rxobject;
+ xref->rxobject = rsrc;
+ return nil;
}
- return nil;
+ else if (!strcmp(fz_toname(subtype), "Image"))
+ {
+ error = pdf_loadimage((pdf_image**)&rsrc->val, xref, obj);
+ fz_dropobj(obj);
+ if (error) {
+ fz_free(rsrc);
+ return error;
+ }
+ rsrc->next = xref->rimage;
+ xref->rimage = rsrc;
+ return nil;
+ }
-cleanup:
- if (font) fz_freefont((fz_font*)font);
- if (ptr) fz_dropobj(ptr);
- fz_dropobj(ref);
- return err;
+ else
+ {
+ fz_dropobj(obj);
+ fz_free(rsrc);
+ return fz_throw("syntaxerror: unknown XObject subtype");
+ }
}
static fz_error *
-loadextgstates(pdf_resources *rdb, pdf_xref *xref, fz_obj *dict)
+preloadfont(pdf_xref *xref, fz_obj *ref)
{
- fz_error *err;
- fz_obj *key, *val;
- int i;
+ fz_error *error;
+ pdf_font *font;
+ pdf_rsrc *rsrc;
+ fz_obj *obj;
- for (i = 0; i < fz_dictlen(dict); i++)
- {
- key = fz_dictgetkey(dict, i);
- val = fz_dictgetval(dict, i);
+ if (pdf_findresource(xref->rfont, ref))
+ return nil;
- err = pdf_resolve(&val, xref);
- if (err) return err;
+ rsrc = fz_malloc(sizeof(pdf_rsrc));
+ if (!rsrc)
+ return fz_outofmem;
+ rsrc->oid = fz_tonum(ref);
+ rsrc->gen = fz_togen(ref);
+
+ error = pdf_loadindirect(&obj, xref, ref);
+ if (error)
+ return error;
+ error = pdf_loadfont(&font, xref, obj);
+ fz_dropobj(obj);
+ if (error) {
+ fz_free(rsrc);
+ return error;
+ }
- err = fz_dictput(rdb->extgstate, key, val);
- if (err) { fz_dropobj(val); return err; }
+ rsrc->val = font;
+ rsrc->next = xref->rfont;
+ xref->rfont = rsrc;
+ return nil;
+}
- fz_dropobj(val);
+static fz_error *
+scanfonts(pdf_xref *xref, fz_obj *rdb)
+{
+ fz_error *error;
+ fz_obj *dict;
+ fz_obj *obj;
+ int i;
+
+ dict = fz_dictgets(rdb, "ExtGState");
+ if (dict)
+ {
+ for (i = 0; i < fz_dictlen(dict); i++)
+ {
+ obj = fz_dictgetval(dict, i);
+ obj = fz_dictgets(obj, "Font");
+ if (obj)
+ {
+ error = preloadfont(xref, fz_arrayget(obj, 0));
+ if (error)
+ return error;
+ }
+ }
+ }
+
+ dict = fz_dictgets(rdb, "Font");
+ if (dict)
+ {
+ for (i = 0; i < fz_dictlen(dict); i++)
+ {
+ obj = fz_dictgetval(dict, i);
+ error = preloadfont(xref, obj);
+ if (error)
+ return error;
+ }
}
return nil;
}
static fz_error *
-loadfonts(pdf_resources *rdb, pdf_xref *xref, fz_obj *dict)
+copyresolved(fz_obj **outp, pdf_xref *xref, fz_obj *dict)
{
- fz_error *err;
- pdf_font *font;
- fz_obj *key, *val;
- fz_obj *ptr;
+ fz_error *error;
+ fz_obj *key, *val, *obj;
+ fz_obj *copy;
int i;
+ error = fz_newdict(&copy, fz_dictlen(dict));
+ if (error)
+ return error;
+
for (i = 0; i < fz_dictlen(dict); i++)
{
- font = nil;
- ptr = nil;
-
key = fz_dictgetkey(dict, i);
val = fz_dictgetval(dict, i);
- err = pdf_resolve(&val, xref);
- if (err) return err;
+ if (fz_isindirect(val))
+ {
+ error = pdf_loadindirect(&obj, xref, val);
+ if (error)
+ goto cleanup;
+ error = fz_dictput(copy, key, obj);
+ fz_dropobj(obj);
+ if (error)
+ goto cleanup;
+ }
+ else
+ {
+ error = fz_dictput(copy, key, val);
+ if (error)
+ goto cleanup;
+ }
+ }
- err = pdf_loadfont(&font, xref, val);
- if (err) goto cleanup;
+ *outp = copy;
+ return nil;
- err = fz_newpointer(&ptr, font);
- if (err) goto cleanup;
+cleanup:
+ fz_dropobj(copy);
+ return error;
+}
- err = fz_dictput(rdb->font, key, ptr);
- if (err) goto cleanup;
+fz_error *
+pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
+{
+ fz_error *error;
+ fz_obj *copy;
+ fz_obj *old;
+ fz_obj *new;
+ fz_obj *dict;
+ fz_obj *obj;
+ int i;
- fz_dropobj(ptr);
- fz_dropobj(val);
+ /*
+ * Resolve indirect objects
+ */
+
+ error = copyresolved(&copy, xref, orig);
+ if (error)
+ return error;
+
+ old = fz_dictgets(copy, "ExtGState");
+ if (old)
+ {
+ error = copyresolved(&new, xref, old);
+ if (error)
+ goto cleanup;
+ error = fz_dictputs(copy, "ExtGState", new);
+ fz_dropobj(new);
+ if (error)
+ goto cleanup;
}
+ /*
+ * Load ColorSpace objects
+ */
+
+ dict = fz_dictgets(copy, "ColorSpace");
+ if (dict)
+ {
+ for (i = 0; i < fz_dictlen(dict); i++)
+ {
+ obj = fz_dictgetval(dict, i);
+ if (fz_isindirect(obj))
+ {
+ error = preloadcolorspace(xref, obj);
+ if (error)
+ return error;
+ }
+ }
+ }
+
+ /*
+ * Load XObjects and Images
+ */
+
+ dict = fz_dictgets(copy, "XObject");
+ if (dict)
+ {
+ for (i = 0; i < fz_dictlen(dict); i++)
+ {
+ obj = fz_dictgetval(dict, i);
+ if (fz_isindirect(obj))
+ {
+ error = preloadxobject(xref, obj);
+ if (error)
+ return error;
+ }
+ }
+ }
+
+ /*
+ * Load Font objects
+ */
+
+ error = scanfonts(xref, copy);
+ if (error)
+ goto cleanup;
+
+ *rdbp = copy;
return nil;
cleanup:
- if (font) fz_freefont((fz_font*)font);
- if (ptr) fz_dropobj(ptr);
- fz_dropobj(val);
- return err;
+ fz_dropobj(copy);
+ return error;
}
+#if 0
+
static fz_error *
loadcolorspaces(pdf_resources *rdb, pdf_xref *xref, fz_obj *dict)
{
@@ -228,15 +450,5 @@ pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *topdict)
return nil;
}
-void
-pdf_freeresources(pdf_resources *rdb)
-{
- /* TODO freefont and freecolorspace */
- if (rdb->extgstate) fz_dropobj(rdb->extgstate);
- if (rdb->colorspace) fz_dropobj(rdb->colorspace);
- if (rdb->font) fz_dropobj(rdb->font);
- if (rdb->ximage) fz_dropobj(rdb->ximage);
- if (rdb->xform) fz_dropobj(rdb->xform);
- fz_free(rdb);
-}
+#endif
diff --git a/mupdf/xref.c b/mupdf/xref.c
index ae11ebb7..5dde5f5f 100644
--- a/mupdf/xref.c
+++ b/mupdf/xref.c
@@ -10,9 +10,10 @@ pdf_newpdf(pdf_xref **xrefp)
{
pdf_xref *xref;
- xref = fz_malloc(sizeof (pdf_xref));
+ xref = fz_malloc(sizeof(pdf_xref));
if (!xref)
return fz_outofmem;
+ memset(xref, 0, sizeof(pdf_xref));
xref->file = nil;
xref->version = 1.3;
diff --git a/render/render.c b/render/render.c
index d46d5b71..29b51480 100644
--- a/render/render.c
+++ b/render/render.c
@@ -5,6 +5,9 @@ fz_error *fz_rendercolorpath(fz_renderer*, fz_pathnode*, fz_colornode*, fz_matri
fz_error *fz_rendertext(fz_renderer*, fz_textnode*, fz_matrix);
fz_error *fz_renderpath(fz_renderer*, fz_pathnode*, fz_matrix);
+fz_error *fz_renderimageover(fz_renderer*, fz_imagenode*, fz_matrix);
+fz_error *fz_renderimage(fz_renderer*, fz_imagenode*, fz_matrix);
+
fz_error *
fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel)
{
@@ -131,7 +134,6 @@ fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
fz_error *error;
fz_pixmap *oldacc = nil;
int oldmode;
-int i;
/* uh-oh! we have a new over cluster */
if (gc->mode != FZ_ROVER)
@@ -209,6 +211,10 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
fz_blendmask(gc->tmp, colorpix, shapepix);
+//printf("mask color");fz_debugpixmap(colorpix);getchar();
+//printf("mask shape");fz_debugpixmap(shapepix);getchar();
+//printf("mask blend");fz_debugpixmap(gc->tmp);getchar();
+
fz_freepixmap(shapepix);
fz_freepixmap(colorpix);
@@ -246,6 +252,8 @@ fz_rendernode(fz_renderer *gc, fz_node *node, fz_matrix ctm)
return fz_renderpath(gc, (fz_pathnode*)node, ctm);
case FZ_NTEXT:
return fz_rendertext(gc, (fz_textnode*)node, ctm);
+ case FZ_NIMAGE:
+ return fz_renderimage(gc, (fz_imagenode*)node, ctm);
default:
return nil;
}
@@ -261,6 +269,10 @@ fz_rendertree(fz_pixmap **outp, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, f
gc->w = ceil(bbox.max.x) - floor(bbox.min.x);
gc->h = ceil(bbox.max.y) - floor(bbox.min.y);
+ /* compensate for rounding */
+ ctm.e -= bbox.min.x - floor(bbox.min.x);
+ ctm.f -= bbox.min.y - floor(bbox.min.y);
+
error = fz_rendernode(gc, tree->root, ctm);
if (error)
return error;
diff --git a/render/renderimage.c b/render/renderimage.c
new file mode 100644
index 00000000..4c6ef816
--- /dev/null
+++ b/render/renderimage.c
@@ -0,0 +1,59 @@
+#include <fitz.h>
+
+static int cmpy(const void *a, const void *b)
+{
+ const fz_point *ap = a;
+ const fz_point *bp = b;
+ return bp->y - ap->y;
+}
+
+static void
+drawtile(fz_pixmap *out, fz_pixmap *tile, fz_matrix ctm)
+{
+ static const fz_point rect[4] = { {0, 0}, {0, 1}, {1, 1}, {1, 0} };
+ fz_point v[4];
+ int i;
+
+ for (i = 0; i < 4; i++)
+ v[i] = fz_transformpoint(ctm, rect[i]);
+
+ qsort(v, 4, sizeof(fz_point), cmpy);
+
+ for (i = 0; i < 4; i++)
+ printf("%d: %g %g\n", i, v[i].x, v[i].y);
+
+}
+
+fz_error *
+fz_renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
+{
+ fz_error *error;
+ fz_pixmap *tile;
+ fz_image *image = node->image;
+ fz_colorspace *cs = image->cs;
+ int w = image->w;
+ int h = image->h;
+ int n = image->n;
+
+ error = fz_newpixmap(&tile, cs, 0, 0, w, h, n, 1);
+ if (error)
+ return error;
+
+ error = fz_newpixmap(&gc->tmp, cs, gc->x, gc->y, gc->w, gc->h, n, 1);
+ if (error)
+ goto cleanup;
+
+ error = image->loadtile(image, tile);
+ if (error)
+ goto cleanup;
+
+ drawtile(gc->tmp, tile, ctm);
+
+ fz_freepixmap(tile);
+ return nil;
+
+cleanup:
+ fz_freepixmap(tile);
+ return error;
+}
+
diff --git a/render/renderpath.c b/render/renderpath.c
index 9e805a53..8d2f875b 100644
--- a/render/renderpath.c
+++ b/render/renderpath.c
@@ -1,6 +1,8 @@
#include <fitz.h>
-enum { HS = 17, VS = 15 };
+// enum { HS = 1, VS = 1, SF = 255 };
+// enum { HS = 5, VS = 3, SF = 17 };
+enum { HS = 17, VS = 15, SF = 1 };
static fz_error *pathtogel(fz_gel *gel, fz_pathnode *path, fz_matrix ctm)
{
@@ -17,7 +19,7 @@ static fz_error *pathtogel(fz_gel *gel, fz_pathnode *path, fz_matrix ctm)
return fz_fillpath(gel, path, ctm, flatness);
}
-static void blitcolorspan(int y, int x0, int n, short *list, void *userdata)
+static void blitcolorspan(int y, int x, int n, unsigned char *alpha, void *userdata)
{
fz_renderer *gc = userdata;
fz_pixmap *pix = gc->acc;
@@ -28,23 +30,24 @@ static void blitcolorspan(int y, int x0, int n, short *list, void *userdata)
unsigned char g = gc->g;
unsigned char b = gc->b;
- sa = 0;
-
- while (x0 < pix->x)
+ if (x < pix->x)
{
- sa += *list++;
- x0 ++;
- n --;
+ alpha += pix->x - x;
+ n -= pix->x - x;
+ x = pix->x;
}
- if (n > pix->w)
- n = pix->w;
+ if (x + n > pix->x + pix->w)
+ n = pix->x + pix->w - x;
+
+ if (n < 0)
+ return;
- p = &pix->samples[(y - pix->y) * pix->stride + (x0 - pix->x) * 4];
+ p = &pix->samples[(y - pix->y) * pix->stride + (x - pix->x) * 4];
while (n--)
{
- sa += *list++;
+ sa = *alpha++ * SF;
ssa = 255 - sa;
p[0] = fz_mul255(r, sa) + fz_mul255(p[0], ssa);
@@ -56,31 +59,27 @@ static void blitcolorspan(int y, int x0, int n, short *list, void *userdata)
}
}
-static void blitalphaspan(int y, int x0, int n, short *list, void *userdata)
+static void blitalphaspan(int y, int x, int n, unsigned char *alpha, void *userdata)
{
fz_pixmap *pix = userdata;
- unsigned char a;
unsigned char *p;
- a = 0;
-
- while (x0 < pix->x)
+ if (x < pix->x)
{
- a += *list++;
- x0 ++;
- n --;
+ alpha += pix->x - x;
+ n -= pix->x - x;
+ x = pix->x;
}
- if (n > pix->w)
- n = pix->w;
+ if (x + n > pix->x + pix->w)
+ n = pix->x + pix->w - x;
- p = &pix->samples[(y - pix->y) * pix->stride + (x0 - pix->x) * 4];
+ if (n < 0)
+ return;
+ p = &pix->samples[(y - pix->y) * pix->stride + (x - pix->x)];
while (n--)
- {
- a += *list++;
- *p++ = a;
- }
+ *p++ = *alpha++ * SF;
}
fz_error *
diff --git a/render/rendertext.c b/render/rendertext.c
index cc181657..81afeafa 100644
--- a/render/rendertext.c
+++ b/render/rendertext.c
@@ -33,13 +33,13 @@ static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, fz_rend
{
for (sx = 0; sx < gl->w; sx++)
{
- dx = xo + sx + gl->lsb - out->x;
dy = yo - sy + gl->top - out->y;
+ if (dy < 0) continue;
+ if (dy >= out->h) break;
+ dx = xo + sx + gl->lsb - out->x;
if (dx < 0) continue;
- if (dy < 0) continue;
- if (dx >= out->w) continue;
- if (dy >= out->h) continue;
+ if (dx >= out->w) break;
sa = gl->bitmap[sx + sy * gl->w];
ssa = 255 - sa;
diff --git a/render/scanconv.c b/render/scanconv.c
index b2689ae2..db859d1f 100644
--- a/render/scanconv.c
+++ b/render/scanconv.c
@@ -1,7 +1,7 @@
#include <fitz.h>
static inline void
-addspan(short *list, int x0, int x1, int xofs, int hs)
+addspan(unsigned char *list, int x0, int x1, int xofs, int hs)
{
int x0pix, x0sub;
int x1pix, x1sub;
@@ -34,7 +34,7 @@ addspan(short *list, int x0, int x1, int xofs, int hs)
}
static inline void
-nonzerowinding(fz_ael *ael, short *list, int xofs, int hs)
+nonzerowinding(fz_ael *ael, unsigned char *list, int xofs, int hs)
{
int winding = 0;
int x = 0;
@@ -50,7 +50,7 @@ nonzerowinding(fz_ael *ael, short *list, int xofs, int hs)
}
static inline void
-evenodd(fz_ael *ael, short *list, int xofs, int hs)
+evenodd(fz_ael *ael, unsigned char *list, int xofs, int hs)
{
int even = 0;
int x = 0;
@@ -65,22 +65,22 @@ evenodd(fz_ael *ael, short *list, int xofs, int hs)
}
}
-/*
-void
-fz_emitdeltas(short *list, int y, int xofs, int n)
+static void toalpha(unsigned char *list, int n)
{
int d = 0;
while (n--)
- d += *list++;
+ {
+ d += *list;
+ *list++ = d;
+ }
}
-*/
fz_error *
fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
- void (*blitfunc)(int,int,int,short*,void*), void *blitdata)
+ void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata)
{
fz_error *error;
- short *deltas;
+ unsigned char *deltas;
int y, e;
int yd, yc;
@@ -96,11 +96,11 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
if (gel->len == 0)
return nil;
- deltas = fz_malloc(sizeof(short) * (xmax - xmin + 1));
+ deltas = fz_malloc(xmax - xmin + 1);
if (!deltas)
return fz_outofmem;
- memset(deltas, 0, sizeof(short) * (xmax - xmin + 1));
+ memset(deltas, 0, xmax - xmin + 1);
e = 0;
y = gel->edges[0].y;
@@ -113,8 +113,9 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
if (yc != yd) {
if (yd >= y0 && yd < y1)
{
+ toalpha(deltas, xmax - xmin);
blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
- memset(deltas, 0, sizeof(short) * (xmax - xmin + 1));
+ memset(deltas, 0, xmax - xmin + 1);
}
}
yd = yc;
@@ -142,7 +143,10 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
}
if (yd >= y0 && yd < y1)
+ {
+ toalpha(deltas, xmax - xmin);
blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
+ }
fz_free(deltas);
return nil;
diff --git a/test/pdfrip.c b/test/pdfrip.c
index f7cbc093..e8cd088f 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -33,23 +33,20 @@ void showpage(pdf_xref *xref, fz_obj *pageobj)
page->mediabox.max.x, page->mediabox.max.y);
printf(" rotate %d\n", page->rotate);
- printf(" fonts\n");
- fz_debugobj(page->rdb->font);
- printf("\n");
-
- printf(" colorspaces\n");
- fz_debugobj(page->rdb->colorspace);
+ printf(" resources\n");
+ fz_debugobj(page->resources);
printf("\n");
printf("tree\n");
fz_debugtree(page->tree);
- printf("endtree");
+ printf("endtree\n");
}
{
fz_pixmap *pix;
fz_renderer *gc;
fz_matrix ctm;
+ fz_rect bbox;
error = fz_newrenderer(&gc, pdf_devicergb);
if (error) fz_abort(error);
@@ -58,8 +55,12 @@ void showpage(pdf_xref *xref, fz_obj *pageobj)
printf("ctm %g %g %g %g %g %g\n",
ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
+printf("bounding!\n");
+ bbox = fz_boundtree(page->tree, ctm);
+printf(" [%g %g %g %g]\n", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
printf("rendering!\n");
error = fz_rendertree(&pix, gc, page->tree, ctm, page->mediabox);
+ //error = fz_rendertree(&pix, gc, page->tree, ctm, bbox);
if (error) fz_abort(error);
printf("done!\n");
diff --git a/tree/debug.c b/tree/debug.c
index 583608f5..e55d56e7 100644
--- a/tree/debug.c
+++ b/tree/debug.c
@@ -13,7 +13,8 @@ static void lispmeta(fz_metanode *node, int level)
fz_node *child;
indent(level);
printf("(meta ");
- fz_debugobj(node->info);
+ if (node->name) { fz_debugobj(node->name); }
+ if (node->dict) { printf("\n"); fz_debugobj(node->dict); }
printf("\n");
for (child = node->super.child; child; child = child->next)
lispnode(child, level + 1);
@@ -141,7 +142,7 @@ static void lisptext(fz_textnode *node, int level)
static void lispimage(fz_imagenode *node, int level)
{
indent(level);
- printf("(image %d %d %d %d)\n", node->w, node->h, node->n, node->a);
+ printf("(image)\n");
}
static void lispnode(fz_node *node, int level)
diff --git a/tree/font.c b/tree/font.c
index 5dfaec2e..58c194ae 100644
--- a/tree/font.c
+++ b/tree/font.c
@@ -39,6 +39,7 @@ fz_setfontwmode(fz_font *font, int wmode)
void
fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax)
{
+printf(" bbox [%d %d %d %d]\n", xmin, ymin, xmax, ymax);
font->bbox.min.x = xmin;
font->bbox.min.y = ymin;
font->bbox.max.x = xmax;
diff --git a/tree/node2.c b/tree/node2.c
index d50936ef..6e28aaac 100644
--- a/tree/node2.c
+++ b/tree/node2.c
@@ -164,7 +164,7 @@ fz_boundtransformnode(fz_transformnode *node, fz_matrix ctm)
*/
fz_error *
-fz_newmetanode(fz_node **nodep, fz_obj *info)
+fz_newmetanode(fz_node **nodep, fz_obj *name, fz_obj *dict)
{
fz_metanode *node;
@@ -174,7 +174,13 @@ fz_newmetanode(fz_node **nodep, fz_obj *info)
*nodep = (fz_node*)node;
fz_initnode((fz_node*)node, FZ_NMETA);
- node->info = fz_keepobj(info);
+ node->name = nil;
+ node->dict = nil;
+
+ if (name)
+ node->name = fz_keepobj(name);
+ if (dict)
+ node->dict = fz_keepobj(dict);
return nil;
}
@@ -182,8 +188,10 @@ fz_newmetanode(fz_node **nodep, fz_obj *info)
void
fz_freemetanode(fz_metanode *node)
{
- if (node->info)
- fz_dropobj(node->info);
+ if (node->name)
+ fz_dropobj(node->name);
+ if (node->dict)
+ fz_dropobj(node->dict);
}
fz_rect
@@ -261,7 +269,7 @@ fz_boundcolornode(fz_colornode *node, fz_matrix ctm)
*/
fz_error *
-fz_newimagenode(fz_node **nodep, fz_colorspace *cs, int w, int h, int n, int a)
+fz_newimagenode(fz_node **nodep, fz_image *image)
{
fz_imagenode *node;
@@ -271,11 +279,7 @@ fz_newimagenode(fz_node **nodep, fz_colorspace *cs, int w, int h, int n, int a)
*nodep = (fz_node*)node;
fz_initnode((fz_node*)node, FZ_NIMAGE);
- node->cs = cs;
- node->w = w;
- node->h = h;
- node->n = n;
- node->a = a;
+ node->image = image;
return nil;
}
diff --git a/tree/text.c b/tree/text.c
index d822ec34..1832df9f 100644
--- a/tree/text.c
+++ b/tree/text.c
@@ -29,9 +29,67 @@ fz_freetextnode(fz_textnode *text)
fz_rect
fz_boundtextnode(fz_textnode *text, fz_matrix ctm)
{
- // FIXME convolve font bbox to all glyph x,y pairs
- /* fz_rect bounds = fz_boundglyph(text->font, text->els[0], ctm); */
- return fz_infiniterect();
+ fz_matrix trm;
+ fz_point ul, ur, ll, lr;
+ fz_rect bbox;
+ fz_rect fbox;
+ int i;
+
+ if (text->len == 0)
+ return fz_infiniterect();
+
+ /* find bbox of glyph origins in ctm space */
+
+ bbox.min.x = bbox.max.x = text->els[0].x;
+ bbox.min.y = bbox.max.y = text->els[0].y;
+
+ for (i = 1; i < text->len; i++)
+ {
+ bbox.min.x = MIN(bbox.min.x, text->els[i].x);
+ bbox.min.y = MIN(bbox.min.y, text->els[i].y);
+ bbox.max.x = MAX(bbox.max.x, text->els[i].x);
+ bbox.max.y = MAX(bbox.max.y, text->els[i].y);
+ }
+
+ ll.x = bbox.min.x; ll.y = bbox.min.y; ll = fz_transformpoint(ctm, ll);
+ ul.x = bbox.min.x; ul.y = bbox.max.y; ul = fz_transformpoint(ctm, ul);
+ ur.x = bbox.max.x; ur.y = bbox.max.y; ur = fz_transformpoint(ctm, ur);
+ lr.x = bbox.max.x; lr.y = bbox.min.y; lr = fz_transformpoint(ctm, lr);
+
+ bbox.min.x = MIN4(ll.x, ul.x, ur.x, lr.x);
+ bbox.min.y = MIN4(ll.y, ul.y, ur.y, lr.y);
+ bbox.max.x = MAX4(ll.x, ul.x, ur.x, lr.x);
+ bbox.max.y = MAX4(ll.y, ul.y, ur.y, lr.y);
+
+ /* find bbox of font in trm * ctm space */
+
+ trm = fz_concat(text->trm, ctm);
+ trm.e = 0;
+ trm.f = 0;
+
+ fbox.min.x = text->font->bbox.min.x * 0.001;
+ fbox.min.y = text->font->bbox.min.y * 0.001;
+ fbox.max.x = text->font->bbox.max.x * 0.001;
+ fbox.max.y = text->font->bbox.max.y * 0.001;
+
+ ll.x = fbox.min.x; ll.y = fbox.min.y; ll = fz_transformpoint(trm, ll);
+ ul.x = fbox.min.x; ul.y = fbox.max.y; ul = fz_transformpoint(trm, ul);
+ ur.x = fbox.max.x; ur.y = fbox.max.y; ur = fz_transformpoint(trm, ur);
+ lr.x = fbox.max.x; lr.y = fbox.min.y; lr = fz_transformpoint(trm, lr);
+
+ fbox.min.x = MIN4(ll.x, ul.x, ur.x, lr.x);
+ fbox.min.y = MIN4(ll.y, ul.y, ur.y, lr.y);
+ fbox.max.x = MAX4(ll.x, ul.x, ur.x, lr.x);
+ fbox.max.y = MAX4(ll.y, ul.y, ur.y, lr.y);
+
+ bbox.min.x += MIN4(ll.x, ul.x, ur.x, lr.x);
+ bbox.min.y += MIN4(ll.y, ul.y, ur.y, lr.y);
+ bbox.max.x += MAX4(ll.x, ul.x, ur.x, lr.x);
+ bbox.max.y += MAX4(ll.y, ul.y, ur.y, lr.y);
+
+// printf("text [ %g %g %g %g ]\n", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
+
+ return bbox;
}
static fz_error *