summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/wrap-source_image.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/wrap-source_image.patch')
-rw-r--r--gfx/cairo/wrap-source_image.patch105
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 000000000..89da5a08d
--- /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);
++ }
+ }
+ }
+ }