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

Jeff Muizelaar jrmuizel at kemper.freedesktop.org
Thu Dec 11 11:39:35 PST 2008


 src/cairo-quartz-surface.c |   55 ++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 18 deletions(-)

New commits:
commit 2f1b581f54713c899f3b03af1e0ac8c38c36c385
Author: Jeff Muizelaar <jmuizelaar at mozilla.com>
Date:   Thu Dec 11 10:34:37 2008 -0500

    [quartz] Create a copy instead of increasing the reference
    
    The pattern could be stack allocated so we can't take a reference to it.
    
    Some testing of quartz shows that it doesn't deal with malloc failure particularily
    well. In the best case CGFunctionCreate returns NULL, in the worst case it just crashes.
    Quartz does seem to be able to handle a NULL CGFunctionRef, so returning NULL if
    we fail to copy the pattern avoids complicating the code to deal with
    propagating the failure and shouldn't cause any additional crashes.
    
    Based on a patch by Paolo Bonzini.

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 9dc5eaa..3466185 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -682,13 +682,19 @@ ComputeGradientValue (void *info, const float *in, float *out)
 static CGFunctionRef
 CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
 {
+    cairo_pattern_t *pat;
     float input_value_range[2] = { 0.f, 1.f };
     float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
     CGFunctionCallbacks callbacks = {
 	0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
     };
 
-    return CGFunctionCreate (cairo_pattern_reference (&gpat->base),
+    if (_cairo_pattern_create_copy (&pat, &gpat->base))
+	/* quartz doesn't deal very well with malloc failing, so there's
+	 * not much point in us trying either */
+	return NULL;
+
+    return CGFunctionCreate (pat,
 			     1,
 			     input_value_range,
 			     4,
@@ -702,6 +708,7 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
 				 CGPoint *start, CGPoint *end,
 				 CGAffineTransform matrix)
 {
+    cairo_pattern_t *pat;
     float input_value_range[2];
     float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
     CGFunctionCallbacks callbacks = {
@@ -766,7 +773,12 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
     input_value_range[0] = 0.0 - 1.0 * rep_start;
     input_value_range[1] = 1.0 + 1.0 * rep_end;
 
-    return CGFunctionCreate (cairo_pattern_reference (&gpat->base),
+    if (_cairo_pattern_create_copy (&pat, &gpat->base))
+	/* quartz doesn't deal very well with malloc failing, so there's
+	 * not much point in us trying either */
+	return NULL;
+
+    return CGFunctionCreate (pat,
 			     1,
 			     input_value_range,
 			     4,
commit f7b3f1b7d70a271575d3bb233b7ee51a21861c05
Author: Jeff Muizelaar <jmuizelaar at mozilla.com>
Date:   Wed Dec 10 17:54:59 2008 -0500

    [quartz] Propagate const patterns through the casts
    
    As part of this avoid using cairo_pattern_get_matrix() because it requires a
    'cairo_pattern_t *' instead of 'const cairo_pattern *'
    
    Also, make a copy of the pattern before pasing it in to cairo_set_source()

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 17fabe0..9dc5eaa 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -680,7 +680,7 @@ ComputeGradientValue (void *info, const float *in, float *out)
 }
 
 static CGFunctionRef
-CreateGradientFunction (cairo_gradient_pattern_t *gpat)
+CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
 {
     float input_value_range[2] = { 0.f, 1.f };
     float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
@@ -698,7 +698,7 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat)
 
 static CGFunctionRef
 CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
-				 cairo_gradient_pattern_t *gpat,
+				 const cairo_gradient_pattern_t *gpat,
 				 CGPoint *start, CGPoint *end,
 				 CGAffineTransform matrix)
 {
@@ -1013,7 +1013,7 @@ typedef enum {
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
-				     cairo_pattern_t *source)
+				     const cairo_pattern_t *source)
 {
     CGRect clipBox = CGContextGetClipBoundingBox (surface->cgContext);
     CGAffineTransform ctm;
@@ -1022,6 +1022,7 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
     cairo_surface_t *fallback;
     cairo_t *fallback_cr;
     CGImageRef img;
+    cairo_pattern_t *source_copy;
 
     cairo_status_t status;
 
@@ -1050,7 +1051,13 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
     /* Paint the source onto our temporary */
     fallback_cr = cairo_create (fallback);
     cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE);
-    cairo_set_source (fallback_cr, source);
+
+    /* Use a copy of the pattern because it is const and could be allocated
+     * on the stack */
+    status = _cairo_pattern_create_copy (&source_copy, source);
+    cairo_set_source (fallback_cr, source_copy);
+    cairo_pattern_destroy (source_copy);
+
     cairo_paint (fallback_cr);
     cairo_destroy (fallback_cr);
 
@@ -1070,9 +1077,9 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
-				   cairo_linear_pattern_t *lpat)
+				   const cairo_linear_pattern_t *lpat)
 {
-    cairo_pattern_t *abspat = &lpat->base.base;
+    const cairo_pattern_t *abspat = &lpat->base.base;
     cairo_matrix_t mat;
     CGPoint start, end;
     CGFunctionRef gradFunc;
@@ -1085,7 +1092,7 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
 	return DO_SOLID;
     }
 
-    cairo_pattern_get_matrix (abspat, &mat);
+    mat = abspat->matrix;
     cairo_matrix_invert (&mat);
     _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
 
@@ -1119,9 +1126,9 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
-				   cairo_radial_pattern_t *rpat)
+				   const cairo_radial_pattern_t *rpat)
 {
-    cairo_pattern_t *abspat = &rpat->base.base;
+    const cairo_pattern_t *abspat = &rpat->base.base;
     cairo_matrix_t mat;
     CGPoint start, end;
     CGFunctionRef gradFunc;
@@ -1145,7 +1152,7 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
 	return _cairo_quartz_setup_fallback_source (surface, &rpat->base.base);
     }
 
-    cairo_pattern_get_matrix (abspat, &mat);
+    mat = abspat->matrix;
     cairo_matrix_invert (&mat);
     _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
 
@@ -1199,13 +1206,13 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
     }
 
     if (source->type == CAIRO_PATTERN_TYPE_LINEAR) {
-	cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *)source;
+	const cairo_linear_pattern_t *lpat = (const cairo_linear_pattern_t *)source;
 	return _cairo_quartz_setup_linear_source (surface, lpat);
 
     }
 
     if (source->type == CAIRO_PATTERN_TYPE_RADIAL) {
-	cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *)source;
+	const cairo_radial_pattern_t *rpat = (const cairo_radial_pattern_t *)source;
 	return _cairo_quartz_setup_radial_source (surface, rpat);
 
     }
@@ -1213,7 +1220,7 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	(source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT)))
     {
-	cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
+	const cairo_surface_pattern_t *spat = (const cairo_surface_pattern_t *) source;
 	cairo_surface_t *pat_surf = spat->surface;
 	CGImageRef img;
 	cairo_matrix_t m = spat->base.matrix;
@@ -2259,7 +2266,7 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
     cairo_t *gradient_surf_cr = NULL;
 
     cairo_surface_pattern_t surface_pattern;
-    cairo_pattern_t *mask_copy = NULL;
+    cairo_pattern_t *mask_copy;
     cairo_int_status_t status;
 
     /* Render the gradient to a surface */
@@ -2271,13 +2278,13 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface,
     /* make a copy of the pattern because because cairo_set_source doesn't take
      * a 'const cairo_pattern_t *' */
     _cairo_pattern_create_copy (&mask_copy, mask);
-
     cairo_set_source (gradient_surf_cr, mask_copy);
+    cairo_pattern_destroy (mask_copy);
+
     cairo_set_operator (gradient_surf_cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (gradient_surf_cr);
     status = cairo_status (gradient_surf_cr);
     cairo_destroy (gradient_surf_cr);
-    cairo_pattern_destroy (mask_copy);
 
     if (status)
 	goto BAIL;


More information about the cairo-commit mailing list