summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-10-19 04:07:51 +0200
committerTor Andersson <tor@ghostscript.com>2004-10-19 04:07:51 +0200
commit3342d0657522d6b3acaae5216b7026165154ab52 (patch)
treec4b06d02c86944a6d835b3614873a0f6ce113cd6
parentbbf53bb5172130d375ac4e6214c685d24120204b (diff)
downloadmupdf-3342d0657522d6b3acaae5216b7026165154ab52.tar.xz
moved cidtogid into pdf_font, added colorspaces and pdf_page object
-rw-r--r--Jamfile3
-rw-r--r--include/fitz.h1
-rw-r--r--include/fitz/colorspace.h15
-rw-r--r--include/fitz/font.h4
-rw-r--r--include/fitz/pixmap.h6
-rw-r--r--include/fitz/render.h2
-rw-r--r--include/fitz/tree.h12
-rw-r--r--include/mupdf.h31
-rw-r--r--mupdf/build.c18
-rw-r--r--mupdf/font.c14
-rw-r--r--mupdf/interpret.c119
-rw-r--r--mupdf/page.c159
-rw-r--r--mupdf/pagetree.c14
-rw-r--r--mupdf/resources.c60
-rw-r--r--render/pixmap.c6
-rw-r--r--render/render.c65
-rw-r--r--test/pdfrip.c105
-rw-r--r--tree/colorspace.c34
-rw-r--r--tree/debug.c6
-rw-r--r--tree/font.c11
-rw-r--r--tree/node2.c21
21 files changed, 518 insertions, 188 deletions
diff --git a/Jamfile b/Jamfile
index d7f69831..cb3da8a7 100644
--- a/Jamfile
+++ b/Jamfile
@@ -65,6 +65,7 @@ Library libfitz :
# tree
tree/cmap.c
tree/font.c
+ tree/colorspace.c
tree/tree.c
tree/node1.c
@@ -99,7 +100,9 @@ Library libmupdf :
mupdf/cmap.c
mupdf/font.c
mupdf/fontfile.c
+ mupdf/colorspace.c
mupdf/resources.c
+ mupdf/page.c
mupdf/pagetree.c
mupdf/build.c
mupdf/interpret.c
diff --git a/include/fitz.h b/include/fitz.h
index 30f37649..85ac8118 100644
--- a/include/fitz.h
+++ b/include/fitz.h
@@ -18,6 +18,7 @@
#include "fitz/cmap.h"
#include "fitz/font.h"
+#include "fitz/colorspace.h"
#include "fitz/tree.h"
#include "fitz/path.h"
diff --git a/include/fitz/colorspace.h b/include/fitz/colorspace.h
new file mode 100644
index 00000000..370c755f
--- /dev/null
+++ b/include/fitz/colorspace.h
@@ -0,0 +1,15 @@
+typedef struct fz_colorspace_s fz_colorspace;
+
+struct fz_colorspace_s
+{
+ char name[16];
+ int frozen;
+ int n;
+ void (*toxyz)(fz_colorspace *, float *src, float *xyz);
+ void (*fromxyz)(fz_colorspace *, float *xyz, float *dst);
+ void (*free)(fz_colorspace *);
+};
+
+void fz_freecolorspace(fz_colorspace *cs);
+void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
+
diff --git a/include/fitz/font.h b/include/fitz/font.h
index b915755b..d64c1fc3 100644
--- a/include/fitz/font.h
+++ b/include/fitz/font.h
@@ -37,9 +37,6 @@ struct fz_font_s
int nvmtx, vmtxcap;
fz_vmtx dvmtx;
fz_vmtx *vmtx;
-
- int ncidtogid;
- unsigned short *cidtogid;
};
struct fz_glyph_s
@@ -53,7 +50,6 @@ void fz_freefont(fz_font *font);
void fz_debugfont(fz_font *font);
void fz_setfontwmode(fz_font *font, int wmode);
void fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax);
-void fz_setcidtogid(fz_font *font, int n, unsigned short *map);
void fz_setdefaulthmtx(fz_font *font, int w);
void fz_setdefaultvmtx(fz_font *font, int y, int w);
fz_error *fz_addhmtx(fz_font *font, int lo, int hi, int w);
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index 462b4ad6..f7bab833 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -1,16 +1,16 @@
typedef struct fz_pixmap_s fz_pixmap;
-typedef struct fz_colorspace_s fz_colorspace;
struct fz_pixmap_s
{
+ fz_colorspace *cs;
int x, y, w, h;
int n, a;
int stride;
- fz_colorspace *cs;
short *samples;
};
-fz_error *fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n, int a);
+fz_error *fz_newpixmap(fz_pixmap **mapp, fz_colorspace *cs, int x, int y, int w, int h, int n, int a);
+fz_error *fz_convertpixmap(fz_pixmap **dstp, fz_pixmap *src, fz_colorspace *dstcs);
void fz_debugpixmap(fz_pixmap *map);
void fz_freepixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
diff --git a/include/fitz/render.h b/include/fitz/render.h
index 09c439c2..7f4e08db 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -1,6 +1,6 @@
typedef struct fz_renderer_s fz_renderer;
-fz_error *fz_newrenderer(fz_renderer **gcp);
+fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm);
void fz_freerenderer(fz_renderer *gc);
fz_error *fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm);
diff --git a/include/fitz/tree.h b/include/fitz/tree.h
index 4d6eb952..6578ab51 100644
--- a/include/fitz/tree.h
+++ b/include/fitz/tree.h
@@ -102,6 +102,7 @@ struct fz_masknode_s
struct fz_blendnode_s
{
fz_node super;
+ fz_colorspace *cs;
fz_blendkind mode;
int isolated;
int knockout;
@@ -110,7 +111,9 @@ struct fz_blendnode_s
struct fz_colornode_s
{
fz_node super;
- float r, g, b;
+ fz_colorspace *cs;
+ int n;
+ float samples[];
};
struct fz_linknode_s
@@ -128,6 +131,7 @@ struct fz_metanode_s
struct fz_imagenode_s
{
fz_node super;
+ fz_colorspace *cs;
int w, h, n, a;
// XXX fz_image *image;
};
@@ -141,7 +145,7 @@ void fz_freenode(fz_node *node);
fz_error *fz_newmetanode(fz_node **nodep, fz_obj *info);
fz_error *fz_newovernode(fz_node **nodep);
fz_error *fz_newmasknode(fz_node **nodep);
-fz_error *fz_newblendnode(fz_node **nodep, fz_blendkind b, int k, int i);
+fz_error *fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i);
fz_error *fz_newtransformnode(fz_node **nodep, fz_matrix m);
int fz_istransformnode(fz_node *node);
@@ -152,8 +156,8 @@ 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, float r, float g, float b);
-fz_error *fz_newimagenode(fz_node **nodep, int w, int h, int n, int a);
+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);
int fz_islinknode(fz_node *node);
int fz_iscolornode(fz_node *node);
diff --git a/include/mupdf.h b/include/mupdf.h
index 2c423408..cd19e55b 100644
--- a/include/mupdf.h
+++ b/include/mupdf.h
@@ -131,10 +131,15 @@ fz_error *pdf_decryptpdf(pdf_xref *xref);
* high-level semantic objects for resources and pages
*/
+extern fz_colorspace *pdf_devicegray;
+extern fz_colorspace *pdf_devicergb;
+extern fz_colorspace *pdf_devicecmyk;
+
typedef struct pdf_nametree_s pdf_nametree;
typedef struct pdf_pagetree_s pdf_pagetree;
typedef struct pdf_font_s pdf_font;
typedef struct pdf_resources_s pdf_resources;
+typedef struct pdf_page_s pdf_page;
typedef struct pdf_gstate_s pdf_gstate;
typedef struct pdf_csi_s pdf_csi;
@@ -171,6 +176,8 @@ struct pdf_font_s
/* Encoding (CMap) */
fz_cmap *encoding;
+ int ncidtogid;
+ unsigned short *cidtogid;
/* Raw data for freetype */
char *filename;
@@ -195,6 +202,14 @@ struct pdf_resources_s
fz_obj *xform;
};
+struct pdf_page_s
+{
+ fz_rect mediabox;
+ int rotate;
+ pdf_resources *rdb;
+ fz_tree *tree;
+};
+
struct pdf_gstate_s
{
/* path stroking */
@@ -206,8 +221,11 @@ struct pdf_gstate_s
int dashlen;
float dashlist[32];
- /* colors and colorspaces */
- struct { float r, g, b; } stroke, fill;
+ /* materials */
+ fz_colorspace *strokecs;
+ float stroke[32];
+ fz_colorspace *fillcs;
+ float fill[32];
/* text state */
float charspace;
@@ -252,9 +270,15 @@ fz_obj *pdf_lookupnames(pdf_nametree *nt, char *name);
/* pagetree.c */
fz_error *pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref);
+int pdf_getpagecount(pdf_pagetree *pages);
+fz_obj *pdf_getpageobject(pdf_pagetree *pages, int p);
void pdf_debugpagetree(pdf_pagetree *pages);
void pdf_freepagetree(pdf_pagetree *pages);
+/* page.c */
+fz_error *pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *ref);
+void pdf_freepage(pdf_page *page);
+
/* cmap.c */
fz_error *pdf_parsecmap(fz_cmap **cmapp, fz_file *file);
fz_error *pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref);
@@ -271,6 +295,9 @@ fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, c
fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *font);
void pdf_freefont(pdf_font *font);
+/* colorspace.c */
+fz_error *pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj);
+
/* resources.c */
fz_error *pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *resdict);
void pdf_freeresources(pdf_resources *rdb);
diff --git a/mupdf/build.c b/mupdf/build.c
index 0e65f6a4..5747b962 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -14,13 +14,11 @@ pdf_initgstate(pdf_gstate *gs)
gs->dashlen = 0;
memset(gs->dashlist, 0, sizeof(gs->dashlist));
- gs->stroke.r = 0;
- gs->stroke.g = 0;
- gs->stroke.b = 0;
+ gs->strokecs = pdf_devicegray;
+ gs->stroke[0] = 0;
- gs->fill.r = 0;
- gs->fill.g = 0;
- gs->fill.b = 0;
+ gs->fillcs = pdf_devicegray;
+ gs->fill[0] = 0;
gs->charspace = 0;
gs->wordspace = 0;
@@ -71,7 +69,7 @@ pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int eofill)
}
static fz_error *
-addcolorshape(pdf_gstate *gs, fz_node *shape, float r, float g, float b)
+addcolorshape(pdf_gstate *gs, fz_node *shape, fz_colorspace *cs, float *v)
{
fz_error *error;
fz_node *mask;
@@ -80,7 +78,7 @@ addcolorshape(pdf_gstate *gs, fz_node *shape, float r, float g, float b)
error = fz_newmasknode(&mask);
if (error) return error;
- error = fz_newcolornode(&solid, r, g, b);
+ error = fz_newcolornode(&solid, cs, cs->n, v);
if (error) return error;
fz_insertnode(mask, shape);
@@ -93,13 +91,13 @@ addcolorshape(pdf_gstate *gs, fz_node *shape, float r, float g, float b)
fz_error *
pdf_addfillshape(pdf_gstate *gs, fz_node *shape)
{
- return addcolorshape(gs, shape, gs->fill.r, gs->fill.g, gs->fill.b);
+ return addcolorshape(gs, shape, gs->fillcs, gs->fill);
}
fz_error *
pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape)
{
- return addcolorshape(gs, shape, gs->stroke.r, gs->stroke.g, gs->stroke.b);
+ return addcolorshape(gs, shape, gs->strokecs, gs->stroke);
}
fz_error *
diff --git a/mupdf/font.c b/mupdf/font.c
index 5ee65f4f..3835a3b8 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -28,8 +28,8 @@ printf(" type %s\n", kind);
static int ftwidth(pdf_font *font, int cid)
{
int e;
- if (font->super.cidtogid)
- cid = font->super.cidtogid[cid];
+ if (font->cidtogid)
+ cid = font->cidtogid[cid];
e = FT_Load_Glyph(font->ftface, cid,
FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
if (e)
@@ -47,8 +47,8 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
FT_Error fterr;
int gid;
- if (fzfont->cidtogid)
- gid = fzfont->cidtogid[cid];
+ if (font->cidtogid)
+ gid = font->cidtogid[cid];
else
gid = cid;
@@ -415,7 +415,8 @@ printf(" builtin encoding\n");
if (error)
goto cleanup;
- fz_setcidtogid((fz_font*)font, 256, etable);
+ font->ncidtogid = 256;
+ font->cidtogid = etable;
/*
* Widths
@@ -613,7 +614,8 @@ printf(" cidtogidmap %d\n", len / 2);
for (i = 0; i < len; i++)
map[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1];
- fz_setcidtogid((fz_font*)font, len, map);
+ font->ncidtogid = len;
+ font->cidtogid = map;
fz_freebuffer(buf);
}
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index ab3b1ea5..14aae160 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -50,8 +50,8 @@ pdf_newcsi(pdf_csi **csip)
csi->tree->root = node;
csi->gstate[0].head = node;
- error = fz_newcolornode(&node, 1, 1, 1);
- fz_insertnode(csi->tree->root, node);
+// error = fz_newcolornode(&node, pdf_devicegray, 1);
+// fz_insertnode(csi->tree->root, node);
csi->clip = nil;
@@ -145,6 +145,7 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
float a, b, c, d, e, f;
float x, y, w, h;
fz_matrix m;
+ int i;
if (strlen(buf) > 1)
{
@@ -282,22 +283,88 @@ runkeyword(pdf_csi *csi, pdf_resources *rdb, char *buf)
if (error) return error;
}
+ else if (!strcmp(buf, "cs"))
+ {
+ fz_obj *obj;
+
+ if (csi->top != 1)
+ goto syntaxerror;
+
+ obj = csi->stack[0];
+
+ if (!strcmp(fz_toname(obj), "DeviceGray"))
+ gstate->fillcs = pdf_devicegray;
+ else if (!strcmp(fz_toname(obj), "DeviceRGB"))
+ gstate->fillcs = pdf_devicergb;
+ else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
+ gstate->fillcs = pdf_devicecmyk;
+ else
+ {
+ obj = fz_dictget(rdb->colorspace, obj);
+ if (!obj)
+ return fz_throw("syntaxerror: missing resource");
+ gstate->fillcs = fz_topointer(obj);
+ }
+ }
+
+ else if (!strcmp(buf, "CS"))
+ {
+ fz_obj *obj;
+
+ if (csi->top != 1)
+ goto syntaxerror;
+
+ obj = csi->stack[0];
+
+ if (!strcmp(fz_toname(obj), "DeviceGray"))
+ gstate->strokecs = pdf_devicegray;
+ else if (!strcmp(fz_toname(obj), "DeviceRGB"))
+ gstate->strokecs = pdf_devicergb;
+ else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
+ gstate->strokecs = pdf_devicecmyk;
+ else
+ {
+ obj = fz_dictget(rdb->colorspace, obj);
+ if (!obj)
+ return fz_throw("syntaxerror: missing resource");
+ gstate->strokecs = fz_topointer(obj);
+ }
+ }
+
+ else if (!strcmp(buf, "sc"))
+ {
+ if (csi->top != gstate->fillcs->n)
+ goto syntaxerror;
+ for (i = 0; i < csi->top; i++)
+ gstate->fill[i] = fz_toreal(csi->stack[i]);
+ }
+
+ else if (!strcmp(buf, "SC"))
+ {
+ if (csi->top != gstate->strokecs->n)
+ goto syntaxerror;
+ for (i = 0; i < csi->top; i++)
+ gstate->stroke[i] = fz_toreal(csi->stack[i]);
+ }
+
else if (!strcmp(buf, "rg"))
{
if (csi->top != 3)
goto syntaxerror;
- gstate->fill.r = fz_toreal(csi->stack[0]);
- gstate->fill.g = fz_toreal(csi->stack[1]);
- gstate->fill.b = fz_toreal(csi->stack[2]);
+ gstate->fillcs = pdf_devicergb;
+ gstate->fill[0] = fz_toreal(csi->stack[0]);
+ gstate->fill[1] = fz_toreal(csi->stack[1]);
+ gstate->fill[2] = fz_toreal(csi->stack[2]);
}
else if (!strcmp(buf, "RG"))
{
if (csi->top != 3)
goto syntaxerror;
- gstate->stroke.r = fz_toreal(csi->stack[0]);
- gstate->stroke.g = fz_toreal(csi->stack[1]);
- gstate->stroke.b = fz_toreal(csi->stack[2]);
+ gstate->strokecs = pdf_devicergb;
+ gstate->stroke[0] = fz_toreal(csi->stack[0]);
+ gstate->stroke[1] = fz_toreal(csi->stack[1]);
+ gstate->stroke[2] = fz_toreal(csi->stack[2]);
}
else if (!strcmp(buf, "BT"))
@@ -615,43 +682,35 @@ fprintf(stderr, "syntaxerror: unknown keyword '%s'\n", buf);
case 'g':
if (csi->top != 1)
goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- gstate->fill.r = a;
- gstate->fill.g = a;
- gstate->fill.b = a;
+ gstate->fillcs = pdf_devicegray;
+ gstate->fill[0] = fz_toreal(csi->stack[0]);
break;
case 'G':
if (csi->top != 1)
goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- gstate->stroke.r = a;
- gstate->stroke.g = a;
- gstate->stroke.b = a;
+ gstate->strokecs = pdf_devicegray;
+ gstate->stroke[0] = fz_toreal(csi->stack[0]);
break;
case 'k':
if (csi->top != 4)
goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
- gstate->fill.r = 1.0 - MIN(1.0, a + d);
- gstate->fill.g = 1.0 - MIN(1.0, b + d);
- gstate->fill.b = 1.0 - MIN(1.0, c + d);
+ gstate->fillcs = pdf_devicecmyk;
+ gstate->fill[0] = fz_toreal(csi->stack[0]);
+ gstate->fill[1] = fz_toreal(csi->stack[1]);
+ gstate->fill[2] = fz_toreal(csi->stack[2]);
+ gstate->fill[3] = fz_toreal(csi->stack[3]);
break;
case 'K':
if (csi->top != 4)
goto syntaxerror;
- a = fz_toreal(csi->stack[0]);
- b = fz_toreal(csi->stack[1]);
- c = fz_toreal(csi->stack[2]);
- d = fz_toreal(csi->stack[3]);
- gstate->stroke.r = 1.0 - MIN(1.0, a + d);
- gstate->stroke.g = 1.0 - MIN(1.0, b + d);
- gstate->stroke.b = 1.0 - MIN(1.0, c + d);
+ gstate->strokecs = pdf_devicecmyk;
+ gstate->stroke[0] = fz_toreal(csi->stack[0]);
+ gstate->stroke[1] = fz_toreal(csi->stack[1]);
+ gstate->stroke[2] = fz_toreal(csi->stack[2]);
+ gstate->stroke[3] = fz_toreal(csi->stack[3]);
break;
case '\'':
diff --git a/mupdf/page.c b/mupdf/page.c
new file mode 100644
index 00000000..4450ae8d
--- /dev/null
+++ b/mupdf/page.c
@@ -0,0 +1,159 @@
+#include <fitz.h>
+#include <mupdf.h>
+
+static fz_error *
+runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref)
+{
+ fz_error *error;
+
+ error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref));
+ if (error)
+ return error;
+
+ error = pdf_runcsi(csi, rdb, xref->stream);
+
+ pdf_closestream(xref);
+
+ return error;
+}
+
+static fz_error *
+loadpagecontents(fz_tree **treep, pdf_xref *xref, pdf_resources *rdb, fz_obj *ref)
+{
+ fz_error *error;
+ fz_obj *obj;
+ pdf_csi *csi;
+ int i;
+
+ error = pdf_newcsi(&csi);
+ if (error)
+ return error;
+
+ if (fz_isindirect(ref))
+ {
+ error = pdf_loadindirect(&obj, xref, ref);
+ if (error)
+ return error;
+
+ if (fz_isarray(obj))
+ {
+ for (i = 0; i < fz_arraylen(obj); i++)
+ {
+ error = runcsi(xref, csi, rdb, fz_arrayget(obj, i));
+ if (error) {
+ fz_dropobj(obj);
+ goto cleanup;
+ }
+ }
+ }
+ else
+ {
+ error = runcsi(xref, csi, rdb, ref);
+ if (error) {
+ fz_dropobj(obj);
+ goto cleanup;
+ }
+ }
+
+ fz_dropobj(obj);
+ }
+
+ else if (fz_isarray(ref))
+ {
+ for (i = 0; i < fz_arraylen(ref); i++)
+ {
+ error = runcsi(xref, csi, rdb, fz_arrayget(ref, i));
+ if (error)
+ goto cleanup;
+ }
+ }
+
+ *treep = csi->tree;
+ csi->tree = nil;
+ error = nil;
+
+cleanup:
+ pdf_freecsi(csi);
+ return error;
+}
+
+fz_error *
+pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
+{
+ fz_error *error;
+ fz_obj *obj;
+ pdf_page *page;
+ pdf_resources *rdb;
+ fz_tree *tree;
+ fz_rect bbox;
+ int rotate;
+
+ obj = fz_dictgets(dict, "MediaBox");
+ if (!fz_isarray(obj))
+ return fz_throw("syntaxerror: Page missing MediaBox");
+ bbox.min.x = fz_toint(fz_arrayget(obj, 0));
+ bbox.min.y = fz_toint(fz_arrayget(obj, 1));
+ bbox.max.x = fz_toint(fz_arrayget(obj, 2));
+ bbox.max.y = fz_toint(fz_arrayget(obj, 3));
+
+ obj = fz_dictgets(dict, "Rotate");
+ if (fz_isint(obj))
+ rotate = fz_toint(obj);
+ else
+ rotate = 0;
+
+ /*
+ * Load resources
+ */
+
+ obj = fz_dictgets(dict, "Resources");
+ if (!obj)
+ return fz_throw("syntaxerror: Page missing Resources");
+ error = pdf_resolve(&obj, xref);
+ if (error) return error;
+ error = pdf_loadresources(&rdb, xref, obj);
+ fz_dropobj(obj);
+ if (error) return error;
+
+ /*
+ * Interpret content stream to build display tree
+ */
+
+ obj = fz_dictgets(dict, "Contents");
+
+ error = loadpagecontents(&tree, xref, rdb, obj);
+ if (error) {
+ pdf_freeresources(rdb);
+ return error;
+ }
+
+ /*
+ * Create page object
+ */
+
+ page = *pagep = fz_malloc(sizeof(pdf_page));
+ if (!page) {
+ fz_droptree(tree);
+ pdf_freeresources(rdb);
+ return fz_outofmem;
+ }
+
+ page->mediabox.min.x = MIN(bbox.min.x, bbox.max.x);
+ page->mediabox.min.y = MIN(bbox.min.y, bbox.max.y);
+ 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->tree = tree;
+
+ return nil;
+}
+
+void
+pdf_freepage(pdf_page *page)
+{
+ pdf_freeresources(page->rdb);
+ fz_droptree(page->tree);
+ fz_free(page);
+}
+
diff --git a/mupdf/pagetree.c b/mupdf/pagetree.c
index 18d07e41..9f6195e6 100644
--- a/mupdf/pagetree.c
+++ b/mupdf/pagetree.c
@@ -157,6 +157,20 @@ error:
return nil;
}
+int
+pdf_getpagecount(pdf_pagetree *pages)
+{
+ return pages->count;
+}
+
+fz_obj *
+pdf_getpageobject(pdf_pagetree *pages, int p)
+{
+ if (p < 0 || p >= pages->count)
+ return nil;
+ return pages->pobj[p];
+}
+
void
pdf_freepagetree(pdf_pagetree *pages)
{
diff --git a/mupdf/resources.c b/mupdf/resources.c
index 487f8713..ef2515a2 100644
--- a/mupdf/resources.c
+++ b/mupdf/resources.c
@@ -121,6 +121,51 @@ cleanup:
return err;
}
+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_freecolorspace(colorspace);
+ if (ptr) fz_dropobj(ptr);
+ fz_dropobj(val);
+ return err;
+}
+
fz_error *
pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *topdict)
{
@@ -167,13 +212,26 @@ pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *topdict)
if (err) { pdf_freeresources(rdb); return err; }
}
+ err = fz_newdict(&rdb->colorspace, 5);
+ if (err) { pdf_freeresources(rdb); return err; }
+
+ subdict = fz_dictgets(topdict, "ColorSpace");
+ if (subdict)
+ {
+ err = pdf_resolve(&subdict, xref);
+ if (err) { pdf_freeresources(rdb); return err; }
+ err = loadcolorspaces(rdb, xref, subdict);
+ fz_dropobj(subdict);
+ if (err) { pdf_freeresources(rdb); return err; }
+ }
+
return nil;
}
void
pdf_freeresources(pdf_resources *rdb)
{
- /* TODO freefont */
+ /* 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);
diff --git a/render/pixmap.c b/render/pixmap.c
index 0902c901..5dd8bcda 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -1,7 +1,7 @@
#include <fitz.h>
fz_error *
-fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n, int a)
+fz_newpixmap(fz_pixmap **pixp, fz_colorspace *cs, int x, int y, int w, int h, int n, int a)
{
fz_pixmap *pix;
@@ -9,13 +9,13 @@ fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n, int a)
if (!pix)
return fz_outofmem;
+ pix->cs = cs;
pix->x = x;
pix->y = y;
pix->w = w;
pix->h = h;
pix->n = n;
pix->a = a;
- pix->cs = nil;
pix->stride = (pix->n + pix->a) * pix->w;
pix->samples = fz_malloc(sizeof(short) * pix->stride * pix->h);
@@ -83,7 +83,7 @@ fz_debugpixmap(fz_pixmap *pix)
void
fz_blendover(fz_pixmap *src, fz_pixmap *dst)
{
- int x, y, k;
+ int x, y;
assert(dst->n == src->n);
assert(dst->a == 1);
diff --git a/render/render.c b/render/render.c
index 183672bf..fab6262d 100644
--- a/render/render.c
+++ b/render/render.c
@@ -4,6 +4,7 @@ enum { NONE, OVER, MASK };
struct fz_renderer_s
{
+ fz_colorspace *model;
fz_glyphcache *cache;
fz_gel *gel;
fz_ael *ael;
@@ -15,7 +16,7 @@ struct fz_renderer_s
};
fz_error *
-fz_newrenderer(fz_renderer **gcp)
+fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel)
{
fz_error *error;
fz_renderer *gc;
@@ -24,6 +25,7 @@ fz_newrenderer(fz_renderer **gcp)
if (!gc)
return fz_outofmem;
+ gc->model = processcolormodel;
gc->cache = nil;
gc->gel = nil;
gc->ael = nil;
@@ -97,7 +99,7 @@ static void blitglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo)
}
}
-static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, short r, short g, short b)
+static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, fz_renderer *gc)
{
int sx, sy, dx, dy, sa, ssa;
short *p;
@@ -118,9 +120,9 @@ static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, short r
ssa = (1 << 14) - sa;
p = out->samples + dx * 4 + dy * out->stride;
- p[0] = ((r * sa) >> 14) + ((p[0] * ssa) >> 14);
- p[1] = ((g * sa) >> 14) + ((p[1] * ssa) >> 14);
- p[2] = ((b * sa) >> 14) + ((p[2] * ssa) >> 14);
+ p[0] = ((gc->r * sa) >> 14) + ((p[0] * ssa) >> 14);
+ p[1] = ((gc->g * sa) >> 14) + ((p[1] * ssa) >> 14);
+ p[2] = ((gc->b * sa) >> 14) + ((p[2] * ssa) >> 14);
p[3] = sa + ((ssa * p[3]) >> 14);
}
}
@@ -137,7 +139,7 @@ fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
puts("render text");
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1);
if (error)
return error;
@@ -177,12 +179,14 @@ rcolortext(fz_renderer *gc, fz_textnode *text, fz_colornode *color, fz_matrix ct
float x, y;
int g, i, ix, iy;
fz_matrix tm, trm;
+ float rgb[3];
puts("render (mask color text)");
- gc->r = color->r * (1 << 14);
- gc->g = color->g * (1 << 14);
- gc->b = color->b * (1 << 14);
+ fz_convertcolor(color->cs, color->samples, gc->model, rgb);
+ gc->r = rgb[0] * (1 << 14);
+ gc->g = rgb[1] * (1 << 14);
+ gc->b = rgb[2] * (1 << 14);
tm = text->trm;
@@ -206,7 +210,7 @@ puts("render (mask color text)");
if (error)
return error;
- blitcolorglyph(gc->acc, &gl, ix, iy, gc->r, gc->g, gc->b);
+ blitcolorglyph(gc->acc, &gl, ix, iy, gc);
}
return nil;
@@ -255,7 +259,7 @@ puts("render path");
fz_sortgel(gc->gel);
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1);
if (error)
return error;
@@ -270,9 +274,6 @@ static void blitcolorspan(int y, int x, int n, short *list, void *userdata)
{
fz_renderer *gc = userdata;
fz_pixmap *pix = gc->acc;
- short r = gc->r;
- short g = gc->g;
- short b = gc->b;
short *p;
short d, sa, ssa;
@@ -289,9 +290,9 @@ static void blitcolorspan(int y, int x, int n, short *list, void *userdata)
sa = d * 64;
ssa = (1 << 14) - sa;
- p[0] = ((r * sa) >> 14) + ((p[0] * ssa) >> 14);
- p[1] = ((g * sa) >> 14) + ((p[1] * ssa) >> 14);
- p[2] = ((b * sa) >> 14) + ((p[2] * ssa) >> 14);
+ p[0] = ((gc->r * sa) >> 14) + ((p[0] * ssa) >> 14);
+ p[1] = ((gc->g * sa) >> 14) + ((p[1] * ssa) >> 14);
+ p[2] = ((gc->b * sa) >> 14) + ((p[2] * ssa) >> 14);
p[3] = sa + ((ssa * p[3]) >> 14);
p += 4;
@@ -301,6 +302,8 @@ static void blitcolorspan(int y, int x, int n, short *list, void *userdata)
static fz_error *
rcolorpath(fz_renderer *gc, fz_pathnode *path, fz_colornode *color, fz_matrix ctm)
{
+ float rgb[3];
+
puts("render (mask color path)");
float flatness = 0.3 / ctm.a;
@@ -319,9 +322,10 @@ puts("render (mask color path)");
fz_sortgel(gc->gel);
- gc->r = color->r * (1 << 14);
- gc->g = color->g * (1 << 14);
- gc->b = color->b * (1 << 14);
+ fz_convertcolor(color->cs, color->samples, gc->model, rgb);
+ gc->r = rgb[0] * (1 << 14);
+ gc->g = rgb[1] * (1 << 14);
+ gc->b = rgb[2] * (1 << 14);
fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL, blitcolorspan, gc);
@@ -332,14 +336,17 @@ fz_error *
fz_rendercolor(fz_renderer *gc, fz_colornode *color, fz_matrix ctm)
{
fz_error *error;
- short r = color->r * (1 << 14);
- short g = color->g * (1 << 14);
- short b = color->b * (1 << 14);
int x, y;
+ float rgb[3];
+
+ fz_convertcolor(color->cs, color->samples, gc->model, rgb);
+ gc->r = rgb[0] * (1 << 14);
+ gc->g = rgb[1] * (1 << 14);
+ gc->b = rgb[2] * (1 << 14);
puts("render color");
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 3, 1);
+ error = fz_newpixmap(&gc->tmp, color->cs, gc->x, gc->y, gc->w, gc->h, 3, 1);
if (error)
return error;
@@ -348,9 +355,9 @@ puts("render color");
short *p = &gc->tmp->samples[y * gc->tmp->stride];
for (x = 0; x < gc->tmp->w; x++)
{
- *p++ = r;
- *p++ = g;
- *p++ = b;
+ *p++ = gc->r;
+ *p++ = gc->g;
+ *p++ = gc->b;
*p++ = 1 << 14;
}
}
@@ -398,7 +405,7 @@ fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
{
puts("render over");
oldacc = gc->acc;
- error = fz_newpixmap(&gc->acc, gc->x, gc->y, gc->w, gc->h, 3, 1);
+ error = fz_newpixmap(&gc->acc, gc->model, gc->x, gc->y, gc->w, gc->h, 3, 1);
if (error)
return error;
fz_clearpixmap(gc->acc);
@@ -465,7 +472,7 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
return error;
shapepix = gc->tmp;
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, colorpix->n, 1);
+ error = fz_newpixmap(&gc->tmp, colorpix->cs, gc->x, gc->y, gc->w, gc->h, colorpix->n, 1);
if (error)
return error;
diff --git a/test/pdfrip.c b/test/pdfrip.c
index f0785055..f7cbc093 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -13,95 +13,54 @@ void usage()
* Draw page
*/
-void runcsi(pdf_xref *xref, pdf_csi *csi, pdf_resources *rdb, fz_obj *stmref)
+void showpage(pdf_xref *xref, fz_obj *pageobj)
{
fz_error *error;
+ pdf_page *page;
- error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref));
- if (error) fz_abort(error);
-
- error = pdf_runcsi(csi, rdb, xref->stream);
- if (error) fz_abort(error);
-
- pdf_closestream(xref);
-}
-
-void showpage(pdf_xref *xref, fz_obj *page)
-{
- fz_error *error;
- pdf_csi *csi;
- pdf_resources *rdb = nil;
- fz_obj *resources;
- fz_obj *contents;
- int i;
-
- fz_debugobj(page);
+ fz_debugobj(pageobj);
printf("\n");
- resources = fz_dictgets(page, "Resources");
- if (resources)
- {
- error = pdf_resolve(&resources, xref);
- if (error) fz_abort(error);
-
- error = pdf_loadresources(&rdb, xref, resources);
- if (error) fz_abort(error);
-
- // parse resources into native res dict
- fz_dropobj(resources);
- }
- else
- fz_abort(fz_throw("syntaxerror: missing resource dictionary"));
-
- error = pdf_newcsi(&csi);
- if (error) fz_abort(error);
+ error = pdf_loadpage(&page, xref, pageobj);
+ if (error)
+ fz_abort(error);
- contents = fz_dictgets(page, "Contents");
- if (contents)
+ if (showtree)
{
- if (fz_isarray(contents))
- {
- for (i = 0; i < fz_arraylen(contents); i++)
- {
- runcsi(xref, csi, rdb, fz_arrayget(contents, i));
- }
- }
- else
- {
- // XXX resolve and check if it is an array
- runcsi(xref, csi, rdb, contents);
- }
- }
+ printf("page\n");
+ printf(" mediabox [ %g %g %g %g ]\n",
+ page->mediabox.min.x, page->mediabox.min.y,
+ 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("\n");
- if (showtree)
- {
- printf("\nfitz tree:\n");
- fz_debugtree(csi->tree);
+ printf("tree\n");
+ fz_debugtree(page->tree);
+ printf("endtree");
}
{
fz_pixmap *pix;
fz_renderer *gc;
fz_matrix ctm;
- fz_rect bbox;
-
-#define SCALE 1.0
-#define W 700
-#define H 900
- fz_newrenderer(&gc);
-
- bbox.min.x = 0;
- bbox.min.y = 0;
- bbox.max.x = W * SCALE;
- bbox.max.y = H * SCALE;
+ error = fz_newrenderer(&gc, pdf_devicergb);
+ if (error) fz_abort(error);
- //ctm = fz_scale(SCALE,SCALE);
- ctm = fz_concat(fz_translate(0, -H), fz_scale(SCALE,-SCALE));
+ ctm = fz_concat(fz_translate(0, -page->mediabox.max.y), fz_scale(1.0, -1.0));
+printf("ctm %g %g %g %g %g %g\n",
+ ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
printf("rendering!\n");
- fz_rendertree(&pix, gc, csi->tree, ctm, bbox);
+ error = fz_rendertree(&pix, gc, page->tree, ctm, page->mediabox);
+ if (error) fz_abort(error);
printf("done!\n");
fz_debugpixmap(pix);
@@ -109,8 +68,6 @@ printf("done!\n");
fz_freerenderer(gc);
}
-
- pdf_freecsi(csi);
}
int main(int argc, char **argv)
@@ -165,10 +122,10 @@ int main(int argc, char **argv)
for ( ; optind < argc; optind++)
{
int page = atoi(argv[optind]);
- if (page < 1 || page > pages->count)
+ if (page < 1 || page > pdf_getpagecount(pages))
fprintf(stderr, "page out of bounds: %d\n", page);
printf("page %d\n", page);
- showpage(xref, pages->pobj[page - 1]);
+ showpage(xref, pdf_getpageobject(pages, page - 1));
}
pdf_closepdf(xref);
diff --git a/tree/colorspace.c b/tree/colorspace.c
new file mode 100644
index 00000000..6ff61d3e
--- /dev/null
+++ b/tree/colorspace.c
@@ -0,0 +1,34 @@
+#include <fitz.h>
+
+void
+fz_freecolorspace(fz_colorspace *cs)
+{
+ if (cs->frozen)
+ return;
+ if (cs->free)
+ cs->free(cs);
+ fz_free(cs);
+}
+
+void
+fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
+{
+ float xyz[3];
+ int i;
+ if (srcs != dsts)
+ {
+printf("convert color from %s to %s\n ", srcs->name, dsts->name);
+for(i=0;i<srcs->n;i++)printf("%g ", srcv[i]);printf("\n");
+ srcs->toxyz(srcs, srcv, xyz);
+printf(" %g %g %g\n ", xyz[0], xyz[1], xyz[2]);
+ dsts->fromxyz(dsts, xyz, dstv);
+for(i=0;i<dsts->n;i++)printf("%g ", dstv[i]);printf("\n");
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < srcs->n; i++)
+ dstv[i] = srcv[i];
+ }
+}
+
diff --git a/tree/debug.c b/tree/debug.c
index c56464ba..583608f5 100644
--- a/tree/debug.c
+++ b/tree/debug.c
@@ -68,8 +68,12 @@ static void lisptransform(fz_transformnode *node, int level)
static void lispcolor(fz_colornode *node, int level)
{
+ int i;
indent(level);
- printf("(color %g %g %g)\n", node->r, node->g, node->b);
+ printf("(color ");
+ for (i = 0; i < node->n; i++)
+ printf("%g ", node->samples[i]);
+ printf(")\n");
}
static void lisplink(fz_linknode *node, int level)
diff --git a/tree/font.c b/tree/font.c
index 207896c5..a8ac016c 100644
--- a/tree/font.c
+++ b/tree/font.c
@@ -28,9 +28,6 @@ fz_initfont(fz_font *font, char *name)
font->dvmtx.x = 0;
font->dvmtx.y = 880;
font->dvmtx.w = -1000;
-
- font->ncidtogid = 0;
- font->cidtogid = nil;
}
void
@@ -49,13 +46,6 @@ fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax)
}
void
-fz_setcidtogid(fz_font *font, int n, unsigned short *map)
-{
- font->ncidtogid = n;
- font->cidtogid = map;
-}
-
-void
fz_setdefaulthmtx(fz_font *font, int w)
{
font->dhmtx.w = w;
@@ -251,7 +241,6 @@ fz_freefont(fz_font *font)
{
if (font->free)
font->free(font);
- fz_free(font->cidtogid);
fz_free(font->hmtx);
fz_free(font->vmtx);
fz_free(font);
diff --git a/tree/node2.c b/tree/node2.c
index 0e173dbf..d50936ef 100644
--- a/tree/node2.c
+++ b/tree/node2.c
@@ -89,7 +89,7 @@ fz_boundmasknode(fz_masknode *node, fz_matrix ctm)
*/
fz_error *
-fz_newblendnode(fz_node **nodep, fz_blendkind b, int k, int i)
+fz_newblendnode(fz_node **nodep, fz_colorspace *cs, fz_blendkind b, int k, int i)
{
fz_blendnode *node;
@@ -99,6 +99,7 @@ fz_newblendnode(fz_node **nodep, fz_blendkind b, int k, int i)
*nodep = (fz_node*)node;
fz_initnode((fz_node*)node, FZ_NBLEND);
+ node->cs = cs;
node->mode = b;
node->knockout = k;
node->isolated = i;
@@ -230,19 +231,21 @@ fz_boundlinknode(fz_linknode *node, fz_matrix ctm)
*/
fz_error *
-fz_newcolornode(fz_node **nodep, float r, float g, float b)
+fz_newcolornode(fz_node **nodep, fz_colorspace *cs, int n, float *v)
{
fz_colornode *node;
+ int i;
- node = fz_malloc(sizeof (fz_colornode));
+ node = fz_malloc(sizeof(fz_colornode) + sizeof(float) * n);
if (!node)
return fz_outofmem;
*nodep = (fz_node*)node;
fz_initnode((fz_node*)node, FZ_NCOLOR);
- node->r = r;
- node->g = g;
- node->b = b;
+ node->cs = cs;
+ node->n = n;
+ for (i = 0; i < n; i++)
+ node->samples[i] = v[i];
return nil;
}
@@ -250,8 +253,7 @@ fz_newcolornode(fz_node **nodep, float r, float g, float b)
fz_rect
fz_boundcolornode(fz_colornode *node, fz_matrix ctm)
{
- /* min > max => no bounds */
- return (fz_rect) { {1,1}, {-1,-1} };
+ return fz_infiniterect();
}
/*
@@ -259,7 +261,7 @@ fz_boundcolornode(fz_colornode *node, fz_matrix ctm)
*/
fz_error *
-fz_newimagenode(fz_node **nodep, int w, int h, int n, int a)
+fz_newimagenode(fz_node **nodep, fz_colorspace *cs, int w, int h, int n, int a)
{
fz_imagenode *node;
@@ -269,6 +271,7 @@ fz_newimagenode(fz_node **nodep, 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;