Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/gfx/cairo/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 3 kB image not shown  

Quelle  26-quartz-surface-mask.patch   Sprache: unbekannt

 
# 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;

[ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ]