Blame gfx/cairo/wrap-source_image.patch

Packit f0b94e
Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
Packit f0b94e
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
Packit f0b94e
index 8278694..12f6242 100644
Packit f0b94e
--- a/src/cairo-surface.c
Packit f0b94e
+++ b/src/cairo-surface.c
Packit f0b94e
@@ -1530,6 +1530,70 @@ _cairo_recording_surface_clone_similar (cairo_surface_t  *surface,
Packit f0b94e
     return CAIRO_STATUS_SUCCESS;
Packit f0b94e
 }
Packit f0b94e
 
Packit f0b94e
+struct acquire_source_image_data
Packit f0b94e
+{
Packit f0b94e
+    cairo_surface_t *src;
Packit f0b94e
+    cairo_image_surface_t *image;
Packit f0b94e
+    void *image_extra;
Packit f0b94e
+};
Packit f0b94e
+
Packit f0b94e
+static void
Packit f0b94e
+_wrap_release_source_image (void *data)
Packit f0b94e
+{
Packit f0b94e
+    struct acquire_source_image_data *acquire_data = data;
Packit f0b94e
+    _cairo_surface_release_source_image (acquire_data->src,
Packit f0b94e
+					 acquire_data->image,
Packit f0b94e
+					 acquire_data->image_extra);
Packit f0b94e
+    free(data);
Packit f0b94e
+}
Packit f0b94e
+
Packit f0b94e
+static cairo_status_t
Packit f0b94e
+_wrap_image (cairo_surface_t *src,
Packit f0b94e
+	     cairo_image_surface_t *image,
Packit f0b94e
+	     void *image_extra,
Packit f0b94e
+	     cairo_image_surface_t **out)
Packit f0b94e
+{
Packit f0b94e
+    static cairo_user_data_key_t wrap_image_key;
Packit f0b94e
+    cairo_image_surface_t *surface;
Packit f0b94e
+    cairo_status_t status;
Packit f0b94e
+
Packit f0b94e
+    struct acquire_source_image_data *data = malloc (sizeof (*data));
Packit f0b94e
+    if (unlikely (data == NULL))
Packit f0b94e
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
Packit f0b94e
+    data->src = src;
Packit f0b94e
+    data->image = image;
Packit f0b94e
+    data->image_extra = image_extra;
Packit f0b94e
+
Packit f0b94e
+    surface = (cairo_image_surface_t *)
Packit f0b94e
+	_cairo_image_surface_create_with_pixman_format (image->data,
Packit f0b94e
+							image->pixman_format,
Packit f0b94e
+							image->width,
Packit f0b94e
+							image->height,
Packit f0b94e
+							image->stride);
Packit f0b94e
+    status = surface->base.status;
Packit f0b94e
+    if (status) {
Packit f0b94e
+	free (data);
Packit f0b94e
+	return status;
Packit f0b94e
+    }
Packit f0b94e
+
Packit f0b94e
+    status = _cairo_user_data_array_set_data (&surface->base.user_data,
Packit f0b94e
+					      &wrap_image_key,
Packit f0b94e
+					      data,
Packit f0b94e
+					      _wrap_release_source_image);
Packit f0b94e
+    if (status) {
Packit f0b94e
+	cairo_surface_destroy (&surface->base);
Packit f0b94e
+	free (data);
Packit f0b94e
+	return status;
Packit f0b94e
+    }
Packit f0b94e
+
Packit f0b94e
+    pixman_image_set_component_alpha (
Packit f0b94e
+	surface->pixman_image,
Packit f0b94e
+	pixman_image_get_component_alpha (surface->pixman_image));
Packit f0b94e
+
Packit f0b94e
+    *out = surface;
Packit f0b94e
+    return CAIRO_STATUS_SUCCESS;
Packit f0b94e
+}
Packit f0b94e
+
Packit f0b94e
 /**
Packit f0b94e
  * _cairo_surface_clone_similar:
Packit f0b94e
  * @surface: a #cairo_surface_t
Packit f0b94e
@@ -1606,15 +1670,19 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
Packit f0b94e
 	    /* If we failed, try again with an image surface */
Packit f0b94e
 	    status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
Packit f0b94e
 	    if (status == CAIRO_STATUS_SUCCESS) {
Packit f0b94e
-		status =
Packit f0b94e
-		    surface->backend->clone_similar (surface, &image->base,
Packit f0b94e
-						     src_x, src_y,
Packit f0b94e
-						     width, height,
Packit f0b94e
-						     clone_offset_x,
Packit f0b94e
-						     clone_offset_y,
Packit f0b94e
-						     clone_out);
Packit f0b94e
-
Packit f0b94e
-		_cairo_surface_release_source_image (src, image, image_extra);
Packit f0b94e
+		status = _wrap_image(src, image, image_extra, &image);
Packit f0b94e
+		if (status != CAIRO_STATUS_SUCCESS) {
Packit f0b94e
+		    _cairo_surface_release_source_image (src, image, image_extra);
Packit f0b94e
+		} else {
Packit f0b94e
+		    status =
Packit f0b94e
+			surface->backend->clone_similar (surface, &image->base,
Packit f0b94e
+							 src_x, src_y,
Packit f0b94e
+							 width, height,
Packit f0b94e
+							 clone_offset_x,
Packit f0b94e
+							 clone_offset_y,
Packit f0b94e
+							 clone_out);
Packit f0b94e
+		    cairo_surface_destroy(&image->base);
Packit f0b94e
+		}
Packit f0b94e
 	    }
Packit f0b94e
 	}
Packit f0b94e
     }