diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
commit | 59203c63bb777a3bacec32fb8830fba33540e809 (patch) | |
tree | 58298e711c0ff0575818c30485b44a2f21bf28a0 /gfx/cairo/26-quartz-surface-mask.patch | |
parent | Adding upstream version 126.0.1. (diff) | |
download | firefox-59203c63bb777a3bacec32fb8830fba33540e809.tar.xz firefox-59203c63bb777a3bacec32fb8830fba33540e809.zip |
Adding upstream version 127.0.upstream/127.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/cairo/26-quartz-surface-mask.patch')
-rw-r--r-- | gfx/cairo/26-quartz-surface-mask.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/gfx/cairo/26-quartz-surface-mask.patch b/gfx/cairo/26-quartz-surface-mask.patch new file mode 100644 index 0000000000..dd5c71c07a --- /dev/null +++ b/gfx/cairo/26-quartz-surface-mask.patch @@ -0,0 +1,124 @@ +# HG changeset patch +# User Jonathan Kew <jkew@mozilla.com> +# Date 1717237382 -3600 +# Sat Jun 01 11:23:02 2024 +0100 +# Node ID d5f7b9fd904e04406c56899c5cac9248b122ea35 +# Parent c8d3e447c892474e061c9ffd22ec1823f06ecffa +Bug 1900028 - Handle CAIRO_FORMAT_A8 in _cairo_surface_to_cgimage for masking operations. + +Differential Revision: https://phabricator.services.mozilla.com/D212354 + +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 +@@ -684,6 +684,55 @@ CairoQuartzCreateGradientFunction (const + &gradient_callbacks); + } + ++static CGImageRef ++CairoQuartzCreateCGImageMask (cairo_format_t format, ++ unsigned int width, ++ unsigned int height, ++ unsigned int stride, ++ void *data, ++ cairo_bool_t interpolate, ++ CGDataProviderReleaseDataCallback releaseCallback, ++ void *releaseInfo) ++{ ++ CGImageRef image = NULL; ++ CGDataProviderRef dataProvider = NULL; ++ int bitsPerComponent = 8, bitsPerPixel = 8; ++ ++ if (format != CAIRO_FORMAT_A8) ++ return NULL; ++ ++ dataProvider = CGDataProviderCreateWithData (releaseInfo, ++ data, ++ height * stride, ++ releaseCallback); ++ ++ if (unlikely (!dataProvider)) { ++ // manually release ++ if (releaseCallback) ++ releaseCallback (releaseInfo, data, height * stride); ++ goto FINISH; ++ } ++ ++ cairo_quartz_float_t decode[] = {1.0, 0.0}; ++ image = CGImageMaskCreate (width, height, ++ bitsPerComponent, ++ bitsPerPixel, ++ stride, ++ dataProvider, ++ decode, ++ interpolate); ++ ++FINISH: ++ CGDataProviderRelease (dataProvider); ++ return image; ++} ++ ++static void ++DataProviderReleaseCallback (void *info, const void *data, size_t size) ++{ ++ free (info); ++} ++ + static cairo_status_t + _cairo_surface_to_cgimage (cairo_surface_t *source, + cairo_rectangle_int_t *extents, +@@ -742,13 +791,48 @@ static cairo_status_t + &image_extra); + if (unlikely (status)) + return status; +- image_surface = +- (cairo_quartz_image_surface_t*)cairo_quartz_image_surface_create (&surface->base); +- status = image_surface->base.status; +- if (status) ++ ++ if (surface->format == CAIRO_FORMAT_A8) { ++ /* cairo_quartz_image_surface_create doesn't handle CAIRO_FORMAT_A8, ++ * so we create a CGImage manually here for masking operations. ++ */ ++ void* image_data = _cairo_malloc_ab (surface->height, surface->stride); ++ if (unlikely (!image_data)) ++ { ++ _cairo_surface_release_source_image (source, surface, image_extra); ++ return _cairo_error (CAIRO_STATUS_NO_MEMORY); ++ } ++ ++ /* The last row of data may have less than stride bytes so make sure we ++ * only copy the minimum amount required from that row. ++ */ ++ memcpy (image_data, surface->data, ++ (surface->height - 1) * surface->stride + ++ cairo_format_stride_for_width (surface->format, ++ surface->width)); ++ *image_out = CairoQuartzCreateCGImageMask (surface->format, ++ surface->width, ++ surface->height, ++ surface->stride, ++ image_data, ++ TRUE, ++ DataProviderReleaseCallback, ++ image_data); ++ /* TODO: differentiate memory error and unsupported surface type */ ++ if (unlikely (*image_out == NULL)) ++ status = CAIRO_INT_STATUS_UNSUPPORTED; ++ + _cairo_surface_release_source_image (source, surface, image_extra); +- else +- acquired = TRUE; ++ return status; ++ } else { ++ image_surface = ++ (cairo_quartz_image_surface_t*)cairo_quartz_image_surface_create (&surface->base); ++ status = image_surface->base.status; ++ if (status) ++ _cairo_surface_release_source_image (source, surface, image_extra); ++ else ++ acquired = TRUE; ++ } + } + + *image_out = NULL; |