summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-01 15:23:08 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-01 15:23:08 +0200
commited88bc126023a80536ba437a75b250ba1a95eafb (patch)
tree597efc732e024a5d0054147d0aea6b206362abed
parent706c332d78120675f26164c93f59f8f16b3a885e (diff)
downloadmupdf-ed88bc126023a80536ba437a75b250ba1a95eafb.tar.xz
xps: Remove 'path' and 'text' state objects from context.
-rw-r--r--xps/muxps.h16
-rw-r--r--xps/xpsglyphs.c53
-rw-r--r--xps/xpspage.c9
-rw-r--r--xps/xpspath.c288
-rw-r--r--xps/xpstile.c15
-rw-r--r--xps/xpszip.c2
6 files changed, 167 insertions, 216 deletions
diff --git a/xps/muxps.h b/xps/muxps.h
index 9154316b..0bb03584 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -199,8 +199,8 @@ void xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char
void xps_parse_matrix_transform(xps_context *ctx, xps_item *root, fz_matrix *matrix);
void xps_parse_render_transform(xps_context *ctx, char *text, fz_matrix *matrix);
void xps_parse_rectangle(xps_context *ctx, char *text, fz_rect *rect);
-void xps_parse_abbreviated_geometry(xps_context *ctx, char *geom);
-void xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking);
+fz_path *xps_parse_abbreviated_geometry(xps_context *ctx, char *geom, int *fill_rule);
+fz_path *xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking, int *fill_rule);
void xps_begin_opacity(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, char *opacity_att, xps_item *opacity_mask_tag);
void xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict, char *opacity_att, xps_item *opacity_mask_tag);
@@ -208,7 +208,7 @@ void xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict, char
void xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
void xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_clip(xps_context *ctx, fz_matrix ctm);
+void xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xps_item *clip_tag);
int xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node);
int xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xps_item *node);
@@ -248,20 +248,10 @@ struct xps_context_s
xps_hash_table *font_table;
xps_hash_table *colorspace_table;
- /* The fill_rule is set by path parsing.
- * It is used by clip/fill functions.
- * 1=nonzero, 0=evenodd
- */
- int fill_rule;
-
/* Opacity attribute stack */
float opacity[64];
int opacity_top;
- /* Current path being accumulated */
- fz_path *path;
- fz_text *text; /* ... or text, for clipping brushes */
-
/* Current color */
fz_colorspace *colorspace;
float color[8];
diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c
index 05b12ed3..f857542c 100644
--- a/xps/xpsglyphs.c
+++ b/xps/xpsglyphs.c
@@ -171,12 +171,13 @@ xps_parse_glyph_metrics(char *s, float *advance, float *uofs, float *vofs)
* Parse unicode and indices strings and encode glyphs.
* Calculate metrics for positioning.
*/
-static void
+static fz_text *
xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
float originx, float originy, int is_sideways, int bidi_level,
- char *indices, char *unicode, int is_charpath)
+ char *indices, char *unicode)
{
xps_glyph_metrics mtx;
+ fz_text *text;
fz_matrix tm;
float e, f;
float x = originx;
@@ -186,10 +187,7 @@ xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
int un = 0;
if (!unicode && !indices)
- {
fz_warn("glyphs element with neither characters nor indices");
- return;
- }
if (us)
{
@@ -203,7 +201,7 @@ xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
else
tm = fz_scale(size, -size);
- ctx->text = fz_newtext(font, tm, is_sideways);
+ text = fz_newtext(font, tm, is_sideways);
while ((us && un > 0) || (is && *is))
{
@@ -277,11 +275,13 @@ xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
f = y - v_offset;
}
- fz_addtext(ctx->text, glyph_index, char_code, e, f);
+ fz_addtext(text, glyph_index, char_code, e, f);
x += advance * 0.01 * size;
}
}
+
+ return text;
}
void
@@ -328,6 +328,7 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
int is_sideways = 0;
int bidi_level = 0;
+ fz_text *text;
fz_rect area;
/*
@@ -445,17 +446,16 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
}
if (clip_att || clip_tag)
- {
- ctx->path = fz_newpath();
- if (clip_att)
- xps_parse_abbreviated_geometry(ctx, clip_att);
- if (clip_tag)
- xps_parse_path_geometry(ctx, dict, clip_tag, 0);
- xps_clip(ctx, ctm);
- }
+ xps_clip(ctx, ctm, dict, clip_att, clip_tag);
font_size = atof(font_size_att);
+ text = xps_parse_glyphs_imp(ctx, ctm, font, font_size,
+ atof(origin_x_att), atof(origin_y_att),
+ is_sideways, bidi_level, indices_att, unicode_att);
+
+ area = fz_boundtext(text, ctm);
+
xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
/*
@@ -479,15 +479,8 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
samples[0] = atof(fill_opacity_att);
xps_set_color(ctx, colorspace, samples);
- xps_parse_glyphs_imp(ctx, ctm, font, font_size,
- atof(origin_x_att), atof(origin_y_att),
- is_sideways, bidi_level,
- indices_att, unicode_att, 0);
-
- ctx->dev->filltext(ctx->dev->user, ctx->text, ctm,
+ ctx->dev->filltext(ctx->dev->user, text, ctm,
ctx->colorspace, ctx->color, ctx->alpha);
- fz_freetext(ctx->text);
- ctx->text = nil;
}
/*
@@ -496,23 +489,15 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
if (fill_tag)
{
- xps_parse_glyphs_imp(ctx, ctm, font, font_size,
- atof(origin_x_att), atof(origin_y_att),
- is_sideways, bidi_level, indices_att, unicode_att, 1);
-
- area = fz_boundtext(ctx->text, ctm);
-
- ctx->dev->cliptext(ctx->dev->user, ctx->text, ctm, 0);
- fz_freetext(ctx->text);
- ctx->text = nil;
-
+ ctx->dev->cliptext(ctx->dev->user, text, ctm, 0);
xps_parse_brush(ctx, ctm, area, fill_uri, dict, fill_tag);
-
ctx->dev->popclip(ctx->dev->user);
}
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
+ fz_freetext(text);
+
if (clip_att || clip_tag)
ctx->dev->popclip(ctx->dev->user);
}
diff --git a/xps/xpspage.c b/xps/xpspage.c
index 39731ef2..0188eb62 100644
--- a/xps/xpspage.c
+++ b/xps/xpspage.c
@@ -60,14 +60,7 @@ xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *
ctm = fz_concat(transform, ctm);
if (clip_att || clip_tag)
- {
- ctx->path = fz_newpath();
- if (clip_att)
- xps_parse_abbreviated_geometry(ctx, clip_att);
- if (clip_tag)
- xps_parse_path_geometry(ctx, dict, clip_tag, 0);
- xps_clip(ctx, ctm);
- }
+ xps_clip(ctx, ctm, dict, clip_att, clip_tag);
xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
diff --git a/xps/xpspath.c b/xps/xpspath.c
index 14de9147..d5063a87 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -36,37 +36,19 @@ fz_currentpoint(fz_path *path)
}
void
-xps_clip(xps_context *ctx, fz_matrix ctm)
+xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xps_item *clip_tag)
{
- ctx->dev->clippath(ctx->dev->user, ctx->path, ctx->fill_rule == 0, ctm);
- fz_freepath(ctx->path);
- ctx->path = NULL;
-}
-
-void
-xps_fill(xps_context *ctx, fz_matrix ctm)
-{
- ctx->dev->fillpath(ctx->dev->user, ctx->path, ctx->fill_rule == 0, ctm,
- ctx->colorspace, ctx->color, ctx->alpha);
- fz_freepath(ctx->path);
- ctx->path = NULL;
-}
+ fz_path *path;
+ int fill_rule = 0;
-static void
-xps_stroke(xps_context *ctx, fz_matrix ctm, fz_strokestate *stroke)
-{
- ctx->dev->strokepath(ctx->dev->user, ctx->path, stroke, ctm,
- ctx->colorspace, ctx->color, ctx->alpha);
- fz_freepath(ctx->path);
- ctx->path = NULL;
-}
-
-static void
-xps_clipstroke(xps_context *ctx, fz_matrix ctm, fz_strokestate *stroke)
-{
- ctx->dev->clipstrokepath(ctx->dev->user, ctx->path, stroke, ctm);
- fz_freepath(ctx->path);
- ctx->path = NULL;
+ if (clip_att)
+ path = xps_parse_abbreviated_geometry(ctx, clip_att, &fill_rule);
+ else if (clip_tag)
+ path = xps_parse_path_geometry(ctx, dict, clip_tag, 0, &fill_rule);
+ else
+ path = fz_newpath();
+ ctx->dev->clippath(ctx->dev->user, path, fill_rule, ctm);
+ fz_freepath(path);
}
/* Draw an arc segment transformed by the matrix, we approximate with straight
@@ -75,7 +57,7 @@ xps_clipstroke(xps_context *ctx, fz_matrix ctm, fz_strokestate *stroke)
* without transforming the line width.
*/
static inline void
-xps_draw_arc_segment(xps_context *ctx, fz_matrix mtx, float th0, float th1, int iscw)
+xps_draw_arc_segment(fz_path *path, fz_matrix mtx, float th0, float th1, int iscw)
{
float t, d;
fz_point p;
@@ -90,18 +72,18 @@ xps_draw_arc_segment(xps_context *ctx, fz_matrix mtx, float th0, float th1, int
p.x = cos(th0);
p.y = sin(th0);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
for (t = th0; t < th1; t += d)
{
p.x = cos(t);
p.y = sin(t);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
}
p.x = cos(th1);
p.y = sin(th1);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
}
else
{
@@ -109,18 +91,18 @@ xps_draw_arc_segment(xps_context *ctx, fz_matrix mtx, float th0, float th1, int
p.x = cos(th0);
p.y = sin(th0);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
for (t = th0; t > th1; t -= d)
{
p.x = cos(t);
p.y = sin(t);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
}
p.x = cos(th1);
p.y = sin(th1);
p = fz_transformpoint(mtx, p);
- fz_lineto(ctx->path, p.x, p.y);
+ fz_lineto(path, p.x, p.y);
}
}
@@ -141,7 +123,7 @@ angle_between(const fz_point u, const fz_point v)
}
static void
-xps_draw_arc(xps_context *ctx,
+xps_draw_arc(fz_path *path,
float size_x, float size_y, float rotation_angle,
int is_large_arc, int is_clockwise,
float point_x, float point_y)
@@ -157,7 +139,7 @@ xps_draw_arc(xps_context *ctx,
double sign;
double th1, dth;
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = pt.x;
y1 = pt.y;
x2 = point_x;
@@ -181,7 +163,7 @@ xps_draw_arc(xps_context *ctx,
ry = fabsf(ry);
if (rx < 0.001 || ry < 0.001)
{
- fz_lineto(ctx->path, x2, y2);
+ fz_lineto(path, x2, y2);
return;
}
@@ -241,9 +223,9 @@ xps_draw_arc(xps_context *ctx,
mtx = fz_concat(fz_translate(cx, cy), mtx);
mtx = fz_concat(fz_rotate(rotation_angle), mtx);
mtx = fz_concat(fz_scale(rx, ry), mtx);
- xps_draw_arc_segment(ctx, mtx, th1, th1 + dth, is_clockwise);
+ xps_draw_arc_segment(path, mtx, th1, th1 + dth, is_clockwise);
- fz_lineto(ctx->path, point_x, point_y);
+ fz_lineto(path, point_x, point_y);
}
/*
@@ -252,9 +234,10 @@ xps_draw_arc(xps_context *ctx,
* build up a path.
*/
-void
-xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
+fz_path *
+xps_parse_abbreviated_geometry(xps_context *ctx, char *geom, int *fill_rule)
{
+ fz_path *path;
char **args;
char **pargs;
char *s = geom;
@@ -265,6 +248,8 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
float smooth_x, smooth_y; /* saved cubic bezier control point for smooth curves */
int reset_smooth;
+ path = fz_newpath();
+
args = fz_calloc(strlen(geom) + 1, sizeof(char*));
pargs = args;
@@ -317,49 +302,49 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
switch (cmd)
{
case 'F':
- ctx->fill_rule = atoi(args[i]);
+ *fill_rule = atoi(args[i]);
i ++;
break;
case 'M':
- fz_moveto(ctx->path, atof(args[i]), atof(args[i+1]));
+ fz_moveto(path, atof(args[i]), atof(args[i+1]));
i += 2;
break;
case 'm':
- pt = fz_currentpoint(ctx->path);
- fz_moveto(ctx->path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
+ pt = fz_currentpoint(path);
+ fz_moveto(path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
i += 2;
break;
case 'L':
- fz_lineto(ctx->path, atof(args[i]), atof(args[i+1]));
+ fz_lineto(path, atof(args[i]), atof(args[i+1]));
i += 2;
break;
case 'l':
- pt = fz_currentpoint(ctx->path);
- fz_lineto(ctx->path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
+ pt = fz_currentpoint(path);
+ fz_lineto(path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
i += 2;
break;
case 'H':
- pt = fz_currentpoint(ctx->path);
- fz_lineto(ctx->path, atof(args[i]), pt.y);
+ pt = fz_currentpoint(path);
+ fz_lineto(path, atof(args[i]), pt.y);
i += 1;
break;
case 'h':
- pt = fz_currentpoint(ctx->path);
- fz_lineto(ctx->path, pt.x + atof(args[i]), pt.y);
+ pt = fz_currentpoint(path);
+ fz_lineto(path, pt.x + atof(args[i]), pt.y);
i += 1;
break;
case 'V':
- pt = fz_currentpoint(ctx->path);
- fz_lineto(ctx->path, pt.x, atof(args[i]));
+ pt = fz_currentpoint(path);
+ fz_lineto(path, pt.x, atof(args[i]));
i += 1;
break;
case 'v':
- pt = fz_currentpoint(ctx->path);
- fz_lineto(ctx->path, pt.x, pt.y + atof(args[i]));
+ pt = fz_currentpoint(path);
+ fz_lineto(path, pt.x, pt.y + atof(args[i]));
i += 1;
break;
@@ -370,7 +355,7 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
y2 = atof(args[i+3]);
x3 = atof(args[i+4]);
y3 = atof(args[i+5]);
- fz_curveto(ctx->path, x1, y1, x2, y2, x3, y3);
+ fz_curveto(path, x1, y1, x2, y2, x3, y3);
i += 6;
reset_smooth = 0;
smooth_x = x3 - x2;
@@ -378,14 +363,14 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
break;
case 'c':
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
x3 = atof(args[i+4]) + pt.x;
y3 = atof(args[i+5]) + pt.y;
- fz_curveto(ctx->path, x1, y1, x2, y2, x3, y3);
+ fz_curveto(path, x1, y1, x2, y2, x3, y3);
i += 6;
reset_smooth = 0;
smooth_x = x3 - x2;
@@ -393,12 +378,12 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
break;
case 'S':
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = atof(args[i+0]);
y1 = atof(args[i+1]);
x2 = atof(args[i+2]);
y2 = atof(args[i+3]);
- fz_curveto(ctx->path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
+ fz_curveto(path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
i += 4;
reset_smooth = 0;
smooth_x = x2 - x1;
@@ -406,12 +391,12 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
break;
case 's':
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
- fz_curveto(ctx->path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
+ fz_curveto(path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
i += 4;
reset_smooth = 0;
smooth_x = x2 - x1;
@@ -419,49 +404,49 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
break;
case 'Q':
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = atof(args[i+0]);
y1 = atof(args[i+1]);
x2 = atof(args[i+2]);
y2 = atof(args[i+3]);
- fz_curveto(ctx->path,
- (pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
- (x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
- x2, y2);
+ fz_curveto(path,
+ (pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
+ (x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
+ x2, y2);
i += 4;
break;
case 'q':
- pt = fz_currentpoint(ctx->path);
+ pt = fz_currentpoint(path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
- fz_curveto(ctx->path,
- (pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
- (x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
- x2, y2);
+ fz_curveto(path,
+ (pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
+ (x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
+ x2, y2);
i += 4;
break;
case 'A':
- xps_draw_arc(ctx,
- atof(args[i+0]), atof(args[i+1]), atof(args[i+2]),
- atoi(args[i+3]), atoi(args[i+4]),
- atof(args[i+5]), atof(args[i+6]));
+ xps_draw_arc(path,
+ atof(args[i+0]), atof(args[i+1]), atof(args[i+2]),
+ atoi(args[i+3]), atoi(args[i+4]),
+ atof(args[i+5]), atof(args[i+6]));
i += 7;
break;
case 'a':
- pt = fz_currentpoint(ctx->path);
- xps_draw_arc(ctx,
- atof(args[i+0]), atof(args[i+1]), atof(args[i+2]),
- atoi(args[i+3]), atoi(args[i+4]),
- atof(args[i+5]) + pt.x, atof(args[i+6]) + pt.y);
+ pt = fz_currentpoint(path);
+ xps_draw_arc(path,
+ atof(args[i+0]), atof(args[i+1]), atof(args[i+2]),
+ atoi(args[i+3]), atoi(args[i+4]),
+ atof(args[i+5]) + pt.x, atof(args[i+6]) + pt.y);
i += 7;
break;
case 'Z':
case 'z':
- fz_closepath(ctx->path);
+ fz_closepath(path);
break;
default:
@@ -473,10 +458,11 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom)
}
fz_free(args);
+ return path;
}
static void
-xps_parse_arc_segment(xps_context *ctx, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_arc_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
{
/* ArcSegment pretty much follows the SVG algorithm for converting an
* arc in endpoint representation to an arc in centerpoint
@@ -516,15 +502,15 @@ xps_parse_arc_segment(xps_context *ctx, xps_item *root, int stroking, int *skipp
if (stroking && !is_stroked)
{
- fz_moveto(ctx->path, point_x, point_y);
+ fz_moveto(path, point_x, point_y);
return;
}
- xps_draw_arc(ctx, size_x, size_y, rotation_angle, is_large_arc, is_clockwise, point_x, point_y);
+ xps_draw_arc(path, size_x, size_y, rotation_angle, is_large_arc, is_clockwise, point_x, point_y);
}
static void
-xps_parse_poly_quadratic_bezier_segment(xps_context *ctx, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_quadratic_bezier_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
{
char *points_att = xps_att(root, "Points");
char *is_stroked_att = xps_att(root, "IsStroked");
@@ -558,12 +544,12 @@ xps_parse_poly_quadratic_bezier_segment(xps_context *ctx, xps_item *root, int st
{
if (stroking && !is_stroked)
{
- fz_moveto(ctx->path, x[1], y[1]);
+ fz_moveto(path, x[1], y[1]);
}
else
{
- pt = fz_currentpoint(ctx->path);
- fz_curveto(ctx->path,
+ pt = fz_currentpoint(path);
+ fz_curveto(path,
(pt.x + 2 * x[0]) / 3, (pt.y + 2 * y[0]) / 3,
(x[1] + 2 * x[0]) / 3, (y[1] + 2 * y[0]) / 3,
x[1], y[1]);
@@ -574,7 +560,7 @@ xps_parse_poly_quadratic_bezier_segment(xps_context *ctx, xps_item *root, int st
}
static void
-xps_parse_poly_bezier_segment(xps_context *ctx, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_bezier_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
{
char *points_att = xps_att(root, "Points");
char *is_stroked_att = xps_att(root, "IsStroked");
@@ -606,16 +592,16 @@ xps_parse_poly_bezier_segment(xps_context *ctx, xps_item *root, int stroking, in
if (n == 3)
{
if (stroking && !is_stroked)
- fz_moveto(ctx->path, x[2], y[2]);
+ fz_moveto(path, x[2], y[2]);
else
- fz_curveto(ctx->path, x[0], y[0], x[1], y[1], x[2], y[2]);
+ fz_curveto(path, x[0], y[0], x[1], y[1], x[2], y[2]);
n = 0;
}
}
}
static void
-xps_parse_poly_line_segment(xps_context *ctx, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_line_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
{
char *points_att = xps_att(root, "Points");
char *is_stroked_att = xps_att(root, "IsStroked");
@@ -641,15 +627,15 @@ xps_parse_poly_line_segment(xps_context *ctx, xps_item *root, int stroking, int
while (*s == ' ') s++;
sscanf(s, "%g,%g", &x, &y);
if (stroking && !is_stroked)
- fz_moveto(ctx->path, x, y);
+ fz_moveto(path, x, y);
else
- fz_lineto(ctx->path, x, y);
+ fz_lineto(path, x, y);
while (*s != ' ' && *s != 0) s++;
}
}
static void
-xps_parse_path_figure(xps_context *ctx, xps_item *root, int stroking)
+xps_parse_path_figure(fz_path *path, xps_item *root, int stroking)
{
xps_item *node;
@@ -678,31 +664,31 @@ xps_parse_path_figure(xps_context *ctx, xps_item *root, int stroking)
if (!stroking && !is_filled) /* not filled, when filling */
return;
- fz_moveto(ctx->path, start_x, start_y);
+ fz_moveto(path, start_x, start_y);
for (node = xps_down(root); node; node = xps_next(node))
{
if (!strcmp(xps_tag(node), "ArcSegment"))
- xps_parse_arc_segment(ctx, node, stroking, &skipped_stroke);
+ xps_parse_arc_segment(path, node, stroking, &skipped_stroke);
if (!strcmp(xps_tag(node), "PolyBezierSegment"))
- xps_parse_poly_bezier_segment(ctx, node, stroking, &skipped_stroke);
+ xps_parse_poly_bezier_segment(path, node, stroking, &skipped_stroke);
if (!strcmp(xps_tag(node), "PolyLineSegment"))
- xps_parse_poly_line_segment(ctx, node, stroking, &skipped_stroke);
+ xps_parse_poly_line_segment(path, node, stroking, &skipped_stroke);
if (!strcmp(xps_tag(node), "PolyQuadraticBezierSegment"))
- xps_parse_poly_quadratic_bezier_segment(ctx, node, stroking, &skipped_stroke);
+ xps_parse_poly_quadratic_bezier_segment(path, node, stroking, &skipped_stroke);
}
if (is_closed)
{
if (stroking && skipped_stroke)
- fz_lineto(ctx->path, start_x, start_y); /* we've skipped using fz_moveto... */
+ fz_lineto(path, start_x, start_y); /* we've skipped using fz_moveto... */
else
- fz_closepath(ctx->path); /* no skipped segments, safe to closepath properly */
+ fz_closepath(path); /* no skipped segments, safe to closepath properly */
}
}
-void
-xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking)
+fz_path *
+xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking, int *fill_rule)
{
xps_item *node;
@@ -714,6 +700,7 @@ xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, in
xps_item *figures_tag = NULL; /* only used by resource */
fz_matrix transform;
+ fz_path *path;
figures_att = xps_att(root, "Figures");
fill_rule_att = xps_att(root, "FillRule");
@@ -731,9 +718,9 @@ xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, in
if (fill_rule_att)
{
if (!strcmp(fill_rule_att, "NonZero"))
- ctx->fill_rule = 1;
+ *fill_rule = 1;
if (!strcmp(fill_rule_att, "EvenOdd"))
- ctx->fill_rule = 0;
+ *fill_rule = 0;
}
transform = fz_identity;
@@ -743,18 +730,23 @@ xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, in
xps_parse_matrix_transform(ctx, transform_tag, &transform);
if (figures_att)
- xps_parse_abbreviated_geometry(ctx, figures_att);
+ path = xps_parse_abbreviated_geometry(ctx, figures_att, fill_rule);
+ else
+ path = fz_newpath();
+
if (figures_tag)
- xps_parse_path_figure(ctx, figures_tag, stroking);
+ xps_parse_path_figure(path, figures_tag, stroking);
for (node = xps_down(root); node; node = xps_next(node))
{
if (!strcmp(xps_tag(node), "PathFigure"))
- xps_parse_path_figure(ctx, node, stroking);
+ xps_parse_path_figure(path, node, stroking);
}
if (transform_att || transform_tag)
- fz_transformpath(ctx->path, transform);
+ fz_transformpath(path, transform);
+
+ return path;
}
static int
@@ -815,9 +807,9 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
fz_matrix transform;
float samples[32];
fz_colorspace *colorspace;
+ fz_path *path;
fz_rect area;
-
- ctx->fill_rule = 0;
+ int fill_rule;
/*
* Extract attributes and extended attributes.
@@ -871,6 +863,9 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
* Act on the information we have gathered:
*/
+ if (!data_att && !data_tag)
+ return;
+
if (fill_tag && !strcmp(xps_tag(fill_tag), "SolidColorBrush"))
{
fill_opacity_att = xps_att(fill_tag, "Opacity");
@@ -932,14 +927,18 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
ctm = fz_concat(transform, ctm);
if (clip_att || clip_tag)
- {
- ctx->path = fz_newpath();
- if (clip_att)
- xps_parse_abbreviated_geometry(ctx, clip_att);
- if (clip_tag)
- xps_parse_path_geometry(ctx, dict, clip_tag, 0);
- xps_clip(ctx, ctm);
- }
+ xps_clip(ctx, ctm, dict, clip_att, clip_tag);
+
+ fill_rule = 0;
+ if (data_att)
+ path = xps_parse_abbreviated_geometry(ctx, data_att, &fill_rule);
+ else if (data_tag)
+ path = xps_parse_path_geometry(ctx, dict, data_tag, 0, &fill_rule);
+
+ if (stroke_att || stroke_tag)
+ area = fz_boundpath(path, &stroke, ctm);
+ else
+ area = fz_boundpath(path, NULL, ctm);
xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
@@ -950,26 +949,15 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
samples[0] = atof(fill_opacity_att);
xps_set_color(ctx, colorspace, samples);
- ctx->path = fz_newpath();
- if (data_att)
- xps_parse_abbreviated_geometry(ctx, data_att);
- if (data_tag)
- xps_parse_path_geometry(ctx, dict, data_tag, 0);
-
- xps_fill(ctx, ctm);
+ ctx->dev->fillpath(ctx->dev->user, path, fill_rule == 0, ctm,
+ ctx->colorspace, ctx->color, ctx->alpha);
}
if (fill_tag)
{
- ctx->path = fz_newpath();
- if (data_att)
- xps_parse_abbreviated_geometry(ctx, data_att);
- if (data_tag)
- xps_parse_path_geometry(ctx, dict, data_tag, 0);
+ area = fz_boundpath(path, NULL, ctm);
- area = fz_boundpath(ctx->path, NULL, ctm);
-
- xps_clip(ctx, ctm);
+ ctx->dev->clippath(ctx->dev->user, path, fill_rule == 0, ctm);
xps_parse_brush(ctx, ctm, area, fill_uri, dict, fill_tag);
ctx->dev->popclip(ctx->dev->user);
}
@@ -981,32 +969,28 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
samples[0] = atof(stroke_opacity_att);
xps_set_color(ctx, colorspace, samples);
- ctx->path = fz_newpath();
- if (data_att)
- xps_parse_abbreviated_geometry(ctx, data_att);
- if (data_tag)
- xps_parse_path_geometry(ctx, dict, data_tag, 1);
-
- xps_stroke(ctx, ctm, &stroke);
+ ctx->dev->strokepath(ctx->dev->user, path, &stroke, ctm,
+ ctx->colorspace, ctx->color, ctx->alpha);
}
if (stroke_tag)
{
- ctx->path = fz_newpath();
+ path = fz_newpath();
if (data_att)
- xps_parse_abbreviated_geometry(ctx, data_att);
+ xps_parse_abbreviated_geometry(ctx, data_att, &fill_rule);
if (data_tag)
- xps_parse_path_geometry(ctx, dict, data_tag, 1);
+ xps_parse_path_geometry(ctx, dict, data_tag, 1, &fill_rule);
- area = fz_boundpath(ctx->path, &stroke, ctm);
-
- xps_clipstroke(ctx, ctm, &stroke);
+ ctx->dev->clipstrokepath(ctx->dev->user, path, &stroke, ctm);
xps_parse_brush(ctx, ctm, area, stroke_uri, dict, stroke_tag);
ctx->dev->popclip(ctx->dev->user);
}
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
+ fz_freepath(path);
+ path = NULL;
+
if (clip_att || clip_tag)
ctx->dev->popclip(ctx->dev->user);
}
diff --git a/xps/xpstile.c b/xps/xpstile.c
index 59cf2f09..dedb0a3d 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -20,13 +20,14 @@ struct closure
static void
xps_paint_tiling_brush_clipped(xps_context *ctx, fz_matrix ctm, fz_rect viewbox, struct closure *c)
{
- ctx->path = fz_newpath();
- fz_moveto(ctx->path, viewbox.x0, viewbox.y0);
- fz_lineto(ctx->path, viewbox.x0, viewbox.y1);
- fz_lineto(ctx->path, viewbox.x1, viewbox.y1);
- fz_lineto(ctx->path, viewbox.x1, viewbox.y0);
- fz_closepath(ctx->path);
- xps_clip(ctx, ctm);
+ fz_path *path = fz_newpath();
+ fz_moveto(path, viewbox.x0, viewbox.y0);
+ fz_lineto(path, viewbox.x0, viewbox.y1);
+ fz_lineto(path, viewbox.x1, viewbox.y1);
+ fz_lineto(path, viewbox.x1, viewbox.y0);
+ fz_closepath(path);
+
+ ctx->dev->clippath(ctx->dev->user, path, 0, ctm);
c->func(ctx, ctm, c->base_uri, c->dict, c->root, c->user);
diff --git a/xps/xpszip.c b/xps/xpszip.c
index 069c83ea..0646b89f 100644
--- a/xps/xpszip.c
+++ b/xps/xpszip.c
@@ -498,8 +498,6 @@ xps_new_context(void)
ctx->start_part = NULL;
- ctx->fill_rule = 0;
-
return ctx;
}