summaryrefslogtreecommitdiff
path: root/graphics/cairo/patches/patch-src_cairo-quartz-image-surface.c
blob: 0ca78d9c51a1f2c8b070043ade5d5f98a1684843 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
$NetBSD: patch-src_cairo-quartz-image-surface.c,v 1.1 2022/05/12 17:13:55 tnn Exp $

Ref and destroy the cairo surface handed off to CoreGraphics.
https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/52

--- src/cairo-quartz-image-surface.c.orig	2018-08-17 01:10:53.000000000 +0000
+++ src/cairo-quartz-image-surface.c
@@ -50,10 +50,9 @@
 #define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT)))
 
 static void
-DataProviderReleaseCallback (void *info, const void *data, size_t size)
+DataProviderReleaseCallback (void *image_info, const void *data, size_t size)
 {
-    cairo_surface_t *surface = (cairo_surface_t *) info;
-    cairo_surface_destroy (surface);
+    free (image_info);
 }
 
 static cairo_surface_t *
@@ -88,9 +87,8 @@ _cairo_quartz_image_surface_finish (void
 {
     cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
 
-    /* the imageSurface will be destroyed by the data provider's release callback */
     CGImageRelease (surface->image);
-
+    cairo_surface_destroy (surface->imageSurface);
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -147,24 +145,29 @@ _cairo_quartz_image_surface_flush (void 
     cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
     CGImageRef oldImage = surface->image;
     CGImageRef newImage = NULL;
-
+    void *image_data;
+    const unsigned int size = surface->imageSurface->height * surface->imageSurface->stride;
     if (flags)
 	return CAIRO_STATUS_SUCCESS;
 
     /* XXX only flush if the image has been modified. */
 
-    /* To be released by the ReleaseCallback */
-    cairo_surface_reference ((cairo_surface_t*) surface->imageSurface);
+    image_data = _cairo_malloc_ab ( surface->imageSurface->height,
+				    surface->imageSurface->stride);
+    if (unlikely (!image_data))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
+    memcpy (image_data, surface->imageSurface->data,
+	    surface->imageSurface->height * surface->imageSurface->stride);
     newImage = CairoQuartzCreateCGImage (surface->imageSurface->format,
 					 surface->imageSurface->width,
 					 surface->imageSurface->height,
 					 surface->imageSurface->stride,
-					 surface->imageSurface->data,
+					 image_data,
 					 TRUE,
 					 NULL,
 					 DataProviderReleaseCallback,
-					 surface->imageSurface);
+					 image_data);
 
     surface->image = newImage;
     CGImageRelease (oldImage);
@@ -308,7 +311,7 @@ cairo_quartz_image_surface_create (cairo
     cairo_image_surface_t *image_surface;
     int width, height, stride;
     cairo_format_t format;
-    unsigned char *data;
+    void *image_data;
 
     if (surface->status)
 	return surface;
@@ -321,7 +324,6 @@ cairo_quartz_image_surface_create (cairo
     height = image_surface->height;
     stride = image_surface->stride;
     format = image_surface->format;
-    data = image_surface->data;
 
     if (!_cairo_quartz_verify_surface_size(width, height))
 	return SURFACE_ERROR_INVALID_SIZE;
@@ -338,20 +340,19 @@ cairo_quartz_image_surface_create (cairo
 
     memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t));
 
-    /* In case the create_cgimage fails, this ref will
-     * be released via the callback (which will be called in
-     * case of failure.)
-     */
-    cairo_surface_reference (surface);
+    image_data = _cairo_malloc_ab (height, stride);
+    if (unlikely (!image_data))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
+    memcpy (image_data, image_surface->data, height * stride);
     image = CairoQuartzCreateCGImage (format,
 				      width, height,
 				      stride,
-				      data,
+				      image_data,
 				      TRUE,
 				      NULL,
 				      DataProviderReleaseCallback,
-				      image_surface);
+				      image_data);
 
     if (!image) {
 	free (qisurf);