mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 14:30:43 +00:00
Bug 1892913 - patch 12 - Update and apply 09-quartz-surface-additions.patch r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D209420
This commit is contained in:
parent
6f3ce9eb6f
commit
3d8675287f
@ -1,22 +1,32 @@
|
||||
diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h
|
||||
--- a/gfx/cairo/cairo/src/cairo-quartz-private.h
|
||||
+++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
|
||||
@@ -71,8 +71,11 @@ typedef struct cairo_quartz_surface {
|
||||
cairo_surface_t *imageSurfaceEquiv;
|
||||
|
||||
cairo_surface_clipper_t clipper;
|
||||
+
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int_t virtual_extents;
|
||||
+
|
||||
+ cairo_bool_t ownsData;
|
||||
} cairo_quartz_surface_t;
|
||||
|
||||
typedef struct cairo_quartz_image_surface {
|
||||
# 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
|
||||
@@ -1520,6 +1520,103 @@ static cairo_int_status_t
|
||||
@@ -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
|
||||
|
||||
|
||||
/*
|
||||
@ -31,17 +41,11 @@ diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/ca
|
||||
+ unsigned char *imageData;
|
||||
+ cairo_image_surface_t *isurf;
|
||||
+
|
||||
+ if (IS_EMPTY(surface)) {
|
||||
+ 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 (surface->imageSurfaceEquiv) {
|
||||
+ CGContextFlush(surface->cgContext);
|
||||
+ *image_out = (cairo_image_surface_t*) cairo_surface_reference(surface->imageSurfaceEquiv);
|
||||
+ return CAIRO_STATUS_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (_cairo_quartz_is_cgcontext_bitmap_context(surface->cgContext)) {
|
||||
+ unsigned int stride;
|
||||
+ unsigned int bitinfo;
|
||||
@ -120,160 +124,11 @@ diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/ca
|
||||
* Cairo surface backend implementations
|
||||
*/
|
||||
|
||||
@@ -1542,11 +1639,14 @@ static cairo_status_t
|
||||
surface->cgContext = NULL;
|
||||
|
||||
if (surface->imageSurfaceEquiv) {
|
||||
+ if (surface->ownsData)
|
||||
+ _cairo_image_surface_assume_ownership_of_data (surface->imageSurfaceEquiv);
|
||||
cairo_surface_destroy (surface->imageSurfaceEquiv);
|
||||
surface->imageSurfaceEquiv = NULL;
|
||||
+ } else if (surface->imageData && surface->ownsData) {
|
||||
+ free (surface->imageData);
|
||||
}
|
||||
|
||||
- free (surface->imageData);
|
||||
surface->imageData = NULL;
|
||||
|
||||
@@ -2478,3 +2570,15 @@ cairo_status_t
|
||||
CGImageRelease (image);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@@ -2298,6 +2398,8 @@ cairo_quartz_surface_t *
|
||||
surface->cgContext = cgContext;
|
||||
surface->cgContextBaseCTM = CGContextGetCTM (cgContext);
|
||||
|
||||
+ surface->ownsData = TRUE;
|
||||
+
|
||||
return surface;
|
||||
}
|
||||
|
||||
@@ -2452,10 +2554,124 @@ cairo_quartz_surface_create (cairo_forma
|
||||
surf->imageData = imageData;
|
||||
surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride);
|
||||
|
||||
+ // We created this data, so we can delete it.
|
||||
+ surf->ownsData = TRUE;
|
||||
+
|
||||
return &surf->base;
|
||||
}
|
||||
|
||||
/**
|
||||
+ * cairo_quartz_surface_create_for_data
|
||||
+ * @data: a pointer to a buffer supplied by the application in which
|
||||
+ * to write contents. This pointer must be suitably aligned for any
|
||||
+ * kind of variable, (for example, a pointer returned by malloc).
|
||||
+ * @format: format of pixels in the surface to create
|
||||
+ * @width: width of the surface, in pixels
|
||||
+ * @height: height of the surface, in pixels
|
||||
+ *
|
||||
+ * Creates a Quartz surface backed by a CGBitmap. The surface is
|
||||
+ * created using the Device RGB (or Device Gray, for A8) color space.
|
||||
+ * All Cairo operations, including those that require software
|
||||
+ * rendering, will succeed on this surface.
|
||||
+ *
|
||||
+ * Return value: the newly created surface.
|
||||
+ *
|
||||
+ * Since: 1.12 [Mozilla addition]
|
||||
+ **/
|
||||
+cairo_surface_t *
|
||||
+cairo_quartz_surface_create_for_data (unsigned char *data,
|
||||
+ cairo_format_t format,
|
||||
+ unsigned int width,
|
||||
+ unsigned int height,
|
||||
+ unsigned int stride)
|
||||
+{
|
||||
+ cairo_quartz_surface_t *surf;
|
||||
+ CGContextRef cgc;
|
||||
+ CGColorSpaceRef cgColorspace;
|
||||
+ CGBitmapInfo bitinfo;
|
||||
+ void *imageData = data;
|
||||
+ int bitsPerComponent;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ // verify width and height of surface
|
||||
+ if (!_cairo_quartz_verify_surface_size(width, height))
|
||||
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
|
||||
+
|
||||
+ if (width == 0 || height == 0) {
|
||||
+ return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format),
|
||||
+ width, height);
|
||||
+ }
|
||||
+
|
||||
+ if (format == CAIRO_FORMAT_ARGB32 ||
|
||||
+ format == CAIRO_FORMAT_RGB24)
|
||||
+ {
|
||||
+ cgColorspace = CGColorSpaceCreateDeviceRGB();
|
||||
+ bitinfo = kCGBitmapByteOrder32Host;
|
||||
+ if (format == CAIRO_FORMAT_ARGB32)
|
||||
+ bitinfo |= kCGImageAlphaPremultipliedFirst;
|
||||
+ else
|
||||
+ bitinfo |= kCGImageAlphaNoneSkipFirst;
|
||||
+ bitsPerComponent = 8;
|
||||
+ } else if (format == CAIRO_FORMAT_A8) {
|
||||
+ cgColorspace = NULL;
|
||||
+ bitinfo = kCGImageAlphaOnly;
|
||||
+ bitsPerComponent = 8;
|
||||
+ } else if (format == CAIRO_FORMAT_A1) {
|
||||
+ /* I don't think we can usefully support this, as defined by
|
||||
+ * cairo_format_t -- these are 1-bit pixels stored in 32-bit
|
||||
+ * quantities.
|
||||
+ */
|
||||
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
|
||||
+ } else {
|
||||
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
|
||||
+ }
|
||||
+
|
||||
+ cgc = CGBitmapContextCreate (imageData,
|
||||
+ width,
|
||||
+ height,
|
||||
+ bitsPerComponent,
|
||||
+ stride,
|
||||
+ cgColorspace,
|
||||
+ bitinfo);
|
||||
+ CGColorSpaceRelease (cgColorspace);
|
||||
+
|
||||
+ if (!cgc) {
|
||||
+ free (imageData);
|
||||
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
+ }
|
||||
+
|
||||
+ /* flip the Y axis */
|
||||
+ CGContextTranslateCTM (cgc, 0.0, height);
|
||||
+ CGContextScaleCTM (cgc, 1.0, -1.0);
|
||||
+
|
||||
+ surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
|
||||
+ width, height);
|
||||
+ if (surf->base.status) {
|
||||
+ CGContextRelease (cgc);
|
||||
+ free (imageData);
|
||||
+ // create_internal will have set an error
|
||||
+ return (cairo_surface_t*) surf;
|
||||
+ }
|
||||
+
|
||||
+ surf->imageData = imageData;
|
||||
+
|
||||
+ cairo_surface_t* tmpImageSurfaceEquiv =
|
||||
+ cairo_image_surface_create_for_data (imageData, format,
|
||||
+ width, height, stride);
|
||||
+
|
||||
+ if (cairo_surface_status (tmpImageSurfaceEquiv)) {
|
||||
+ // Tried & failed to create an imageSurfaceEquiv!
|
||||
+ cairo_surface_destroy (tmpImageSurfaceEquiv);
|
||||
+ surf->imageSurfaceEquiv = NULL;
|
||||
+ } else {
|
||||
+ surf->imageSurfaceEquiv = tmpImageSurfaceEquiv;
|
||||
+ surf->ownsData = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return (cairo_surface_t *) surf;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* cairo_quartz_surface_get_cg_context:
|
||||
* @surface: the Cairo Quartz surface
|
||||
*
|
||||
@@ -2497,6 +2713,18 @@ cairo_bool_t
|
||||
return surface->backend == &cairo_quartz_surface_backend;
|
||||
}
|
||||
|
||||
+cairo_surface_t *
|
||||
+cairo_quartz_surface_get_image (cairo_surface_t *surface)
|
||||
+{
|
||||
@ -285,24 +140,10 @@ diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/ca
|
||||
+
|
||||
+ return (cairo_surface_t *)image;
|
||||
+}
|
||||
+
|
||||
/* Debug stuff */
|
||||
|
||||
#ifdef QUARTZ_DEBUG
|
||||
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
|
||||
@@ -54,9 +54,19 @@ cairo_quartz_surface_create_for_cg_conte
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
+cairo_surface_t *
|
||||
+cairo_quartz_surface_create_for_data (unsigned char *data,
|
||||
+ cairo_format_t format,
|
||||
+ unsigned int width,
|
||||
+ unsigned int height,
|
||||
+ unsigned int stride);
|
||||
+
|
||||
@@ -57,6 +57,9 @@ cairo_quartz_surface_create_for_cg_conte
|
||||
cairo_public CGContextRef
|
||||
cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
|
||||
|
||||
|
@ -409,6 +409,7 @@ _cairo_quartz_cairo_operator_to_quartz_blend (cairo_operator_t op)
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
return kCGBlendModeNormal; /* unreached */
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -998,7 +999,7 @@ _cairo_quartz_setup_pattern_source (cairo_quartz_drawing_state_t *state,
|
||||
_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 &&
|
||||
@ -1401,6 +1402,97 @@ _cairo_quartz_surface_unmap_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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_quartz_surface_to_png (cairo_surface_t *abstract_surface, const char *des
|
||||
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;
|
||||
}
|
||||
|
@ -57,6 +57,9 @@ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
|
||||
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
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user