summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-04-25 00:09:00 +0200
committerTor Andersson <tor@ghostscript.com>2010-04-25 00:09:00 +0200
commitbc29aa90e5b0d1bf813f9eacb8bce53f5174bec6 (patch)
treeedd403655f13aa2e71f801f98ed0d89ae3534bea
parent01f6c576de71948cbc8adfe66524aeb43a2ce515 (diff)
downloadmupdf-bc29aa90e5b0d1bf813f9eacb8bce53f5174bec6.tar.xz
Move stroking state to a separate struct in preparation for stroked text rendering mode support.
-rw-r--r--draw/pathstroke.c22
-rw-r--r--fitz/dev_draw.c36
-rw-r--r--fitz/dev_list.c43
-rw-r--r--fitz/dev_null.c12
-rw-r--r--fitz/dev_trace.c36
-rw-r--r--fitz/fitz_draw.h4
-rw-r--r--fitz/fitz_res.h26
-rw-r--r--fitz/res_path.c15
-rw-r--r--mupdf/mupdf.h8
-rw-r--r--mupdf/pdf_build.c49
-rw-r--r--mupdf/pdf_interpret.c34
11 files changed, 141 insertions, 144 deletions
diff --git a/draw/pathstroke.c b/draw/pathstroke.c
index 73d3bba3..94d986db 100644
--- a/draw/pathstroke.c
+++ b/draw/pathstroke.c
@@ -388,7 +388,7 @@ strokebezier(struct sctx *s,
}
void
-fz_strokepath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float linewidth)
+fz_strokepath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth)
{
struct sctx s;
fz_point p0, p1, p2, p3;
@@ -398,10 +398,10 @@ fz_strokepath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float l
s.ctm = &ctm;
s.flatness = flatness;
- s.linecap = path->linecap;
- s.linejoin = path->linejoin;
+ s.linecap = stroke->linecap;
+ s.linejoin = stroke->linejoin;
s.linewidth = linewidth * 0.5; /* hairlines use a different value from the path value */
- s.miterlimit = path->miterlimit;
+ s.miterlimit = stroke->miterlimit;
s.sn = 0;
s.bn = 0;
s.dot = 0;
@@ -571,7 +571,7 @@ dashbezier(struct sctx *s,
}
void
-fz_dashpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float linewidth)
+fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth)
{
struct sctx s;
fz_point p0, p1, p2, p3, beg;
@@ -581,17 +581,17 @@ fz_dashpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float lin
s.ctm = &ctm;
s.flatness = flatness;
- s.linecap = path->linecap;
- s.linejoin = path->linejoin;
+ s.linecap = stroke->linecap;
+ s.linejoin = stroke->linejoin;
s.linewidth = linewidth * 0.5;
- s.miterlimit = path->miterlimit;
+ s.miterlimit = stroke->miterlimit;
s.sn = 0;
s.bn = 0;
s.dot = 0;
- s.dashlist = path->dashlist;
- s.dashphase = path->dashphase;
- s.dashlen = path->dashlen;
+ s.dashlist = stroke->dashlist;
+ s.dashphase = stroke->dashphase;
+ s.dashlen = stroke->dashlen;
s.toggle = 0;
s.offset = 0;
s.phase = 0;
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index 319617eb..4e53669c 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -105,7 +105,7 @@ blendmaskover(fz_pixmap *src, fz_pixmap *msk, fz_pixmap *dst)
}
static void
-fz_drawfillpath(void *user, fz_path *path, fz_matrix ctm,
+fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
@@ -137,22 +137,22 @@ fz_drawfillpath(void *user, fz_path *path, fz_matrix ctm,
argb[1] = rgb[0] * 255;
argb[2] = rgb[1] * 255;
argb[3] = rgb[2] * 255;
- fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, dev->dest, argb, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, argb, 1);
}
else
{
- fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, dev->dest, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, 1);
}
}
static void
-fz_drawstrokepath(void *user, fz_path *path, fz_matrix ctm,
+fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3 / expansion;
- float linewidth = path->linewidth;
+ float linewidth = stroke->linewidth;
fz_bbox bbox;
fz_bbox clip;
@@ -165,10 +165,10 @@ fz_drawstrokepath(void *user, fz_path *path, fz_matrix ctm,
clip.y1 = dev->dest->y + dev->dest->h;
fz_resetgel(dev->gel, clip);
- if (path->dashlen > 0)
- fz_dashpath(dev->gel, path, ctm, flatness, linewidth);
+ if (stroke->dashlen > 0)
+ fz_dashpath(dev->gel, path, stroke, ctm, flatness, linewidth);
else
- fz_strokepath(dev->gel, path, ctm, flatness, linewidth);
+ fz_strokepath(dev->gel, path, stroke, ctm, flatness, linewidth);
fz_sortgel(dev->gel);
bbox = fz_boundgel(dev->gel);
@@ -194,7 +194,7 @@ fz_drawstrokepath(void *user, fz_path *path, fz_matrix ctm,
}
static void
-fz_drawclippath(void *user, fz_path *path, fz_matrix ctm)
+fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
{
fz_drawdevice *dev = user;
float expansion = fz_matrixexpansion(ctm);
@@ -227,7 +227,7 @@ fz_drawclippath(void *user, fz_path *path, fz_matrix ctm)
memset(dest->samples, 0, dest->w * dest->h * dest->n);
if (!fz_isemptyrect(bbox))
- fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, mask, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, 1);
dev->clipstack[dev->cliptop].mask = mask;
dev->clipstack[dev->cliptop].dest = dev->dest;
@@ -236,12 +236,12 @@ fz_drawclippath(void *user, fz_path *path, fz_matrix ctm)
}
static void
-fz_drawclipstrokepath(void *user, fz_path *path, fz_matrix ctm)
+fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm)
{
fz_drawdevice *dev = user;
float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3 / expansion;
- float linewidth = path->linewidth;
+ float linewidth = stroke->linewidth;
fz_bbox clip, bbox;
fz_pixmap *mask, *dest;
@@ -260,10 +260,10 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_matrix ctm)
linewidth = 1.0 / expansion;
fz_resetgel(dev->gel, clip);
- if (path->dashlen > 0)
- fz_dashpath(dev->gel, path, ctm, flatness, linewidth);
+ if (stroke->dashlen > 0)
+ fz_dashpath(dev->gel, path, stroke, ctm, flatness, linewidth);
else
- fz_strokepath(dev->gel, path, ctm, flatness, linewidth);
+ fz_strokepath(dev->gel, path, stroke, ctm, flatness, linewidth);
fz_sortgel(dev->gel);
bbox = fz_boundgel(dev->gel);
@@ -276,7 +276,7 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_matrix ctm)
memset(dest->samples, 0, dest->w * dest->h * dest->n);
if (!fz_isemptyrect(bbox))
- fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, mask, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, 1);
dev->clipstack[dev->cliptop].mask = mask;
dev->clipstack[dev->cliptop].dest = dev->dest;
@@ -379,7 +379,7 @@ fz_drawfilltext(void *user, fz_text *text, fz_matrix ctm,
}
static void
-fz_drawstroketext(void *user, fz_text *text, fz_matrix ctm,
+fz_drawstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_warn("stroked text not implemented; filling instead");
@@ -447,7 +447,7 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm)
}
static void
-fz_drawclipstroketext(void *user, fz_text *text, fz_matrix ctm)
+fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm)
{
fz_drawcliptext(user, text, ctm);
}
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index 38b333cd..2abdabbf 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -10,6 +10,9 @@ fz_newdisplaynode(fz_displaycommand cmd, fz_matrix ctm,
node = fz_malloc(sizeof(fz_displaynode));
node->cmd = cmd;
node->next = nil;
+ node->item.path = nil;
+ node->stroke = nil;
+ node->evenodd = 0;
node->ctm = ctm;
if (colorspace)
{
@@ -26,6 +29,14 @@ fz_newdisplaynode(fz_displaycommand cmd, fz_matrix ctm,
return node;
}
+static fz_strokestate *
+fz_clonestrokestate(fz_strokestate *stroke)
+{
+ fz_strokestate *newstroke = fz_malloc(sizeof(fz_strokestate));
+ *newstroke = *stroke;
+ return newstroke;
+}
+
static void
fz_appenddisplaynode(fz_displaylist *list, fz_displaynode *node)
{
@@ -70,46 +81,52 @@ fz_freedisplaynode(fz_displaynode *node)
case FZ_CMDPOPCLIP:
break;
}
+ if (node->stroke)
+ fz_free(node->stroke);
if (node->colorspace)
fz_dropcolorspace(node->colorspace);
fz_free(node);
}
static void
-fz_listfillpath(void *user, fz_path *path, fz_matrix ctm,
+fz_listfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDFILLPATH, ctm, colorspace, color, alpha);
node->item.path = fz_clonepath(path);
+ node->evenodd = evenodd;
fz_appenddisplaynode(user, node);
}
static void
-fz_liststrokepath(void *user, fz_path *path, fz_matrix ctm,
+fz_liststrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDSTROKEPATH, ctm, colorspace, color, alpha);
node->item.path = fz_clonepath(path);
+ node->stroke = fz_clonestrokestate(stroke);
fz_appenddisplaynode(user, node);
}
static void
-fz_listclippath(void *user, fz_path *path, fz_matrix ctm)
+fz_listclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDCLIPPATH, ctm, nil, nil, 0.0);
node->item.path = fz_clonepath(path);
+ node->evenodd = evenodd;
fz_appenddisplaynode(user, node);
}
static void
-fz_listclipstrokepath(void *user, fz_path *path, fz_matrix ctm)
+fz_listclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDCLIPSTROKEPATH, ctm, nil, nil, 0.0);
node->item.path = fz_clonepath(path);
+ node->stroke = fz_clonestrokestate(stroke);
fz_appenddisplaynode(user, node);
}
@@ -124,12 +141,13 @@ fz_listfilltext(void *user, fz_text *text, fz_matrix ctm,
}
static void
-fz_liststroketext(void *user, fz_text *text, fz_matrix ctm,
+fz_liststroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDSTROKETEXT, ctm, colorspace, color, alpha);
node->item.text = fz_clonetext(text);
+ node->stroke = fz_clonestrokestate(stroke);
fz_appenddisplaynode(user, node);
}
@@ -143,11 +161,12 @@ fz_listcliptext(void *user, fz_text *text, fz_matrix ctm)
}
static void
-fz_listclipstroketext(void *user, fz_text *text, fz_matrix ctm)
+fz_listclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm)
{
fz_displaynode *node;
node = fz_newdisplaynode(FZ_CMDCLIPSTROKETEXT, ctm, nil, nil, 0.0);
node->item.text = fz_clonetext(text);
+ node->stroke = fz_clonestrokestate(stroke);
fz_appenddisplaynode(user, node);
}
@@ -262,32 +281,32 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
switch (node->cmd)
{
case FZ_CMDFILLPATH:
- dev->fillpath(dev->user, node->item.path, ctm,
+ dev->fillpath(dev->user, node->item.path, node->evenodd, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMDSTROKEPATH:
- dev->strokepath(dev->user, node->item.path, ctm,
+ dev->strokepath(dev->user, node->item.path, node->stroke, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMDCLIPPATH:
- dev->clippath(dev->user, node->item.path, ctm);
+ dev->clippath(dev->user, node->item.path, node->evenodd, ctm);
break;
case FZ_CMDCLIPSTROKEPATH:
- dev->clipstrokepath(dev->user, node->item.path, ctm);
+ dev->clipstrokepath(dev->user, node->item.path, node->stroke, ctm);
break;
case FZ_CMDFILLTEXT:
dev->filltext(dev->user, node->item.text, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMDSTROKETEXT:
- dev->stroketext(dev->user, node->item.text, ctm,
+ dev->stroketext(dev->user, node->item.text, node->stroke, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMDCLIPTEXT:
dev->cliptext(dev->user, node->item.text, ctm);
break;
case FZ_CMDCLIPSTROKETEXT:
- dev->clipstroketext(dev->user, node->item.text, ctm);
+ dev->clipstroketext(dev->user, node->item.text, node->stroke, ctm);
break;
case FZ_CMDIGNORETEXT:
dev->ignoretext(dev->user, node->item.text, ctm);
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index 5c57e15d..d7a95db3 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -1,14 +1,14 @@
#include "fitz.h"
static void fz_nullfreeuser(void *user) {}
-static void fz_nullfillpath(void *user, fz_path *path, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
-static void fz_nullstrokepath(void *user, fz_path *path, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
-static void fz_nullclippath(void *user, fz_path *path, fz_matrix ctm) {}
-static void fz_nullclipstrokepath(void *user, fz_path *path, fz_matrix ctm) {}
+static void fz_nullfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm) {}
+static void fz_nullclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm) {}
static void fz_nullfilltext(void *user, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
-static void fz_nullstroketext(void *user, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
static void fz_nullcliptext(void *user, fz_text *text, fz_matrix ctm) {}
-static void fz_nullclipstroketext(void *user, fz_text *text, fz_matrix ctm) {}
+static void fz_nullclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm) {}
static void fz_nullignoretext(void *user, fz_text *text, fz_matrix ctm) {}
static void fz_nullpopclip(void *user) {}
static void fz_nullfillshade(void *user, fz_shade *shade, fz_matrix ctm) {}
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index 751b94bb..eb87764b 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -59,11 +59,11 @@ fz_tracepath(fz_path *path, int indent)
}
static void
-fz_tracefillpath(void *user, fz_path *path, fz_matrix ctm,
+fz_tracefillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<fillpath ");
- if (path->evenodd)
+ if (evenodd)
printf("winding=\"eofill\" ");
else
printf("winding=\"nonzero\" ");
@@ -75,22 +75,22 @@ fz_tracefillpath(void *user, fz_path *path, fz_matrix ctm,
}
static void
-fz_tracestrokepath(void *user, fz_path *path, fz_matrix ctm,
+fz_tracestrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
int i;
printf("<strokepath ");
- printf("linewidth=\"%g\" ", path->linewidth);
- printf("miterlimit=\"%g\" ", path->miterlimit);
- printf("linecap=\"%d\" ", path->linecap);
- printf("linejoin=\"%d\" ", path->linejoin);
+ printf("linewidth=\"%g\" ", stroke->linewidth);
+ printf("miterlimit=\"%g\" ", stroke->miterlimit);
+ printf("linecap=\"%d\" ", stroke->linecap);
+ printf("linejoin=\"%d\" ", stroke->linejoin);
- if (path->dashlen)
+ if (stroke->dashlen)
{
- printf("dashphase=\"%g\" dash=\"", path->dashphase);
- for (i = 0; i < path->dashlen; i++)
- printf("%g ", path->dashlist[i]);
+ printf("dashphase=\"%g\" dash=\"", stroke->dashphase);
+ for (i = 0; i < stroke->dashlen; i++)
+ printf("%g ", stroke->dashlist[i]);
printf("\"");
}
@@ -104,11 +104,11 @@ fz_tracestrokepath(void *user, fz_path *path, fz_matrix ctm,
}
static void
-fz_traceclippath(void *user, fz_path *path, fz_matrix ctm)
+fz_traceclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
{
printf("<gsave>\n");
printf("<clippath ");
- if (path->evenodd)
+ if (evenodd)
printf("winding=\"eofill\" ");
else
printf("winding=\"nonzero\" ");
@@ -119,14 +119,10 @@ fz_traceclippath(void *user, fz_path *path, fz_matrix ctm)
}
static void
-fz_traceclipstrokepath(void *user, fz_path *path, fz_matrix ctm)
+fz_traceclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix ctm)
{
printf("<gsave>\n");
printf("<clipstrokepath ");
- if (path->evenodd)
- printf("winding=\"eofill\" ");
- else
- printf("winding=\"nonzero\" ");
fz_tracematrix(ctm);
printf(">\n");
fz_tracepath(path, 0);
@@ -146,7 +142,7 @@ fz_tracefilltext(void *user, fz_text *text, fz_matrix ctm,
}
static void
-fz_tracestroketext(void *user, fz_text *text, fz_matrix ctm,
+fz_tracestroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<stroketext font=\"%s\" ", text->font->name);
@@ -169,7 +165,7 @@ fz_tracecliptext(void *user, fz_text *text, fz_matrix ctm)
}
static void
-fz_traceclipstroketext(void *user, fz_text *text, fz_matrix ctm)
+fz_traceclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm)
{
printf("<gsave>\n");
printf("<clipstroketext font=\"%s\" ", text->font->name);
diff --git a/fitz/fitz_draw.h b/fitz/fitz_draw.h
index 8ca536d7..673a9633 100644
--- a/fitz/fitz_draw.h
+++ b/fitz/fitz_draw.h
@@ -59,8 +59,8 @@ fz_error fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill,
fz_bbox clip, fz_pixmap *pix, unsigned char *argb, int over);
void fz_fillpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness);
-void fz_strokepath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float linewidth);
-void fz_dashpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness, float linewidth);
+void fz_strokepath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth);
+void fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth);
/*
* Function pointers -- they can be replaced by cpu-optimized versions
diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h
index 157875f2..26cc0ae8 100644
--- a/fitz/fitz_res.h
+++ b/fitz/fitz_res.h
@@ -9,6 +9,8 @@ typedef struct fz_text_s fz_text;
typedef struct fz_font_s fz_font;
typedef struct fz_shade_s fz_shade;
+typedef struct fz_strokestate_s fz_strokestate;
+
enum { FZ_MAXCOLORS = 32 };
typedef enum fz_blendkind_e
@@ -75,15 +77,15 @@ struct fz_device_s
void *user;
void (*freeuser)(void *);
- void (*fillpath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*strokepath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*clippath)(void *, fz_path *, fz_matrix);
- void (*clipstrokepath)(void *, fz_path *, fz_matrix);
+ void (*fillpath)(void *, fz_path *, int evenodd, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*strokepath)(void *, fz_path *, fz_strokestate *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*clippath)(void *, fz_path *, int evenodd, fz_matrix);
+ void (*clipstrokepath)(void *, fz_path *, fz_strokestate *, fz_matrix);
void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*stroketext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*stroketext)(void *, fz_text *, fz_strokestate *, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*cliptext)(void *, fz_text *, fz_matrix);
- void (*clipstroketext)(void *, fz_text *, fz_matrix);
+ void (*clipstroketext)(void *, fz_text *, fz_strokestate *, fz_matrix);
void (*ignoretext)(void *, fz_text *, fz_matrix);
void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm);
@@ -166,6 +168,8 @@ struct fz_displaynode_s
fz_shade *shade;
fz_pixmap *image;
} item;
+ fz_strokestate *stroke;
+ int evenodd;
fz_matrix ctm;
fz_colorspace *colorspace;
float alpha;
@@ -186,7 +190,6 @@ void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm);
* into the Global Edge List.
*/
-typedef struct fz_stroke_s fz_stroke;
typedef union fz_pathel_s fz_pathel;
typedef enum fz_pathelkind_e
@@ -203,9 +206,8 @@ union fz_pathel_s
float v;
};
-struct fz_path_s
+struct fz_strokestate_s
{
- int evenodd;
int linecap;
int linejoin;
float linewidth;
@@ -213,6 +215,10 @@ struct fz_path_s
float dashphase;
int dashlen;
float dashlist[32];
+};
+
+struct fz_path_s
+{
int len, cap;
fz_pathel *els;
};
@@ -228,7 +234,7 @@ void fz_freepath(fz_path *path);
fz_path *fz_clonepath(fz_path *old);
-fz_rect fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke);
+fz_rect fz_boundpath(fz_path *path, fz_strokestate *stroke, fz_matrix ctm);
void fz_debugpath(fz_path *, int indent);
/*
diff --git a/fitz/res_path.c b/fitz/res_path.c
index 2817c721..c3838937 100644
--- a/fitz/res_path.c
+++ b/fitz/res_path.c
@@ -6,13 +6,6 @@ fz_newpath(void)
fz_path *path;
path = fz_malloc(sizeof(fz_path));
- path->dashlen = 0;
- path->dashphase = 0;
- path->evenodd = 0;
- path->linecap = 0;
- path->linejoin = 0;
- path->linewidth = 1.0;
- path->miterlimit = 10.0;
path->len = 0;
path->cap = 0;
path->els = nil;
@@ -124,7 +117,7 @@ static inline fz_rect boundexpand(fz_rect r, fz_point p)
}
fz_rect
-fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke)
+fz_boundpath(fz_path *path, fz_strokestate *stroke, fz_matrix ctm)
{
fz_point p;
fz_rect r = fz_emptyrect;
@@ -161,10 +154,10 @@ fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke)
}
}
- if (dostroke)
+ if (stroke)
{
- float miterlength = sin(path->miterlimit / 2.0);
- float linewidth = path->linewidth;
+ float miterlength = sin(stroke->miterlimit / 2.0);
+ float linewidth = stroke->linewidth;
float expand = MAX(miterlength, linewidth) / 2.0;
r.x0 -= expand;
r.y0 -= expand;
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index 4ae17c2b..ac88a2b7 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -611,13 +611,7 @@ struct pdf_gstate_s
int clipdepth;
/* path stroking */
- float linewidth;
- int linecap;
- int linejoin;
- float miterlimit;
- float dashphase;
- int dashlen;
- float dashlist[32];
+ fz_strokestate strokestate;
/* materials */
pdf_material stroke;
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index ea589f64..706858f7 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -7,13 +7,13 @@ pdf_initgstate(pdf_gstate *gs, fz_matrix ctm)
gs->ctm = ctm;
gs->clipdepth = 0;
- gs->linewidth = 1.0;
- gs->linecap = 0;
- gs->linejoin = 0;
- gs->miterlimit = 10;
- gs->dashphase = 0;
- gs->dashlen = 0;
- memset(gs->dashlist, 0, sizeof(gs->dashlist));
+ gs->strokestate.linewidth = 1.0;
+ gs->strokestate.linecap = 0;
+ gs->strokestate.linejoin = 0;
+ gs->strokestate.miterlimit = 10;
+ gs->strokestate.dashphase = 0;
+ gs->strokestate.dashlen = 0;
+ memset(gs->strokestate.dashlist, 0, sizeof(gs->strokestate.dashlist));
gs->stroke.kind = PDF_MCOLOR;
gs->stroke.cs = fz_keepcolorspace(pdf_devicegray);
@@ -329,7 +329,6 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_rect bbox;
fz_path *path;
- int i;
path = csi->path;
csi->path = fz_newpath();
@@ -337,20 +336,10 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
if (doclose)
fz_closepath(path);
- path->evenodd = evenodd;
- path->linewidth = gstate->linewidth;
- path->linecap = gstate->linecap;
- path->linejoin = gstate->linejoin;
- path->miterlimit = gstate->miterlimit;
- path->dashlen = gstate->dashlen;
- path->dashphase = gstate->dashphase;
- for (i = 0; i < path->dashlen; i++)
- path->dashlist[i] = gstate->dashlist[i];
-
if (csi->clip)
{
gstate->clipdepth++;
- csi->dev->clippath(csi->dev->user, path, gstate->ctm);
+ csi->dev->clippath(csi->dev->user, path, evenodd, gstate->ctm);
csi->clip = 0;
}
@@ -363,17 +352,17 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->fillpath(csi->dev->user, path, gstate->ctm,
+ csi->dev->fillpath(csi->dev->user, path, evenodd, gstate->ctm,
gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
- bbox = fz_boundpath(path, gstate->ctm, 0);
- csi->dev->clippath(csi->dev->user, path, gstate->ctm);
+ bbox = fz_boundpath(path, nil, gstate->ctm);
+ csi->dev->clippath(csi->dev->user, path, evenodd, gstate->ctm);
pdf_showpattern(csi, gstate->fill.pattern, bbox, PDF_MFILL);
csi->dev->popclip(csi->dev->user);
break;
case PDF_MSHADE:
- csi->dev->clippath(csi->dev->user, path, gstate->ctm);
+ csi->dev->clippath(csi->dev->user, path, evenodd, gstate->ctm);
csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm);
csi->dev->popclip(csi->dev->user);
break;
@@ -389,17 +378,17 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd)
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->strokepath(csi->dev->user, path, gstate->ctm,
+ csi->dev->strokepath(csi->dev->user, path, &gstate->strokestate, gstate->ctm,
gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
- bbox = fz_boundpath(path, gstate->ctm, 1);
- csi->dev->clipstrokepath(csi->dev->user, path, gstate->ctm);
+ bbox = fz_boundpath(path, &gstate->strokestate, gstate->ctm);
+ csi->dev->clipstrokepath(csi->dev->user, path, &gstate->strokestate, gstate->ctm);
pdf_showpattern(csi, gstate->stroke.pattern, bbox, PDF_MFILL);
csi->dev->popclip(csi->dev->user);
break;
case PDF_MSHADE:
- csi->dev->clipstrokepath(csi->dev->user, path, gstate->ctm);
+ csi->dev->clipstrokepath(csi->dev->user, path, &gstate->strokestate, gstate->ctm);
csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, gstate->ctm);
csi->dev->popclip(csi->dev->user);
break;
@@ -514,17 +503,17 @@ pdf_flushtext(pdf_csi *csi)
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->stroketext(csi->dev->user, text, gstate->ctm,
+ csi->dev->stroketext(csi->dev->user, text, &gstate->strokestate, gstate->ctm,
gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
bbox = fz_boundtext(text, gstate->ctm);
- csi->dev->clipstroketext(csi->dev->user, text, gstate->ctm);
+ csi->dev->clipstroketext(csi->dev->user, text, &gstate->strokestate, gstate->ctm);
pdf_showpattern(csi, gstate->stroke.pattern, bbox, PDF_MFILL);
csi->dev->popclip(csi->dev->user);
break;
case PDF_MSHADE:
- csi->dev->clipstroketext(csi->dev->user, text, gstate->ctm);
+ csi->dev->clipstroketext(csi->dev->user, text, &gstate->strokestate, gstate->ctm);
csi->dev->fillshade(csi->dev->user, gstate->stroke.shade, gstate->ctm);
csi->dev->popclip(csi->dev->user);
break;
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index 456e5bb1..1defd223 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -284,23 +284,23 @@ pdf_runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *rdb, fz_obj *extgst
}
else if (!strcmp(s, "LW"))
- gstate->linewidth = fz_toreal(val);
+ gstate->strokestate.linewidth = fz_toreal(val);
else if (!strcmp(s, "LC"))
- gstate->linecap = fz_toint(val);
+ gstate->strokestate.linecap = fz_toint(val);
else if (!strcmp(s, "LJ"))
- gstate->linejoin = fz_toint(val);
+ gstate->strokestate.linejoin = fz_toint(val);
else if (!strcmp(s, "ML"))
- gstate->miterlimit = fz_toreal(val);
+ gstate->strokestate.miterlimit = fz_toreal(val);
else if (!strcmp(s, "D"))
{
if (fz_isarray(val) && fz_arraylen(val) == 2)
{
fz_obj *dashes = fz_arrayget(val, 0);
- gstate->dashlen = MAX(fz_arraylen(dashes), 32);
- for (k = 0; k < gstate->dashlen; k++)
- gstate->dashlist[k] = fz_toreal(fz_arrayget(dashes, k));
- gstate->dashphase = fz_toreal(fz_arrayget(val, 1));
+ gstate->strokestate.dashlen = MAX(fz_arraylen(dashes), 32);
+ for (k = 0; k < gstate->strokestate.dashlen; k++)
+ gstate->strokestate.dashlist[k] = fz_toreal(fz_arrayget(dashes, k));
+ gstate->strokestate.dashphase = fz_toreal(fz_arrayget(val, 1));
}
else
return fz_throw("malformed /D");
@@ -989,25 +989,25 @@ Lsetcolor:
case 'w':
if (csi->top != 1)
goto syntaxerror;
- gstate->linewidth = fz_toreal(csi->stack[0]);
+ gstate->strokestate.linewidth = fz_toreal(csi->stack[0]);
break;
case 'J':
if (csi->top != 1)
goto syntaxerror;
- gstate->linecap = fz_toint(csi->stack[0]);
+ gstate->strokestate.linecap = fz_toint(csi->stack[0]);
break;
case 'j':
if (csi->top != 1)
goto syntaxerror;
- gstate->linejoin = fz_toint(csi->stack[0]);
+ gstate->strokestate.linejoin = fz_toint(csi->stack[0]);
break;
case 'M':
if (csi->top != 1)
goto syntaxerror;
- gstate->miterlimit = fz_toreal(csi->stack[0]);
+ gstate->strokestate.miterlimit = fz_toreal(csi->stack[0]);
break;
case 'd':
@@ -1016,12 +1016,12 @@ Lsetcolor:
{
int i;
fz_obj *array = csi->stack[0];
- gstate->dashlen = fz_arraylen(array);
- if (gstate->dashlen > 32)
+ gstate->strokestate.dashlen = fz_arraylen(array);
+ if (gstate->strokestate.dashlen > 32)
return fz_throw("assert: dash pattern too big");
- for (i = 0; i < gstate->dashlen; i++)
- gstate->dashlist[i] = fz_toreal(fz_arrayget(array, i));
- gstate->dashphase = fz_toreal(csi->stack[1]);
+ for (i = 0; i < gstate->strokestate.dashlen; i++)
+ gstate->strokestate.dashlist[i] = fz_toreal(fz_arrayget(array, i));
+ gstate->strokestate.dashphase = fz_toreal(csi->stack[1]);
}
break;