[cairo-commit] cairo/src cairo-path-stroke.c,1.25,1.25.2.1
Carl Worth
commit at pdx.freedesktop.org
Fri Sep 16 10:25:42 PDT 2005
Committed by: cworth
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv28600/src
Modified Files:
Tag: BRANCH_1_0
cairo-path-stroke.c
Log Message:
2005-09-16 Carl Worth <cworth at 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).
Index: cairo-path-stroke.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-path-stroke.c,v
retrieving revision 1.25
retrieving revision 1.25.2.1
diff -u -d -r1.25 -r1.25.2.1
--- cairo-path-stroke.c 23 Aug 2005 14:44:14 -0000 1.25
+++ cairo-path-stroke.c 16 Sep 2005 17:25:40 -0000 1.25.2.1
@@ -81,6 +81,12 @@
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);
static void
@@ -801,6 +807,74 @@
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_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
More information about the cairo-commit
mailing list