[cairo-commit] cairo/src cairo-path-stroke.c,1.25,1.26

Carl Worth commit at pdx.freedesktop.org
Fri Sep 16 10:24:56 PDT 2005


Committed by: cworth

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv28326/src

Modified Files:
	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.26
diff -u -d -r1.25 -r1.26
--- cairo-path-stroke.c	23 Aug 2005 14:44:14 -0000	1.25
+++ cairo-path-stroke.c	16 Sep 2005 17:24:54 -0000	1.26
@@ -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