[cairo-commit] 6 commits - src/cairo-path-stroke.c src/cairo-pdf-surface.c src/cairo-png.c src/cairo-ps-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 11 07:02:30 PDT 2007


 src/cairo-path-stroke.c |    2 
 src/cairo-pdf-surface.c |  112 ++++++++++++++++++++++++++++--------------------
 src/cairo-png.c         |    2 
 src/cairo-ps-surface.c  |   18 ++++---
 4 files changed, 79 insertions(+), 55 deletions(-)

New commits:
diff-tree b7adcf67f8c640c146bada1fbeaa1cda1cfa825a (from 0222c02d9525dc8ff1ad5a2bea46e623d9db1e43)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 11 14:11:06 2007 +0100

    [cairo-path-stroke] Jump to cleanup after error.
    
    Incorrect early return in _cairo_stroker_curve_to() after
    _cairo_stroker_join() resulted in leaking the local spline and pen.

diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index ce523b0..a2fed55 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -816,7 +816,7 @@ _cairo_stroker_curve_to (void *closure,
     if (stroker->has_current_face) {
 	status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
 	if (status)
-	    return status;
+	    goto CLEANUP_PEN;
     } else if (!stroker->has_first_face) {
 	stroker->first_face = start;
 	stroker->has_first_face = TRUE;
diff-tree 0222c02d9525dc8ff1ad5a2bea46e623d9db1e43 (from 981bc12e5b9b91ce1c5abe343ace837561059658)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 11 14:01:20 2007 +0100

    [cairo-pdf-surface] Return UNSUPPORTED from _to_unicode_stream().
    
    Distinguish the UNSUPPORTED case where the font backend does not
    support conversion to unicode from other fatal errors by returning a
    status value rather than using stream.id == 0 to indicate any error.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index eec7ab6..f2679e1 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1276,6 +1276,7 @@ compress_dup (const void *data, unsigned
     }
 
     if (compress (compressed, compressed_size, data, data_size) != Z_OK) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	free (compressed);
 	compressed = NULL;
     }
@@ -2770,35 +2771,32 @@ _cairo_pdf_surface_write_pages (cairo_pd
 				 "endobj\r\n");
 }
 
-static cairo_pdf_resource_t
+static cairo_int_status_t
 _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t		*surface,
 					   cairo_scaled_font_subset_t	*font_subset,
-                                           cairo_bool_t                  is_composite)
+                                           cairo_bool_t                  is_composite,
+					   cairo_pdf_resource_t         *stream)
 {
     const cairo_scaled_font_backend_t *backend;
-    cairo_pdf_resource_t stream;
     unsigned int i, num_bfchar;
-    cairo_status_t status;
 
-    if (font_subset->to_unicode == NULL) {
-        stream.id = 0;
-        return stream;
-    }
+    stream->id = 0;
+    if (font_subset->to_unicode == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (_cairo_truetype_create_glyph_to_unicode_map (font_subset) != CAIRO_STATUS_SUCCESS) {
         backend = font_subset->scaled_font->backend;
-        if (backend->map_glyphs_to_unicode == NULL) {
-            stream.id = 0;
-            return stream;
-        }
+        if (backend->map_glyphs_to_unicode == NULL)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
         backend->map_glyphs_to_unicode (font_subset->scaled_font, font_subset);
     }
 
-    stream = _cairo_pdf_surface_open_stream (surface,
+    *stream = _cairo_pdf_surface_open_stream (surface,
 					     surface->compress_content,
 					     NULL);
-    if (stream.id == 0)
-	return stream;
+    if (stream->id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_output_stream_printf (surface->output,
                                  "/CIDInit /ProcSet findresource begin\r\n"
@@ -2855,11 +2853,7 @@ _cairo_pdf_surface_emit_to_unicode_strea
                                  "end\r\n"
                                  "end\r\n");
 
-    status = _cairo_pdf_surface_close_stream (surface);
-    if (status)
-	stream.id = 0;
-
-    return stream;
+    return _cairo_pdf_surface_close_stream (surface);
 }
 
 static cairo_status_t
@@ -2901,9 +2895,11 @@ _cairo_pdf_surface_emit_cff_font (cairo_
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, TRUE);
-    if (to_unicode_stream.id == 0)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
+	                                                font_subset, TRUE,
+							&to_unicode_stream);
+    if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     if (descriptor.id == 0)
@@ -3045,6 +3041,7 @@ _cairo_pdf_surface_emit_type1_font (cair
 {
     cairo_pdf_resource_t stream, descriptor, subset_resource, to_unicode_stream;
     cairo_pdf_font_t font;
+    cairo_status_t status;
     unsigned long length, compressed_length;
     char *compressed;
     unsigned int i;
@@ -3082,9 +3079,11 @@ _cairo_pdf_surface_emit_type1_font (cair
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, FALSE);
-    if (to_unicode_stream.id == 0)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
+	                                                font_subset, FALSE,
+							&to_unicode_stream);
+    if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     if (descriptor.id == 0)
@@ -3247,9 +3246,13 @@ _cairo_pdf_surface_emit_truetype_font_su
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, TRUE);
-    if (to_unicode_stream.id == 0)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
+	                                                font_subset, TRUE,
+							&to_unicode_stream);
+    if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	_cairo_truetype_subset_fini (&subset);
+	return status;
+    }
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     if (descriptor.id == 0) {
@@ -3604,9 +3607,13 @@ _cairo_pdf_surface_emit_type3_font_subse
 
     free (glyphs);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, FALSE);
-    if (to_unicode_stream.id == 0)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
+	                                                font_subset, FALSE,
+							&to_unicode_stream);
+    if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	free (widths);
+	return status;
+    }
 
     subset_resource = _cairo_pdf_surface_get_font_resource (surface,
 							    font_subset->font_id,
diff-tree 981bc12e5b9b91ce1c5abe343ace837561059658 (from c1db44b26501cd905fb9ca858f41632c148b6b07)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 10 23:58:43 2007 +0100

    [cairo-ps-surface] Close a couple of memory leaks.
    
    Adjust error paths to free local resources.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 9a774e2..77ef97e 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1626,6 +1626,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto bail0;
 	}
+	opaque_image = (cairo_image_surface_t *) opaque;
 
 	_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
 
@@ -1636,7 +1637,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 					       	image->width, image->height);
 	if (status) {
 	    _cairo_pattern_fini (&pattern.base);
-	    goto bail0;
+	    goto bail1;
 	}
 
 	status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
@@ -1650,11 +1651,10 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 					   image->height);
 	if (status) {
 	    _cairo_pattern_fini (&pattern.base);
-	    goto bail0;
+	    goto bail1;
 	}
 
 	_cairo_pattern_fini (&pattern.base);
-	opaque_image = (cairo_image_surface_t *) opaque;
     } else {
 	opaque = &image->base;
 	opaque_image = image;
@@ -1815,11 +1815,15 @@ _cairo_ps_surface_emit_surface_pattern (
 	status = _cairo_surface_acquire_source_image (pattern->surface,
 						      &image,
 						      &image_extra);
-	assert (status == CAIRO_STATUS_SUCCESS);
+	if (status)
+	    return status;
 
 	status = _cairo_ps_surface_emit_image (surface, image, "MyPattern");
-	if (status)
+	if (status) {
+	    _cairo_surface_release_source_image (pattern->surface,
+		                                 image, image_extra);
 	    return status;
+	}
 
 	bbox_width = image->width;
 	bbox_height = image->height;
@@ -1868,8 +1872,8 @@ _cairo_ps_surface_emit_surface_pattern (
 	    ystep = 0;
 	}
 
-	_cairo_surface_release_source_image (pattern->surface, image,
-					     image_extra);
+	_cairo_surface_release_source_image (pattern->surface,
+		                             image, image_extra);
     }
     _cairo_output_stream_printf (surface->stream,
 				 "<< /PatternType 1\n"
diff-tree c1db44b26501cd905fb9ca858f41632c148b6b07 (from 05702b8b6ea73fecd04dc5cc4b26ad1d46fa8850)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 10 15:15:55 2007 +0100

    [cairo-png] Clean up volatile warning.
    
    gcc warns that 'rows' is missing a volatile qualifier - so add it.

diff --git a/src/cairo-png.c b/src/cairo-png.c
index 03a7375..c503994 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -119,7 +119,7 @@ write_png (cairo_surface_t	*surface,
     png_struct *png;
     png_info *info;
     png_time pt;
-    png_byte **rows = NULL;
+    png_byte **volatile rows = NULL;
     png_color_16 white;
     int png_color_type;
     int depth;
diff-tree 05702b8b6ea73fecd04dc5cc4b26ad1d46fa8850 (from 8fa5f638a5f8eee4f9efe267ede20344fc7bd4e2)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 9 23:37:34 2007 +0100

    [cairo-pdf-surface] Free the clip path on error.
    
    If we fail to add the clip path to the current group, destroy it.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 87fa714..eec7ab6 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2667,18 +2667,26 @@ _cairo_pdf_surface_add_clip (cairo_pdf_s
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	status = _cairo_path_fixed_init_copy (elem.clip_path, path);
-	if (status)
+	if (status) {
+	    _cairo_path_fixed_destroy (elem.clip_path);
 	    return status;
+	}
     }
     elem.fill_rule = fill_rule;
 
     status = _cairo_pdf_surface_stop_content_stream (surface);
-    if (status)
+    if (status) {
+	if (elem.clip_path != NULL)
+	    _cairo_path_fixed_destroy (elem.clip_path);
 	return status;
+    }
 
     status = _cairo_array_append (surface->current_group, &elem);
-    if (status)
+    if (status) {
+	if (elem.clip_path != NULL)
+	    _cairo_path_fixed_destroy (elem.clip_path);
 	return status;
+    }
 
     status = _cairo_pdf_surface_start_content_stream (surface);
     if (status)
diff-tree 8fa5f638a5f8eee4f9efe267ede20344fc7bd4e2 (from 8eb9fcf67336a8e4f95366956ae6f1880af4a93e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 9 23:36:52 2007 +0100

    [cairo-pdf-surface] Restore old_group for failed emit_meta_surface().
    
    Ensure we restore the surface->current_group if we encounter an error
    during _cairo_pdf_surface_emit_meta_surface() lest we leak the
    current_group array.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 77e6c8d..87fa714 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1576,12 +1576,13 @@ _cairo_pdf_surface_emit_meta_surface (ca
 
     status = _cairo_pdf_surface_start_content_stream (surface);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
 
     if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
 	status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
 	if (status)
-	    return status;
+	    goto CLEANUP_GROUP;
+
 	_cairo_output_stream_printf (surface->output,
 				     "q /a%d gs 0 0 0 rg 0 0 %f %f re f Q\r\n",
 				     alpha,
@@ -1591,38 +1592,42 @@ _cairo_pdf_surface_emit_meta_surface (ca
 
     status = _cairo_meta_surface_replay (meta_surface, &surface->base);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
+
     status = _cairo_pdf_surface_stop_content_stream (surface);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
 
     status = _cairo_pdf_surface_open_group (surface);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
 
     status = _cairo_pdf_surface_write_group_list (surface, &group);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
 
     status = _cairo_pdf_surface_close_group (surface, resource);
     if (status)
-	return status;
+	goto CLEANUP_GROUP;
 
+ CLEANUP_GROUP:
     surface->current_group = old_group;
     surface->width = old_width;
     surface->height = old_height;
     surface->cairo_to_pdf = old_cairo_to_pdf;
 
-    status = _cairo_pdf_surface_start_content_stream (surface);
+    _cairo_pdf_group_element_array_finish (&group);
+    _cairo_array_fini (&group);
     if (status)
 	return status;
 
-    _cairo_pdf_group_element_array_finish (&group);
-    _cairo_array_fini (&group);
+    status = _cairo_pdf_surface_start_content_stream (surface);
+    if (status)
+	return status;
 
     _cairo_pdf_surface_pause_content_stream (surface);
 
-    return 0;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void


More information about the cairo-commit mailing list