[cairo-commit] cairo/src cairo-gstate.c, 1.140, 1.141 cairo-pattern.c, 1.42, 1.43 cairo.c, 1.102, 1.103 cairo.h, 1.126, 1.127 cairoint.h, 1.151, 1.152

Carl Worth commit at pdx.freedesktop.org
Mon Jun 13 16:36:42 PDT 2005


Committed by: cworth

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv9236/src

Modified Files:
	cairo-gstate.c cairo-pattern.c cairo.c cairo.h cairoint.h 
Log Message:

        * src/cairo.c (_cairo_set_source_solid),
        (cairo_set_source_surface), (cairo_mask_surface): No longer need
        to check for NULL after creating a pattern.

        * src/cairo.c (cairo_set_source), (cairo_mask): Propagate status
        errors from pattern->status to cr->status.

        Originally 2005-05-08  Owen Taylor  <otaylor at redhat.com>:

        * src/cairo-pattern.c src/cairoint.h: If allocation of pattern
        objects fails, return special static nil pattern objects.

        * src/cairo-pattern.c: If adding a color stop fails to allocate
        memory, set pattern->status. (And fix a memory leak.) Make public
        functions return when pattern->status is set, (and no longer
        return a cairo_status_t).

        * src/cairo-pattern.c src/cairo.h doc/public/cairo-sections.txt:
        Add cairo_pattern_status()

        * src/cairo-gstate.c: Check the status of gstate->source and
        of mask patterns passed in.


Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.140
retrieving revision 1.141
diff -u -d -r1.140 -r1.141
--- cairo-gstate.c	11 Jun 2005 08:09:15 -0000	1.140
+++ cairo-gstate.c	13 Jun 2005 23:36:40 -0000	1.141
@@ -128,7 +128,7 @@
     cairo_surface_reference (gstate->target);
 
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
-    if (gstate->source == NULL)
+    if (gstate->source->status)
 	return CAIRO_STATUS_NO_MEMORY;
 
     gstate->next = NULL;
@@ -393,8 +393,8 @@
 _cairo_gstate_set_source (cairo_gstate_t  *gstate,
 			  cairo_pattern_t *source)
 {
-    if (source == NULL)
-	return CAIRO_STATUS_NULL_POINTER;
+    if (source->status)
+	return source->status;
 
     cairo_pattern_reference (source);
     cairo_pattern_destroy (gstate->source);
@@ -723,6 +723,9 @@
     cairo_box_t box;
     cairo_traps_t traps;
 
+    if (gstate->source->status)
+	return gstate->source->status;
+
     status = _cairo_gstate_set_clip (gstate);
     if (status)
 	return status;
@@ -865,6 +868,12 @@
     cairo_status_t status;
     int mask_x, mask_y;
 
+    if (mask->status)
+	return mask->status;
+
+    if (gstate->source->status)
+	return gstate->source->status;
+
     status = _cairo_gstate_set_clip (gstate);
     if (status)
 	return status;
@@ -937,6 +946,9 @@
     cairo_status_t status;
     cairo_traps_t traps;
 
+    if (gstate->source->status)
+	return gstate->source->status;
+
     if (gstate->line_width <= 0.0)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -1416,6 +1428,9 @@
     cairo_status_t status;
     cairo_traps_t traps;
 
+    if (gstate->source->status)
+	return gstate->source->status;
+    
     status = _cairo_gstate_set_clip (gstate);
     if (status)
 	return status;
@@ -1989,6 +2004,9 @@
     cairo_box_t bbox;
     cairo_rectangle_t extents;
 
+    if (gstate->source->status)
+	return gstate->source->status;
+
     status = _cairo_gstate_set_clip (gstate);
     if (status)
 	return status;

Index: cairo-pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pattern.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- cairo-pattern.c	10 Jun 2005 19:18:21 -0000	1.42
+++ cairo-pattern.c	13 Jun 2005 23:36:40 -0000	1.43
@@ -50,20 +50,67 @@
     ((unsigned char) \
      ((((unsigned char) (c1)) * (int) ((unsigned char) (c2))) / 0xff))
 
+static const cairo_solid_pattern_t cairo_solid_pattern_nil = {
+    { CAIRO_PATTERN_SOLID, 	/* type */
+      (unsigned int)-1,		/* ref_count */
+      CAIRO_STATUS_NO_MEMORY,	/* status */
+      { 1., 0., 0., 1., 0., 0., }, /* matrix */
+      CAIRO_FILTER_DEFAULT,	/* filter */
+      CAIRO_EXTEND_DEFAULT },	/* extend */
+    { 0.0, 0.0, 0.0, 1.0,	/* solid black */
+      0x0, 0x0, 0x0, 0xffff }
+};
+
+static const cairo_surface_pattern_t cairo_surface_pattern_nil = {
+    { CAIRO_PATTERN_SURFACE, 	/* type */
+      (unsigned int)-1,		/* ref_count */
+      CAIRO_STATUS_NO_MEMORY,	/* status */
+      { 1., 0., 0., 1., 0., 0., }, /* matrix */
+      CAIRO_FILTER_DEFAULT,	/* filter */
+      CAIRO_EXTEND_DEFAULT },	/* extend */
+    NULL			/* surface */
+};
+
+static const cairo_linear_pattern_t cairo_linear_pattern_nil = {
+    { { CAIRO_PATTERN_LINEAR, 	/* type */
+	(unsigned int)-1,	/* ref_count */
+	CAIRO_STATUS_NO_MEMORY,	/* status */
+	{ 1., 0., 0., 1., 0., 0., }, /* matrix */
+	CAIRO_FILTER_DEFAULT,	/* filter */
+	CAIRO_EXTEND_DEFAULT },	/* extend */
+      NULL,			/* stops */
+      0 },			/* n_stops */
+    { 0., 0. }, { 1.0, 1.0 }	/* point0, point1 */
+};
+
+static const cairo_radial_pattern_t cairo_radial_pattern_nil = {
+    { { CAIRO_PATTERN_RADIAL, 	/* type */
+	(unsigned int)-1,	/* ref_count */
+	CAIRO_STATUS_NO_MEMORY,	/* status */
+	{ 1., 0., 0., 1., 0., 0., }, /* matrix */
+	CAIRO_FILTER_DEFAULT,	/* filter */
+	CAIRO_EXTEND_DEFAULT },	/* extend */
+      NULL,			/* stops */
+      0 },			/* n_stops */
+    { 0., 0. }, { 0.0, 0.0 },	/* center0, center1 */
+    1.0, 1.0,			/* radius0, radius1 */
+};
+
 static void
 _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
 {
     pattern->type      = type; 
     pattern->ref_count = 1;
+    pattern->status    = CAIRO_STATUS_SUCCESS;
     pattern->extend    = CAIRO_EXTEND_DEFAULT;
     pattern->filter    = CAIRO_FILTER_DEFAULT;
 
     cairo_matrix_init_identity (&pattern->matrix);
 }
 
-static cairo_status_t
-_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
-				   cairo_gradient_pattern_t *other)
+static void
+_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t	  *pattern,
+				   const cairo_gradient_pattern_t *other)
 {
     if (other->base.type == CAIRO_PATTERN_LINEAR)
     {
@@ -83,18 +130,22 @@
     if (other->n_stops)
     {
 	pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
-	if (!pattern->stops)
-	    return CAIRO_STATUS_NO_MEMORY;
+	if (!pattern->stops) {
+	    if (other->base.type == CAIRO_PATTERN_LINEAR)
+		_cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base);
+	    else
+		_cairo_gradient_pattern_init_copy (pattern, &cairo_radial_pattern_nil.base);
+	    return;
+	}
 	
 	memcpy (pattern->stops, other->stops,
 		other->n_stops * sizeof (cairo_color_stop_t));
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
-_cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other)
+void
+_cairo_pattern_init_copy (cairo_pattern_t	*pattern,
+			  const cairo_pattern_t *other)
 {
     switch (other->type) {
     case CAIRO_PATTERN_SOLID: {
@@ -114,17 +165,12 @@
     case CAIRO_PATTERN_RADIAL: {
 	cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
 	cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
-	cairo_status_t		 status;
 	
-	status = _cairo_gradient_pattern_init_copy (dst, src);
-	if (status)
-	    return status;
+	_cairo_gradient_pattern_init_copy (dst, src);
     } break;
     }
     
     pattern->ref_count = 1;
-    
-    return CAIRO_STATUS_SUCCESS;
 }
 
 void
@@ -210,7 +256,7 @@
 
     pattern = malloc (sizeof (cairo_solid_pattern_t));
     if (pattern == NULL)
-	return NULL;
+	return (cairo_pattern_t *) &cairo_solid_pattern_nil.base;
 
     _cairo_pattern_init_solid (pattern, color);
 
@@ -224,7 +270,7 @@
 
     pattern = malloc (sizeof (cairo_surface_pattern_t));
     if (pattern == NULL)
-	return NULL;
+	return (cairo_pattern_t *)&cairo_surface_pattern_nil.base;
 
     _cairo_pattern_init_for_surface (pattern, surface);
 
@@ -244,7 +290,7 @@
 
     pattern = malloc (sizeof (cairo_linear_pattern_t));
     if (pattern == NULL)
-	return NULL;
+	return (cairo_pattern_t *) &cairo_linear_pattern_nil.base;
 
     _cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
 
@@ -259,7 +305,7 @@
     
     pattern = malloc (sizeof (cairo_radial_pattern_t));
     if (pattern == NULL)
-	return NULL;
+	return (cairo_pattern_t *) &cairo_radial_pattern_nil.base;
 
     _cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
 
@@ -272,15 +318,36 @@
     if (pattern == NULL)
 	return;
 
+    if (pattern->ref_count == (unsigned int)-1)
+	return;
+
     pattern->ref_count++;
 }
 
+/**
+ * cairo_pattern_status:
+ * @pattern: a #cairo_pattern_t
+ * 
+ * Checks whether an error has previously occurred for this
+ * pattern.
+ * 
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
+ **/
+cairo_status_t
+cairo_pattern_status (cairo_pattern_t *pattern)
+{
+    return pattern->status;
+}
+
 void
 cairo_pattern_destroy (cairo_pattern_t *pattern)
 {
     if (pattern == NULL)
 	return;
 
+    if (pattern->ref_count == (unsigned int)-1)
+	return;
+
     pattern->ref_count--;
     if (pattern->ref_count)
 	return;
@@ -289,31 +356,31 @@
     free (pattern);
 }
 
-static cairo_status_t
+static void
 _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
 			       double			 offset,
 			       cairo_color_t		*color)
 {
     cairo_color_stop_t *stop;
+    cairo_color_stop_t *new_stops;
 
     pattern->n_stops++;
-    pattern->stops = realloc (pattern->stops,
-			      pattern->n_stops * sizeof (cairo_color_stop_t));
-    if (pattern->stops == NULL) {
-	pattern->n_stops = 0;
-    
-	return CAIRO_STATUS_NO_MEMORY;
+    new_stops = realloc (pattern->stops,
+			 pattern->n_stops * sizeof (cairo_color_stop_t));
+    if (new_stops == NULL) {
+	pattern->base.status = CAIRO_STATUS_NO_MEMORY;
+	return;
     }
+    
+    pattern->stops = new_stops;
 
     stop = &pattern->stops[pattern->n_stops - 1];
 
     stop->offset = _cairo_fixed_from_double (offset);
     stop->color = *color;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
 				  double	   offset,
 				  double	   red,
@@ -322,11 +389,14 @@
 {
     cairo_color_t color;
 
+    if (pattern->status)
+	return;
+
     if (pattern->type != CAIRO_PATTERN_LINEAR &&
 	pattern->type != CAIRO_PATTERN_RADIAL)
     {
-	/* XXX: CAIRO_STATUS_INVALID_PATTERN? */
-	return CAIRO_STATUS_SUCCESS;
+	pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return;
     }
 
     _cairo_restrict_value (&offset, 0.0, 1.0);
@@ -335,12 +405,12 @@
     _cairo_restrict_value (&blue,   0.0, 1.0);
 
     _cairo_color_init_rgb (&color, red, green, blue);
-    return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
-					  offset,
-					  &color);
+    _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
+				   offset,
+				   &color);
 }
 
-cairo_status_t
+void
 cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
 				   double	   offset,
 				   double	   red,
@@ -350,11 +420,14 @@
 {
     cairo_color_t color;
 
+    if (pattern->status)
+	return;
+
     if (pattern->type != CAIRO_PATTERN_LINEAR &&
 	pattern->type != CAIRO_PATTERN_RADIAL)
     {
-	/* XXX: CAIRO_STATUS_INVALID_PATTERN? */
-	return CAIRO_STATUS_SUCCESS;
+	pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return;
     }
 
     _cairo_restrict_value (&offset, 0.0, 1.0);
@@ -364,34 +437,34 @@
     _cairo_restrict_value (&alpha,  0.0, 1.0);
 
     _cairo_color_init_rgba (&color, red, green, blue, alpha);
-    return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
-					  offset,
-					  &color);
+    _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern,
+				   offset,
+				   &color);
 }
 
-cairo_status_t
+void
 cairo_pattern_set_matrix (cairo_pattern_t      *pattern,
 			  const cairo_matrix_t *matrix)
 {
-    pattern->matrix = *matrix;
+    if (pattern->status)
+	return;
 
-    return CAIRO_STATUS_SUCCESS;
+    pattern->matrix = *matrix;
 }
 
-cairo_status_t
+void
 cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
 {
     *matrix = pattern->matrix;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
 {
-    pattern->filter = filter;
+    if (pattern->status)
+	return;
 
-    return CAIRO_STATUS_SUCCESS;
+    pattern->filter = filter;
 }
 
 cairo_filter_t
@@ -400,12 +473,13 @@
     return pattern->filter;
 }
 
-cairo_status_t
+void
 cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
 {
-    pattern->extend = extend;
+    if (pattern->status)
+	return;
 
-    return CAIRO_STATUS_SUCCESS;
+    pattern->extend = extend;
 }
 
 cairo_extend_t
@@ -418,6 +492,8 @@
 _cairo_pattern_transform (cairo_pattern_t	*pattern,
 			  const cairo_matrix_t  *ctm_inverse)
 {
+    assert (pattern->status == CAIRO_STATUS_SUCCESS);
+
     cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix);
 }
 
@@ -1098,6 +1174,9 @@
 {
     cairo_status_t status;
     
+    if (pattern->status)
+	return pattern->status;
+
     switch (pattern->type) {
     case CAIRO_PATTERN_SOLID: {
 	cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) pattern;
@@ -1197,6 +1276,11 @@
     cairo_int_status_t	  status;
     cairo_pattern_union_t tmp;
 
+    if (src->status)
+	return src->status;
+    if (mask && mask->status)
+	return mask->status;
+
     /* If src and mask are both solid, then the mask alpha can be
      * combined into src and mask can be ignored. */
 

Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -d -r1.102 -r1.103
--- cairo.c	13 Jun 2005 23:35:03 -0000	1.102
+++ cairo.c	13 Jun 2005 23:36:40 -0000	1.103
@@ -328,10 +328,6 @@
     cairo_pattern_t *source;
 
     source = _cairo_pattern_create_solid (color);
-    if (source == NULL) {
-	cr->status = CAIRO_STATUS_NO_MEMORY;
-	return;
-    }
 
     cairo_set_source (cr, source);
 
@@ -426,10 +422,6 @@
 	return;
 
     pattern = cairo_pattern_create_for_surface (surface);
-    if (!pattern) {
-	cr->status = CAIRO_STATUS_NO_MEMORY;
-	return;
-    }
 
     cairo_matrix_init_translate (&matrix, -x, -y);
     cairo_pattern_set_matrix (pattern, &matrix);
@@ -461,6 +453,16 @@
     if (cr->status)
 	return;
 
+    if (source == NULL) {
+	cr->status = CAIRO_STATUS_NULL_POINTER;
+	return;
+    }
+
+    if (source->status) {
+	cr->status = source->status;
+	return;
+    }
+
     cr->status = _cairo_gstate_set_source (cr->gstate, source);
     CAIRO_CHECK_SANITY (cr);
 }
@@ -1235,6 +1237,16 @@
     if (cr->status)
 	return;
 
+    if (pattern == NULL) {
+	cr->status = CAIRO_STATUS_NULL_POINTER;
+	return;
+    }
+    
+    if (pattern->status) {
+	cr->status = pattern->status;
+	return;
+    }
+
     cr->status = _cairo_gstate_mask (cr->gstate, pattern);
 
     CAIRO_CHECK_SANITY (cr);
@@ -1266,10 +1278,6 @@
 	return;
 
     pattern = cairo_pattern_create_for_surface (surface);
-    if (!pattern) {
-	cr->status = CAIRO_STATUS_NO_MEMORY;
-	return;
-    }
 
     cairo_matrix_init_translate (&matrix, - surface_x, - surface_y);
     cairo_pattern_set_matrix (pattern, &matrix);
@@ -2229,6 +2237,8 @@
 	return "the target surface has been finished";
     case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
 	return "the surface type is not appropriate for the operation";
+    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
+	return "the pattern type is not appropriate for the operation";
     }
 
     return "<unknown error status>";

Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- cairo.h	13 Jun 2005 23:29:26 -0000	1.126
+++ cairo.h	13 Jun 2005 23:36:40 -0000	1.127
@@ -160,7 +160,8 @@
     CAIRO_STATUS_READ_ERROR,
     CAIRO_STATUS_WRITE_ERROR,
     CAIRO_STATUS_SURFACE_FINISHED,
-    CAIRO_STATUS_SURFACE_TYPE_MISMATCH
+    CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
+    CAIRO_STATUS_PATTERN_TYPE_MISMATCH
 } cairo_status_t;
 
 /**
@@ -1014,21 +1015,24 @@
 cairo_pattern_destroy (cairo_pattern_t *pattern);
   
 cairo_status_t
+cairo_pattern_status (cairo_pattern_t *pattern);
+
+void
 cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
 				  double offset,
 				  double red, double green, double blue);
 
-cairo_status_t
+void
 cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
 				   double offset,
 				   double red, double green, double blue,
 				   double alpha);
 
-cairo_status_t
+void
 cairo_pattern_set_matrix (cairo_pattern_t      *pattern,
 			  const cairo_matrix_t *matrix);
 
-cairo_status_t
+void
 cairo_pattern_get_matrix (cairo_pattern_t *pattern,
 			  cairo_matrix_t  *matrix);
 
@@ -1038,7 +1042,7 @@
     CAIRO_EXTEND_REFLECT
 } cairo_extend_t;
 
-cairo_status_t
+void
 cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend);
 
 cairo_extend_t
@@ -1053,7 +1057,7 @@
     CAIRO_FILTER_GAUSSIAN
 } cairo_filter_t;
   
-cairo_status_t
+void
 cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
 
 cairo_filter_t

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -d -r1.151 -r1.152
--- cairoint.h	11 Jun 2005 08:09:15 -0000	1.151
+++ cairoint.h	13 Jun 2005 23:36:40 -0000	1.152
@@ -785,6 +785,7 @@
 struct _cairo_pattern {
     cairo_pattern_type_t type;
     unsigned int	 ref_count;
+    cairo_status_t       status;
     cairo_matrix_t	 matrix;
     cairo_filter_t	 filter;
     cairo_extend_t	 extend;
@@ -1689,8 +1690,9 @@
 
 /* cairo_pattern.c */
 
-cairo_private cairo_status_t
-_cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other);
+cairo_private void
+_cairo_pattern_init_copy (cairo_pattern_t	*pattern,
+			  const cairo_pattern_t *other);
 
 cairo_private void
 _cairo_pattern_init_solid (cairo_solid_pattern_t *pattern,




More information about the cairo-commit mailing list