diff options
Diffstat (limited to 'gfx/cairo/wrap-source_image.patch')
-rw-r--r-- | gfx/cairo/wrap-source_image.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/gfx/cairo/wrap-source_image.patch b/gfx/cairo/wrap-source_image.patch new file mode 100644 index 0000000000..89da5a08dc --- /dev/null +++ b/gfx/cairo/wrap-source_image.patch @@ -0,0 +1,105 @@ +Author: Jeff Muizelaar <jmuizelaar@mozilla.com> +diff --git a/src/cairo-surface.c b/src/cairo-surface.c +index 8278694..12f6242 100644 +--- a/src/cairo-surface.c ++++ b/src/cairo-surface.c +@@ -1530,6 +1530,70 @@ _cairo_recording_surface_clone_similar (cairo_surface_t *surface, + return CAIRO_STATUS_SUCCESS; + } + ++struct acquire_source_image_data ++{ ++ cairo_surface_t *src; ++ cairo_image_surface_t *image; ++ void *image_extra; ++}; ++ ++static void ++_wrap_release_source_image (void *data) ++{ ++ struct acquire_source_image_data *acquire_data = data; ++ _cairo_surface_release_source_image (acquire_data->src, ++ acquire_data->image, ++ acquire_data->image_extra); ++ free(data); ++} ++ ++static cairo_status_t ++_wrap_image (cairo_surface_t *src, ++ cairo_image_surface_t *image, ++ void *image_extra, ++ cairo_image_surface_t **out) ++{ ++ static cairo_user_data_key_t wrap_image_key; ++ cairo_image_surface_t *surface; ++ cairo_status_t status; ++ ++ struct acquire_source_image_data *data = malloc (sizeof (*data)); ++ if (unlikely (data == NULL)) ++ return _cairo_error (CAIRO_STATUS_NO_MEMORY); ++ data->src = src; ++ data->image = image; ++ data->image_extra = image_extra; ++ ++ surface = (cairo_image_surface_t *) ++ _cairo_image_surface_create_with_pixman_format (image->data, ++ image->pixman_format, ++ image->width, ++ image->height, ++ image->stride); ++ status = surface->base.status; ++ if (status) { ++ free (data); ++ return status; ++ } ++ ++ status = _cairo_user_data_array_set_data (&surface->base.user_data, ++ &wrap_image_key, ++ data, ++ _wrap_release_source_image); ++ if (status) { ++ cairo_surface_destroy (&surface->base); ++ free (data); ++ return status; ++ } ++ ++ pixman_image_set_component_alpha ( ++ surface->pixman_image, ++ pixman_image_get_component_alpha (surface->pixman_image)); ++ ++ *out = surface; ++ return CAIRO_STATUS_SUCCESS; ++} ++ + /** + * _cairo_surface_clone_similar: + * @surface: a #cairo_surface_t +@@ -1606,15 +1670,19 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, + /* 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_offset_x, +- clone_offset_y, +- clone_out); +- +- _cairo_surface_release_source_image (src, image, image_extra); ++ status = _wrap_image(src, image, image_extra, &image); ++ if (status != CAIRO_STATUS_SUCCESS) { ++ _cairo_surface_release_source_image (src, image, image_extra); ++ } else { ++ status = ++ surface->backend->clone_similar (surface, &image->base, ++ src_x, src_y, ++ width, height, ++ clone_offset_x, ++ clone_offset_y, ++ clone_out); ++ cairo_surface_destroy(&image->base); ++ } + } + } + } |