summaryrefslogtreecommitdiff
path: root/src/cairo-clip.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-clip.c
parentd7b0c3b784faba756b10b66b9757e6e4c3fce38c (diff)
[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-clip.c')
-rw-r--r--src/cairo-clip.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 8d68e47e..cd6cfec1 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -755,7 +755,7 @@ _region_clip_to_boxes (const cairo_region_t *region,
goto CLEANUP;
}
- status = _cairo_bentley_ottmann_tessellate_rectilinear_traps (&traps, CAIRO_FILL_RULE_WINDING);
+ status = _cairo_bentley_ottmann_tessellate_rectangular_traps (&traps, CAIRO_FILL_RULE_WINDING);
if (unlikely (status))
goto CLEANUP;
@@ -804,25 +804,35 @@ _rectilinear_clip_to_boxes (const cairo_path_fixed_t *path,
cairo_traps_t traps;
cairo_status_t status;
+ _cairo_traps_init (&traps);
+ _cairo_traps_limit (&traps, *boxes, *num_boxes);
+
_cairo_polygon_init (&polygon);
_cairo_polygon_limit (&polygon, *boxes, *num_boxes);
+ status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
+ fill_rule,
+ &traps);
+ if (unlikely (_cairo_status_is_error (status)))
+ goto CLEANUP;
+ if (status == CAIRO_STATUS_SUCCESS)
+ goto BOXES;
+
/* tolerance will be ignored as the path is rectilinear */
status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon);
if (unlikely (status))
- goto CLEANUP_POLYGON;
+ goto CLEANUP;
if (polygon.num_edges == 0) {
*num_boxes = 0;
} else {
- _cairo_traps_init (&traps);
-
status = _cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps,
&polygon,
fill_rule);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
int i;
+ BOXES:
i = *size_boxes;
if (i < 0)
i = -i;
@@ -835,7 +845,7 @@ _rectilinear_clip_to_boxes (const cairo_path_fixed_t *path,
new_boxes = _cairo_malloc_ab (new_size, sizeof (cairo_box_t));
if (unlikely (new_boxes == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto CLEANUP_TRAPS;
+ goto CLEANUP;
}
if (*size_boxes > 0)
@@ -853,13 +863,11 @@ _rectilinear_clip_to_boxes (const cairo_path_fixed_t *path,
}
*num_boxes = i;
}
-
- CLEANUP_TRAPS:
- _cairo_traps_fini (&traps);
}
- CLEANUP_POLYGON:
+ CLEANUP:
_cairo_polygon_fini (&polygon);
+ _cairo_traps_fini (&traps);
return status;
}