summaryrefslogtreecommitdiff
path: root/src/cairo-xcb-surface.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-09-27 00:18:07 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-09-27 02:20:42 +0100
commit5b97ee65259cafb335c1a2c53f1a55dfcb175e20 (patch)
tree0e5fe01b793350974ea16b39ee2f543b8c28c3a6 /src/cairo-xcb-surface.c
parent7f3a48f90b409653a2d4fb802779ecb7508e4d6e (diff)
Allow cloning sub-regions of similar surfaces.
Previously the rule for clone_similar() was that the returned surface had exactly the same size as the original, but only the contents within the region of interest needed to be copied. This caused failures for very large images in the xlib-backend (see test/large-source). The obvious solution to allow cloning only the region of interest seemed to be to simply set the device offset on the cloned surface. However, this fails as a) nothing respects the device offset on the surface at that layer in the compositing stack and b) possibly returning references to the original source surface provides further confusion by mixing in another source of device offset. The second method was to add extra out parameters so that the device offset could be returned separately and, for example, mixed into the pattern matrix. Not as elegant, a couple of extra warts to the interface, but it works - one less XFAIL...
Diffstat (limited to 'src/cairo-xcb-surface.c')
-rw-r--r--src/cairo-xcb-surface.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 7251824b..7aa80bdd 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -695,6 +695,8 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
int src_y,
int width,
int height,
+ int *device_offset_x,
+ int *device_offset_y,
cairo_surface_t **clone_out)
{
cairo_xcb_surface_t *surface = abstract_surface;
@@ -704,6 +706,8 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
cairo_xcb_surface_t *xcb_src = (cairo_xcb_surface_t *)src;
if (_cairo_xcb_surface_same_screen(surface, xcb_src)) {
+ *device_offset_x = 0;
+ *device_offset_y = 0;
*clone_out = cairo_surface_reference (src);
return CAIRO_STATUS_SUCCESS;
@@ -716,14 +720,20 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
return surface->base.status;
clone = (cairo_xcb_surface_t *)
- _cairo_xcb_surface_create_similar (surface, content,
- image_src->width, image_src->height);
+ _cairo_xcb_surface_create_similar (surface, content, width, height);
if (clone->base.status)
return clone->base.status;
- _draw_image_surface (clone, image_src, src_x, src_y,
- width, height, src_x, src_y);
+ status = _draw_image_surface (clone, image_src,
+ src_x, src_y,
+ width, height, x, y);
+ if (status) {
+ cairo_surface_destroy (&clone->base);
+ return status;
+ }
+ *device_offset_x = src_x;
+ *device_offset_y = src_y;
*clone_out = &clone->base;
return CAIRO_STATUS_SUCCESS;