pjs/gfx/cairo/quartz-create-for-data.patch

310 строки
11 KiB
Diff

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