summaryrefslogtreecommitdiff
path: root/src/cairo-path-stroke-boxes.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-29 15:49:40 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-04-29 15:55:16 +0100
commita1d4f416e403359b713f6d10d557a190458bbb16 (patch)
tree885d8aaa7ac7e0a08973b105fec207942321dc5e /src/cairo-path-stroke-boxes.c
parent71df65f95a238c53fa0a64759b41af85c0b1b059 (diff)
downloadcairo-a1d4f416e403359b713f6d10d557a190458bbb16.tar.gz
path-stroke-boxes: Fix degenerate end-caps for anti-clockwise paths
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-path-stroke-boxes.c')
-rw-r--r--src/cairo-path-stroke-boxes.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/src/cairo-path-stroke-boxes.c b/src/cairo-path-stroke-boxes.c
index 9b194b269..50c53f37e 100644
--- a/src/cairo-path-stroke-boxes.c
+++ b/src/cairo-path-stroke-boxes.c
@@ -48,8 +48,10 @@
typedef struct _segment_t {
cairo_point_t p1, p2;
- cairo_bool_t is_horizontal;
- cairo_bool_t has_join;
+ unsigned flags;
+#define HORIZONTAL 0x1
+#define FORWARDS 0x2
+#define JOIN 0x4
} segment_t;
typedef struct _cairo_rectilinear_stroker {
@@ -159,8 +161,7 @@ static cairo_status_t
_cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
const cairo_point_t *p1,
const cairo_point_t *p2,
- cairo_bool_t is_horizontal,
- cairo_bool_t has_join)
+ unsigned flags)
{
if (CAIRO_INJECT_FAULT ())
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -189,8 +190,7 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
stroker->segments[stroker->num_segments].p1 = *p1;
stroker->segments[stroker->num_segments].p2 = *p2;
- stroker->segments[stroker->num_segments].has_join = has_join;
- stroker->segments[stroker->num_segments].is_horizontal = is_horizontal;
+ stroker->segments[stroker->num_segments].flags = flags;
stroker->num_segments++;
return CAIRO_STATUS_SUCCESS;
@@ -317,44 +317,42 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
a = &stroker->segments[i].p1;
b = &stroker->segments[i].p2;
- is_horizontal = stroker->segments[i].is_horizontal;
+ is_horizontal = stroker->segments[i].flags & HORIZONTAL;
/* Handle the joins for a potentially degenerate segment. */
if (line_cap == CAIRO_LINE_CAP_BUTT &&
- stroker->segments[i].has_join &&
+ stroker->segments[i].flags & JOIN &&
(i != stroker->num_segments - 1 ||
(! stroker->open_sub_path && stroker->dash.dash_starts_on)))
{
cairo_slope_t out_slope;
int j = (i + 1) % stroker->num_segments;
+ cairo_bool_t forwards = !!(stroker->segments[i].flags & FORWARDS);
- box.p1 = stroker->segments[i].p1;
- box.p2 = stroker->segments[i].p2;
_cairo_slope_init (&out_slope,
&stroker->segments[j].p1,
&stroker->segments[j].p2);
+ box.p2 = box.p1 = stroker->segments[i].p2;
if (is_horizontal) {
- if (box.p1.x <= box.p2.x) {
- box.p1.x = box.p2.x;
+ if (forwards)
box.p2.x += half_line_x;
- } else {
- box.p1.x = box.p2.x - half_line_x;
- }
- if (out_slope.dy >= 0)
+ else
+ box.p1.x -= half_line_x;
+
+ if (out_slope.dy > 0)
box.p1.y -= half_line_y;
- if (out_slope.dy <= 0)
+ else
box.p2.y += half_line_y;
} else {
- if (box.p1.y <= box.p2.y) {
- box.p1.y = box.p2.y;
+ if (forwards)
box.p2.y += half_line_y;
- } else {
- box.p1.y = box.p2.y - half_line_y;
- }
- if (out_slope.dx >= 0)
+ else
+ box.p1.y -= half_line_y;
+
+ if (out_slope.dx > 0)
box.p1.x -= half_line_x;
- if (out_slope.dx <= 0)
+ else
box.p2.x += half_line_x;
}
@@ -459,8 +457,7 @@ _cairo_rectilinear_stroker_line_to (void *closure,
return CAIRO_STATUS_SUCCESS;
status = _cairo_rectilinear_stroker_add_segment (stroker, a, b,
- a->y == b->y,
- TRUE);
+ (a->y == b->y) | JOIN);
stroker->current_point = *b;
stroker->open_sub_path = TRUE;
@@ -481,7 +478,7 @@ _cairo_rectilinear_stroker_line_to_dashed (void *closure,
cairo_status_t status;
cairo_line_t segment;
cairo_bool_t dash_on = FALSE;
- cairo_bool_t is_horizontal;
+ unsigned is_horizontal;
/* We don't draw anything for degenerate paths. */
if (a->x == b->x && a->y == b->y)
@@ -511,6 +508,7 @@ _cairo_rectilinear_stroker_line_to_dashed (void *closure,
sign = 1.;
} else {
remain = _cairo_fixed_to_double (mag);
+ is_horizontal |= FORWARDS;
sign = -1.;
}
@@ -522,7 +520,7 @@ _cairo_rectilinear_stroker_line_to_dashed (void *closure,
remain -= step_length;
mag = _cairo_fixed_from_double (sign*remain);
- if (is_horizontal)
+ if (is_horizontal & 0x1)
segment.p2.x = b->x + mag;
else
segment.p2.y = b->y + mag;
@@ -534,8 +532,7 @@ _cairo_rectilinear_stroker_line_to_dashed (void *closure,
status = _cairo_rectilinear_stroker_add_segment (stroker,
&segment.p1,
&segment.p2,
- is_horizontal,
- remain <= 0.);
+ is_horizontal | (remain <= 0.) << 2);
if (unlikely (status))
return status;
@@ -562,8 +559,7 @@ _cairo_rectilinear_stroker_line_to_dashed (void *closure,
status = _cairo_rectilinear_stroker_add_segment (stroker,
&segment.p1,
&segment.p1,
- is_horizontal,
- TRUE);
+ is_horizontal | JOIN);
if (unlikely (status))
return status;
}