summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2009-12-07 17:12:25 +0100
committerTor Andersson <tor@ghostscript.com>2009-12-07 17:12:25 +0100
commitd11dfefb1fcd1f557eae0f02dac142ffa3c3676c (patch)
treed3dd32d32dc644b8dc9d155645b612f0ad5e0f25
parentef4e06b7e423ada49a2e749d55687da756925cc8 (diff)
downloadmupdf-d11dfefb1fcd1f557eae0f02dac142ffa3c3676c.tar.xz
Implement a device interface and a tracing device for fitz.
-rw-r--r--apps/pdfdraw.c6
-rw-r--r--fitz/Jamfile5
-rw-r--r--fitz/dev_trace.c132
-rw-r--r--fitz/fitz_res.h59
-rw-r--r--fitz/node_path.c82
-rw-r--r--fitz/node_text.c1
-rw-r--r--mupdf/mupdf.h10
-rw-r--r--mupdf/pdf_build.c159
-rw-r--r--mupdf/pdf_interpret.c4
9 files changed, 286 insertions, 172 deletions
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index 88b930b9..4f9e6354 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -223,14 +223,16 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *
showsafe(drawpage->contents->rp,
drawpage->contents->wp - drawpage->contents->rp);
printf("END.\n");
-
+
+ fz_device *dev = fz_newtracedevice();
drawpage->contents->rp = drawpage->contents->bp;
fz_stream *file = fz_openrbuffer(drawpage->contents);
- pdf_csi *csi = pdf_newcsi(0);
+ pdf_csi *csi = pdf_newcsi(dev, 0);
error = pdf_runcsi(csi, xref, drawpage->resources, file);
fz_dropstream(file);
if (error)
die(error);
+ fz_free(dev);
if (drawpattern)
{
diff --git a/fitz/Jamfile b/fitz/Jamfile
index 14b15d74..f085507e 100644
--- a/fitz/Jamfile
+++ b/fitz/Jamfile
@@ -78,5 +78,8 @@ Library libfitz :
res_font.c
res_image.c
res_shade.c
+ dev_trace.c
+ # dev_text.c
+ # dev_draw.c
+ # dev_ghost.c
;
-
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
new file mode 100644
index 00000000..85118e1b
--- /dev/null
+++ b/fitz/dev_trace.c
@@ -0,0 +1,132 @@
+#include "fitz.h"
+
+static void fz_tracematrix(fz_matrix *ctm)
+{
+ printf("%g %g %g %g %g %g setmatrix\n",
+ ctm->a, ctm->b, ctm->c, ctm->d, ctm->e, ctm->f);
+}
+
+static void fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha)
+{
+ printf("... setcolor\n");
+ printf("%g setalpha\n", alpha);
+}
+
+void fz_tracefillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_tracematrix(&path->ctm);
+ fz_printpath(path, 0);
+ if (path->winding == FZ_EVENODD)
+ printf("eofill\n");
+ else
+ printf("fill\n");
+}
+
+void fz_tracestrokepath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+{
+ int i;
+
+ fz_tracecolor(colorspace, color, alpha);
+ fz_tracematrix(&path->ctm);
+
+ printf("%g setlinewidth\n", path->linewidth);
+ printf("%g setmiterlimit\n", path->miterlimit);
+ printf("%d setlinecap\n", path->linecap);
+ printf("%d setlinejoin\n", path->linejoin);
+
+ if (path->dashlen)
+ {
+ printf("%g [ ", path->dashphase);
+ for (i = 0; i < path->dashlen; i++)
+ printf("%g ", path->dashlist[i]);
+ printf("] setdash\n");
+ }
+
+ fz_printpath(path, 0);
+
+ printf("stroke\n");
+}
+
+void fz_traceclippath(void *user, fz_path *path)
+{
+ printf("gsave\n");
+ fz_tracematrix(&path->ctm);
+ fz_printpath(path, 0);
+ if (path->winding == FZ_EVENODD)
+ printf("eoclip\n");
+ else
+ printf("clip\n");
+}
+
+void fz_tracefilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+{
+ printf("/%s setfont\n", text->font->name);
+ fz_tracematrix(&text->trm);
+ fz_debugtext(text, 0);
+ printf("show\n");
+}
+
+void fz_tracestroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+{
+ printf("/%s setfont\n", text->font->name);
+ fz_tracematrix(&text->trm);
+ fz_debugtext(text, 0);
+ printf("charpath stroke\n");
+}
+
+void fz_tracecliptext(void *user, fz_text *text)
+{
+ printf("gsave\n");
+ printf("/%s setfont\n", text->font->name);
+ fz_tracematrix(&text->trm);
+ fz_debugtext(text, 0);
+ printf("charpath clip\n");
+}
+
+void fz_traceignoretext(void *user, fz_text *text)
+{
+ printf("/%s setfont\n", text->font->name);
+ fz_tracematrix(&text->trm);
+ fz_debugtext(text, 0);
+ printf("invisibletext\n");
+}
+
+void fz_tracedrawimage(void *user, fz_image *image, fz_matrix *ctm)
+{
+ fz_tracematrix(ctm);
+ printf("drawimage\n");
+}
+
+void fz_tracedrawshade(void *user, fz_shade *shade, fz_matrix *ctm)
+{
+ fz_tracematrix(ctm);
+ printf("drawshade\n");
+}
+
+void fz_tracepopclip(void *user)
+{
+ printf("grestore\n");
+}
+
+fz_device *fz_newtracedevice(void)
+{
+ fz_device *dev = fz_malloc(sizeof(fz_device));
+ dev->user = nil;
+
+ dev->fillpath = fz_tracefillpath;
+ dev->strokepath = fz_tracestrokepath;
+ dev->clippath = fz_traceclippath;
+
+ dev->filltext = fz_tracefilltext;
+ dev->stroketext = fz_tracestroketext;
+ dev->cliptext = fz_tracecliptext;
+ dev->ignoretext = fz_traceignoretext;
+
+ dev->drawimage = fz_tracedrawimage;
+ dev->drawshade = fz_tracedrawshade;
+
+ dev->popclip = fz_tracepopclip;
+
+ return dev;
+}
+
diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h
index 3c93d34f..d6120fcd 100644
--- a/fitz/fitz_res.h
+++ b/fitz/fitz_res.h
@@ -1,7 +1,7 @@
/*
*
*/
-
+
typedef struct fz_path_s fz_path;
typedef struct fz_text_s fz_text;
typedef struct fz_font_s fz_font;
@@ -9,6 +9,29 @@ typedef struct fz_image_s fz_image;
typedef struct fz_shade_s fz_shade;
typedef struct fz_colorspace_s fz_colorspace;
+typedef struct fz_device_s fz_device;
+
+struct fz_device_s
+{
+ void *user;
+
+ void (*fillpath)(void *, fz_path *, fz_colorspace *, float *color, float alpha);
+ void (*strokepath)(void *, fz_path *, fz_colorspace *, float *color, float alpha);
+ void (*clippath)(void *, fz_path *);
+
+ void (*filltext)(void *, fz_text *, fz_colorspace *, float *color, float alpha);
+ void (*stroketext)(void *, fz_text *, fz_colorspace *, float *color, float alpha);
+ void (*cliptext)(void *, fz_text *);
+ void (*ignoretext)(void *, fz_text *);
+
+ void (*drawimage)(void *, fz_image *img, fz_matrix *ctm);
+ void (*drawshade)(void *, fz_shade *shd, fz_matrix *ctm);
+
+ void (*popclip)(void *);
+};
+
+fz_device *fz_newtracedevice(void);
+
typedef enum fz_blendkind_e
{
/* PDF 1.4 -- standard separable */
@@ -48,12 +71,11 @@ typedef struct fz_stroke_s fz_stroke;
typedef struct fz_dash_s fz_dash;
typedef union fz_pathel_s fz_pathel;
-typedef enum fz_pathkind_e
+typedef enum fz_pathwinding_e
{
- FZ_STROKE,
- FZ_FILL,
- FZ_EOFILL
-} fz_pathkind;
+ FZ_EVENODD,
+ FZ_NONZERO,
+} fz_pathwinding;
typedef enum fz_pathelkind_e
{
@@ -63,21 +85,6 @@ typedef enum fz_pathelkind_e
FZ_CLOSEPATH
} fz_pathelkind;
-struct fz_stroke_s
-{
- int linecap;
- int linejoin;
- float linewidth;
- float miterlimit;
-};
-
-struct fz_dash_s
-{
- int len;
- float phase;
- float array[FZ_FLEX];
-};
-
union fz_pathel_s
{
fz_pathelkind k;
@@ -86,12 +93,15 @@ union fz_pathel_s
struct fz_path_s
{
- fz_pathkind paint;
- fz_dash *dash;
+ fz_matrix ctm;
+ fz_pathwinding winding;
int linecap;
int linejoin;
float linewidth;
float miterlimit;
+ float dashphase;
+ int dashlen;
+ float dashlist[32];
int len, cap;
fz_pathel *els;
};
@@ -103,11 +113,10 @@ void fz_curveto(fz_path*, float, float, float, float, float, float);
void fz_curvetov(fz_path*, float, float, float, float);
void fz_curvetoy(fz_path*, float, float, float, float);
void fz_closepath(fz_path*);
-void fz_setpathstate(fz_path*, fz_pathkind paint, fz_stroke *stroke, fz_dash *dash);
void fz_resetpath(fz_path *path);
void fz_freepath(fz_path *path);
-fz_rect fz_boundpath(fz_path *, fz_matrix ctm);
+fz_rect fz_boundpath(fz_path *, fz_matrix ctm, int dostroke);
void fz_debugpath(fz_path *, int indent);
void fz_printpath(fz_path *, int indent);
diff --git a/fitz/node_path.c b/fitz/node_path.c
index b2f22a89..9f581cd9 100644
--- a/fitz/node_path.c
+++ b/fitz/node_path.c
@@ -6,16 +6,17 @@ fz_newpath(void)
fz_path *path;
path = fz_malloc(sizeof(fz_path));
- path->dash = nil;
- path->len = 0;
- path->cap = 0;
- path->els = nil;
-
- path->paint = FZ_FILL;
+ path->ctm = fz_identity();
+ path->dashlen = 0;
+ path->dashphase = 0;
+ path->winding = FZ_NONZERO;
path->linecap = 0;
path->linejoin = 0;
path->linewidth = 1.0;
path->miterlimit = 10.0;
+ path->len = 0;
+ path->cap = 0;
+ path->els = nil;
return path;
}
@@ -23,23 +24,22 @@ fz_newpath(void)
void
fz_freepath(fz_path *path)
{
- fz_free(path->dash);
fz_free(path->els);
+ fz_free(path);
}
void
fz_resetpath(fz_path *path)
{
- if (path->dash)
- fz_free(path->dash);
- path->dash = nil;
- path->len = 0;
-
- path->paint = FZ_FILL;
+ path->ctm = fz_identity();
+ path->dashlen = 0;
+ path->dashphase = 0;
+ path->winding = FZ_NONZERO;
path->linecap = 0;
path->linejoin = 0;
path->linewidth = 1.0;
path->miterlimit = 10.0;
+ path->len = 0;
}
static void
@@ -113,20 +113,6 @@ fz_closepath(fz_path *path)
path->els[path->len++].k = FZ_CLOSEPATH;
}
-void
-fz_setpathstate(fz_path *path, fz_pathkind paint, fz_stroke *stroke, fz_dash *dash)
-{
- path->paint = paint;
- path->dash = dash;
- if (stroke)
- {
- path->linecap = stroke->linecap;
- path->linejoin = stroke->linejoin;
- path->linewidth = stroke->linewidth;
- path->miterlimit = stroke->miterlimit;
- }
-}
-
static inline fz_rect boundexpand(fz_rect r, fz_point p)
{
if (p.x < r.x0) r.x0 = p.x;
@@ -137,7 +123,7 @@ static inline fz_rect boundexpand(fz_rect r, fz_point p)
}
fz_rect
-fz_boundpath(fz_path *path, fz_matrix ctm)
+fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke)
{
fz_point p;
fz_rect r = fz_emptyrect;
@@ -174,7 +160,7 @@ fz_boundpath(fz_path *path, fz_matrix ctm)
}
}
- if (path->paint == FZ_STROKE)
+ if (dostroke)
{
float miterlength = sin(path->miterlimit / 2.0);
float linewidth = path->linewidth;
@@ -225,22 +211,6 @@ fz_printpath(fz_path *path, int indent)
printf("h\n");
}
}
-
- for (n = 0; n < indent; n++)
- putchar(' ');
-
- switch (path->paint)
- {
- case FZ_STROKE:
- printf("S\n");
- break;
- case FZ_FILL:
- printf("f\n");
- break;
- case FZ_EOFILL:
- printf("f*\n");
- break;
- }
}
void
@@ -281,25 +251,3 @@ fz_debugpath(fz_path *path, int indent)
}
}
}
-
-fz_dash *
-fz_newdash(float phase, int len, float *array)
-{
- fz_dash *dash;
- int i;
-
- dash = fz_malloc(sizeof(fz_dash) + sizeof(float) * len);
- dash->len = len;
- dash->phase = phase;
- for (i = 0; i < len; i++)
- dash->array[i] = array[i];
-
- return dash;
-}
-
-void
-fz_freedash(fz_dash *dash)
-{
- fz_free(dash);
-}
-
diff --git a/fitz/node_text.c b/fitz/node_text.c
index 28ea3efc..d94f3de3 100644
--- a/fitz/node_text.c
+++ b/fitz/node_text.c
@@ -20,6 +20,7 @@ fz_freetext(fz_text *text)
{
fz_dropfont(text->font);
fz_free(text->els);
+ fz_free(text);
}
fz_rect
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index a584a0cf..940b33cb 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -677,8 +677,8 @@ struct pdf_gstate_s
struct pdf_csi_s
{
- pdf_gstate gstate[32];
- int gtop;
+ fz_device *dev;
+
fz_obj *stack[32];
int top;
int xbalance;
@@ -694,6 +694,10 @@ struct pdf_csi_s
fz_matrix tlm;
fz_matrix tm;
int textmode;
+
+ /* graphics state */
+ pdf_gstate gstate[32];
+ int gtop;
};
/* build.c */
@@ -709,7 +713,7 @@ void pdf_showimage(pdf_csi*, pdf_image *img);
void pdf_showshade(pdf_csi*, fz_shade *shd);
/* interpret.c */
-pdf_csi *pdf_newcsi(int maskonly);
+pdf_csi *pdf_newcsi(fz_device *dev, int maskonly);
fz_error pdf_runcsi(pdf_csi *, pdf_xref *xref, fz_obj *resources, fz_stream *contents);
void pdf_dropcsi(pdf_csi *csi);
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 895aaa6f..46112ca1 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -162,31 +162,6 @@ pdf_setshade(pdf_csi *csi, int what, fz_shade *shade)
}
void
-pdf_buildstrokepath(pdf_gstate *gs, fz_path *path)
-{
- fz_stroke stroke;
- fz_dash *dash;
-
- stroke.linecap = gs->linecap;
- stroke.linejoin = gs->linejoin;
- stroke.linewidth = gs->linewidth;
- stroke.miterlimit = gs->miterlimit;
-
- if (gs->dashlen)
- dash = fz_newdash(gs->dashphase, gs->dashlen, gs->dashlist);
- else
- dash = nil;
-
- fz_setpathstate(path, FZ_STROKE, &stroke, dash);
-}
-
-void
-pdf_buildfillpath(pdf_gstate *gs, fz_path *path, int eofill)
-{
- fz_setpathstate(path, eofill ? FZ_EOFILL : FZ_FILL, nil, nil);
-}
-
-void
pdf_showpattern(pdf_gstate *gs, pdf_pattern *pat, fz_colorspace *cs, float *v)
{
fz_matrix ctm;
@@ -229,52 +204,57 @@ pdf_showpattern(pdf_gstate *gs, pdf_pattern *pat, fz_colorspace *cs, float *v)
}
void
-pdf_showshade(pdf_csi *csi, fz_shade *shade)
+pdf_showshade(pdf_csi *csi, fz_shade *shd)
{
- // pdf_gstate *gstate = csi->gstate + csi->gtop;
- printf("draw shade\n");
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ csi->dev->drawshade(csi->dev->user, shd, &gstate->ctm);
}
void
pdf_showimage(pdf_csi *csi, pdf_image *img)
{
- // pdf_gstate *gstate = csi->gstate + csi->gtop;
- printf("draw image\n");
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ csi->dev->drawimage(csi->dev->user, (fz_image*)img, &gstate->ctm);
}
void
pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
{
- // pdf_gstate *gstate = csi->gstate + csi->gtop;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ int i;
if (doclose)
fz_closepath(csi->path);
+ csi->path->ctm = gstate->ctm;
+ csi->path->winding = evenodd ? FZ_EVENODD : FZ_NONZERO;
+ csi->path->linewidth = gstate->linewidth;
+ csi->path->linecap = gstate->linecap;
+ csi->path->linejoin = gstate->linejoin;
+ csi->path->miterlimit = gstate->miterlimit;
+ csi->path->dashlen = gstate->dashlen;
+ csi->path->dashphase = gstate->dashphase;
+ for (i = 0; i < csi->path->dashlen; i++)
+ csi->path->dashlist[i] = gstate->dashlist[i];
+
if (csi->clip)
{
- printf("clip\n");
+ csi->dev->clippath(csi->dev->user, csi->path);
csi->clip = 0;
}
-
- if (dofill && dostroke)
+ if (dofill)
{
- printf("fill-and-stroke\n");
+ // TODO: indexed, pattern, shade materials
+ csi->dev->fillpath(csi->dev->user, csi->path,
+ gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
}
- else if (dofill)
- {
- printf("fill\n");
- }
- else if (dostroke)
- {
- printf("stroke\n");
- }
- else
+ if (dostroke)
{
- printf("newpath\n");
+ // TODO: indexed, pattern, shade materials
+ csi->dev->strokepath(csi->dev->user, csi->path,
+ gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
}
- fz_printpath(csi->path, 4);
-
fz_resetpath(csi->path);
}
@@ -285,37 +265,70 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
void
pdf_flushtext(pdf_csi *csi)
{
- // pdf_gstate *gstate = csi->gstate + csi->gtop;
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ int dofill = 0;
+ int dostroke = 0;
+ int doclip = 0;
+ int doinvisible = 0;
+
+ if (!csi->text)
+ return;
- if (csi->text)
+ switch (csi->textmode)
{
- switch (csi->textmode)
- {
- case 0: /* fill */
- case 1: /* stroke */
- case 2: /* stroke + fill */
- puts("fill text");
- break;
-
- case 3: /* invisible */
- puts("invisible text");
- break;
-
- case 4: /* fill + clip */
- case 5: /* stroke + clip */
- case 6: /* stroke + fill + clip */
- puts("clip text");
- /* fall through */
-
- case 7: /* invisible clip ( + fallthrough clips ) */
- break;
- }
+ case 0:
+ dofill = 1;
+ break;
+ case 1:
+ dostroke = 1;
+ break;
+ case 2:
+ dofill = 1;
+ dostroke = 1;
+ break;
+ case 3:
+ doinvisible = 1;
+ break;
+ case 4:
+ dofill = 1;
+ doclip = 1;
+ break;
+ case 5:
+ dostroke = 1;
+ doclip = 1;
+ break;
+ case 6:
+ dofill = 1;
+ dostroke = 1;
+ doclip = 1;
+ break;
+ case 7:
+ doclip = 1;
+ break;
+ }
+
+ if (doinvisible)
+ csi->dev->ignoretext(csi->dev->user, csi->text);
- fz_debugtext(csi->text, 4);
+ if (doclip)
+ csi->dev->cliptext(csi->dev->user, csi->text);
- fz_freetext(csi->text);
- csi->text = nil;
+ if (dofill)
+ {
+ // TODO: indexed, pattern, shade materials
+ csi->dev->filltext(csi->dev->user, csi->text,
+ gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
}
+
+ if (dostroke)
+ {
+ // TODO: indexed, pattern, shade materials
+ csi->dev->stroketext(csi->dev->user, csi->text,
+ gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
+ }
+
+ fz_freetext(csi->text);
+ csi->text = nil;
}
static void
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 78a23731..e96d5905 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -2,7 +2,7 @@
#include "mupdf.h"
pdf_csi *
-pdf_newcsi(int maskonly)
+pdf_newcsi(fz_device *dev, int maskonly)
{
pdf_csi *csi;
@@ -31,6 +31,8 @@ pdf_newcsi(int maskonly)
csi->tm = fz_identity();
csi->tlm = fz_identity();
+ csi->dev = dev;
+
return csi;
}