[cairo-commit] src/cairo-path-stroke-boxes.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Aug 20 06:26:53 PDT 2012
src/cairo-path-stroke-boxes.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
New commits:
commit ee7f5607192a3341df45199b1c7c8996f2b7347d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Aug 20 14:21:23 2012 +0100
stroker: Avoid emitting a miter join for across an elided degenerate segment
Given the criteria of the rectlinear stroker that it only handles
horizontal and vertical line segments, and eliminates degenerate
segments before stroking, we must be careful not to apply a join between
two horizontal segments (for example if the intervening vertical segment
was degenerate and so elided). A miter join between two colinear
segments is empty, yet we were blissfully extending the line caps to
cover the join.
Fixes: outline-tolerance
Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=407107
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-path-stroke-boxes.c b/src/cairo-path-stroke-boxes.c
index 50c53f3..7f25bf7 100644
--- a/src/cairo-path-stroke-boxes.c
+++ b/src/cairo-path-stroke-boxes.c
@@ -203,7 +203,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
cairo_fixed_t half_line_x = stroker->half_line_x;
cairo_fixed_t half_line_y = stroker->half_line_y;
cairo_status_t status;
- int i;
+ int i, j;
/* For each segment we generate a single rectangle.
* This rectangle is based on a perpendicular extension (by half the
@@ -221,20 +221,24 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
/* We adjust the initial point of the segment to extend the
* rectangle to include the previous cap or join, (this
* adjustment applies to all segments except for the first
- * segment of open, butt-capped paths).
+ * segment of open, butt-capped paths). However, we must be
+ * careful not to emit a miter join across a degenerate segment
+ * which has been elided.
*
* Overlapping segments will be eliminated by the tessellation.
* Ideally, we would not emit these self-intersections at all,
* but that is tricky with segments shorter than half_line_width.
*/
- lengthen_initial = TRUE;
- lengthen_final = TRUE;
- if (stroker->open_sub_path && line_cap == CAIRO_LINE_CAP_BUTT) {
+ j = i == 0 ? stroker->num_segments - 1 : i-1;
+ lengthen_initial = (stroker->segments[i].flags ^ stroker->segments[j].flags) & HORIZONTAL;
+ j = i == stroker->num_segments - 1 ? 0 : i+1;
+ lengthen_final = (stroker->segments[i].flags ^ stroker->segments[j].flags) & HORIZONTAL;
+ if (stroker->open_sub_path) {
if (i == 0)
- lengthen_initial = FALSE;
+ lengthen_initial = line_cap != CAIRO_LINE_CAP_BUTT;
if (i == stroker->num_segments - 1)
- lengthen_final = FALSE;
+ lengthen_final = line_cap != CAIRO_LINE_CAP_BUTT;
}
/* Perform the adjustments of the endpoints. */
More information about the cairo-commit
mailing list