[PATCH 2/2] stroke: Use round-joins near inflection points of splines

Martin Robinson <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Similar to b7bd5ae4f3da44131261711bb236cd7aa24a3ae3, but applied to the
fallback stroke shaper.
---
 src/cairo-path-stroke.c |   36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 7d99f7f..180fce7 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -54,6 +54,7 @@ typedef struct cairo_stroker {
     const cairo_matrix_t *ctm_inverse;
     double half_line_width;
     double tolerance;
+    double spline_cusp_tolerance;
     double ctm_determinant;
     cairo_bool_t ctm_det_positive;
 
@@ -137,6 +138,18 @@ _cairo_stroker_init (cairo_stroker_t		*stroker,
     stroker->tolerance = tolerance;
     stroker->half_line_width = stroke_style->line_width / 2.0;
 
+    /* To test whether we need to join two segments of a spline using
+     * a round-join or a bevel-join, we can inspect the angle between the
+     * two segments. If the difference between the chord distance
+     * (half-line-width times the cosine of the bisection angle) and the
+     * half-line-width itself is greater than tolerance then we need to
+     * inject a point.
+     */
+    stroker->spline_cusp_tolerance = 1 - tolerance / stroker->half_line_width;
+    stroker->spline_cusp_tolerance *= stroker->spline_cusp_tolerance;
+    stroker->spline_cusp_tolerance *= 2;
+    stroker->spline_cusp_tolerance -= 1;
+
     stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm);
     stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0;
 
@@ -1012,6 +1025,29 @@ _cairo_stroker_spline_to (void *closure,
 
     assert (stroker->has_current_face);
 
+    if ((new_face.dev_slope.x * stroker->current_face.dev_slope.x +
+         new_face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance) {
+
+	const cairo_point_t *inpt, *outpt;
+	int clockwise = _cairo_stroker_join_is_clockwise (&new_face,
+							  &stroker->current_face);
+
+	if (clockwise) {
+	    inpt = &stroker->current_face.cw;
+	    outpt = &new_face.cw;
+	} else {
+	    inpt = &stroker->current_face.ccw;
+	    outpt = &new_face.ccw;
+	}
+
+	_tessellate_fan (stroker,
+			 &stroker->current_face.dev_vector,
+			 &new_face.dev_vector,
+			 &stroker->current_face.point,
+			 inpt, outpt,
+			 clockwise);
+    }
+
     if (_slow_segment_intersection (&stroker->current_face.cw,
 				    &stroker->current_face.ccw,
 				    &new_face.cw,
-- 
1.7.10.4

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.