Add support for dashed splines. (The antialiasing quality isn't perfect, but at least the curves are dashed now).
This commit is contained in:
Carl Worth 2005-09-16 10:24:54 +00:00
parent a7459e0057
commit 5b9be26d26
2 changed files with 86 additions and 1 deletions

View file

@ -1,3 +1,14 @@
2005-09-16 Carl Worth <cworth@cworth.org>
Tested by: John Ellson
Closes bug #4408
https://bugs.freedesktop.org/show_bug.cgi?id=4408
* src/cairo-path-stroke.c: (_cairo_stroker_curve_to_dashed),
(_cairo_path_fixed_stroke_to_traps): Add support for dashed
splines. (The antialiasing quality isn't perfect, but at least the
curves are dashed now).
2005-09-16 Carl Worth <cworth@cworth.org>
* ROADMAP: Mark 4260 as resolved. Add 4414 to the 1.0.2 roadmap.

View file

@ -80,6 +80,12 @@ _cairo_stroker_curve_to (void *closure,
cairo_point_t *c,
cairo_point_t *d);
static cairo_status_t
_cairo_stroker_curve_to_dashed (void *closure,
cairo_point_t *b,
cairo_point_t *c,
cairo_point_t *d);
static cairo_status_t
_cairo_stroker_close_path (void *closure);
@ -801,6 +807,74 @@ _cairo_stroker_curve_to (void *closure,
return status;
}
/* We're using two different algorithms here for dashed and un-dashed
* splines. The dashed alogorithm uses the existing line dashing
* code. It's linear in path length, but gets subtly wrong results for
* self-intersecting paths (an outstanding but for self-intersecting
* non-curved paths as well). The non-dashed algorithm tessellates a
* single polygon for the whole curve. It handles the
* self-intersecting problem, but it's (unsurprisingly) not O(n) and
* more significantly, it doesn't yet handle dashes.
*
* The only reason we're doing split algortihms here is to
* minimize the impact of fixing the splines-aren't-dashed bug for
* 1.0.2. Long-term the right answer is to rewrite the whole pile
* of stroking code so that the entire result is computed as a
* single polygon that is tessellated, (that is, stroking can be
* built on top of filling). That will solve the self-intersecting
* problem. It will also increase the importance of implementing
* an efficient and more robust tessellator.
*/
static cairo_status_t
_cairo_stroker_curve_to_dashed (void *closure,
cairo_point_t *b,
cairo_point_t *c,
cairo_point_t *d)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_stroker_t *stroker = closure;
cairo_gstate_t *gstate = stroker->gstate;
cairo_spline_t spline;
cairo_point_t *a = &stroker->current_point;
cairo_line_join_t line_join_save;
int i;
status = _cairo_spline_init (&spline, a, b, c, d);
if (status == CAIRO_INT_STATUS_DEGENERATE)
return CAIRO_STATUS_SUCCESS;
/* If the line width is so small that the pen is reduced to a
single point, then we have nothing to do. */
if (gstate->pen_regular.num_vertices <= 1)
goto CLEANUP_SPLINE;
/* Temporarily modify the gstate to use round joins to guarantee
* smooth stroked curves. */
line_join_save = gstate->line_join;
gstate->line_join = CAIRO_LINE_JOIN_ROUND;
status = _cairo_spline_decompose (&spline, gstate->tolerance);
if (status)
goto CLEANUP_GSTATE;
for (i = 1; i < spline.num_points; i++) {
if (stroker->dashed)
status = _cairo_stroker_line_to_dashed (stroker, &spline.points[i]);
else
status = _cairo_stroker_line_to (stroker, &spline.points[i]);
if (status)
break;
}
CLEANUP_GSTATE:
gstate->line_join = line_join_save;
CLEANUP_SPLINE:
_cairo_spline_fini (&spline);
return status;
}
static cairo_status_t
_cairo_stroker_close_path (void *closure)
{
@ -844,7 +918,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
CAIRO_DIRECTION_FORWARD,
_cairo_stroker_move_to,
_cairo_stroker_line_to_dashed,
_cairo_stroker_curve_to,
_cairo_stroker_curve_to_dashed,
_cairo_stroker_close_path,
&stroker);
else