summaryrefslogtreecommitdiff
path: root/xps/xps_path.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-03-14 19:11:02 +0000
committerRobin Watts <robin.watts@artifex.com>2012-03-14 21:16:27 +0000
commit77eed8154c782a4d3b0e38a49986c18c240ab2f2 (patch)
tree4349aa1ce473250ba9186ed11498af96aeb4d40e /xps/xps_path.c
parentebd905bf410d0093bf68ff1af2621fc4303ed2bd (diff)
downloadmupdf-77eed8154c782a4d3b0e38a49986c18c240ab2f2.tar.xz
Bug 692917: Move to dynamic stroke_states.
Move fz_stroke_state from being a simple structure whose contents are copied repeatedly to being a dynamically allocated reference counted object so we can cope with large numbers of entries in the dash array.
Diffstat (limited to 'xps/xps_path.c')
-rw-r--r--xps/xps_path.c92
1 files changed, 57 insertions, 35 deletions
diff --git a/xps/xps_path.c b/xps/xps_path.c
index e368776d..6720390d 100644
--- a/xps/xps_path.c
+++ b/xps/xps_path.c
@@ -857,7 +857,7 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
char *stroke_thickness_att;
char *navigate_uri_att;
- fz_stroke_state stroke;
+ fz_stroke_state *stroke = NULL;
fz_matrix transform;
float samples[32];
fz_colorspace *colorspace;
@@ -865,6 +865,7 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
fz_path *stroke_path = NULL;
fz_rect area;
int fill_rule;
+ int dash_len = 0;
/*
* Extract attributes and extended attributes.
@@ -936,43 +937,63 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
stroke_tag = NULL;
}
- stroke.start_cap = xps_parse_line_cap(stroke_start_line_cap_att);
- stroke.dash_cap = xps_parse_line_cap(stroke_dash_cap_att);
- stroke.end_cap = xps_parse_line_cap(stroke_end_line_cap_att);
-
- stroke.linejoin = FZ_LINEJOIN_MITER_XPS;
- if (stroke_line_join_att)
- {
- if (!strcmp(stroke_line_join_att, "Miter")) stroke.linejoin = FZ_LINEJOIN_MITER_XPS;
- if (!strcmp(stroke_line_join_att, "Round")) stroke.linejoin = FZ_LINEJOIN_ROUND;
- if (!strcmp(stroke_line_join_att, "Bevel")) stroke.linejoin = FZ_LINEJOIN_BEVEL;
- }
+ if (stroke_att || stroke_tag)
+ {
+ if (stroke_dash_array_att)
+ {
+ char *s = stroke_dash_array_att;
- stroke.miterlimit = 10;
- if (stroke_miter_limit_att)
- stroke.miterlimit = fz_atof(stroke_miter_limit_att);
+ while (*s)
+ {
+ while (*s == ' ')
+ s++;
+ if (*s) /* needed in case of a space before the last quote */
+ dash_len++;
+
+ while (*s && *s != ' ')
+ s++;
+ }
+ }
+ stroke = fz_new_stroke_state_with_len(doc->ctx, dash_len);
+ stroke->start_cap = xps_parse_line_cap(stroke_start_line_cap_att);
+ stroke->dash_cap = xps_parse_line_cap(stroke_dash_cap_att);
+ stroke->end_cap = xps_parse_line_cap(stroke_end_line_cap_att);
- stroke.linewidth = 1;
- if (stroke_thickness_att)
- stroke.linewidth = fz_atof(stroke_thickness_att);
+ stroke->linejoin = FZ_LINEJOIN_MITER_XPS;
+ if (stroke_line_join_att)
+ {
+ if (!strcmp(stroke_line_join_att, "Miter")) stroke->linejoin = FZ_LINEJOIN_MITER_XPS;
+ if (!strcmp(stroke_line_join_att, "Round")) stroke->linejoin = FZ_LINEJOIN_ROUND;
+ if (!strcmp(stroke_line_join_att, "Bevel")) stroke->linejoin = FZ_LINEJOIN_BEVEL;
+ }
- stroke.dash_phase = 0;
- stroke.dash_len = 0;
- if (stroke_dash_array_att)
- {
- char *s = stroke_dash_array_att;
+ stroke->miterlimit = 10;
+ if (stroke_miter_limit_att)
+ stroke->miterlimit = fz_atof(stroke_miter_limit_att);
- if (stroke_dash_offset_att)
- stroke.dash_phase = fz_atof(stroke_dash_offset_att) * stroke.linewidth;
+ stroke->linewidth = 1;
+ if (stroke_thickness_att)
+ stroke->linewidth = fz_atof(stroke_thickness_att);
- while (*s && stroke.dash_len < nelem(stroke.dash_list))
+ stroke->dash_phase = 0;
+ stroke->dash_len = 0;
+ if (stroke_dash_array_att)
{
- while (*s == ' ')
- s++;
- if (*s) /* needed in case of a space before the last quote */
- stroke.dash_list[stroke.dash_len++] = fz_atof(s) * stroke.linewidth;
- while (*s && *s != ' ')
- s++;
+ char *s = stroke_dash_array_att;
+
+ if (stroke_dash_offset_att)
+ stroke->dash_phase = fz_atof(stroke_dash_offset_att) * stroke->linewidth;
+
+ while (*s)
+ {
+ while (*s == ' ')
+ s++;
+ if (*s) /* needed in case of a space before the last quote */
+ stroke->dash_list[stroke->dash_len++] = fz_atof(s) * stroke->linewidth;
+ while (*s && *s != ' ')
+ s++;
+ }
+ stroke->dash_len = dash_len;
}
}
@@ -1000,7 +1021,7 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
if (stroke_att || stroke_tag)
{
- area = fz_bound_path(doc->ctx, stroke_path, &stroke, ctm);
+ area = fz_bound_path(doc->ctx, stroke_path, stroke, ctm);
if (stroke_path != path && (fill_att || fill_tag))
area = fz_union_rect(area, fz_bound_path(doc->ctx, path, NULL, ctm));
}
@@ -1037,13 +1058,13 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
samples[0] *= fz_atof(stroke_opacity_att);
xps_set_color(doc, colorspace, samples);
- fz_stroke_path(doc->dev, stroke_path, &stroke, ctm,
+ fz_stroke_path(doc->dev, stroke_path, stroke, ctm,
doc->colorspace, doc->color, doc->alpha);
}
if (stroke_tag)
{
- fz_clip_stroke_path(doc->dev, stroke_path, NULL, &stroke, ctm);
+ fz_clip_stroke_path(doc->dev, stroke_path, NULL, stroke, ctm);
xps_parse_brush(doc, ctm, area, stroke_uri, dict, stroke_tag);
fz_pop_clip(doc->dev);
}
@@ -1054,6 +1075,7 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
fz_free_path(doc->ctx, stroke_path);
fz_free_path(doc->ctx, path);
path = NULL;
+ fz_drop_stroke_state(doc->ctx, stroke);
if (clip_att || clip_tag)
fz_pop_clip(doc->dev);