[cairo-commit] src/cairoint.h src/cairo-pattern.c
Carl Worth
cworth at kemper.freedesktop.org
Wed Oct 25 10:40:49 PDT 2006
src/cairo-pattern.c | 54 ++++++++++++++++++++++++++++++++--------------------
src/cairoint.h | 10 +++++++++
2 files changed, 44 insertions(+), 20 deletions(-)
New commits:
diff-tree 7e9aad228971a81783e09edfef58c5165a3c932e (from 804e5b58cd3a4032bfa1d0c8cccac92a70c3c635)
Author: Carl Worth <cworth at cworth.org>
Date: Wed Oct 25 10:32:37 2006 -0700
Fix repeating source surface patterns with xlib backend.
This broke with the clone_similar optimization in
8d7a02ed58e06584eb09575e6ca11d0a81094ab6 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.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 08f2321..9589b34 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1159,29 +1159,43 @@ _cairo_pattern_acquire_surface_for_surfa
}
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;
-
- _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;
+ /* 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;
+ }
+ 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;
diff --git a/src/cairoint.h b/src/cairoint.h
index 2c5856d..06fc8d4 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -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,
More information about the cairo-commit
mailing list