mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 04:08:13 +02:00
[clip] Use the rectangular tessellator to extract boxes
This commit is contained in:
parent
ab035ab2c7
commit
33ef32af4e
3 changed files with 38 additions and 20 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, ®ion);
|
||||
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, ®ion);
|
||||
|
||||
_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) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue