summaryrefslogtreecommitdiff
path: root/src/cairo-path-stroke.c
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2009-11-10 23:09:56 +0100
committerAndrea Canciani <ranma42@gmail.com>2009-11-11 18:21:04 +0100
commit26e9f149063b9e1fdb54fc54fccbefdf04a68190 (patch)
tree002b1632435e47bf43174299d67f787127cd5a1f /src/cairo-path-stroke.c
parent9c24288c820069e80b0feb5e99ece4c89e92c0c6 (diff)
downloadcairo-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.c24
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;
}