[cairo] [PATCH 3/3] quartz: Provide a valid implementation of map_to_image

Andrea Canciani ranma42 at gmail.com
Thu May 17 13:33:44 PDT 2012


and reuse it to implement acquire_source.

Fixes

cairo-quartz-surface.c: In function '_cairo_quartz_surface_map_to_image':
cairo-quartz-surface.c:1568: warning: return from incompatible pointer type
cairo-quartz-surface.c:1576: warning: return from incompatible pointer type
---
 src/cairo-quartz-surface.c |  203 +++++++++++++++----------------------------
 1 files changed, 71 insertions(+), 132 deletions(-)

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 994b92f..7c8c453 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -43,7 +43,7 @@
 #include "cairo-compositor-private.h"
 #include "cairo-default-context-private.h"
 #include "cairo-error-private.h"
-#include "cairo-image-surface-private.h"
+#include "cairo-image-surface-inline.h"
 #include "cairo-pattern-private.h"
 #include "cairo-surface-backend-private.h"
 #include "cairo-surface-clipper-private.h"
@@ -1386,96 +1386,82 @@ _cairo_quartz_draw_source (cairo_quartz_drawing_state_t *state,
     }
 }
 
-/*
- * get source/dest image implementation
- */
-
-/* Read the image from the surface's front buffer */
-static cairo_int_status_t
-_cairo_quartz_get_image (cairo_quartz_surface_t *surface,
-			 cairo_image_surface_t **image_out)
+static cairo_image_surface_t *
+_cairo_quartz_surface_map_to_image (void *abstract_surface,
+				    const cairo_rectangle_int_t *extents)
 {
-    unsigned char *imageData;
-    cairo_image_surface_t *isurf;
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    unsigned int stride, bitinfo, bpp, color_comps;
+    CGColorSpaceRef colorspace;
+    void *imageData;
+    cairo_format_t format;
 
-    if (IS_EMPTY (surface)) {
-	*image_out = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (surface->imageSurfaceEquiv)
+	return _cairo_surface_map_to_image (surface->imageSurfaceEquiv, extents);
 
-    if (surface->imageSurfaceEquiv) {
-	*image_out = (cairo_image_surface_t*) cairo_surface_reference (surface->imageSurfaceEquiv);
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (IS_EMPTY (surface))
+	return (cairo_image_surface_t *) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
 
-    if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) {
-	unsigned int stride;
-	unsigned int bitinfo;
-	unsigned int bpc, bpp;
-	CGColorSpaceRef colorspace;
-	unsigned int color_comps;
+    if (! _cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext))
+	return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-	imageData = (unsigned char *) CGBitmapContextGetData (surface->cgContext);
+    bitinfo = CGBitmapContextGetBitmapInfo (surface->cgContext);
+    bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext);
 
-	bitinfo = CGBitmapContextGetBitmapInfo (surface->cgContext);
-	stride = CGBitmapContextGetBytesPerRow (surface->cgContext);
-	bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext);
-	bpc = CGBitmapContextGetBitsPerComponent (surface->cgContext);
+    // let's hope they don't add YUV under us
+    colorspace = CGBitmapContextGetColorSpace (surface->cgContext);
+    color_comps = CGColorSpaceGetNumberOfComponents (colorspace);
 
-	// let's hope they don't add YUV under us
-	colorspace = CGBitmapContextGetColorSpace (surface->cgContext);
-	color_comps = CGColorSpaceGetNumberOfComponents (colorspace);
+    /* XXX TODO: We can handle many more data formats by
+     * converting to pixman_format_t */
 
-	// XXX TODO: We can handle all of these by converting to
-	// pixman masks, including non-native-endian masks
-	if (bpc != 8)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (bpp == 32 && color_comps == 3 &&
+	(bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst &&
+	(bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
+    {
+	format = CAIRO_FORMAT_ARGB32;
+    }
+    else if (bpp == 32 && color_comps == 3 &&
+	     (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaNoneSkipFirst &&
+	     (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
+    {
+	format = CAIRO_FORMAT_RGB24;
+    }
+    else if (bpp == 8 && color_comps == 1)
+    {
+	format = CAIRO_FORMAT_A1;
+    }
+    else
+    {
+	return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+    }
 
-	if (bpp != 32 && bpp != 8)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    imageData = CGBitmapContextGetData (surface->cgContext);
+    stride = CGBitmapContextGetBytesPerRow (surface->cgContext);
 
-	if (color_comps != 3 && color_comps != 1)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    return (cairo_image_surface_t *) cairo_image_surface_create_for_data (imageData,
+									  format,
+									  extents->width,
+									  extents->height,
+									  stride);
+}
 
-	if (bpp == 32 && color_comps == 3 &&
-	    (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst &&
-	    (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
-	{
-	    isurf = (cairo_image_surface_t *)
-		cairo_image_surface_create_for_data (imageData,
-						     CAIRO_FORMAT_ARGB32,
-						     surface->extents.width,
-						     surface->extents.height,
-						     stride);
-	} else if (bpp == 32 && color_comps == 3 &&
-		   (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaNoneSkipFirst &&
-		   (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host)
-	{
-	    isurf = (cairo_image_surface_t *)
-		cairo_image_surface_create_for_data (imageData,
-						     CAIRO_FORMAT_RGB24,
-						     surface->extents.width,
-						     surface->extents.height,
-						     stride);
-	} else if (bpp == 8 && color_comps == 1)
-	{
-	    isurf = (cairo_image_surface_t *)
-		cairo_image_surface_create_for_data (imageData,
-						     CAIRO_FORMAT_A8,
-						     surface->extents.width,
-						     surface->extents.height,
-						     stride);
-	} else {
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	}
-    } else {
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+static cairo_int_status_t
+_cairo_quartz_surface_unmap_image (void *abstract_surface,
+				   cairo_image_surface_t *image)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+
+    if (surface->imageSurfaceEquiv)
+	return _cairo_surface_unmap_image (surface->imageSurfaceEquiv, image);
+
+    cairo_surface_finish (&image->base);
+    cairo_surface_destroy (&image->base);
 
-    *image_out = isurf;
     return CAIRO_STATUS_SUCCESS;
 }
 
+
 /*
  * Cairo surface backend implementations
  */
@@ -1514,35 +1500,20 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface,
 					     cairo_image_surface_t **image_out,
 					     void **image_extra)
 {
-    cairo_int_status_t status;
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
 
     //ND ((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface));
 
-    status = _cairo_quartz_get_image (surface, image_out);
-    if (unlikely (status))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
     *image_extra = NULL;
 
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_surface_t *
-_cairo_quartz_surface_snapshot (void *abstract_surface)
-{
-    cairo_int_status_t status;
-    cairo_quartz_surface_t *surface = abstract_surface;
-    cairo_image_surface_t *image;
-
-    if (surface->imageSurfaceEquiv)
-	return NULL;
-
-    status = _cairo_quartz_get_image (surface, &image);
-    if (unlikely (status))
-        return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
+    *image_out = _cairo_quartz_surface_map_to_image (surface, &surface->extents);
+    if (unlikely (cairo_surface_status(&(*image_out)->base))) {
+	cairo_surface_destroy (&(*image_out)->base);
+	*image_out = NULL;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
 
-    return &image->base;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -1550,39 +1521,7 @@ _cairo_quartz_surface_release_source_image (void *abstract_surface,
 					    cairo_image_surface_t *image,
 					    void *image_extra)
 {
-    cairo_surface_destroy (&image->base);
-}
-
-
-static cairo_image_surface_t *
-_cairo_quartz_surface_map_to_image (void *abstract_surface,
-				    const cairo_rectangle_int_t *extents)
-{
-    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
-    cairo_image_surface_t *image;
-    cairo_surface_t *subsurface;
-    cairo_status_t status;
-
-    status = _cairo_quartz_get_image (surface, &image);
-    if (unlikely (status))
-	return _cairo_surface_create_in_error (status);
-
-    /* Is this legitimate? shouldn't it return an image surface? */
-    /* XXX: BROKEN! */
-
-    subsurface = _cairo_surface_create_for_rectangle_int (&image->base, extents);
-    cairo_surface_destroy (&image->base);
-
-    return subsurface;
-}
-
-static cairo_int_status_t
-_cairo_quartz_surface_unmap_image (void *abstract_surface,
-				   cairo_image_surface_t *image)
-{
-    cairo_surface_destroy (&image->base);
-
-    return CAIRO_STATUS_SUCCESS;
+    _cairo_quartz_surface_unmap_image (abstract_surface, image);
 }
 
 static cairo_surface_t *
@@ -2221,7 +2160,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
     _cairo_surface_default_source,
     _cairo_quartz_surface_acquire_source_image,
     _cairo_quartz_surface_release_source_image,
-    _cairo_quartz_surface_snapshot,
+    NULL, /* snapshot */
 
     NULL, /* copy_page */
     NULL, /* show_page */
-- 
1.7.7.5 (Apple Git-26)



More information about the cairo mailing list