diff options
author | Vladimir Vukicevic <vladimir@pobox.com> | 2007-08-28 16:47:24 -0700 |
---|---|---|
committer | Vladimir Vukicevic <vladimir@feisty.(none)> | 2007-08-28 16:47:24 -0700 |
commit | 93aee43690c329f43be9e7b840851267ceb17956 (patch) | |
tree | 9a138f2cdb055d33d0eb2a3c274becf34bf4c198 /src | |
parent | 6525d4debb6df67126b04609bb04d23d9c9bd7a6 (diff) | |
download | cairo-93aee43690c329f43be9e7b840851267ceb17956.tar.gz |
Fix previous create_similar fallback patch
We can't use composite, as some backends don't implement it.
Use paint() instead.
Diffstat (limited to 'src')
-rw-r--r-- | src/cairo-pattern.c | 32 | ||||
-rw-r--r-- | src/cairo-surface-fallback.c | 28 | ||||
-rw-r--r-- | src/cairo-surface.c | 55 |
3 files changed, 45 insertions, 70 deletions
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index abda3688e..b75040b45 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1677,38 +1677,6 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, status = _cairo_surface_clone_similar (dst, pattern->surface, x, y, width, height, out); - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - - cairo_t *cr; - - *out = cairo_surface_create_similar (dst, dst->content, - width, height); - status = cairo_surface_status (*out); - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - return status; - } - - (*out)->device_transform = pattern->surface->device_transform; - (*out)->device_transform_inverse = pattern->surface->device_transform_inverse; - - /* XXX Use _cairo_surface_composite directly */ - cr = cairo_create (*out); - - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_surface (cr, pattern->surface, -x, -y); - cairo_paint (cr); - - status = cairo_status (cr); - cairo_destroy (cr); - - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - } - } } return status; diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 75b9f125e..ab19d2c22 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1264,8 +1264,8 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, cairo_surface_t **clone_out) { cairo_status_t status; - cairo_pattern_union_t src_pattern; cairo_surface_t *new_surface = NULL; + cairo_t *cr; new_surface = _cairo_surface_create_similar_scratch (surface, cairo_surface_get_content (src), @@ -1273,18 +1273,22 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, if (new_surface->status) return new_surface->status; - _cairo_pattern_init_for_surface (&src_pattern.surface, src); + /* We have to copy these here, so that the coordinate spaces are correct */ + new_surface->device_transform = src->device_transform; + new_surface->device_transform_inverse = src->device_transform_inverse; - status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, - &src_pattern.base, - NULL, - new_surface, - src_x, src_y, - 0, 0, - 0, 0, - width, height); - - _cairo_pattern_fini (&src_pattern.base); + /* We can't use _cairo_composite directly, because backends that + * implement the "high-level" API may not have it implemented. + * (For example, SVG.) We can fix this by either checking if the + * destination supports composite first, or we can make clone a + * required "high-level" operation. + */ + cr = cairo_create (new_surface); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_surface (cr, src, -src_x, -src_y); + cairo_paint (cr); + status = cairo_status (cr); + cairo_destroy (cr); if (status == CAIRO_STATUS_SUCCESS) *clone_out = new_surface; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index a87b776c9..b44b853ff 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1024,46 +1024,49 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, int height, cairo_surface_t **clone_out) { - cairo_status_t status; + cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; cairo_image_surface_t *image; void *image_extra; if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; - if (surface->backend->clone_similar == NULL) - return (cairo_int_status_t) - _cairo_surface_fallback_clone_similar (surface, src, - src_x, src_y, - width, height, - clone_out); + if (surface->backend->clone_similar) { + status = surface->backend->clone_similar (surface, src, src_x, src_y, + width, height, clone_out); - status = surface->backend->clone_similar (surface, src, src_x, src_y, - width, height, clone_out); - if (status == CAIRO_STATUS_SUCCESS && *clone_out != src) - (*clone_out)->device_transform = src->device_transform; + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + /* If we failed, try again with an image surface */ + status = _cairo_surface_acquire_source_image (src, &image, &image_extra); + if (status == CAIRO_STATUS_SUCCESS) { + status = + surface->backend->clone_similar (surface, &image->base, + src_x, src_y, + width, height, + clone_out); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; + _cairo_surface_release_source_image (src, image, image_extra); + } + } + } - status = _cairo_surface_acquire_source_image (src, &image, &image_extra); - if (status != CAIRO_STATUS_SUCCESS) + /* If we're still unsupported, hit our fallback path to get a clone */ + if (status == CAIRO_INT_STATUS_UNSUPPORTED) + status = + _cairo_surface_fallback_clone_similar (surface, src, src_x, src_y, + width, height, clone_out); + + /* We should never get UNSUPPORTED here, so if we have an error, bail. */ + if (status) return status; - status = surface->backend->clone_similar (surface, &image->base, src_x, - src_y, width, height, clone_out); - if (status == CAIRO_STATUS_SUCCESS && *clone_out != src) { + /* Update the clone's device_transform (which the underlying surface + * backend knows nothing about) */ + if (*clone_out != src) { (*clone_out)->device_transform = src->device_transform; (*clone_out)->device_transform_inverse = src->device_transform_inverse; - } - - /* If the above failed point, we could implement a full fallback - * using acquire_dest_image, but that's going to be very - * inefficient compared to a backend-specific implementation of - * clone_similar() with an image source. So we don't bother - */ + } - _cairo_surface_release_source_image (src, image, image_extra); return status; } |