[cairo-commit] 3 commits - src/cairo-quartz-surface.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Tue Feb 2 10:59:29 PST 2010


 src/cairo-quartz-surface.c |  325 +++++++++++++++++++++++++++++++++------------
 1 file changed, 244 insertions(+), 81 deletions(-)

New commits:
commit e2be50c722347734801468d7d9568a18dbbaaa17
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Fri Jan 29 12:06:13 2010 +0100

    [quartz] Fix UNSUPPORTED operations
    
    The fallback path shouldn't be used anymore, thus fallbacks are now
    handled by passing unsupported ops to the image backend.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 904cbb8..3efd8b4 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1868,10 +1868,10 @@ _cairo_quartz_surface_get_extents (void *abstract_surface,
 }
 
 static cairo_int_status_t
-_cairo_quartz_surface_paint (void *abstract_surface,
-			     cairo_operator_t op,
-			     const cairo_pattern_t *source,
-			     cairo_clip_t *clip)
+_cairo_quartz_surface_paint_cg (void *abstract_surface,
+				cairo_operator_t op,
+				const cairo_pattern_t *source,
+				cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -1917,16 +1917,43 @@ _cairo_quartz_surface_paint (void *abstract_surface,
 }
 
 static cairo_int_status_t
-_cairo_quartz_surface_fill (void *abstract_surface,
+_cairo_quartz_surface_paint (void *abstract_surface,
 			     cairo_operator_t op,
 			     const cairo_pattern_t *source,
-			     cairo_path_fixed_t *path,
-			     cairo_fill_rule_t fill_rule,
-			     double tolerance,
-			     cairo_antialias_t antialias,
 			     cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    cairo_int_status_t rv;
+    cairo_image_surface_t *image;
+
+    rv = _cairo_quartz_surface_paint_cg (abstract_surface,
+					 op,
+					 source,
+					 clip);
+
+    if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+	return rv;
+
+    rv = _cairo_quartz_get_image (surface, &image);
+    if (rv == CAIRO_STATUS_SUCCESS) {
+	rv = _cairo_surface_paint (&image->base, op, source, clip);
+	cairo_surface_destroy (&image->base);
+    }
+
+    return rv;
+}
+
+static cairo_int_status_t
+_cairo_quartz_surface_fill_cg (void *abstract_surface,
+			       cairo_operator_t op,
+			       const cairo_pattern_t *source,
+			       cairo_path_fixed_t *path,
+			       cairo_fill_rule_t fill_rule,
+			       double tolerance,
+			       cairo_antialias_t antialias,
+			       cairo_clip_t *clip)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
     cairo_quartz_action_t action;
     quartz_stroke_t stroke;
@@ -2009,16 +2036,53 @@ _cairo_quartz_surface_fill (void *abstract_surface,
 }
 
 static cairo_int_status_t
-_cairo_quartz_surface_stroke (void *abstract_surface,
-			      cairo_operator_t op,
-			      const cairo_pattern_t *source,
-			      cairo_path_fixed_t *path,
-			      const cairo_stroke_style_t *style,
-			      const cairo_matrix_t *ctm,
-			      const cairo_matrix_t *ctm_inverse,
-			      double tolerance,
-			      cairo_antialias_t antialias,
-			      cairo_clip_t *clip)
+_cairo_quartz_surface_fill (void *abstract_surface,
+			    cairo_operator_t op,
+			    const cairo_pattern_t *source,
+			    cairo_path_fixed_t *path,
+			    cairo_fill_rule_t fill_rule,
+			    double tolerance,
+			    cairo_antialias_t antialias,
+			    cairo_clip_t *clip)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    cairo_int_status_t rv;
+    cairo_image_surface_t *image;
+
+    rv = _cairo_quartz_surface_fill_cg (abstract_surface,
+					op,
+					source,
+					path,
+					fill_rule,
+					tolerance,
+					antialias,
+					clip);
+
+    if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+	return rv;
+
+    rv = _cairo_quartz_get_image (surface, &image);
+    if (rv == CAIRO_STATUS_SUCCESS) {
+	rv = _cairo_surface_fill (&image->base, op, source,
+				  path, fill_rule, tolerance, antialias,
+				  clip);
+	cairo_surface_destroy (&image->base);
+    }
+
+    return rv;
+}
+
+static cairo_int_status_t
+_cairo_quartz_surface_stroke_cg (void *abstract_surface,
+				 cairo_operator_t op,
+				 const cairo_pattern_t *source,
+				 cairo_path_fixed_t *path,
+				 const cairo_stroke_style_t *style,
+				 const cairo_matrix_t *ctm,
+				 const cairo_matrix_t *ctm_inverse,
+				 double tolerance,
+				 cairo_antialias_t antialias,
+				 cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -2140,16 +2204,52 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
     return rv;
 }
 
+static cairo_int_status_t
+_cairo_quartz_surface_stroke (void *abstract_surface,
+			      cairo_operator_t op,
+			      const cairo_pattern_t *source,
+			      cairo_path_fixed_t *path,
+			      const cairo_stroke_style_t *style,
+			      const cairo_matrix_t *ctm,
+			      const cairo_matrix_t *ctm_inverse,
+			      double tolerance,
+			      cairo_antialias_t antialias,
+			      cairo_clip_t *clip)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    cairo_int_status_t rv;
+    cairo_image_surface_t *image;
+
+    rv = _cairo_quartz_surface_stroke_cg (abstract_surface, op, source,
+					  path, style, ctm, ctm_inverse,
+					  tolerance, antialias,
+					  clip);
+
+    if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+	return rv;
+
+    rv = _cairo_quartz_get_image (surface, &image);
+    if (rv == CAIRO_STATUS_SUCCESS) {
+	rv = _cairo_surface_stroke (&image->base, op, source,
+				    path, style, ctm, ctm_inverse,
+				    tolerance, antialias,
+				    clip);
+	cairo_surface_destroy (&image->base);
+    }
+
+    return rv;
+}
+
 #if CAIRO_HAS_QUARTZ_FONT
 static cairo_int_status_t
-_cairo_quartz_surface_show_glyphs (void *abstract_surface,
-				   cairo_operator_t op,
-				   const cairo_pattern_t *source,
-				   cairo_glyph_t *glyphs,
-				   int num_glyphs,
-				   cairo_scaled_font_t *scaled_font,
-				   cairo_clip_t *clip,
-				   int *remaining_glyphs)
+_cairo_quartz_surface_show_glyphs_cg (void *abstract_surface,
+				      cairo_operator_t op,
+				      const cairo_pattern_t *source,
+				      cairo_glyph_t *glyphs,
+				      int num_glyphs,
+				      cairo_scaled_font_t *scaled_font,
+				      cairo_clip_t *clip,
+				      int *remaining_glyphs)
 {
     CGAffineTransform textTransform, ctm;
 #define STATIC_BUF_SIZE 64
@@ -2348,6 +2448,43 @@ BAIL:
 #endif /* CAIRO_HAS_QUARTZ_FONT */
 
 static cairo_int_status_t
+_cairo_quartz_surface_show_glyphs (void *abstract_surface,
+				   cairo_operator_t op,
+				   const cairo_pattern_t *source,
+				   cairo_glyph_t *glyphs,
+				   int num_glyphs,
+				   cairo_scaled_font_t *scaled_font,
+				   cairo_clip_t *clip,
+				   int *remaining_glyphs)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    cairo_int_status_t rv = CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_image_surface_t *image;
+
+#if CAIRO_HAS_QUARTZ_FONT
+    rv = _cairo_quartz_surface_show_glyphs_cg (abstract_surface, op, source,
+					       glyphs, num_glyphs,
+					       scaled_font, clip, remaining_glyphs);
+
+    if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+	return rv;
+
+#endif
+
+    rv = _cairo_quartz_get_image (surface, &image);
+    if (rv == CAIRO_STATUS_SUCCESS) {
+	rv = _cairo_surface_show_text_glyphs (&image->base, op, source,
+					      NULL, 0,
+					      glyphs, num_glyphs,
+					      NULL, 0, 0,
+					      scaled_font, clip);
+	cairo_surface_destroy (&image->base);
+    }
+
+    return rv;
+}
+
+static cairo_int_status_t
 _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
                                          cairo_operator_t op,
                                          const cairo_pattern_t *source,
@@ -2445,11 +2582,11 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
 }
 
 static cairo_int_status_t
-_cairo_quartz_surface_mask (void *abstract_surface,
-			    cairo_operator_t op,
-			    const cairo_pattern_t *source,
-			    const cairo_pattern_t *mask,
-			    cairo_clip_t *clip)
+_cairo_quartz_surface_mask_cg (void *abstract_surface,
+			       cairo_operator_t op,
+			       const cairo_pattern_t *source,
+			       const cairo_pattern_t *mask,
+			       cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -2493,6 +2630,35 @@ _cairo_quartz_surface_mask (void *abstract_surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_int_status_t
+_cairo_quartz_surface_mask (void *abstract_surface,
+			    cairo_operator_t op,
+			    const cairo_pattern_t *source,
+			    const cairo_pattern_t *mask,
+			    cairo_clip_t *clip)
+{
+    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
+    cairo_int_status_t rv;
+    cairo_image_surface_t *image;
+
+    rv = _cairo_quartz_surface_mask_cg (abstract_surface,
+					op,
+					source,
+					mask,
+					clip);
+
+    if (likely (rv != CAIRO_INT_STATUS_UNSUPPORTED))
+	return rv;
+
+    rv = _cairo_quartz_get_image (surface, &image);
+    if (rv == CAIRO_STATUS_SUCCESS) {
+	rv = _cairo_surface_mask (&image->base, op, source, mask, clip);
+	cairo_surface_destroy (&image->base);
+    }
+
+    return rv;
+}
+
 static cairo_status_t
 _cairo_quartz_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
 						   cairo_path_fixed_t *path,
@@ -2574,11 +2740,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
     _cairo_quartz_surface_mask,
     _cairo_quartz_surface_stroke,
     _cairo_quartz_surface_fill,
-#if CAIRO_HAS_QUARTZ_FONT
     _cairo_quartz_surface_show_glyphs,
-#else
-    NULL, /* show_glyphs */
-#endif
 
     _cairo_quartz_surface_snapshot,
     NULL, /* is_similar */
commit 3e69c38fe642be467fee0cad166b83006741d55c
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Sun Jan 24 21:59:32 2010 +0100

    [quartz] Fix surface to CGImage conversion
    
    Snapshotting a surface doesn't produce a cairo_image_surface_t.
    Acquiring (and later releasing) the surface is needed to access
    its image data.

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index a7a94b4..904cbb8 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -920,11 +920,18 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
 
 /* Obtain a CGImageRef from a #cairo_surface_t * */
 
+typedef struct {
+    cairo_surface_t *surface;
+    cairo_image_surface_t *image_out;
+    void *image_extra;
+} quartz_source_image_t;
+
 static void
 DataProviderReleaseCallback (void *info, const void *data, size_t size)
 {
-    cairo_surface_t *surface = (cairo_surface_t *) info;
-    cairo_surface_destroy (surface);
+    quartz_source_image_t *source_img = info;
+    _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra);
+    free (source_img);
 }
 
 static cairo_status_t
@@ -932,11 +939,9 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
 			   cairo_surface_t *source,
 			   CGImageRef *image_out)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    cairo_surface_type_t stype = cairo_surface_get_type (source);
-    cairo_image_surface_t *isurf;
-    CGImageRef image;
-    void *image_extra;
+    cairo_status_t status;
+    quartz_source_image_t *source_img;
+    cairo_surface_type_t stype = source->backend->type;
 
     if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
 	cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source;
@@ -958,43 +963,39 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
 	}
     }
 
-    if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
-	status = _cairo_surface_acquire_source_image (source,
-						      &isurf, &image_extra);
-	if (status)
-	    return status;
-    } else {
-	isurf = (cairo_image_surface_t *) source;
+    source_img = malloc (sizeof (quartz_source_image_t));
+    if (source_img == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    source_img->surface = source;
+
+    status = _cairo_surface_acquire_source_image (source_img->surface, &source_img->image_out, &source_img->image_extra);
+    if (status) {
+	free (source_img);
+	return status;
     }
 
-    if (isurf->width == 0 || isurf->height == 0) {
+    if (source_img->image_out->width == 0 || source_img->image_out->height == 0) {
 	*image_out = NULL;
+	DataProviderReleaseCallback (source_img,
+				     source_img->image_out->data,
+				     source_img->image_out->height * source_img->image_out->stride);
     } else {
-	cairo_image_surface_t *isurf_snap = NULL;
-
-	isurf_snap = (cairo_image_surface_t*)
-	    _cairo_surface_snapshot (&isurf->base);
-	if (isurf_snap->base.status)
-	    return isurf_snap->base.status;
-
-	image = _cairo_quartz_create_cgimage (isurf_snap->format,
-					      isurf_snap->width,
-					      isurf_snap->height,
-					      isurf_snap->stride,
-					      isurf_snap->data,
-					      TRUE,
-					      NULL,
-					      DataProviderReleaseCallback,
-					      isurf_snap);
-
-	*image_out = image;
-	if (image == NULL)
+	*image_out = _cairo_quartz_create_cgimage (source_img->image_out->format,
+						   source_img->image_out->width,
+						   source_img->image_out->height,
+						   source_img->image_out->stride,
+						   source_img->image_out->data,
+						   TRUE,
+						   NULL,
+						   DataProviderReleaseCallback,
+						   source_img);
+
+	/* TODO: differentiate memory error and unsupported surface type */
+	if (*image_out == NULL)
 	    status = CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (&isurf->base != source)
-	_cairo_surface_release_source_image (source, isurf, image_extra);
-
     return status;
 }
 
commit 7aba47e9d87bf09a5fa7e41a3c76c775f28b08f3
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Jan 25 15:09:51 2010 +0100

    [quartz] Silence compiler warnings

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index bbfff37..a7a94b4 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -182,14 +182,14 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
     CGImageRef image = NULL;
     CGDataProviderRef dataProvider = NULL;
     CGColorSpaceRef colorSpace = colorSpaceOverride;
-    CGBitmapInfo bitinfo;
+    CGBitmapInfo bitinfo = kCGBitmapByteOrder32Host;
     int bitsPerComponent, bitsPerPixel;
 
     switch (format) {
 	case CAIRO_FORMAT_ARGB32:
 	    if (colorSpace == NULL)
 		colorSpace = CGColorSpaceCreateDeviceRGB();
-	    bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+	    bitinfo |= kCGImageAlphaPremultipliedFirst;
 	    bitsPerComponent = 8;
 	    bitsPerPixel = 32;
 	    break;
@@ -197,7 +197,7 @@ _cairo_quartz_create_cgimage (cairo_format_t format,
 	case CAIRO_FORMAT_RGB24:
 	    if (colorSpace == NULL)
 		colorSpace = CGColorSpaceCreateDeviceRGB();
-	    bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+	    bitinfo |= kCGImageAlphaNoneSkipFirst;
 	    bitsPerComponent = 8;
 	    bitsPerPixel = 32;
 	    break;
@@ -302,7 +302,7 @@ _cairo_quartz_verify_surface_size(int width, int height)
 
 typedef struct _quartz_stroke {
     CGContextRef cgContext;
-    cairo_matrix_t *ctm_inverse;
+    const cairo_matrix_t *ctm_inverse;
 } quartz_stroke_t;
 
 /* cairo path -> execute in context */
@@ -864,8 +864,8 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
     dy = fabs (mend.y - mstart.y);
 
     if (dx > 1e-6) {
-	x_rep_start = (int) ceil(MIN(mstart.x, mend.x) / dx);
-	x_rep_end = (int) ceil((surface->extents.width - MAX(mstart.x, mend.x)) / dx);
+	x_rep_start = ceil(MIN(mstart.x, mend.x) / dx);
+	x_rep_end = ceil((surface->extents.width - MAX(mstart.x, mend.x)) / dx);
 
 	if (mend.x < mstart.x) {
 	    int swap = x_rep_end;
@@ -875,8 +875,8 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
     }
 
     if (dy > 1e-6) {
-	y_rep_start = (int) ceil(MIN(mstart.y, mend.y) / dy);
-	y_rep_end = (int) ceil((surface->extents.width - MAX(mstart.y, mend.y)) / dy);
+	y_rep_start = ceil(MIN(mstart.y, mend.y) / dy);
+	y_rep_end = ceil((surface->extents.width - MAX(mstart.y, mend.y)) / dy);
 
 	if (mend.y < mstart.y) {
 	    int swap = y_rep_end;


More information about the cairo-commit mailing list