mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 02:38:07 +02:00
clip: Apply clip boxes to the clip surface
As we convert the unaligned clip boxes to a region, we need to process the intersection of the boxes with the clip surface as a separate step. Fixes tighten-box for the base compositor. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
4ea3ace6c8
commit
6cd1f5040f
3 changed files with 77 additions and 9 deletions
|
|
@ -91,6 +91,33 @@ _cairo_clip_combine_with_surface (const cairo_clip_t *clip,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
|
||||||
|
const cairo_box_t *box,
|
||||||
|
cairo_fixed_t fx,
|
||||||
|
cairo_fixed_t fy)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_move_to (path, box->p1.x + fx, box->p1.y + fy);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p1.y + fy);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p2.y + fy);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_line_to (path, box->p1.x + fx, box->p2.y + fy);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return _cairo_path_fixed_close_path (path);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_clip_get_surface (const cairo_clip_t *clip,
|
_cairo_clip_get_surface (const cairo_clip_t *clip,
|
||||||
cairo_surface_t *target,
|
cairo_surface_t *target,
|
||||||
|
|
@ -98,16 +125,51 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_clip_t *copy;
|
cairo_clip_t *copy, *region;
|
||||||
cairo_clip_path_t *copy_path, *clip_path;
|
cairo_clip_path_t *copy_path, *clip_path;
|
||||||
|
|
||||||
surface = _cairo_surface_create_similar_solid (target,
|
if (clip->num_boxes) {
|
||||||
CAIRO_CONTENT_ALPHA,
|
cairo_path_fixed_t path;
|
||||||
clip->extents.width,
|
int i;
|
||||||
clip->extents.height,
|
|
||||||
CAIRO_COLOR_WHITE);
|
surface = _cairo_surface_create_similar_solid (target,
|
||||||
if (unlikely (surface->status))
|
CAIRO_CONTENT_ALPHA,
|
||||||
return surface;
|
clip->extents.width,
|
||||||
|
clip->extents.height,
|
||||||
|
CAIRO_COLOR_TRANSPARENT);
|
||||||
|
if (unlikely (surface->status))
|
||||||
|
return surface;
|
||||||
|
|
||||||
|
_cairo_path_fixed_init (&path);
|
||||||
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
|
for (i = 0; status == CAIRO_STATUS_SUCCESS && i < clip->num_boxes; i++) {
|
||||||
|
status = _cairo_path_fixed_add_box (&path, &clip->boxes[i],
|
||||||
|
-_cairo_fixed_from_int (clip->extents.x),
|
||||||
|
-_cairo_fixed_from_int (clip->extents.y));
|
||||||
|
}
|
||||||
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
|
status = _cairo_surface_fill (surface,
|
||||||
|
CAIRO_OPERATOR_ADD,
|
||||||
|
&_cairo_pattern_white.base,
|
||||||
|
&path,
|
||||||
|
CAIRO_FILL_RULE_WINDING,
|
||||||
|
1.,
|
||||||
|
CAIRO_ANTIALIAS_DEFAULT,
|
||||||
|
NULL);
|
||||||
|
_cairo_path_fixed_fini (&path);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
return _cairo_surface_create_in_error (status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
surface = _cairo_surface_create_similar_solid (target,
|
||||||
|
CAIRO_CONTENT_ALPHA,
|
||||||
|
clip->extents.width,
|
||||||
|
clip->extents.height,
|
||||||
|
CAIRO_COLOR_WHITE);
|
||||||
|
if (unlikely (surface->status))
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
copy = _cairo_clip_copy_with_translation (clip,
|
copy = _cairo_clip_copy_with_translation (clip,
|
||||||
-clip->extents.x,
|
-clip->extents.x,
|
||||||
|
|
@ -115,6 +177,10 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
|
||||||
copy_path = copy->path;
|
copy_path = copy->path;
|
||||||
copy->path = NULL;
|
copy->path = NULL;
|
||||||
|
|
||||||
|
region = copy;
|
||||||
|
if (! _cairo_clip_is_region (copy))
|
||||||
|
region = _cairo_clip_copy_region (copy);
|
||||||
|
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
clip_path = copy_path;
|
clip_path = copy_path;
|
||||||
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
|
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
|
||||||
|
|
@ -125,12 +191,14 @@ _cairo_clip_get_surface (const cairo_clip_t *clip,
|
||||||
clip_path->fill_rule,
|
clip_path->fill_rule,
|
||||||
clip_path->tolerance,
|
clip_path->tolerance,
|
||||||
clip_path->antialias,
|
clip_path->antialias,
|
||||||
copy);
|
region);
|
||||||
clip_path = clip_path->prev;
|
clip_path = clip_path->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy->path = copy_path;
|
copy->path = copy_path;
|
||||||
_cairo_clip_destroy (copy);
|
_cairo_clip_destroy (copy);
|
||||||
|
if (region != copy)
|
||||||
|
_cairo_clip_destroy (region);
|
||||||
|
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Loading…
Add table
Reference in a new issue