diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-08-28 10:06:04 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-08-29 08:08:38 +0100 |
commit | ab035ab2c7bec254fc94d6391398905b5039e777 (patch) | |
tree | 49312efc13ca5778e7c09c1e17de987b74ca89c1 /src/cairo-clip.c | |
parent | d7b0c3b784faba756b10b66b9757e6e4c3fce38c (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.c | 26 |
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; } |