summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/quartz-create-for-data.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/quartz-create-for-data.patch')
-rw-r--r--gfx/cairo/quartz-create-for-data.patch309
1 files changed, 309 insertions, 0 deletions
diff --git a/gfx/cairo/quartz-create-for-data.patch b/gfx/cairo/quartz-create-for-data.patch
new file mode 100644
index 000000000..ae374fafe
--- /dev/null
+++ b/gfx/cairo/quartz-create-for-data.patch
@@ -0,0 +1,309 @@
+diff --git a/gfx/cairo/README b/gfx/cairo/README
+--- a/gfx/cairo/README
++++ b/gfx/cairo/README
+@@ -71,16 +71,18 @@ quartz-cache-CGImageRef.patch: cache CGI
+ quartz-remove-snapshot.patch: remove broken implementation of backend snapshot
+
+ quartz-cglayers.patch: add support for cairo surfaces backed by CGLayers
+
+ quartz-cglayers-fix-fallback.patch: Bug 572912; fix bug in fallback code in previous patch
+
+ quartz-get-image.patch: Bug 575521; add a way to get the image surface associated with a surface
+
++quartz-create-for-data.patch: Bug 575521; add a way to create quartz surfaces backed with application-provided data
++
+ premultiply-alpha-solid-gradients.patch: bug 539165; multiply the solid color by the alpha component before using it for a solid surface
+
+ xlib-initialize-members.path: bug 548793; initialize XRender version if the server doesn't have the extension
+
+ remove-comma: remove a comma from enum
+
+ d2d.patch: add d2d support
+
+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
+@@ -63,16 +63,18 @@ typedef struct cairo_quartz_surface {
+ CGImageRef bitmapContextImage;
+
+ /**
+ * If non-null, this is the CGLayer for the surface.
+ */
+ CGLayerRef cgLayer;
+
+ cairo_rectangle_int_t extents;
++
++ cairo_bool_t ownsData;
+ } cairo_quartz_surface_t;
+
+ typedef struct cairo_quartz_image_surface {
+ cairo_surface_t base;
+
+ cairo_rectangle_int_t extents;
+
+ CGImageRef image;
+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
+@@ -1880,20 +1880,21 @@ _cairo_quartz_surface_finish (void *abst
+ surface->cgContext = NULL;
+
+ if (surface->bitmapContextImage) {
+ CGImageRelease (surface->bitmapContextImage);
+ surface->bitmapContextImage = NULL;
+ }
+
+ if (surface->imageSurfaceEquiv) {
+- _cairo_image_surface_assume_ownership_of_data (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) {
++ } else if (surface->imageData && surface->ownsData) {
+ free (surface->imageData);
+ }
+
+ surface->imageData = NULL;
+
+ if (surface->cgLayer) {
+ CGLayerRelease (surface->cgLayer);
+ }
+@@ -2888,16 +2889,17 @@ _cairo_quartz_surface_create_internal (C
+
+ surface->cgContext = cgContext;
+ surface->cgContextBaseCTM = CGContextGetCTM (cgContext);
+
+ surface->imageData = NULL;
+ surface->imageSurfaceEquiv = NULL;
+ surface->bitmapContextImage = NULL;
+ surface->cgLayer = NULL;
++ surface->ownsData = TRUE;
+
+ return surface;
+ }
+
+ /**
+ * cairo_quartz_surface_create_for_cg_context
+ * @cgContext: the existing CGContext for which to create the surface
+ * @width: width of the surface, in pixels
+@@ -3031,23 +3033,103 @@ cairo_quartz_surface_create_cg_layer (ca
+ *
+ * Since: 1.4
+ **/
+ cairo_surface_t *
+ cairo_quartz_surface_create (cairo_format_t format,
+ unsigned int width,
+ unsigned int height)
+ {
++ int stride;
++ unsigned char *data;
++
++ 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)
++ {
++ stride = width * 4;
++ } else if (format == CAIRO_FORMAT_A8) {
++ stride = width;
++ } 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));
++ }
++
++ /* The Apple docs say that for best performance, the stride and the data
++ * pointer should be 16-byte aligned. malloc already aligns to 16-bytes,
++ * so we don't have to anything special on allocation.
++ */
++ stride = (stride + 15) & ~15;
++
++ data = _cairo_malloc_ab (height, stride);
++ if (!data) {
++ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
++ }
++
++ /* zero the memory to match the image surface behaviour */
++ memset (data, 0, height * stride);
++
++ cairo_quartz_surface_t *surf;
++ surf = (cairo_quartz_surface_t *) cairo_quartz_surface_create_for_data
++ (data, format, width, height, stride);
++ if (surf->base.status) {
++ free (data);
++ return (cairo_surface_t *) surf;
++ }
++
++ // We created this data, so we can delete it.
++ surf->ownsData = TRUE;
++
++ return (cairo_surface_t *) surf;
++}
++
++/**
++ * 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
++ **/
++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;
+- int stride;
++ 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);
+@@ -3058,47 +3140,30 @@ cairo_quartz_surface_create (cairo_forma
+ {
+ cgColorspace = CGColorSpaceCreateDeviceRGB();
+ bitinfo = kCGBitmapByteOrder32Host;
+ if (format == CAIRO_FORMAT_ARGB32)
+ bitinfo |= kCGImageAlphaPremultipliedFirst;
+ else
+ bitinfo |= kCGImageAlphaNoneSkipFirst;
+ bitsPerComponent = 8;
+- stride = width * 4;
+ } else if (format == CAIRO_FORMAT_A8) {
+ cgColorspace = NULL;
+- stride = width;
+ 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));
+ }
+
+- /* The Apple docs say that for best performance, the stride and the data
+- * pointer should be 16-byte aligned. malloc already aligns to 16-bytes,
+- * so we don't have to anything special on allocation.
+- */
+- stride = (stride + 15) & ~15;
+-
+- imageData = _cairo_malloc_ab (height, stride);
+- if (!imageData) {
+- CGColorSpaceRelease (cgColorspace);
+- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+- }
+-
+- /* zero the memory to match the image surface behaviour */
+- memset (imageData, 0, height * stride);
+-
+ cgc = CGBitmapContextCreate (imageData,
+ width,
+ height,
+ bitsPerComponent,
+ stride,
+ cgColorspace,
+ bitinfo);
+ CGColorSpaceRelease (cgColorspace);
+@@ -3118,16 +3183,17 @@ cairo_quartz_surface_create (cairo_forma
+ CGContextRelease (cgc);
+ free (imageData);
+ // create_internal will have set an error
+ return (cairo_surface_t*) surf;
+ }
+
+ surf->imageData = imageData;
+ surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride);
++ surf->ownsData = FALSE;
+
+ return (cairo_surface_t *) surf;
+ }
+
+ /**
+ * cairo_quartz_surface_get_cg_context
+ * @surface: the Cairo Quartz surface
+ *
+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
+@@ -45,16 +45,23 @@
+ CAIRO_BEGIN_DECLS
+
+ cairo_public cairo_surface_t *
+ cairo_quartz_surface_create (cairo_format_t format,
+ unsigned int width,
+ unsigned int height);
+
+ cairo_public 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_public cairo_surface_t *
+ cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface,
+ unsigned int width,
+ unsigned int height);
+
+ cairo_public cairo_surface_t *
+ cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
+ unsigned int width,
+ unsigned int height);
+diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h
+--- a/gfx/cairo/cairo/src/cairo-rename.h
++++ b/gfx/cairo/cairo/src/cairo-rename.h
+@@ -176,16 +176,17 @@
+ #define cairo_qpainter_surface_get_image _moz_cairo_qpainter_surface_get_image
+ #define cairo_qpainter_surface_get_qimage _moz_cairo_qpainter_surface_get_qimage
+ #define cairo_qpainter_surface_get_qpainter _moz_cairo_qpainter_surface_get_qpainter
+ #define cairo_quartz_font_face_create_for_atsu_font_id _moz_cairo_quartz_font_face_create_for_atsu_font_id
+ #define cairo_quartz_font_face_create_for_cgfont _moz_cairo_quartz_font_face_create_for_cgfont
+ #define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create
+ #define cairo_quartz_image_surface_get_image _moz_cairo_quartz_image_surface_get_image
+ #define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
++#define cairo_quartz_surface_create_for_data _moz_cairo_quartz_surface_create_for_data
+ #define cairo_quartz_surface_create_for_cg_context _moz_cairo_quartz_surface_create_for_cg_context
+ #define cairo_quartz_surface_get_cg_context _moz_cairo_quartz_surface_get_cg_context
+ #define cairo_quartz_surface_get_image _moz_cairo_quartz_surface_get_image
+ #define cairo_rectangle _moz_cairo_rectangle
+ #define cairo_rectangle_list_destroy _moz_cairo_rectangle_list_destroy
+ #define cairo_reference _moz_cairo_reference
+ #define cairo_rel_curve_to _moz_cairo_rel_curve_to
+ #define cairo_rel_line_to _moz_cairo_rel_line_to