diff options
author | Tor Andersson <tor@ghostscript.com> | 2009-12-07 17:12:25 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2009-12-07 17:12:25 +0100 |
commit | d11dfefb1fcd1f557eae0f02dac142ffa3c3676c (patch) | |
tree | d3dd32d32dc644b8dc9d155645b612f0ad5e0f25 | |
parent | ef4e06b7e423ada49a2e749d55687da756925cc8 (diff) | |
download | mupdf-d11dfefb1fcd1f557eae0f02dac142ffa3c3676c.tar.xz |
Implement a device interface and a tracing device for fitz.
-rw-r--r-- | apps/pdfdraw.c | 6 | ||||
-rw-r--r-- | fitz/Jamfile | 5 | ||||
-rw-r--r-- | fitz/dev_trace.c | 132 | ||||
-rw-r--r-- | fitz/fitz_res.h | 59 | ||||
-rw-r--r-- | fitz/node_path.c | 82 | ||||
-rw-r--r-- | fitz/node_text.c | 1 | ||||
-rw-r--r-- | mupdf/mupdf.h | 10 | ||||
-rw-r--r-- | mupdf/pdf_build.c | 159 | ||||
-rw-r--r-- | mupdf/pdf_interpret.c | 4 |
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; } |