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:
Carl Worth 2006-10-25 10:32:37 -07:00
parent 804e5b58cd
commit 7e9aad2289
2 changed files with 43 additions and 19 deletions

View file

@ -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;

View file

@ -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,