diff options
author | Andrea Canciani <ranma42@gmail.com> | 2009-11-10 23:09:56 +0100 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2009-11-11 18:21:04 +0100 |
commit | 26e9f149063b9e1fdb54fc54fccbefdf04a68190 (patch) | |
tree | 002b1632435e47bf43174299d67f787127cd5a1f /src/cairo-path-stroke.c | |
parent | 9c24288c820069e80b0feb5e99ece4c89e92c0c6 (diff) | |
download | cairo-26e9f149063b9e1fdb54fc54fccbefdf04a68190.tar.gz |
Improve stroking of densely dashed styles
Add some auxiliary functions to cairo-stroke-style to compute
properties of the dashed patterns (period, "on" coverage) and to
generate approximations when the dash pattern is sub-tolerance.
These functions are used in cairo-path-stroke to simplify dash
patterns stroked by cairo.
Fixes dash-infinite-loop
See http://bugs.freedesktop.org/show_bug.cgi?id=24702
Diffstat (limited to 'src/cairo-path-stroke.c')
-rw-r--r-- | src/cairo-path-stroke.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 5c4f4fc7b..272045a87 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -51,6 +51,7 @@ typedef struct _cairo_stroker_dash { double dash_offset; const double *dashes; + double approximate_dashes[2]; unsigned int num_dashes; } cairo_stroker_dash_t; @@ -137,15 +138,25 @@ _cairo_stroker_dash_step (cairo_stroker_dash_t *dash, double step) static void _cairo_stroker_dash_init (cairo_stroker_dash_t *dash, - const cairo_stroke_style_t *style) + const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + double tolerance) { dash->dashed = style->dash != NULL; if (! dash->dashed) return; - dash->dashes = style->dash; - dash->num_dashes = style->num_dashes; - dash->dash_offset = style->dash_offset; + if (_cairo_stroke_style_dash_can_approximate (style, ctm, tolerance)) { + _cairo_stroke_style_dash_approximate (style, ctm, tolerance, + &dash->dash_offset, + dash->approximate_dashes, + &dash->num_dashes); + dash->dashes = dash->approximate_dashes; + } else { + dash->dashes = style->dash; + dash->num_dashes = style->num_dashes; + dash->dash_offset = style->dash_offset; + } _cairo_stroker_dash_start (dash); } @@ -179,7 +190,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker, stroker->has_first_face = FALSE; stroker->has_initial_sub_path = FALSE; - _cairo_stroker_dash_init (&stroker->dash, stroke_style); + _cairo_stroker_dash_init (&stroker->dash, stroke_style, ctm, tolerance); stroker->add_external_edge = NULL; @@ -1490,7 +1501,8 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker, stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded); stroker->num_segments = 0; - _cairo_stroker_dash_init (&stroker->dash, stroke_style); + /* Assume 2*EPSILON tolerance */ + _cairo_stroker_dash_init (&stroker->dash, stroke_style, ctm, _cairo_fixed_to_double (2 * CAIRO_FIXED_EPSILON)); stroker->has_bounds = FALSE; } |