diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-27 00:18:07 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-27 02:20:42 +0100 |
commit | 5b97ee65259cafb335c1a2c53f1a55dfcb175e20 (patch) | |
tree | 0e5fe01b793350974ea16b39ee2f543b8c28c3a6 /src/cairo-xcb-surface.c | |
parent | 7f3a48f90b409653a2d4fb802779ecb7508e4d6e (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.c | 18 |
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; |