summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/09-quartz-surface-additions.patch
blob: 287a0dc9e084c22c0aaa3aae1bd8ea4f126d17d6 (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# HG changeset patch
# User Jonathan Kew <jkew@mozilla.com>
# Date 1713889662 -3600
#      Tue Apr 23 17:27:42 2024 +0100
# Node ID fd010d43c6a9aabbffd9cba9d0f290996c052c65
# Parent  cf33e155ac6207c3903408de7341e0ac68be7474
Bug 1892913 - patch 12 - Update and apply 09-quartz-surface-additions.patch

diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -409,6 +409,7 @@ static CGBlendMode
         default:
 	    ASSERT_NOT_REACHED;
     }
+    return kCGBlendModeNormal; /* unreached */
 }
 
 static cairo_int_status_t
@@ -998,7 +999,7 @@ static cairo_int_status_t
 	_cairo_surface_get_extents (&surface->base, &pattern_extents);
     }
 
-    if (source->extend == CAIRO_EXTEND_NONE) {
+    if (source->extend == CAIRO_EXTEND_NONE || source->extend == CAIRO_EXTEND_PAD) {
 	int x, y;
 
 	if (op == CAIRO_OPERATOR_SOURCE &&
@@ -1402,6 +1403,97 @@ static cairo_int_status_t
 
 
 /*
+ * get source/dest image implementation
+ */
+
+/* Read the image from the surface's front buffer */
+static cairo_int_status_t
+_cairo_quartz_get_image (cairo_quartz_surface_t *surface,
+			 cairo_image_surface_t **image_out)
+{
+    unsigned char *imageData;
+    cairo_image_surface_t *isurf;
+
+    if (_cairo_quartz_is_zero_surface (&surface->base)) {
+	*image_out = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (_cairo_quartz_is_cgcontext_bitmap_context(surface->cgContext)) {
+	unsigned int stride;
+	unsigned int bitinfo;
+	unsigned int bpc, bpp;
+	CGColorSpaceRef colorspace;
+	unsigned int color_comps;
+
+	CGContextFlush(surface->cgContext);
+	imageData = (unsigned char *) CGBitmapContextGetData(surface->cgContext);
+
+#ifdef USE_10_3_WORKAROUNDS
+	bitinfo = CGBitmapContextGetAlphaInfo (surface->cgContext);
+#else
+	bitinfo = CGBitmapContextGetBitmapInfo (surface->cgContext);
+#endif
+	stride = CGBitmapContextGetBytesPerRow (surface->cgContext);
+	bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext);
+	bpc = CGBitmapContextGetBitsPerComponent (surface->cgContext);
+
+	// let's hope they don't add YUV under us
+	colorspace = CGBitmapContextGetColorSpace (surface->cgContext);
+	color_comps = CGColorSpaceGetNumberOfComponents(colorspace);
+
+	// XXX TODO: We can handle all of these by converting to
+	// pixman masks, including non-native-endian masks
+	if (bpc != 8)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	if (bpp != 32 && bpp != 8)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	if (color_comps != 3 && color_comps != 1)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	if (bpp == 32 && color_comps == 3 &&
+	    (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst &&
+	    (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
+	{
+	    isurf = (cairo_image_surface_t *)
+		cairo_image_surface_create_for_data (imageData,
+						     CAIRO_FORMAT_ARGB32,
+						     surface->extents.width,
+						     surface->extents.height,
+						     stride);
+	} else if (bpp == 32 && color_comps == 3 &&
+		   (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaNoneSkipFirst &&
+		   (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
+	{
+	    isurf = (cairo_image_surface_t *)
+		cairo_image_surface_create_for_data (imageData,
+						     CAIRO_FORMAT_RGB24,
+						     surface->extents.width,
+						     surface->extents.height,
+						     stride);
+	} else if (bpp == 8 && color_comps == 1)
+	{
+	    isurf = (cairo_image_surface_t *)
+		cairo_image_surface_create_for_data (imageData,
+						     CAIRO_FORMAT_A8,
+						     surface->extents.width,
+						     surface->extents.height,
+						     stride);
+	} else {
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	}
+    } else {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
+    *image_out = isurf;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+
+/*
  * Cairo surface backend implementations
  */
 
@@ -2478,3 +2570,15 @@ cairo_status_t
     CGImageRelease (image);
     return CAIRO_STATUS_SUCCESS;
 }
+
+cairo_surface_t *
+cairo_quartz_surface_get_image (cairo_surface_t *surface)
+{
+    cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t *)surface;
+    cairo_image_surface_t *image;
+
+    if (_cairo_quartz_get_image(quartz, &image))
+        return NULL;
+
+    return (cairo_surface_t *)image;
+}
diff --git a/gfx/cairo/cairo/src/cairo-quartz.h b/gfx/cairo/cairo/src/cairo-quartz.h
--- a/gfx/cairo/cairo/src/cairo-quartz.h
+++ b/gfx/cairo/cairo/src/cairo-quartz.h
@@ -57,6 +57,9 @@ cairo_quartz_surface_create_for_cg_conte
 cairo_public CGContextRef
 cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
 
+cairo_public cairo_surface_t *
+cairo_quartz_surface_get_image (cairo_surface_t *surface);
+
 #if CAIRO_HAS_QUARTZ_FONT
 
 /*