michael@0: diff --git a/gfx/cairo/README b/gfx/cairo/README michael@0: --- a/gfx/cairo/README michael@0: +++ b/gfx/cairo/README michael@0: @@ -71,16 +71,18 @@ quartz-cache-CGImageRef.patch: cache CGI michael@0: quartz-remove-snapshot.patch: remove broken implementation of backend snapshot michael@0: michael@0: quartz-cglayers.patch: add support for cairo surfaces backed by CGLayers michael@0: michael@0: quartz-cglayers-fix-fallback.patch: Bug 572912; fix bug in fallback code in previous patch michael@0: michael@0: quartz-get-image.patch: Bug 575521; add a way to get the image surface associated with a surface michael@0: michael@0: +quartz-create-for-data.patch: Bug 575521; add a way to create quartz surfaces backed with application-provided data michael@0: + michael@0: premultiply-alpha-solid-gradients.patch: bug 539165; multiply the solid color by the alpha component before using it for a solid surface michael@0: michael@0: xlib-initialize-members.path: bug 548793; initialize XRender version if the server doesn't have the extension michael@0: michael@0: remove-comma: remove a comma from enum michael@0: michael@0: d2d.patch: add d2d support michael@0: michael@0: diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h michael@0: --- a/gfx/cairo/cairo/src/cairo-quartz-private.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-quartz-private.h michael@0: @@ -63,16 +63,18 @@ typedef struct cairo_quartz_surface { michael@0: CGImageRef bitmapContextImage; michael@0: michael@0: /** michael@0: * If non-null, this is the CGLayer for the surface. michael@0: */ michael@0: CGLayerRef cgLayer; michael@0: michael@0: cairo_rectangle_int_t extents; michael@0: + michael@0: + cairo_bool_t ownsData; michael@0: } cairo_quartz_surface_t; michael@0: michael@0: typedef struct cairo_quartz_image_surface { michael@0: cairo_surface_t base; michael@0: michael@0: cairo_rectangle_int_t extents; michael@0: michael@0: CGImageRef image; michael@0: diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c michael@0: @@ -1880,20 +1880,21 @@ _cairo_quartz_surface_finish (void *abst michael@0: surface->cgContext = NULL; michael@0: michael@0: if (surface->bitmapContextImage) { michael@0: CGImageRelease (surface->bitmapContextImage); michael@0: surface->bitmapContextImage = NULL; michael@0: } michael@0: michael@0: if (surface->imageSurfaceEquiv) { michael@0: - _cairo_image_surface_assume_ownership_of_data (surface->imageSurfaceEquiv); michael@0: + if (surface->ownsData) michael@0: + _cairo_image_surface_assume_ownership_of_data (surface->imageSurfaceEquiv); michael@0: cairo_surface_destroy (surface->imageSurfaceEquiv); michael@0: surface->imageSurfaceEquiv = NULL; michael@0: - } else if (surface->imageData) { michael@0: + } else if (surface->imageData && surface->ownsData) { michael@0: free (surface->imageData); michael@0: } michael@0: michael@0: surface->imageData = NULL; michael@0: michael@0: if (surface->cgLayer) { michael@0: CGLayerRelease (surface->cgLayer); michael@0: } michael@0: @@ -2888,16 +2889,17 @@ _cairo_quartz_surface_create_internal (C michael@0: michael@0: surface->cgContext = cgContext; michael@0: surface->cgContextBaseCTM = CGContextGetCTM (cgContext); michael@0: michael@0: surface->imageData = NULL; michael@0: surface->imageSurfaceEquiv = NULL; michael@0: surface->bitmapContextImage = NULL; michael@0: surface->cgLayer = NULL; michael@0: + surface->ownsData = TRUE; michael@0: michael@0: return surface; michael@0: } michael@0: michael@0: /** michael@0: * cairo_quartz_surface_create_for_cg_context michael@0: * @cgContext: the existing CGContext for which to create the surface michael@0: * @width: width of the surface, in pixels michael@0: @@ -3031,23 +3033,103 @@ cairo_quartz_surface_create_cg_layer (ca michael@0: * michael@0: * Since: 1.4 michael@0: **/ michael@0: cairo_surface_t * michael@0: cairo_quartz_surface_create (cairo_format_t format, michael@0: unsigned int width, michael@0: unsigned int height) michael@0: { michael@0: + int stride; michael@0: + unsigned char *data; michael@0: + michael@0: + if (!_cairo_quartz_verify_surface_size(width, height)) michael@0: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); michael@0: + michael@0: + if (width == 0 || height == 0) { michael@0: + return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format), michael@0: + width, height); michael@0: + } michael@0: + michael@0: + if (format == CAIRO_FORMAT_ARGB32 || michael@0: + format == CAIRO_FORMAT_RGB24) michael@0: + { michael@0: + stride = width * 4; michael@0: + } else if (format == CAIRO_FORMAT_A8) { michael@0: + stride = width; michael@0: + } else if (format == CAIRO_FORMAT_A1) { michael@0: + /* I don't think we can usefully support this, as defined by michael@0: + * cairo_format_t -- these are 1-bit pixels stored in 32-bit michael@0: + * quantities. michael@0: + */ michael@0: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); michael@0: + } else { michael@0: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); michael@0: + } michael@0: + michael@0: + /* The Apple docs say that for best performance, the stride and the data michael@0: + * pointer should be 16-byte aligned. malloc already aligns to 16-bytes, michael@0: + * so we don't have to anything special on allocation. michael@0: + */ michael@0: + stride = (stride + 15) & ~15; michael@0: + michael@0: + data = _cairo_malloc_ab (height, stride); michael@0: + if (!data) { michael@0: + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); michael@0: + } michael@0: + michael@0: + /* zero the memory to match the image surface behaviour */ michael@0: + memset (data, 0, height * stride); michael@0: + michael@0: + cairo_quartz_surface_t *surf; michael@0: + surf = (cairo_quartz_surface_t *) cairo_quartz_surface_create_for_data michael@0: + (data, format, width, height, stride); michael@0: + if (surf->base.status) { michael@0: + free (data); michael@0: + return (cairo_surface_t *) surf; michael@0: + } michael@0: + michael@0: + // We created this data, so we can delete it. michael@0: + surf->ownsData = TRUE; michael@0: + michael@0: + return (cairo_surface_t *) surf; michael@0: +} michael@0: + michael@0: +/** michael@0: + * cairo_quartz_surface_create_for_data michael@0: + * @data: a pointer to a buffer supplied by the application in which michael@0: + * to write contents. This pointer must be suitably aligned for any michael@0: + * kind of variable, (for example, a pointer returned by malloc). michael@0: + * @format: format of pixels in the surface to create michael@0: + * @width: width of the surface, in pixels michael@0: + * @height: height of the surface, in pixels michael@0: + * michael@0: + * Creates a Quartz surface backed by a CGBitmap. The surface is michael@0: + * created using the Device RGB (or Device Gray, for A8) color space. michael@0: + * All Cairo operations, including those that require software michael@0: + * rendering, will succeed on this surface. michael@0: + * michael@0: + * Return value: the newly created surface. michael@0: + * michael@0: + * Since: 1.12 michael@0: + **/ michael@0: +cairo_surface_t * michael@0: +cairo_quartz_surface_create_for_data (unsigned char *data, michael@0: + cairo_format_t format, michael@0: + unsigned int width, michael@0: + unsigned int height, michael@0: + unsigned int stride) michael@0: +{ michael@0: cairo_quartz_surface_t *surf; michael@0: CGContextRef cgc; michael@0: CGColorSpaceRef cgColorspace; michael@0: CGBitmapInfo bitinfo; michael@0: - void *imageData; michael@0: - int stride; michael@0: + void *imageData = data; michael@0: int bitsPerComponent; michael@0: + unsigned int i; michael@0: michael@0: // verify width and height of surface michael@0: if (!_cairo_quartz_verify_surface_size(width, height)) michael@0: return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); michael@0: michael@0: if (width == 0 || height == 0) { michael@0: return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format), michael@0: width, height); michael@0: @@ -3058,47 +3140,30 @@ cairo_quartz_surface_create (cairo_forma michael@0: { michael@0: cgColorspace = CGColorSpaceCreateDeviceRGB(); michael@0: bitinfo = kCGBitmapByteOrder32Host; michael@0: if (format == CAIRO_FORMAT_ARGB32) michael@0: bitinfo |= kCGImageAlphaPremultipliedFirst; michael@0: else michael@0: bitinfo |= kCGImageAlphaNoneSkipFirst; michael@0: bitsPerComponent = 8; michael@0: - stride = width * 4; michael@0: } else if (format == CAIRO_FORMAT_A8) { michael@0: cgColorspace = NULL; michael@0: - stride = width; michael@0: bitinfo = kCGImageAlphaOnly; michael@0: bitsPerComponent = 8; michael@0: } else if (format == CAIRO_FORMAT_A1) { michael@0: /* I don't think we can usefully support this, as defined by michael@0: * cairo_format_t -- these are 1-bit pixels stored in 32-bit michael@0: * quantities. michael@0: */ michael@0: return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); michael@0: } else { michael@0: return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); michael@0: } michael@0: michael@0: - /* The Apple docs say that for best performance, the stride and the data michael@0: - * pointer should be 16-byte aligned. malloc already aligns to 16-bytes, michael@0: - * so we don't have to anything special on allocation. michael@0: - */ michael@0: - stride = (stride + 15) & ~15; michael@0: - michael@0: - imageData = _cairo_malloc_ab (height, stride); michael@0: - if (!imageData) { michael@0: - CGColorSpaceRelease (cgColorspace); michael@0: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); michael@0: - } michael@0: - michael@0: - /* zero the memory to match the image surface behaviour */ michael@0: - memset (imageData, 0, height * stride); michael@0: - michael@0: cgc = CGBitmapContextCreate (imageData, michael@0: width, michael@0: height, michael@0: bitsPerComponent, michael@0: stride, michael@0: cgColorspace, michael@0: bitinfo); michael@0: CGColorSpaceRelease (cgColorspace); michael@0: @@ -3118,16 +3183,17 @@ cairo_quartz_surface_create (cairo_forma michael@0: CGContextRelease (cgc); michael@0: free (imageData); michael@0: // create_internal will have set an error michael@0: return (cairo_surface_t*) surf; michael@0: } michael@0: michael@0: surf->imageData = imageData; michael@0: surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride); michael@0: + surf->ownsData = FALSE; michael@0: michael@0: return (cairo_surface_t *) surf; michael@0: } michael@0: michael@0: /** michael@0: * cairo_quartz_surface_get_cg_context michael@0: * @surface: the Cairo Quartz surface michael@0: * michael@0: diff --git a/gfx/cairo/cairo/src/cairo-quartz.h b/gfx/cairo/cairo/src/cairo-quartz.h michael@0: --- a/gfx/cairo/cairo/src/cairo-quartz.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-quartz.h michael@0: @@ -45,16 +45,23 @@ michael@0: CAIRO_BEGIN_DECLS michael@0: michael@0: cairo_public cairo_surface_t * michael@0: cairo_quartz_surface_create (cairo_format_t format, michael@0: unsigned int width, michael@0: unsigned int height); michael@0: michael@0: cairo_public cairo_surface_t * michael@0: +cairo_quartz_surface_create_for_data (unsigned char *data, michael@0: + cairo_format_t format, michael@0: + unsigned int width, michael@0: + unsigned int height, michael@0: + unsigned int stride); michael@0: + michael@0: +cairo_public cairo_surface_t * michael@0: cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface, michael@0: unsigned int width, michael@0: unsigned int height); michael@0: michael@0: cairo_public cairo_surface_t * michael@0: cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext, michael@0: unsigned int width, michael@0: unsigned int height); michael@0: diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h michael@0: --- a/gfx/cairo/cairo/src/cairo-rename.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-rename.h michael@0: @@ -176,16 +176,17 @@ michael@0: #define cairo_qpainter_surface_get_image _moz_cairo_qpainter_surface_get_image michael@0: #define cairo_qpainter_surface_get_qimage _moz_cairo_qpainter_surface_get_qimage michael@0: #define cairo_qpainter_surface_get_qpainter _moz_cairo_qpainter_surface_get_qpainter michael@0: #define cairo_quartz_font_face_create_for_atsu_font_id _moz_cairo_quartz_font_face_create_for_atsu_font_id michael@0: #define cairo_quartz_font_face_create_for_cgfont _moz_cairo_quartz_font_face_create_for_cgfont michael@0: #define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create michael@0: #define cairo_quartz_image_surface_get_image _moz_cairo_quartz_image_surface_get_image michael@0: #define cairo_quartz_surface_create _moz_cairo_quartz_surface_create michael@0: +#define cairo_quartz_surface_create_for_data _moz_cairo_quartz_surface_create_for_data michael@0: #define cairo_quartz_surface_create_for_cg_context _moz_cairo_quartz_surface_create_for_cg_context michael@0: #define cairo_quartz_surface_get_cg_context _moz_cairo_quartz_surface_get_cg_context michael@0: #define cairo_quartz_surface_get_image _moz_cairo_quartz_surface_get_image michael@0: #define cairo_rectangle _moz_cairo_rectangle michael@0: #define cairo_rectangle_list_destroy _moz_cairo_rectangle_list_destroy michael@0: #define cairo_reference _moz_cairo_reference michael@0: #define cairo_rel_curve_to _moz_cairo_rel_curve_to michael@0: #define cairo_rel_line_to _moz_cairo_rel_line_to