summaryrefslogtreecommitdiff
path: root/src/cairo-traps.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-08-28 10:06:04 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-08-29 08:08:38 +0100
commitab035ab2c7bec254fc94d6391398905b5039e777 (patch)
tree49312efc13ca5778e7c09c1e17de987b74ca89c1 /src/cairo-traps.c
parentd7b0c3b784faba756b10b66b9757e6e4c3fce38c (diff)
downloadcairo-ab035ab2c7bec254fc94d6391398905b5039e777.tar.gz
[tessellate] Rectangular special case
Add an even simpler sweep-line tessellator for rectangular trapezoids (as produced by the rectilinear stoker and box filler). This is so simple it even outperforms pixman's region validation code for the purposes of path-to-region conversion.
Diffstat (limited to 'src/cairo-traps.c')
-rw-r--r--src/cairo-traps.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index d5b41e5d4..d6fec2602 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -53,6 +53,7 @@ _cairo_traps_init (cairo_traps_t *traps)
traps->maybe_region = 1;
traps->is_rectilinear = 0;
+ traps->is_rectangular = 0;
traps->num_traps = 0;
@@ -79,6 +80,7 @@ _cairo_traps_clear (cairo_traps_t *traps)
traps->maybe_region = 1;
traps->is_rectilinear = 0;
+ traps->is_rectangular = 0;
traps->num_traps = 0;
traps->has_intersections = FALSE;
@@ -170,6 +172,7 @@ _cairo_traps_init_boxes (cairo_traps_t *traps,
traps->num_traps = num_boxes;
traps->is_rectilinear = TRUE;
+ traps->is_rectangular = TRUE;
trap = &traps->traps[0];
while (num_boxes--) {
@@ -206,6 +209,12 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
cairo_line_t right;
cairo_fixed_t top, bottom;
+ if (top_left->y == bottom_right->y)
+ return CAIRO_STATUS_SUCCESS;
+
+ if (top_left->x == bottom_right->x)
+ return CAIRO_STATUS_SUCCESS;
+
left.p1.x = left.p2.x = top_left->x;
left.p1.y = right.p1.y = top_left->y;
right.p1.x = right.p2.x = bottom_right->x;
@@ -214,15 +223,17 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
top = top_left->y;
bottom = bottom_right->y;
- if (top == bottom)
- return CAIRO_STATUS_SUCCESS;
-
- if (left.p1.x == right.p1.x)
- return CAIRO_STATUS_SUCCESS;
-
if (traps->num_limits) {
+ cairo_bool_t reversed;
int n;
+ /* support counter-clockwise winding for rectangular tessellation */
+ reversed = top_left->x > bottom_right->x;
+ if (reversed) {
+ right.p1.x = right.p2.x = top_left->x;
+ left.p1.x = left.p2.x = bottom_right->x;
+ }
+
for (n = 0; n < traps->num_limits; n++) {
const cairo_box_t *limits = &traps->limits[n];
cairo_line_t _left, _right;
@@ -275,7 +286,10 @@ _cairo_traps_tessellate_rectangle (cairo_traps_t *traps,
if (left.p1.x >= right.p1.x)
continue;
- _cairo_traps_add_trap (traps, _top, _bottom, &_left, &_right);
+ if (reversed)
+ _cairo_traps_add_trap (traps, _top, _bottom, &_right, &_left);
+ else
+ _cairo_traps_add_trap (traps, _top, _bottom, &_left, &_right);
}
} else {
_cairo_traps_add_trap (traps, top, bottom, &left, &right);