mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-06 09:18:11 +02:00
Fix repeating source surface patterns with xlib backend.
This broke with the clone_similar optimization in
8d7a02ed58 The optimization added an
interest rectangle to clone_similar, but with a repeating source
pattern, the interest rectangle might not intersect the extents of the
surface at all.
The test suite caught this with the trap-clip case.
The fix here is to clone the entire surface if the pattern has an
extend mode of REPEAT.
This commit is contained in:
parent
804e5b58cd
commit
7e9aad2289
2 changed files with 43 additions and 19 deletions
|
|
@ -1159,29 +1159,43 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Before we can clone, we must transform the rectangle to the
|
||||
* coordinate space of the source surface. */
|
||||
if (! _cairo_matrix_is_identity (&attr->matrix)) {
|
||||
double src_x = x;
|
||||
double src_y = y;
|
||||
double src_width = width;
|
||||
double src_height = height;
|
||||
double x2, y2;
|
||||
cairo_bool_t is_tight;
|
||||
/* If we're repeating, we just play it safe and clone the entire surface. */
|
||||
if (attr->extend == CAIRO_EXTEND_REPEAT) {
|
||||
cairo_rectangle_int16_t extents;
|
||||
status = _cairo_surface_get_extents (pattern->surface, &extents);
|
||||
x = extents.x;
|
||||
y = extents.y;
|
||||
width = extents.width;
|
||||
height = extents.height;
|
||||
} else {
|
||||
/* Otherwise, we first transform the rectangle to the
|
||||
* coordinate space of the source surface so that we can
|
||||
* clone only that portion of the surface that will be
|
||||
* read. */
|
||||
if (! _cairo_matrix_is_identity (&attr->matrix)) {
|
||||
double src_x = x;
|
||||
double src_y = y;
|
||||
double src_width = width;
|
||||
double src_height = height;
|
||||
double x2, y2;
|
||||
cairo_bool_t is_tight;
|
||||
|
||||
_cairo_matrix_transform_bounding_box (&attr->matrix, &src_x, &src_y,
|
||||
&src_width, &src_height,
|
||||
&is_tight);
|
||||
x2 = src_x + src_width;
|
||||
y2 = src_y + src_height;
|
||||
x = floor (src_x);
|
||||
y = floor (src_y);
|
||||
width = ceil (x2) - x;
|
||||
height = ceil (y2) - y;
|
||||
_cairo_matrix_transform_bounding_box (&attr->matrix, &src_x, &src_y,
|
||||
&src_width, &src_height,
|
||||
&is_tight);
|
||||
x2 = src_x + src_width;
|
||||
y2 = src_y + src_height;
|
||||
x = floor (src_x);
|
||||
y = floor (src_y);
|
||||
width = ceil (x2) - x;
|
||||
height = ceil (y2) - y;
|
||||
}
|
||||
x += tx;
|
||||
y += ty;
|
||||
}
|
||||
|
||||
status = _cairo_surface_clone_similar (dst, pattern->surface,
|
||||
x+tx, y+ty, width, height, out);
|
||||
x, y, width, height, out);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -720,6 +720,16 @@ struct _cairo_surface_backend {
|
|||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra);
|
||||
|
||||
/* Create a new surface (@clone_out) with the following
|
||||
* characteristics:
|
||||
*
|
||||
* 1. It is as compatible as possible with @surface (in terms of
|
||||
* efficiency)
|
||||
*
|
||||
* 2. It has the same size as @src
|
||||
*
|
||||
* 3. It has the same contents as @src within the given rectangle.
|
||||
*/
|
||||
cairo_status_t
|
||||
(*clone_similar) (void *surface,
|
||||
cairo_surface_t *src,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue