[cairo-commit] 20 commits - pixman/src src/cairo-deflate-stream.c src/cairo-ft-font.c src/cairo-gstate.c src/cairo-paginated-surface.c src/cairo-path.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-traps.c src/cairo-truetype-subset.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Wed May 16 18:14:40 EEST 2007


 pixman/src/pixregion.c          |   24 +++++++++++++++++-------
 src/cairo-deflate-stream.c      |    4 +++-
 src/cairo-ft-font.c             |   30 ++++++++++++++++++------------
 src/cairo-gstate.c              |    9 ++-------
 src/cairo-paginated-surface.c   |   11 +++++++++--
 src/cairo-path.c                |   10 +++++++++-
 src/cairo-pattern.c             |   26 ++++++++++++++++++++++----
 src/cairo-pdf-surface.c         |   20 ++++++++++----------
 src/cairo-scaled-font-subsets.c |   22 ++++++++++++++++------
 src/cairo-scaled-font.c         |    3 +++
 src/cairo-traps.c               |   26 ++++++--------------------
 src/cairo-truetype-subset.c     |   22 +++++++++++-----------
 src/cairo-xlib-private.h        |    2 +-
 src/cairo-xlib-screen.c         |   14 ++++++++------
 src/cairo-xlib-surface.c        |   11 +++++------
 15 files changed, 140 insertions(+), 94 deletions(-)

New commits:
diff-tree e37bee3f52282a042251f2dfc8e051943fd8f1d7 (from 27de1869f5a837b79812cd4b04e17621ec0f848c)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 16 14:47:33 2007 +0100

    [cairo-pdf-surface] emit_pattern_stops() array overrun.
    
    _cairo_pdf_surface_emit_pattern_stops() tried to set the last element
    to have an offset of exactly 1.0, but missed and set the next element
    after the end of the array.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index db8aa97..1e73c4c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1294,7 +1294,7 @@ _cairo_pdf_surface_emit_pattern_stops (c
 		    sizeof (cairo_pdf_color_stop_t));
 	    n_stops++;
     }
-    stops[n_stops].offset = 1.0;
+    stops[n_stops-1].offset = 1.0;
 
     if (n_stops == 2) {
         /* no need for stitched function */
diff-tree 27de1869f5a837b79812cd4b04e17621ec0f848c (from 79e6c0207cb65b6bc1f38537f42632d623a1bc9a)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 16 13:10:58 2007 +0100

    [cairo-pdf-surface] Free allstops on error.
    
    Ensure the locally allocated resources are freed on the error paths.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f488bde..db8aa97 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1247,7 +1247,7 @@ _cairo_pdf_surface_emit_stitched_colorgr
 
 #define COLOR_STOP_EPSILON 1e-6
 
-static  cairo_status_t
+static cairo_status_t
 _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t      *surface,
                                        cairo_gradient_pattern_t *pattern,
                                        cairo_pdf_resource_t     *color_function,
@@ -1263,9 +1263,8 @@ _cairo_pdf_surface_emit_pattern_stops (c
     alpha_function->id = 0;
 
     allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t));
-    if (allstops == NULL) {
+    if (allstops == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
-    }
 
     stops = &allstops[1];
     n_stops = pattern->n_stops;
@@ -1304,7 +1303,7 @@ _cairo_pdf_surface_emit_pattern_stops (c
                                                              &stops[1],
                                                              color_function);
         if (status)
-            return status;
+            goto BAIL;
 
         if (emit_alpha) {
             status = cairo_pdf_surface_emit_alpha_linear_function (surface,
@@ -1312,7 +1311,7 @@ _cairo_pdf_surface_emit_pattern_stops (c
                                                                    &stops[1],
                                                                    alpha_function);
             if (status)
-                return status;
+                goto BAIL;
         }
     } else {
         /* multiple stops: stitch. XXX possible optimization: regulary spaced
@@ -1323,7 +1322,7 @@ _cairo_pdf_surface_emit_pattern_stops (c
                                                                  FALSE,
                                                                  color_function);
         if (status)
-            return status;
+            goto BAIL;
 
         if (emit_alpha) {
             status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
@@ -1332,12 +1331,13 @@ _cairo_pdf_surface_emit_pattern_stops (c
                                                                      TRUE,
                                                                      alpha_function);
             if (status)
-                return status;
+                goto BAIL;
         }
     }
-    free (allstops);
 
-    return CAIRO_STATUS_SUCCESS;
+BAIL:
+    free (allstops);
+    return status;
 }
 
 static cairo_pdf_resource_t
diff-tree 79e6c0207cb65b6bc1f38537f42632d623a1bc9a (from 32c0ef9f145cec8b997c011b13208362eaf03004)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 18:27:58 2007 +0100

    [cairo-pattern] Check for the nil surface.
    
    cairo_surface_create_similar() does not return NULL as was being checked
    for, but the nil surface on error. Also ensure that the returned surface
    is destroyed if we encounter an error whilst compositing.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 151fc3c..867898b 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1515,8 +1515,12 @@ _cairo_pattern_acquire_surface_for_surfa
 	h = 2 * extents.height;
 
 	*out = cairo_surface_create_similar (dst, dst->content, w, h);
-	if (!*out)
-	    return CAIRO_STATUS_NO_MEMORY;
+	status = cairo_surface_status (*out);
+	if (status) {
+	    cairo_surface_destroy (*out);
+	    *out = NULL;
+	    return status;
+	}
 
 	(*out)->device_transform = pattern->surface->device_transform;
 	(*out)->device_transform_inverse = pattern->surface->device_transform_inverse;
@@ -1541,6 +1545,11 @@ _cairo_pattern_acquire_surface_for_surfa
 	status = cairo_status (cr);
 	cairo_destroy (cr);
 
+	if (status) {
+	    cairo_surface_destroy (*out);
+	    *out = NULL;
+	}
+
 	return status;
     }
 
@@ -1617,8 +1626,12 @@ _cairo_pattern_acquire_surface_for_surfa
 
 	    *out = cairo_surface_create_similar (dst, dst->content,
 						 width, height);
-	    if (!*out)
-		return CAIRO_STATUS_NO_MEMORY;
+	    status = cairo_surface_status (*out);
+	    if (status) {
+		cairo_surface_destroy (*out);
+		*out = NULL;
+		return status;
+	    }
 
 	    (*out)->device_transform = pattern->surface->device_transform;
 	    (*out)->device_transform_inverse = pattern->surface->device_transform_inverse;
@@ -1632,6 +1645,11 @@ _cairo_pattern_acquire_surface_for_surfa
 
 	    status = cairo_status (cr);
 	    cairo_destroy (cr);
+
+	    if (status) {
+		cairo_surface_destroy (*out);
+		*out = NULL;
+	    }
 	}
     }
 
diff-tree 32c0ef9f145cec8b997c011b13208362eaf03004 (from 37d8c18b3fc489d6336131bae6ec219cafc35718)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 16:20:00 2007 +0100

    [cairo-gstate] Remove a redundant conditional.
    
    Simplify _cairo_gstate_text_to_glyphs() with a tail call.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index ad560cd..286800e 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1499,13 +1499,8 @@ _cairo_gstate_text_to_glyphs (cairo_gsta
     if (status)
 	return status;
 
-    status = _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
-						utf8, glyphs, num_glyphs);
-
-    if (status || !glyphs || !num_glyphs || !(*glyphs) || !(num_glyphs))
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
+					      utf8, glyphs, num_glyphs);
 }
 
 cairo_status_t
diff-tree 37d8c18b3fc489d6336131bae6ec219cafc35718 (from 76e758df5b99fd4dee64481b9039b0d44dd01587)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 15:42:59 2007 +0100

    [cairo-scaled-font-subsets] Destroy the glyph if we fail to cache it.
    
    If we fail to insert the glyph into the sub_font glyph cache then we
    must destroy it before propagating the error.

diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 53ea5af..b327963 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -338,8 +338,10 @@ _cairo_sub_font_map_glyph (cairo_sub_fon
         }
 
 	status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
-	if (status)
+	if (status) {
+	    _cairo_sub_font_glyph_destroy (sub_font_glyph);
 	    return status;
+	}
     }
 
     subset_glyph->font_id = sub_font->font_id;
diff-tree 76e758df5b99fd4dee64481b9039b0d44dd01587 (from b63b32958e690409448ddc14e19b1856b9ef555a)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 15:40:39 2007 +0100

    [cairo-truetype-subset] Destroy the arrays on error.
    
    Growing the arrays may successfully allocate the indirect pointer, but
    fail whilst allocating the actual array - so always call
    _cairo_array_fini after _cairo_array_grow_by().

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index f4bb66c..f045410 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -160,13 +160,13 @@ _cairo_truetype_font_create (cairo_scale
     font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
     if (font->glyphs == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
-	goto fail2;
+	goto fail1;
     }
 
     font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->parent_to_subset == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
-	goto fail3;
+	goto fail2;
     }
 
     font->base.num_glyphs = 0;
@@ -210,7 +210,7 @@ _cairo_truetype_font_create (cairo_scale
         font->base.base_font = malloc (30);
         if (font->base.base_font == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
-            goto fail4; 
+            goto fail3;
 	}
 
         snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
@@ -228,13 +228,13 @@ _cairo_truetype_font_create (cairo_scale
     font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->base.widths == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
-	goto fail5;
+	goto fail4;
     }
 
     _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
     status = _cairo_array_grow_by (&font->string_offsets, 10);
     if (status)
-	goto fail6;
+	goto fail5;
 
     font->status = CAIRO_STATUS_SUCCESS;
 
@@ -242,17 +242,17 @@ _cairo_truetype_font_create (cairo_scale
 
     return CAIRO_STATUS_SUCCESS;
 
- fail6:
-    free (font->base.widths);
  fail5:
-    free (font->base.base_font);
+    _cairo_array_fini (&font->string_offsets);
+    free (font->base.widths);
  fail4:
-    free (font->parent_to_subset);
+    free (font->base.base_font);
  fail3:
-    free (font->glyphs);
+    free (font->parent_to_subset);
  fail2:
-    _cairo_array_fini (&font->output);
+    free (font->glyphs);
  fail1:
+    _cairo_array_fini (&font->output);
     free (font);
  fail0:
     if (name)
diff-tree b63b32958e690409448ddc14e19b1856b9ef555a (from fcd1076bcffa20b7770a1b447a46232760972e2f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 15:32:34 2007 +0100

    [cairo-scaled-font-subsets] Destroy the parent and subfont on error.
    
    If we fail to create the sub font destroy the local reference to the
    parent font and if we fail to insert the sub font into the hash table,
    destroy the newly create sub font.

diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 1846db8..53ea5af 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -553,13 +553,17 @@ _cairo_scaled_font_subsets_map_glyph (ca
                                                max_glyphs,
                                                subset_glyph->is_scaled,
                                                subset_glyph->is_composite);
-            if (sub_font == NULL)
+            if (sub_font == NULL) {
+		cairo_scaled_font_destroy (unscaled_font);
                 return CAIRO_STATUS_NO_MEMORY;
+	    }
 
             status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
                                                &sub_font->base);
-            if (status)
+            if (status) {
+		_cairo_sub_font_destroy (sub_font);
                 return status;
+	    }
         }
     } else {
         /* No path available. Add to scaled subset. */
@@ -581,13 +585,17 @@ _cairo_scaled_font_subsets_map_glyph (ca
                                                max_glyphs,
                                                subset_glyph->is_scaled,
                                                subset_glyph->is_composite);
-            if (sub_font == NULL)
+            if (sub_font == NULL) {
+		cairo_scaled_font_destroy (scaled_font);
                 return CAIRO_STATUS_NO_MEMORY;
+	    }
 
             status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
                                                &sub_font->base);
-            if (status)
+            if (status) {
+		_cairo_sub_font_destroy (sub_font);
                 return status;
+	    }
         }
     }
 
diff-tree fcd1076bcffa20b7770a1b447a46232760972e2f (from abb19e61cf076c62c7626094c70de0530bd9fd00)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 14:36:11 2007 +0100

    [cairo-ft-font] Destroy the path on error.
    
    During _decompose_glyph_outline() destroy the fixed path if we
    encounter an error.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 36a15aa..6e23963 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1751,7 +1751,7 @@ _decompose_glyph_outline (FT_Face		  fac
 
     FT_GlyphSlot glyph;
     cairo_path_fixed_t *path;
-    cairo_status_t status, status2;
+    cairo_status_t status;
 
     path = _cairo_path_fixed_create ();
     if (!path)
@@ -1759,20 +1759,22 @@ _decompose_glyph_outline (FT_Face		  fac
 
     glyph = face->glyph;
 
-    status = CAIRO_STATUS_SUCCESS;
     /* Font glyphs have an inverted Y axis compared to cairo. */
     FT_Outline_Transform (&glyph->outline, &invert_y);
-    if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path))
-	status = CAIRO_STATUS_NO_MEMORY;
+    if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
+	_cairo_path_fixed_destroy (path);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
 
-    status2 = _cairo_path_fixed_close_path (path);
-    if (status == CAIRO_STATUS_SUCCESS)
-	status = status2;
+    status = _cairo_path_fixed_close_path (path);
+    if (status) {
+	_cairo_path_fixed_destroy (path);
+	return status;
+    }
 
-    if (status == CAIRO_STATUS_SUCCESS)
-	*pathp = path;
+    *pathp = path;
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /*
diff-tree abb19e61cf076c62c7626094c70de0530bd9fd00 (from e4055f02a1f5a3d7942c7c2bb4f460ce0a8b5481)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 14:32:52 2007 +0100

    [cairo-ft-font] Destroy the unscaled reference on error.
    
    Release the reference to the unscaled font if we encounter an error
    whilst initialising the cairo_ft_scaled_font_t.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 158abfb..36a15aa 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1466,6 +1466,7 @@ _cairo_ft_scaled_font_create (cairo_ft_u
 				      &cairo_ft_scaled_font_backend);
     if (status) {
 	free (scaled_font);
+	_cairo_unscaled_font_destroy (&unscaled->base);
 	_cairo_ft_unscaled_font_unlock_face (unscaled);
 	return NULL;
     }
diff-tree e4055f02a1f5a3d7942c7c2bb4f460ce0a8b5481 (from f239308ef1014174d554ccaeab1fe7c2d84e26dc)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 14:29:28 2007 +0100

    [cairo-ft-font] Race between unscaled removal from hash table and creation
    
    Small window of opportunity for the unscaled font to be destroyed and
    removed from the hash table before
    _cairo_ft_unscaled_font_create_for_pattern() takes a reference on behalf
    of its cairo. Close the window by taking the reference with the font
    map lock held.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 7cdc3ab..158abfb 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -413,8 +413,8 @@ _cairo_ft_unscaled_font_create_for_patte
     if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
 				  (cairo_hash_entry_t **) &unscaled))
     {
-	_cairo_ft_unscaled_font_map_unlock ();
 	_cairo_unscaled_font_reference (&unscaled->base);
+	_cairo_ft_unscaled_font_map_unlock ();
 	return unscaled;
     }
 
diff-tree f239308ef1014174d554ccaeab1fe7c2d84e26dc (from 35a2ed03352a1abc42e441ce5f52f2704de9be85)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 13:27:09 2007 +0100

    [cairo-deflate-stream] Free the stream on error.
    
    Before returning the nil output stream, free the locally allocated
    stream when encountering an error during _cairo_deflate_stream_Create().

diff --git a/src/cairo-deflate-stream.c b/src/cairo-deflate-stream.c
index 563c7be..38ce639 100644
--- a/src/cairo-deflate-stream.c
+++ b/src/cairo-deflate-stream.c
@@ -130,8 +130,10 @@ _cairo_deflate_stream_create (cairo_outp
     stream->zlib_stream.zfree  = Z_NULL;
     stream->zlib_stream.opaque  = Z_NULL;
 
-    if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
+    if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
+	free (stream);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+    }
 
     stream->zlib_stream.next_in = stream->input_buf;
     stream->zlib_stream.avail_in = 0;
diff-tree 35a2ed03352a1abc42e441ce5f52f2704de9be85 (from 6a43c027238d2302f9e01ee7a780370d330def6c)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 12:36:47 2007 +0100

    [cairo-ft-font] Destroy surface if glyph transformation fails.
    
    As we allocated the surface we need to destroy it if we encounter an
    error.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 8be1cae..7cdc3ab 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1964,9 +1964,12 @@ _cairo_ft_scaled_glyph_init (void			*abs
 	} else {
 	    status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
 					   &surface);
-	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape)
+	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape) {
 		status = _transform_glyph_bitmap (&unscaled->current_shape,
 						  &surface);
+		if (status)
+		    cairo_surface_destroy (&surface->base);
+	    }
 	}
 	if (status)
 	    goto FAIL;
diff-tree 6a43c027238d2302f9e01ee7a780370d330def6c (from 70611846ded98ffa0f085f5a704979384b37e84c)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 09:43:30 2007 +0100

    [cairo-xlib-screen] Increase number of GC depths.
    
    Add support for depths 12 and 30, and a separate unknown.

diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 4594f13..6157775 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -76,7 +76,7 @@ struct _cairo_xlib_screen_info {
 
     cairo_font_options_t font_options;
 
-    GC gc[6];
+    GC gc[9];
     unsigned int gc_needs_clip_reset;
 };
 
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index f757742..2e8c913 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -364,12 +364,14 @@ static int
 depth_to_index (int depth)
 {
     switch(depth){
-	case 1:  return 0;
-	case 8:  return 1;
-	case 15: return 2;
-	case 16: return 3;
-	case 24: return 4;
-	case 32: return 5;
+	case 1:  return 1;
+	case 8:  return 2;
+	case 12: return 3;
+	case 15: return 4;
+	case 16: return 5;
+	case 24: return 6;
+	case 30: return 7;
+	case 32: return 8;
     }
     return 0;
 }
diff-tree 70611846ded98ffa0f085f5a704979384b37e84c (from 58c35e6d7b2e153dc9cd6ff89fa91497c507afaf)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 09:40:13 2007 +0100

    [cairo-xlib-surface] Always nullify GC after pushing to screen.
    
    The status return from _cairo_xlib_screen_put_gc() indicates the failure
    to queue a job to free an old GC - the current GC is always transferred
    away from the caller, so always nullify it in the surface.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index f63fa5b..103757b 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -310,12 +310,11 @@ _cairo_xlib_surface_finish (void *abstra
     if (surface->gc != NULL) {
 	cairo_status_t status2;
 	status2 = _cairo_xlib_screen_put_gc (surface->screen_info,
-		                   surface->depth,
-				   surface->gc,
-				   surface->have_clip_rects);
-	if (status2 == CAIRO_STATUS_SUCCESS)
-	    surface->gc = NULL;
-	else if (status == CAIRO_STATUS_SUCCESS)
+		                             surface->depth,
+				             surface->gc,
+				             surface->have_clip_rects);
+	surface->gc = NULL;
+	if (status == CAIRO_STATUS_SUCCESS)
 	    status = status2;
     }
 
diff-tree 58c35e6d7b2e153dc9cd6ff89fa91497c507afaf (from 9ffd8154e2ec2ccbeeefd3e4a34b2aa16844c1ce)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 12 00:10:26 2007 +0100

    [cairo-paginated-surface] Check surface status during finish.
    
    Propagate children status during finish.

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 1fa0e7b..1747094 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -134,11 +134,15 @@ _cairo_paginated_surface_finish (void *a
     if (surface->page_is_blank == FALSE || surface->page_num == 1)
 	status = _cairo_paginated_surface_show_page (abstract_surface);
 
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_STATUS_SUCCESS) {
 	cairo_surface_finish (surface->target);
+	status = cairo_surface_status (surface->target);
+    }
 
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_STATUS_SUCCESS) {
 	cairo_surface_finish (surface->meta);
+	status = cairo_surface_status (surface->meta);
+    }
 
     cairo_surface_destroy (surface->target);
 
@@ -318,6 +322,9 @@ _cairo_paginated_surface_show_page (void
     if (status)
 	return status;
 
+    if (cairo_surface_status (surface->meta))
+	return cairo_surface_status (surface->meta);
+
     cairo_surface_destroy (surface->meta);
 
     surface->meta = _cairo_meta_surface_create (surface->content,
diff-tree 9ffd8154e2ec2ccbeeefd3e4a34b2aa16844c1ce (from bcfc5f0bdbd4c1eedc22bde5eed464a8bd18211e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 23:43:53 2007 +0100

    [cairo-scaled-font-subsets] Correctly destroy the hash table.
    
    After an allocation failure in
    _cairo_scaled_font_subsets_create_internal() call
    _cairo_hash_table_destroy() instead of a mere free().

diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 3489ee6..1846db8 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -425,7 +425,7 @@ _cairo_scaled_font_subsets_create_intern
 
     subsets->scaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal);
     if (! subsets->scaled_sub_fonts) {
-        free (subsets->unscaled_sub_fonts);
+	_cairo_hash_table_destroy (subsets->unscaled_sub_fonts);
 	free (subsets);
 	return NULL;
     }
diff-tree bcfc5f0bdbd4c1eedc22bde5eed464a8bd18211e (from 9e99f0611c834f80903e3554663f71682ef59ef3)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 20:57:12 2007 +0100

    [pixman] Propagate allocation failure.
    
    pixman_op() failed to propagate the failure from
    pixman_region_appendNonO() and the generic op.

diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c
index 9df6611..0c214cb 100644
--- a/pixman/src/pixregion.c
+++ b/pixman/src/pixregion.c
@@ -553,7 +553,7 @@ pixman_region_appendNonO (
 {									\
     int newRects;							\
     if ((newRects = rEnd - r)) {					\
-	RECTALLOC(newReg, newRects);					\
+	RECTALLOC_BAIL(newReg, newRects, bail);				\
 	memmove((char *)PIXREGION_TOP(newReg),(char *)r, 			\
               newRects * sizeof(pixman_box16_t));				\
 	newReg->data->numRects += newRects;				\
@@ -733,7 +733,8 @@ pixman_op(
 		bot = MIN(r1->y2, r2y1);
 		if (top != bot)	{
 		    curBand = newReg->data->numRects;
-		    pixman_region_appendNonO(newReg, r1, r1BandEnd, top, bot);
+		    if (!pixman_region_appendNonO(newReg, r1, r1BandEnd, top, bot))
+			goto bail;
 		    Coalesce(newReg, prevBand, curBand);
 		}
 	    }
@@ -744,7 +745,8 @@ pixman_op(
 		bot = MIN(r2->y2, r1y1);
 		if (top != bot) {
 		    curBand = newReg->data->numRects;
-		    pixman_region_appendNonO(newReg, r2, r2BandEnd, top, bot);
+		    if (!pixman_region_appendNonO(newReg, r2, r2BandEnd, top, bot))
+			goto bail;
 		    Coalesce(newReg, prevBand, curBand);
 		}
 	    }
@@ -760,8 +762,9 @@ pixman_op(
 	ybot = MIN(r1->y2, r2->y2);
 	if (ybot > ytop) {
 	    curBand = newReg->data->numRects;
-	    (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
-			    pOverlap);
+	    if (!(* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
+			    pOverlap))
+		goto bail;
 	    Coalesce(newReg, prevBand, curBand);
 	}
 
@@ -786,7 +789,8 @@ pixman_op(
 	/* Do first nonOverlap1Func call, which may be able to coalesce */
 	FindBand(r1, r1BandEnd, r1End, r1y1);
 	curBand = newReg->data->numRects;
-	pixman_region_appendNonO(newReg, r1, r1BandEnd, MAX(r1y1, ybot), r1->y2);
+	if (!pixman_region_appendNonO(newReg, r1, r1BandEnd, MAX(r1y1, ybot), r1->y2))
+	    goto bail;
 	Coalesce(newReg, prevBand, curBand);
 	/* Just append the rest of the boxes  */
 	AppendRegions(newReg, r1BandEnd, r1End);
@@ -795,7 +799,8 @@ pixman_op(
 	/* Do first nonOverlap2Func call, which may be able to coalesce */
 	FindBand(r2, r2BandEnd, r2End, r2y1);
 	curBand = newReg->data->numRects;
-	pixman_region_appendNonO(newReg, r2, r2BandEnd, MAX(r2y1, ybot), r2->y2);
+	if (!pixman_region_appendNonO(newReg, r2, r2BandEnd, MAX(r2y1, ybot), r2->y2))
+	    goto bail;
 	Coalesce(newReg, prevBand, curBand);
 	/* Append rest of boxes */
 	AppendRegions(newReg, r2BandEnd, r2End);
@@ -821,6 +826,11 @@ pixman_op(
     }
 
     return PIXMAN_REGION_STATUS_SUCCESS;
+
+bail:
+    if (oldData)
+	free(oldData);
+    return PIXMAN_REGION_STATUS_FAILURE;
 }
 
 /*-
diff-tree 9e99f0611c834f80903e3554663f71682ef59ef3 (from 35eb65b7772459266e2f954fb370bfdca12b5b64)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 20:38:24 2007 +0100

    [cairo-traps] Initialize traps to use embedded buffer.
    
    Set the traps to use the embedded buffer during initialization which will
    save one redundant _cairo_traps_grow()

diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 51ea1a3..f7171dd 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -57,8 +57,8 @@ _cairo_traps_init (cairo_traps_t *traps)
 
     traps->num_traps = 0;
 
-    traps->traps_size = 0;
-    traps->traps = NULL;
+    traps->traps_size = ARRAY_LENGTH (traps->traps_embedded);
+    traps->traps = traps->traps_embedded;
     traps->extents.p1.x = traps->extents.p1.y = INT32_MAX;
     traps->extents.p2.x = traps->extents.p2.y = INT32_MIN;
 
@@ -100,9 +100,7 @@ _cairo_traps_init_box (cairo_traps_t *tr
 {
     _cairo_traps_init (traps);
 
-    traps->status = _cairo_traps_grow (traps);
-    if (traps->status)
-	return traps->status;
+    assert (traps->traps_size >= 1);
 
     traps->num_traps = 1;
 
@@ -256,19 +254,7 @@ static cairo_status_t
 _cairo_traps_grow (cairo_traps_t *traps)
 {
     cairo_trapezoid_t *new_traps;
-    int old_size = traps->traps_size;
-    int embedded_size = ARRAY_LENGTH (traps->traps_embedded);
-    int new_size = 2 * MAX (old_size, 16);
-
-    /* we have a local buffer at traps->traps_embedded.  try to fulfill the request
-     * from there. */
-    if (old_size < embedded_size) {
-	traps->traps = traps->traps_embedded;
-	traps->traps_size = embedded_size;
-	return traps->status;
-    }
-
-    assert (traps->num_traps <= traps->traps_size);
+    int new_size = 2 * MAX (traps->traps_size, 16);
 
     if (traps->status)
 	return traps->status;
@@ -276,7 +262,7 @@ _cairo_traps_grow (cairo_traps_t *traps)
     if (traps->traps == traps->traps_embedded) {
 	new_traps = malloc (new_size * sizeof (cairo_trapezoid_t));
 	if (new_traps)
-	    memcpy (new_traps, traps->traps, old_size * sizeof (cairo_trapezoid_t));
+	    memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded));
     } else {
 	new_traps = realloc (traps->traps, new_size * sizeof (cairo_trapezoid_t));
     }
@@ -289,7 +275,7 @@ _cairo_traps_grow (cairo_traps_t *traps)
     traps->traps = new_traps;
     traps->traps_size = new_size;
 
-    return traps->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static int
diff-tree 35eb65b7772459266e2f954fb370bfdca12b5b64 (from a60afb0e78ab42498158ef852fcea35c8f71e8ec)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 18:25:13 2007 +0100

    [cairo-path] Check for errors during the count.
    
    Return the nil object if we encounter any error whilst trying to
    generate the path.
    
    Also special case the NO_MEMORY error object to return the nil object.

diff --git a/src/cairo-path.c b/src/cairo-path.c
index cf2dd4d..4c8e09e 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -154,7 +154,7 @@ _cairo_path_count (cairo_path_t		*path,
 					  _cpc_close_path,
 					  &cpc);
     if (status)
-	return 0;
+	return -1;
 
     return cpc.count;
 }
@@ -347,6 +347,10 @@ _cairo_path_create_in_error (cairo_statu
 {
     cairo_path_t *path;
 
+    /* special case NO_MEMORY so as to avoid allocations */
+    if (status == CAIRO_STATUS_NO_MEMORY)
+	return (cairo_path_t*) &_cairo_path_nil;
+
     path = malloc (sizeof (cairo_path_t));
     if (path == NULL)
 	return (cairo_path_t*) &_cairo_path_nil;
@@ -372,6 +376,10 @@ _cairo_path_create_internal (cairo_path_
     path->num_data = _cairo_path_count (path, path_fixed,
 					_cairo_gstate_get_tolerance (gstate),
 					flatten);
+    if (path->num_data <= 0) {
+	free (path);
+	return (cairo_path_t*) &_cairo_path_nil;
+    }
 
     path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
     if (path->data == NULL) {
diff-tree a60afb0e78ab42498158ef852fcea35c8f71e8ec (from d46f6872a5fe601862e2f63455c97a15c4667cf2)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 11 16:01:26 2007 +0100

    [cairo-scaled-font] Return status of _cairo_scaled_font_glyph_path()
    
    The status return of _cairo_path_fixed_interpret() was being ignored,
    propagate it.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 40ff698..0d5c76b 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1360,6 +1360,9 @@ _cairo_scaled_font_glyph_path (cairo_sca
 					      &closure);
 	if (glyph_path != scaled_glyph->path)
 	    _cairo_path_fixed_destroy (glyph_path);
+
+	if (status)
+	    return status;
     }
 
     return CAIRO_STATUS_SUCCESS;


More information about the cairo-commit mailing list