[clip] Use the rectangular tessellator to extract boxes

This commit is contained in:
Chris Wilson 2009-08-16 12:46:20 +01:00
parent ab035ab2c7
commit 33ef32af4e
3 changed files with 38 additions and 20 deletions

View file

@ -737,6 +737,7 @@ _region_clip_to_boxes (const cairo_region_t *region,
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, *boxes, *num_boxes);
traps.is_rectilinear = TRUE;
traps.is_rectangular = TRUE;
num_rects = cairo_region_num_rectangles (region);
for (n = 0; n < num_rects; n++) {
@ -1459,17 +1460,19 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
} else {
cairo_rectangle_int_t extents;
n_rects = 1;
rectangles = malloc(sizeof (cairo_rectangle_t));
if (unlikely (rectangles == NULL)) {
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
&extents))
{
/* unbounded surface -> unclipped */
goto DONE;
}
if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
&extents) ||
! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles))
{
n_rects = 1;
rectangles = malloc(sizeof (cairo_rectangle_t));
if (unlikely (rectangles == NULL))
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
free (rectangles);
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
}

View file

@ -176,6 +176,20 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
cairo_status_t status;
cairo_region_t *region;
/* first try to bypass fill-to-polygon */
_cairo_traps_init (&traps);
status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
fill_rule,
&traps);
if (_cairo_status_is_error (status))
goto CLEANUP_TRAPS;
if (status == CAIRO_STATUS_SUCCESS) {
status = _cairo_traps_extract_region (&traps, &region);
goto CLEANUP_TRAPS;
}
/* path is not rectangular, try extracting clipped rectilinear edges */
_cairo_polygon_init (&polygon);
if (extents != NULL) {
_cairo_box_from_rectangle (&box, extents);
@ -190,20 +204,20 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
if (polygon.num_edges == 0) {
region = cairo_region_create ();
} else {
_cairo_traps_init (&traps);
status = _cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps,
&polygon,
fill_rule);
status =
_cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps,
&polygon,
fill_rule);
if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_traps_extract_region (&traps, &region);
_cairo_traps_fini (&traps);
}
CLEANUP_POLYGON:
_cairo_polygon_fini (&polygon);
CLEANUP_TRAPS:
_cairo_traps_fini (&traps);
if (unlikely (status)) { /* XXX _cairo_region_create_in_error() */
region = cairo_region_create ();
if (likely (region->status) == CAIRO_STATUS_SUCCESS)
@ -230,6 +244,7 @@ _cairo_path_fixed_fill_rectilinear_to_region (const cairo_path_fixed_t *path,
cairo_region_t *region = NULL;
assert (path->maybe_fill_region);
assert (! path->is_empty_fill);
if (_cairo_path_fixed_is_box (path, &box)) {
if (box.p1.x > box.p2.x) {

View file

@ -917,7 +917,7 @@ _clip_to_boxes (cairo_clip_t **clip,
if (*clip == NULL) {
status = CAIRO_STATUS_SUCCESS;
goto OUT;
goto EXTENTS;
}
/* In some cases it may be preferable to always use boxes instead
@ -927,7 +927,7 @@ _clip_to_boxes (cairo_clip_t **clip,
*/
status = _cairo_clip_get_region (*clip, NULL);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto OUT;
goto EXTENTS;
status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
switch ((int) status) {
@ -937,10 +937,10 @@ _clip_to_boxes (cairo_clip_t **clip,
case CAIRO_INT_STATUS_UNSUPPORTED:
status = CAIRO_STATUS_SUCCESS;
goto OUT;
goto EXTENTS;
}
OUT:
EXTENTS:
_cairo_box_from_rectangle (&(*boxes)[0], extents);
*num_boxes = 1;
DONE: