[cairo-commit] 7 commits - src/cairo-image-surface.c src/cairo-meta-surface.c src/cairo-output-stream.c src/cairo-ps-surface.c src/cairo-surface.c src/cairo-truetype-subset.c src/cairo-type1-subset.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 4 12:09:48 PDT 2007


 src/cairo-image-surface.c   |    7 
 src/cairo-meta-surface.c    |    5 
 src/cairo-output-stream.c   |    6 
 src/cairo-ps-surface.c      |   18 +-
 src/cairo-surface.c         |  131 ++++++++-------
 src/cairo-truetype-subset.c |  363 ++++++++++++++++++++++++++------------------
 src/cairo-type1-subset.c    |  123 +++++++++-----
 7 files changed, 405 insertions(+), 248 deletions(-)

New commits:
diff-tree 8fb40aee97fdb3ae2cbbfa5c6a350c7b8b030005 (from b61931640d384707a6fc48f9ba4a4f2ddf675c32)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 19:20:35 2007 +0100

    [cairo-image-surface] Check for errors whilst cloning.
    
    After attempting to clone an image, check the context status and return
    the nil surface if there was an error.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3331e55..5b1ad76 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1354,6 +1354,7 @@ _cairo_image_surface_clone (cairo_image_
 			    cairo_format_t		 format)
 {
     cairo_image_surface_t *clone;
+    cairo_status_t status;
     cairo_t *cr;
     double x, y;
 
@@ -1369,7 +1370,13 @@ _cairo_image_surface_clone (cairo_image_
     cairo_set_source_surface (cr, &surface->base, 0, 0);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
+    status = cairo_status (cr);
     cairo_destroy (cr);
 
+    if (status) {
+	cairo_surface_destroy (&clone->base);
+	return (cairo_image_surface_t *) &_cairo_surface_nil;
+    }
+
     return clone;
 }
diff-tree b61931640d384707a6fc48f9ba4a4f2ddf675c32 (from 353c2ab5c0e10f267a1adf3957b5d6af4e6a2e29)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 19:12:10 2007 +0100

    [cairo-ps-surface] Check the creation of output streams.
    
    Check for allocation errors during the creation of the output streams.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 23a478c..7bf2af5 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -271,6 +271,9 @@ _cairo_ps_surface_emit_path (cairo_ps_su
     ps_path_info_t path_info;
 
     word_wrap = _word_wrap_stream_create (stream, 79);
+    status = _cairo_output_stream_get_status (word_wrap);
+    if (status)
+	return status;
 
     path_info.surface = surface;
     path_info.stream = word_wrap;
@@ -283,8 +286,6 @@ _cairo_ps_surface_emit_path (cairo_ps_su
 					  _cairo_ps_surface_path_close_path,
 					  &path_info);
 
-    if (status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_output_stream_get_status (word_wrap);
     status2 = _cairo_output_stream_destroy (word_wrap);
     if (status == CAIRO_STATUS_SUCCESS)
 	status = status2;
@@ -1675,7 +1676,16 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 				 "/%sData [\n", name);
 
     string_array_stream = _string_array_stream_create (surface->stream);
+    status = _cairo_output_stream_get_status (string_array_stream);
+    if (status)
+	goto bail3;
+
     base85_stream = _cairo_base85_stream_create (string_array_stream);
+    status = _cairo_output_stream_get_status (base85_stream);
+    if (status) {
+	status2 = _cairo_output_stream_destroy (string_array_stream);
+	goto bail3;
+    }
 
     _cairo_output_stream_write (base85_stream, compressed, compressed_size);
 
@@ -2354,6 +2364,10 @@ _cairo_ps_surface_show_glyphs (void		   
             _cairo_output_stream_printf (surface->stream, "<%02x> S\n", glyph_ids[i].glyph_id);
         } else {
             word_wrap = _word_wrap_stream_create (surface->stream, 79);
+	    status = _cairo_output_stream_get_status (word_wrap);
+	    if (status)
+		goto fail;
+
             _cairo_output_stream_printf (word_wrap, "<");
             for (j = i; j < last+1; j++)
                 _cairo_output_stream_printf (word_wrap, "%02x", glyph_ids[j].glyph_id);
diff-tree 353c2ab5c0e10f267a1adf3957b5d6af4e6a2e29 (from 7cc7bf09c1a61f407fdb054640ebf24039f985db)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 19:10:42 2007 +0100

    [cairo-output-stream] Guard against destroying the nil streams.
    
    Add a guard to return early if we attempt to call
    _cairo_output_stream_destroy() on the nil cairo_output_stream_t streams.

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 323bd06..5bce0e3 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -166,6 +166,12 @@ _cairo_output_stream_destroy (cairo_outp
     if (stream == NULL)
 	return _cairo_error (CAIRO_STATUS_NULL_POINTER);
 
+    if (stream == &_cairo_output_stream_nil ||
+	stream == &_cairo_output_stream_nil_write_error)
+    {
+	return stream->status;
+    }
+
     status = _cairo_output_stream_fini (stream);
     free (stream);
 
diff-tree 7cc7bf09c1a61f407fdb054640ebf24039f985db (from 042821b566daf4aa17d662e7422d1b98858954d7)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 18:52:50 2007 +0100

    [cairo-meta-surface] Propagate errors during replay to the surface.
    
    Store any fatal errors raised during the replay on the surface object.

diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index d353d2e..deda858 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -671,6 +671,9 @@ _cairo_meta_surface_replay_internal (cai
     if (surface->status)
 	return surface->status;
 
+    if (target->status)
+	return _cairo_surface_set_error (surface, target->status);
+
     meta = (cairo_meta_surface_t *) surface;
     status = CAIRO_STATUS_SUCCESS;
 
@@ -860,7 +863,7 @@ _cairo_meta_surface_replay_internal (cai
 
     _cairo_clip_reset (&clip);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_status_t
diff-tree 042821b566daf4aa17d662e7422d1b98858954d7 (from 535e7c161b907292eac098b6b4305373558948df)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 20:05:58 2007 +0100

    [cairo-surface] Propagate fatal errors to the surface.
    
    Store errors raised by the backend on the surface.

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 3c95198..94ee2de 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -111,6 +111,9 @@ cairo_status_t
 _cairo_surface_set_error (cairo_surface_t *surface,
 			  cairo_status_t status)
 {
+    if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
     /* Don't overwrite an existing error. This preserves the first
      * error, which is the most significant. */
     _cairo_status_set_error (&surface->status, status);
@@ -435,7 +438,7 @@ _cairo_surface_reset (cairo_surface_t *s
     if (surface->backend->reset != NULL) {
 	cairo_status_t status = surface->backend->reset (surface);
 	if (status)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
     }
 
     _cairo_surface_init (surface, surface->backend, surface->content);
@@ -914,8 +917,9 @@ _cairo_surface_acquire_source_image (cai
 {
     assert (!surface->finished);
 
-    return surface->backend->acquire_source_image (surface,
-						   image_out, image_extra);
+    return _cairo_surface_set_error (surface,
+	    surface->backend->acquire_source_image (surface,
+						    image_out, image_extra));
 }
 
 /**
@@ -976,9 +980,12 @@ _cairo_surface_acquire_dest_image (cairo
 {
     assert (!surface->finished);
 
-    return surface->backend->acquire_dest_image (surface,
-						 interest_rect,
-						 image_out, image_rect, image_extra);
+    return _cairo_surface_set_error (surface,
+	    surface->backend->acquire_dest_image (surface,
+						  interest_rect,
+						  image_out,
+						  image_rect,
+						  image_extra));
 }
 
 /**
@@ -1169,7 +1176,7 @@ _cairo_surface_composite (cairo_operator
 	return dst->status;
 
     if (dst->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->composite) {
 	status = dst->backend->composite (op,
@@ -1179,15 +1186,16 @@ _cairo_surface_composite (cairo_operator
                                           dst_x, dst_y,
 					  width, height);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+	    return _cairo_surface_set_error (dst, status);
     }
 
-    return _cairo_surface_fallback_composite (op,
+    return _cairo_surface_set_error (dst,
+	    _cairo_surface_fallback_composite (op,
 					      src, mask, dst,
 					      src_x, src_y,
 					      mask_x, mask_y,
 					      dst_x, dst_y,
-					      width, height);
+					      width, height));
 }
 
 /**
@@ -1222,7 +1230,7 @@ _cairo_surface_fill_rectangle (cairo_sur
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     rect.x = x;
     rect.y = y;
@@ -1272,7 +1280,7 @@ _cairo_surface_fill_region (cairo_surfac
 	rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
 	if (!rects) {
 	    _cairo_region_boxes_fini (region, boxes);
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
         }
     }
 
@@ -1291,7 +1299,7 @@ _cairo_surface_fill_region (cairo_surfac
     if (rects != stack_rects)
 	free (rects);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 /**
@@ -1325,7 +1333,7 @@ _cairo_surface_fill_rectangles (cairo_su
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     if (num_rects == 0)
 	return CAIRO_STATUS_SUCCESS;
@@ -1334,11 +1342,12 @@ _cairo_surface_fill_rectangles (cairo_su
 	status = surface->backend->fill_rectangles (surface, op, color,
 						    rects, num_rects);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
     }
 
-    return _cairo_surface_fallback_fill_rectangles (surface, op, color,
-						    rects, num_rects);
+    return _cairo_surface_set_error (surface,
+	    _cairo_surface_fallback_fill_rectangles (surface, op, color,
+						     rects, num_rects));
 }
 
 cairo_status_t
@@ -1353,7 +1362,7 @@ _cairo_surface_paint (cairo_surface_t	*s
 
     status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     if (surface->backend->paint) {
 	status = surface->backend->paint (surface, op, &dev_source.base);
@@ -1366,7 +1375,7 @@ _cairo_surface_paint (cairo_surface_t	*s
  FINISH:
     _cairo_pattern_fini (&dev_source.base);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_status_t
@@ -1384,6 +1393,7 @@ _cairo_surface_mask (cairo_surface_t	*su
     status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
     if (status)
 	goto FINISH;
+
     status = _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
     if (status)
 	goto CLEANUP_SOURCE;
@@ -1402,7 +1412,7 @@ _cairo_surface_mask (cairo_surface_t	*su
     _cairo_pattern_fini (&dev_source.base);
  FINISH:
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_status_t
@@ -1431,12 +1441,12 @@ _cairo_surface_fill_stroke (cairo_surfac
 
 	status = _cairo_surface_copy_pattern_for_destination (stroke_source, surface, &dev_stroke_source.base);
 	if (status)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
 
 	status = _cairo_surface_copy_pattern_for_destination (fill_source, surface, &dev_fill_source.base);
 	if (status) {
 	    _cairo_pattern_fini (&dev_stroke_source.base);
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
 	}
 
 	status = surface->backend->fill_stroke (surface, fill_op, &dev_fill_source.base,
@@ -1449,19 +1459,21 @@ _cairo_surface_fill_stroke (cairo_surfac
 	_cairo_pattern_fini (&dev_fill_source.base);
 
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
     }
 
     status = _cairo_surface_fill (surface, fill_op, fill_source, path,
 				  fill_rule, fill_tolerance, fill_antialias);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
 				    stroke_style, stroke_ctm, stroke_ctm_inverse,
 				    stroke_tolerance, stroke_antialias);
+    if (status)
+	return _cairo_surface_set_error (surface, status);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
@@ -1486,7 +1498,7 @@ _cairo_surface_stroke (cairo_surface_t		
 
     status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     if (surface->backend->stroke) {
 	status = surface->backend->stroke (surface, op, &dev_source.base,
@@ -1508,7 +1520,7 @@ _cairo_surface_stroke (cairo_surface_t		
         _cairo_path_fixed_fini (&real_dev_path);
     _cairo_pattern_fini (&dev_source.base);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_status_t
@@ -1527,7 +1539,7 @@ _cairo_surface_fill (cairo_surface_t	*su
 
     status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     if (surface->backend->fill) {
 	status = surface->backend->fill (surface, op, &dev_source.base,
@@ -1545,7 +1557,7 @@ _cairo_surface_fill (cairo_surface_t	*su
  FINISH:
     _cairo_pattern_fini (&dev_source.base);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_status_t
@@ -1575,7 +1587,7 @@ _cairo_surface_composite_trapezoids (cai
 	return dst->status;
 
     if (dst->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->composite_trapezoids) {
 	status = dst->backend->composite_trapezoids (op,
@@ -1586,15 +1598,16 @@ _cairo_surface_composite_trapezoids (cai
 						     width, height,
 						     traps, num_traps);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+	    return _cairo_surface_set_error (dst, status);
     }
 
-    return  _cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
+    return  _cairo_surface_set_error (dst,
+	    _cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
 							  antialias,
 							  src_x, src_y,
 							  dst_x, dst_y,
 							  width, height,
-							  traps, num_traps);
+							  traps, num_traps));
 }
 
 /**
@@ -1617,13 +1630,14 @@ cairo_surface_copy_page (cairo_surface_t
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     /* It's fine if some backends don't implement copy_page */
     if (surface->backend->copy_page == NULL)
 	return CAIRO_STATUS_SUCCESS;
 
-    return surface->backend->copy_page (surface);
+    return _cairo_surface_set_error (surface,
+	                             surface->backend->copy_page (surface));
 }
 slim_hidden_def (cairo_surface_copy_page);
 
@@ -1646,13 +1660,14 @@ cairo_surface_show_page (cairo_surface_t
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     /* It's fine if some backends don't implement show_page */
     if (surface->backend->show_page == NULL)
 	return CAIRO_STATUS_SUCCESS;
 
-    return surface->backend->show_page (surface);
+    return _cairo_surface_set_error (surface,
+	                             surface->backend->show_page (surface));
 }
 slim_hidden_def (cairo_surface_show_page);
 
@@ -1712,7 +1727,7 @@ _cairo_surface_reset_clip (cairo_surface
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     surface->current_clip_serial = 0;
 
@@ -1723,13 +1738,13 @@ _cairo_surface_reset_clip (cairo_surface
 							0,
 							CAIRO_ANTIALIAS_DEFAULT);
 	if (status)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
     }
 
     if (surface->backend->set_clip_region != NULL) {
 	status = surface->backend->set_clip_region (surface, NULL);
 	if (status)
-	    return status;
+	    return _cairo_surface_set_error (surface, status);
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -1756,7 +1771,7 @@ _cairo_surface_set_clip_region (cairo_su
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->set_clip_region != NULL);
 
@@ -1764,7 +1779,7 @@ _cairo_surface_set_clip_region (cairo_su
 
     status = surface->backend->set_clip_region (surface, region);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 cairo_int_status_t
@@ -1781,7 +1796,7 @@ _cairo_surface_intersect_clip_path (cair
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->intersect_clip_path != NULL);
 
@@ -1791,7 +1806,7 @@ _cairo_surface_intersect_clip_path (cair
 						    tolerance,
 						    antialias);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 static cairo_status_t
@@ -1834,7 +1849,7 @@ _cairo_surface_set_clip_path (cairo_surf
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->intersect_clip_path != NULL);
 
@@ -1844,11 +1859,11 @@ _cairo_surface_set_clip_path (cairo_surf
 						    0,
 						    CAIRO_ANTIALIAS_DEFAULT);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     status = _cairo_surface_set_clip_path_recursive (surface, clip_path);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     surface->current_clip_serial = serial;
 
@@ -1860,14 +1875,11 @@ _cairo_surface_set_clip (cairo_surface_t
 {
     unsigned int serial = 0;
 
-    if (!surface)
-	return _cairo_error (CAIRO_STATUS_NULL_POINTER);
-
     if (surface->status)
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
     if (clip) {
 	serial = clip->serial;
@@ -1927,9 +1939,10 @@ _cairo_surface_get_extents (cairo_surfac
 	return surface->status;
 
     if (surface->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
 
-    return surface->backend->get_extents (surface, rectangle);
+    return _cairo_surface_set_error (surface,
+	    surface->backend->get_extents (surface, rectangle));
 }
 
 /* Note: the backends may modify the contents of the glyph array as long as
@@ -1962,7 +1975,7 @@ _cairo_surface_show_glyphs (cairo_surfac
 						          surface,
 							  &dev_source.base);
     if (status)
-	return status;
+	return _cairo_surface_set_error (surface, status);
 
     cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
 
@@ -1986,7 +1999,7 @@ _cairo_surface_show_glyphs (cairo_surfac
     status = cairo_scaled_font_status (dev_scaled_font);
     if (status) {
 	_cairo_pattern_fini (&dev_source.base);
-	return status;
+	return _cairo_surface_set_error (surface, status);
     }
 
     CAIRO_MUTEX_LOCK (dev_scaled_font->mutex);
@@ -2010,7 +2023,7 @@ _cairo_surface_show_glyphs (cairo_surfac
 
     _cairo_pattern_fini (&dev_source.base);
 
-    return status;
+    return _cairo_surface_set_error (surface, status);
 }
 
 /* XXX: Previously, we had a function named _cairo_surface_show_glyphs
@@ -2040,7 +2053,7 @@ _cairo_surface_old_show_glyphs (cairo_sc
 	return dst->status;
 
     if (dst->finished)
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+	return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->old_show_glyphs) {
 	status = dst->backend->old_show_glyphs (scaled_font,
@@ -2052,7 +2065,7 @@ _cairo_surface_old_show_glyphs (cairo_sc
     } else
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
 
-    return status;
+    return _cairo_surface_set_error (dst, status);
 }
 
 static cairo_status_t
@@ -2113,7 +2126,7 @@ CLEANUP_REGIONS:
     if (has_clear_region)
         _cairo_region_fini (&clear_region);
 
-    return status;
+    return _cairo_surface_set_error (dst, status);
 }
 
 /**
diff-tree 535e7c161b907292eac098b6b4305373558948df (from bb8d4c0b14ec175637f57a3b51c4997c0be12a0f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 18:45:17 2007 +0100

    [cairo-type1-subset] Do not mask error returns.
    
    When propagating errors, check that we do not overwrite a pre-existing
    error.

diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index cbc4126..cdd6dfc 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -103,6 +103,17 @@ typedef struct _cairo_type1_font_subset 
     cairo_status_t status;
 } cairo_type1_font_subset_t;
 
+static cairo_status_t
+_cairo_type1_font_subset_set_error (cairo_type1_font_subset_t *font,
+	                            cairo_status_t status)
+{
+    if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    _cairo_status_set_error (&font->status, status);
+
+    return _cairo_error (status);
+}
 
 static cairo_status_t
 _cairo_type1_font_subset_create (cairo_unscaled_font_t      *unscaled_font,
@@ -229,6 +240,9 @@ cairo_type1_font_subset_find_segments (c
     const char *eexec_token;
     int size;
 
+    if (font->status)
+	return font->status;
+
     p = (unsigned char *) font->type1_data;
     font->type1_end = font->type1_data + font->type1_length;
     if (p[0] == 0x80 && p[1] == 0x01) {
@@ -251,7 +265,7 @@ cairo_type1_font_subset_find_segments (c
     } else {
 	eexec_token = find_token ((char *) p, font->type1_end, "eexec");
 	if (eexec_token == NULL)
-	    return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	    return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
 
 	font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
 	font->header_segment = (char *) p;
@@ -270,11 +284,14 @@ cairo_type1_font_subset_write_header (ca
     const char *start, *end, *segment_end;
     unsigned int i;
 
+    if (font->status)
+	return font->status;
+
     segment_end = font->header_segment + font->header_segment_size;
 
     start = find_token (font->header_segment, segment_end, "/FontName");
     if (start == NULL)
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
 
     _cairo_output_stream_write (font->output, font->header_segment,
 				start - font->header_segment);
@@ -283,12 +300,12 @@ cairo_type1_font_subset_write_header (ca
 
     end = find_token (start, segment_end, "def");
     if (end == NULL)
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
     end += 3;
 
     start = find_token (end, segment_end, "/Encoding");
     if (start == NULL)
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
     _cairo_output_stream_write (font->output, end, start - end);
 
     _cairo_output_stream_printf (font->output,
@@ -306,12 +323,12 @@ cairo_type1_font_subset_write_header (ca
 
     end = find_token (start, segment_end, "def");
     if (end == NULL)
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
     end += 3;
 
     _cairo_output_stream_write (font->output, end, segment_end - end);
 
-    return font->status;
+    return _cairo_type1_font_subset_set_error(font, font->output->status);
 }
 
 static int
@@ -325,7 +342,7 @@ hex_to_int (int ch)
 	return ch - 'a' + 10;
 }
 
-static void
+static cairo_status_t
 cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
 					 const char *data, unsigned int length)
 {
@@ -334,6 +351,9 @@ cairo_type1_font_subset_write_encrypted 
     static const char hex_digits[16] = "0123456789abcdef";
     char digits[3];
 
+    if (font->status)
+	return font->status;
+
     in = (const unsigned char *) data;
     end = (const unsigned char *) data + length;
     while (in < end) {
@@ -358,6 +378,8 @@ cairo_type1_font_subset_write_encrypted 
 	    _cairo_output_stream_write (font->output, digits, 1);
 	}
     }
+
+    return _cairo_type1_font_subset_set_error (font, font->output->status);
 }
 
 static cairo_status_t
@@ -368,14 +390,15 @@ cairo_type1_font_subset_decrypt_eexec_se
     char *out;
     int c, p;
 
+    if (font->status)
+	return font->status;
+
     in = (unsigned char *) font->eexec_segment;
     end = (unsigned char *) in + font->eexec_segment_size;
 
     font->cleartext = malloc (font->eexec_segment_size);
-    if (font->cleartext == NULL) {
-	font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return font->status;
-    }
+    if (font->cleartext == NULL)
+	return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
 
     out = font->cleartext;
     while (in < end) {
@@ -394,7 +417,7 @@ cairo_type1_font_subset_decrypt_eexec_se
     }
     font->cleartext_end = out;
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static const char *
@@ -435,6 +458,9 @@ cairo_type1_font_subset_get_glyph_names_
     char buffer[256];
     FT_Error error;
 
+    if (font->status)
+	return font->status;
+
     /* Get glyph names and width using the freetype API */
     for (i = 0; i < font->base.num_glyphs; i++) {
 	if (font->glyphs[i].name != NULL)
@@ -445,7 +471,7 @@ cairo_type1_font_subset_get_glyph_names_
 			       FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
 	if (error != 0) {
 	    printf ("could not load glyph %d\n", i);
-	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
 	}
 
 	font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
@@ -453,12 +479,12 @@ cairo_type1_font_subset_get_glyph_names_
 	error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
 	if (error != 0) {
 	    printf ("could not get glyph name for glyph %d\n", i);
-	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
 	}
 
 	font->glyphs[i].name = strdup (buffer);
 	if (font->glyphs[i].name == NULL)
-	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return _cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -720,7 +746,7 @@ cairo_type1_font_subset_look_for_seac(ca
 
     charstring = malloc (encrypted_charstring_length);
     if (charstring == NULL) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	_cairo_type1_font_subset_set_error (font, CAIRO_STATUS_NO_MEMORY);
 	return;
     }
 
@@ -823,7 +849,7 @@ cairo_type1_font_subset_for_each_glyph (
 
 	charstring_length = strtol (p, &end, 10);
 	if (p == end) {
-	    font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	    _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
 	    return NULL;
 	}
 
@@ -839,7 +865,7 @@ cairo_type1_font_subset_for_each_glyph (
 	/* In case any of the skip_token() calls above reached EOF, p will
 	 * be equal to dict_end. */
 	if (p == dict_end) {
-	    font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	    _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
 	    return NULL;
 	}
 
@@ -847,13 +873,16 @@ cairo_type1_font_subset_for_each_glyph (
 							    name, name_length);
 	if (font->glyphs[glyph_index].subset_index >= 0)
 	    func (font, name, name_length, charstring, charstring_length);
+
+	if (font->status)
+	    return NULL;
     }
 
     return p;
 }
 
 
-static const char *
+static void
 cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
 					    const char                *name)
 {
@@ -862,6 +891,9 @@ cairo_type1_font_subset_write_private_di
     char buffer[32], *glyph_count_end;
     int num_charstrings, length;
 
+    if (font->status)
+	return;
+
     /* The private dict holds hint information, common subroutines and
      * the actual glyph definitions (charstrings).
      *
@@ -880,16 +912,16 @@ cairo_type1_font_subset_write_private_di
      * this more cleverly. */
     charstrings = find_token (font->cleartext, font->cleartext_end, "/CharStrings");
     if (charstrings == NULL) {
-	font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-	return NULL;
+	_cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+	return;
     }
 
     /* Scan past /CharStrings and the integer following it. */
     p = charstrings + strlen ("/CharStrings");
     num_charstrings = strtol (p, &glyph_count_end, 10);
     if (p == glyph_count_end) {
-	font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-	return NULL;
+	_cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+	return;
     }
 
     /* Look for a '/' which marks the beginning of the first glyph
@@ -898,13 +930,13 @@ cairo_type1_font_subset_write_private_di
 	if (*p == '/')
 	    break;
     if (p == font->cleartext_end) {
-	font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-	return NULL;
+	_cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+	return;
     }
     dict_start = p;
 
     if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
-	return NULL;
+	return;
 
     /* Now that we have the private dictionary broken down in
      * sections, do the first pass through the glyph definitions to
@@ -917,17 +949,17 @@ cairo_type1_font_subset_write_private_di
 
     closefile_token = find_token (p, font->cleartext_end, "closefile");
     if (closefile_token == NULL) {
-	font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-	return NULL;
+	_cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
+	return;
     }
 
     if (cairo_type1_font_subset_get_glyph_names_and_widths (font))
-	return NULL;
+	return;
 
     /* We're ready to start outputting. First write the header,
      * i.e. the public part of the font dict.*/
     if (cairo_type1_font_subset_write_header (font, name))
-	return NULL;
+	return;
 
     font->base.header_size = _cairo_output_stream_get_position (font->output);
 
@@ -959,8 +991,6 @@ cairo_type1_font_subset_write_private_di
     cairo_type1_font_subset_write_encrypted (font, p,
 					     closefile_token - p + strlen ("closefile") + 1);
     _cairo_output_stream_write (font->output, "\n", 1);
-
-    return p;
 }
 
 static cairo_status_t
@@ -980,35 +1010,44 @@ cairo_type1_font_subset_write_trailer(ca
 
     cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
     if (cleartomark_token == NULL)
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
 
     _cairo_output_stream_write (font->output, cleartomark_token,
 				font->type1_end - cleartomark_token);
 
-    return font->status;
+    return _cairo_type1_font_subset_set_error(font, font->output->status);
 }
 
 static cairo_status_t
 type1_font_write (void *closure, const unsigned char *data, unsigned int length)
 {
     cairo_type1_font_subset_t *font = closure;
+    cairo_status_t status;
 
-    font->status =
-	_cairo_array_append_multiple (&font->contents, data, length);
+    if (font->status)
+	return font->status;
 
-    return font->status;
+    status = _cairo_array_append_multiple (&font->contents, data, length);
+
+    return _cairo_type1_font_subset_set_error (font, status);
 }
 
 static cairo_status_t
 cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
 			       const char *name)
 {
-    if (cairo_type1_font_subset_find_segments (font))
-	return font->status;
+    cairo_status_t status;
 
-    if (cairo_type1_font_subset_decrypt_eexec_segment (font))
+    if (font->status)
 	return font->status;
 
+    status = cairo_type1_font_subset_find_segments (font);
+    if (status)
+	return status;
+
+    status = cairo_type1_font_subset_decrypt_eexec_segment (font);
+	return status;
+
     /* Determine which glyph definition delimiters to use. */
     if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) {
 	font->rd = "-|";
@@ -1018,7 +1057,7 @@ cairo_type1_font_subset_write (cairo_typ
 	font->nd = "ND";
     } else {
 	/* Don't know *what* kind of font this is... */
-	return font->status = CAIRO_INT_STATUS_UNSUPPORTED;
+	return _cairo_type1_font_subset_set_error (font, CAIRO_INT_STATUS_UNSUPPORTED);
     }
 
     font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
@@ -1035,7 +1074,7 @@ cairo_type1_font_subset_write (cairo_typ
 	_cairo_output_stream_get_position (font->output) -
 	font->base.header_size - font->base.data_size;
 
-    return font->status;
+    return _cairo_type1_font_subset_set_error(font, font->output->status);
 }
 
 static cairo_status_t
diff-tree bb8d4c0b14ec175637f57a3b51c4997c0be12a0f (from 37fd0d8967df21695d6536af1d7aedbeef2d2449)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 18:33:24 2007 +0100

    [cairo-truetype-subset] Do mask error status returns.
    
    Be careful not to overwrite existing the error status when propagating
    errors and to not blindly return INT_STATUS_UNSUPPORTED from
    load_truetype_table() as this will mask fatal errors.

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 899f012..5e392d4 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -91,6 +91,18 @@ cairo_truetype_font_use_glyph (cairo_tru
 #define SFNT_STRING_MAX_LENGTH  65535
 
 static cairo_status_t
+_cairo_truetype_font_set_error (cairo_truetype_font_t *font,
+			        cairo_status_t status)
+{
+    if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    _cairo_status_set_error (&font->status, status);
+
+    return _cairo_error (status);
+}
+
+static cairo_status_t
 _cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
 			     cairo_truetype_font_t      **font_return)
 {
@@ -119,35 +131,44 @@ _cairo_truetype_font_create (cairo_scale
      */
 
     size = sizeof (tt_head_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_head, 0, (unsigned char *) &head,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                          TT_TAG_head, 0,
+					  (unsigned char *) &head,
+                                          &size);
+    if (status)
+	return status;
 
     size = sizeof (tt_maxp_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_maxp, 0, (unsigned char *) &maxp,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                           TT_TAG_maxp, 0,
+					   (unsigned char *) &maxp,
+					   &size);
+    if (status)
+	return status;
 
     size = sizeof (tt_hhea_t);
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_hhea, 0, (unsigned char *) &hhea,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
+                                           TT_TAG_hhea, 0,
+					   (unsigned char *) &hhea,
+					   &size);
+    if (status)
+	return status;
 
     size = 0;
-    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
-                                      TT_TAG_name, 0, NULL,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
+	                                   TT_TAG_name, 0,
+					   NULL,
+					   &size);
+    if (status)
+	return status;
 
     name = malloc(size);
     if (name == NULL)
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
-					   TT_TAG_name, 0, (unsigned char *) name,
+					   TT_TAG_name, 0,
+					   (unsigned char *) name,
 					   &size);
     if (status)
 	goto fail0;
@@ -292,9 +313,12 @@ cairo_truetype_font_allocate_write_buffe
 {
     cairo_status_t status;
 
+    if (font->status)
+	return font->status;
+
     status = _cairo_array_allocate (&font->output, length, (void **) buffer);
     if (status)
-	return status;
+	return _cairo_truetype_font_set_error (font, status);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -306,9 +330,12 @@ cairo_truetype_font_write (cairo_truetyp
 {
     cairo_status_t status;
 
+    if (font->status)
+	return font->status;
+
     status = _cairo_array_append_multiple (&font->output, data, length);
     if (status)
-	return status;
+	return _cairo_truetype_font_set_error (font, status);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -319,6 +346,9 @@ cairo_truetype_font_write_be16 (cairo_tr
 {
     uint16_t be16_value;
 
+    if (font->status)
+	return;
+
     be16_value = cpu_to_be16 (value);
     cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
 }
@@ -329,6 +359,9 @@ cairo_truetype_font_write_be32 (cairo_tr
 {
     uint32_t be32_value;
 
+    if (font->status)
+	return;
+
     be32_value = cpu_to_be32 (value);
     cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
 }
@@ -357,12 +390,15 @@ cairo_truetype_font_check_boundary (cair
 {
     cairo_status_t status;
 
+    if (font->status)
+	return font->status;
+
     if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
     {
         status = _cairo_array_append (&font->string_offsets,
 				      &font->last_boundary);
 	if (status)
-	    return status;
+	    return _cairo_truetype_font_set_error (font, status);
 
         font->last_offset = font->last_boundary;
     }
@@ -428,21 +464,23 @@ cairo_truetype_font_write_generic_table 
     unsigned char *buffer;
     unsigned long size;
 
+    if (font->status)
+	return font->status;
+
     size = 0;
-    if (font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
-					    tag, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) {
-        font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-        return font->status;
-    }
+    status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
+					        tag, 0, NULL, &size);
+    if (status)
+        return _cairo_truetype_font_set_error (font, status);
 
     status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
     if (status)
-	return status;
+	return _cairo_truetype_font_set_error (font, status);
 
     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 						 tag, 0, buffer, &size);
     if (status)
-	return status;
+	return _cairo_truetype_font_set_error (font, status);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -458,6 +496,9 @@ cairo_truetype_font_remap_composite_glyp
     unsigned short flags;
     unsigned short index;
 
+    if (font->status)
+	return;
+
     glyph_data = (tt_glyph_data_t *) buffer;
     if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
         return;
@@ -495,13 +536,17 @@ cairo_truetype_font_write_glyf_table (ca
 	uint16_t      *short_offsets;
 	uint32_t      *long_offsets;
     } u;
+    cairo_status_t status;
 
-    size = sizeof (tt_head_t);
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       TT_TAG_head, 0,
-						       (unsigned char*) &header, &size);
     if (font->status)
 	return font->status;
+
+    size = sizeof (tt_head_t);
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 TT_TAG_head, 0,
+						 (unsigned char*) &header, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
     
     if (be16_to_cpu (header.index_to_loc_format) == 0)
 	size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
@@ -509,16 +554,13 @@ cairo_truetype_font_write_glyf_table (ca
 	size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
 
     u.bytes = malloc (size);
-    if (u.bytes == NULL) {
-	font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return font->status;
-    }
+    if (u.bytes == NULL)
+	return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
 
-    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                            TT_TAG_loca, 0, u.bytes, &size) != CAIRO_STATUS_SUCCESS) {
-        font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-        return font->status;
-    }
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                 TT_TAG_loca, 0, u.bytes, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
 
     start_offset = _cairo_array_num_elements (&font->output);
     for (i = 0; i < font->base.num_glyphs; i++) {
@@ -536,21 +578,21 @@ cairo_truetype_font_write_glyf_table (ca
 
         next = cairo_truetype_font_align_output (font);
 
-        font->status = cairo_truetype_font_check_boundary (font, next);
-	if (font->status)
-	    break;
+        status = cairo_truetype_font_check_boundary (font, next);
+	if (status)
+	    goto FAIL;
 
         font->glyphs[i].location = next - start_offset;
 
-	font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
-	if (font->status)
-	    break;
+	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
+	if (status)
+	    goto FAIL;
 
         if (size != 0) {
-            font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-							       TT_TAG_glyf, begin, buffer, &size);
-	    if (font->status)
-		break;
+            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+							 TT_TAG_glyf, begin, buffer, &size);
+	    if (status)
+		goto FAIL;
 
             cairo_truetype_font_remap_composite_glyph (font, buffer);
         }
@@ -559,9 +601,11 @@ cairo_truetype_font_write_glyf_table (ca
     font->glyphs[i].location =
 	cairo_truetype_font_align_output (font) - start_offset;
 
+    status = font->status;
+FAIL:
     free (u.bytes);
 
-    return font->status;
+    return _cairo_truetype_font_set_error (font, status);
 }
 
 static cairo_status_t
@@ -570,27 +614,31 @@ cairo_truetype_font_write_head_table (ca
 {
     unsigned char *buffer;
     unsigned long size;
+    cairo_status_t status;
 
-    size = 0;
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       tag, 0, NULL, &size);
     if (font->status)
 	return font->status;
 
+    size = 0;
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 tag, 0, NULL, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
+
     font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
-    font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
-    if (font->status)
-	return font->status;
+    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
 
-    font->status = font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
-						       tag, 0, buffer, &size);
-    if (font->status)
-	return font->status;
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 tag, 0, buffer, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
 
     /* set checkSumAdjustment to 0 for table checksum calcualtion */
     *(uint32_t *)(buffer + 8) = 0;
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -598,20 +646,24 @@ cairo_truetype_font_write_hhea_table (ca
 {
     tt_hhea_t *hhea;
     unsigned long size;
+    cairo_status_t status;
 
-    size = sizeof (tt_hhea_t);
-    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
     if (font->status)
 	return font->status;
 
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       tag, 0, (unsigned char *) hhea, &size);
-    if (font->status)
-	return font->status;
+    size = sizeof (tt_hhea_t);
+    status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
+
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 tag, 0, (unsigned char *) hhea, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
 
     hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -625,54 +677,58 @@ cairo_truetype_font_write_hmtx_table (ca
     unsigned int i;
     tt_hhea_t hhea;
     int num_hmetrics;
+    cairo_status_t status;
 
-    size = sizeof (tt_hhea_t);
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       TT_TAG_hhea, 0,
-						       (unsigned char*) &hhea, &size);
     if (font->status)
 	return font->status;
 
+    size = sizeof (tt_hhea_t);
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 TT_TAG_hhea, 0,
+						 (unsigned char*) &hhea, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
+
     num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
 
     for (i = 0; i < font->base.num_glyphs; i++) {
         long_entry_size = 2 * sizeof (int16_t);
         short_entry_size = sizeof (int16_t);
-        font->status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size,
-								  (unsigned char **) &p);
-	if (font->status)
-	    return font->status;
+        status = cairo_truetype_font_allocate_write_buffer (font,
+		                                            long_entry_size,
+							    (unsigned char **) &p);
+	if (status)
+	    return _cairo_truetype_font_set_error (font, status);
 
         if (font->glyphs[i].parent_index < num_hmetrics) {
-            if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                    TT_TAG_hmtx,
-                                                    font->glyphs[i].parent_index * long_entry_size,
-                                                    (unsigned char *) p, &long_entry_size) != CAIRO_STATUS_SUCCESS) {
-                font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-                return font->status;
-            }
+            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                         TT_TAG_hmtx,
+                                                         font->glyphs[i].parent_index * long_entry_size,
+                                                         (unsigned char *) p, &long_entry_size);
+	    if (status)
+		return _cairo_truetype_font_set_error (font, status);
         }
         else
         {
-            if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-                                                    TT_TAG_hmtx,
-                                                    (num_hmetrics - 1) * long_entry_size,
-                                                    (unsigned char *) p, &short_entry_size) != CAIRO_STATUS_SUCCESS) {
-                font->status = CAIRO_INT_STATUS_UNSUPPORTED;
-                return font->status;
-            }
-            font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-							       TT_TAG_hmtx,
-							       num_hmetrics * long_entry_size +
-							       (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
-							       (unsigned char *) (p + 1), &short_entry_size);
-	    if (font->status)
-		return font->status;
+            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+                                                         TT_TAG_hmtx,
+							 (num_hmetrics - 1) * long_entry_size,
+							 (unsigned char *) p, &short_entry_size);
+	    if (status)
+		return _cairo_truetype_font_set_error (font, status);
+
+            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+							 TT_TAG_hmtx,
+							 num_hmetrics * long_entry_size +
+							 (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
+							 (unsigned char *) (p + 1), &short_entry_size);
+	    if (status)
+		return _cairo_truetype_font_set_error (font, status);
         }
         font->base.widths[i] = be16_to_cpu (p[0]);
     }
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -682,14 +738,18 @@ cairo_truetype_font_write_loca_table (ca
     unsigned int i;
     tt_head_t header;
     unsigned long size;
+    cairo_status_t status;
 
-    size = sizeof(tt_head_t);
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       TT_TAG_head, 0,
-						       (unsigned char*) &header, &size);
     if (font->status)
 	return font->status;
 
+    size = sizeof(tt_head_t);
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 TT_TAG_head, 0,
+						 (unsigned char*) &header, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
+
     if (be16_to_cpu (header.index_to_loc_format) == 0)
     {
 	for (i = 0; i < font->base.num_glyphs + 1; i++)
@@ -708,20 +768,24 @@ cairo_truetype_font_write_maxp_table (ca
 {
     tt_maxp_t *maxp;
     unsigned long size;
+    cairo_status_t status;
 
-    size = sizeof (tt_maxp_t);
-    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
     if (font->status)
 	return font->status;
 
-    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
-						       tag, 0, (unsigned char *) maxp, &size);
-    if (font->status)
-	return font->status;
+    size = sizeof (tt_maxp_t);
+    status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
+
+    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
+						 tag, 0, (unsigned char *) maxp, &size);
+    if (status)
+	return _cairo_truetype_font_set_error (font, status);
 
     maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -732,6 +796,9 @@ cairo_truetype_font_write_offset_table (
     size_t table_buffer_length;
     unsigned short search_range, entry_selector, range_shift;
 
+    if (font->status)
+	return font->status;
+
     search_range = 1;
     entry_selector = 0;
     while (search_range * 2 <= font->num_tables) {
@@ -754,9 +821,9 @@ cairo_truetype_font_write_offset_table (
     status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
 						      &table_buffer);
     if (status)
-	return status;
+	return _cairo_truetype_font_set_error (font, status);
 
-    return font->status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static uint32_t
@@ -807,26 +874,29 @@ cairo_truetype_font_generate (cairo_true
     uint32_t checksum, *checksum_location;
     int i;
 
-    if (cairo_truetype_font_write_offset_table (font))
-	goto fail;
+    if (font->status)
+	return font->status;
+
+    status = cairo_truetype_font_write_offset_table (font);
+    if (status)
+	goto FAIL;
 
     start = cairo_truetype_font_align_output (font);
     end = start;
 
     end = 0;
     for (i = 0; i < font->num_tables; i++) {
-	if (font->truetype_tables[i].write (font, font->truetype_tables[i].tag))
-	    goto fail;
+	status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
+	if (status)
+	    goto FAIL;
 
 	end = _cairo_array_num_elements (&font->output);
 	next = cairo_truetype_font_align_output (font);
 	cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
                                           font->truetype_tables[i].tag, start, end);
         status = cairo_truetype_font_check_boundary (font, next);
-	if (status) {
-	    font->status = status;
-	    goto fail;
-	}
+	if (status)
+	    goto FAIL;
 
 	start = next;
     }
@@ -844,8 +914,8 @@ cairo_truetype_font_generate (cairo_true
     else
 	*string_offsets = NULL;
 
- fail:
-    return font->status;
+ FAIL:
+    return _cairo_truetype_font_set_error (font, status);
 }
 
 static int
@@ -1038,7 +1108,10 @@ _cairo_truetype_subset_init (cairo_truet
  fail1:
     cairo_truetype_font_destroy (font);
 
-    return _cairo_error (status);
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	status = _cairo_error (status);
+
+    return status;
 }
 
 void
@@ -1054,7 +1127,7 @@ static cairo_int_status_t
 _cairo_truetype_map_glyphs_to_unicode (cairo_scaled_font_subset_t *font_subset,
                                        unsigned long               table_offset)
 {
-    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_status_t status;
     const cairo_scaled_font_backend_t *backend;
     tt_segment_map_t *map;
     char buf[4];
@@ -1069,12 +1142,12 @@ _cairo_truetype_map_glyphs_to_unicode (c
 
     backend = font_subset->scaled_font->backend;
     size = 4;
-    if (backend->load_truetype_table (font_subset->scaled_font,
-                                      TT_TAG_cmap, table_offset,
-                                      (unsigned char *) &buf,
-                                      &size) != CAIRO_STATUS_SUCCESS) {
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    status = backend->load_truetype_table (font_subset->scaled_font,
+                                           TT_TAG_cmap, table_offset,
+					   (unsigned char *) &buf,
+					   &size);
+    if (status)
+	return status;
 
     /* All table formats have the same first two words */
     map = (tt_segment_map_t *) buf;
@@ -1086,12 +1159,12 @@ _cairo_truetype_map_glyphs_to_unicode (c
     if (map == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    if (backend->load_truetype_table (font_subset->scaled_font,
-                                      TT_TAG_cmap, table_offset,
-                                      (unsigned char *) map,
-                                      &size) != CAIRO_STATUS_SUCCESS) {
+    status = backend->load_truetype_table (font_subset->scaled_font,
+                                           TT_TAG_cmap, table_offset,
+                                           (unsigned char *) map,
+                                           &size);
+    if (status)
 	goto fail;
-    }
 
     num_segments = be16_to_cpu (map->segCountX2)/2;
     end_code = map->endCount;
@@ -1159,10 +1232,12 @@ _cairo_truetype_create_glyph_to_unicode_
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     size = 4;
-    if (backend->load_truetype_table (font_subset->scaled_font,
-                                      TT_TAG_cmap, 0, (unsigned char *) &buf,
-                                      &size) != CAIRO_STATUS_SUCCESS)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (font_subset->scaled_font,
+                                           TT_TAG_cmap, 0,
+					   (unsigned char *) &buf,
+					   &size);
+    if (status)
+	return status;
 
     cmap = (tt_cmap_t *) buf;
     num_tables = be16_to_cpu (cmap->num_tables);
@@ -1171,12 +1246,12 @@ _cairo_truetype_create_glyph_to_unicode_
     if (cmap == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    if (backend->load_truetype_table (font_subset->scaled_font,
-                                      TT_TAG_cmap, 0, (unsigned char *) cmap,
-                                      &size) != CAIRO_STATUS_SUCCESS) {
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    status = backend->load_truetype_table (font_subset->scaled_font,
+	                                   TT_TAG_cmap, 0,
+					   (unsigned char *) cmap,
+					   &size);
+    if (status)
         goto cleanup;
-    }
 
     /* Find a table with Unicode mapping */
     for (i = 0; i < num_tables; i++) {


More information about the cairo-commit mailing list