[cairo-commit] 9 commits - boilerplate/cairo-boilerplate-xlib.c src/cairo-paginated-surface.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font-subsets.c src/cairo-xlib-display.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Oct 5 10:47:46 PDT 2007


 boilerplate/cairo-boilerplate-xlib.c |    9 ++-
 src/cairo-paginated-surface.c        |   57 ++++++++++++++---------
 src/cairo-pdf-surface.c              |   84 +++++++++++++++++++++++++++--------
 src/cairo-ps-surface.c               |   38 +++++++++++----
 src/cairo-scaled-font-subsets.c      |   24 ++++++----
 src/cairo-xlib-display.c             |   48 +++++++++++---------
 6 files changed, 175 insertions(+), 85 deletions(-)

New commits:
diff-tree a1633df6eebd9b1252d832c7a70cea6150c818d3 (from cf2f994a319da1230c5d53f3dd81e7715e44a162)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 17:21:00 2007 +0100

    [cairo-scaled-font-subsets] Increment the sub_font counter after insertion.
    
    Do not modify the parent subsets->num_sub_font until after we have
    successfully created the sub_font and inserted it into the hash table.

diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 4912793..d9795eb 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -326,11 +326,19 @@ _cairo_sub_font_map_glyph (cairo_sub_fon
 
         sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
 						       sub_font->current_subset,
-						       sub_font->num_glyphs_in_current_subset++,
+						       sub_font->num_glyphs_in_current_subset,
                                                        scaled_glyph->metrics.x_advance);
 	if (sub_font_glyph == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
+	status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
+	if (status) {
+	    _cairo_sub_font_glyph_destroy (sub_font_glyph);
+	    return status;
+	}
+
+	sub_font->num_glyphs_in_current_subset++;
+
         if (sub_font->is_scaled)
         {
             if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_scaled_subset_used)
@@ -341,12 +349,6 @@ _cairo_sub_font_map_glyph (cairo_sub_fon
             if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_unscaled_subset_used)
                 sub_font->parent->max_glyphs_per_unscaled_subset_used = sub_font->num_glyphs_in_current_subset;
         }
-
-	status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
-	if (status) {
-	    _cairo_sub_font_glyph_destroy (sub_font_glyph);
-	    return status;
-	}
     }
 
     subset_glyph->font_id = sub_font->font_id;
@@ -568,7 +570,7 @@ _cairo_scaled_font_subsets_map_glyph (ca
 
             sub_font = _cairo_sub_font_create (subsets,
                                                unscaled_font,
-                                               subsets->num_sub_fonts++,
+                                               subsets->num_sub_fonts,
                                                max_glyphs,
                                                subset_glyph->is_scaled,
                                                subset_glyph->is_composite);
@@ -583,6 +585,8 @@ _cairo_scaled_font_subsets_map_glyph (ca
 		_cairo_sub_font_destroy (sub_font);
                 return status;
 	    }
+
+	    subsets->num_sub_fonts++;
         }
     } else {
         /* No path available. Add to scaled subset. */
@@ -600,7 +604,7 @@ _cairo_scaled_font_subsets_map_glyph (ca
 
             sub_font = _cairo_sub_font_create (subsets,
                                                cairo_scaled_font_reference (scaled_font),
-                                               subsets->num_sub_fonts++,
+                                               subsets->num_sub_fonts,
                                                max_glyphs,
                                                subset_glyph->is_scaled,
                                                subset_glyph->is_composite);
@@ -615,6 +619,8 @@ _cairo_scaled_font_subsets_map_glyph (ca
 		_cairo_sub_font_destroy (sub_font);
                 return status;
 	    }
+
+	    subsets->num_sub_fonts++;
         }
     }
 
diff-tree cf2f994a319da1230c5d53f3dd81e7715e44a162 (from 3da62fdd2848bd9d06b83534adfee2afa17828ba)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 17:15:29 2007 +0100

    [cairo-paginated-surface] Propagate backend errors to the surface.
    
    If we call a srface backend function directly, then it our
    responsibility to propagate any fatal errors to the surface.

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index d7f02f3..0ebe2c1 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -76,8 +76,10 @@ _cairo_paginated_surface_create (cairo_s
     cairo_paginated_surface_t *surface;
 
     surface = malloc (sizeof (cairo_paginated_surface_t));
-    if (surface == NULL)
+    if (surface == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
+    }
 
     _cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
 			 content);
@@ -106,7 +108,6 @@ _cairo_paginated_surface_create (cairo_s
   FAIL_CLEANUP_SURFACE:
     free (surface);
   FAIL:
-    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
 
@@ -129,11 +130,12 @@ _cairo_paginated_surface_get_target (cai
 }
 
 cairo_status_t
-_cairo_paginated_surface_set_size (cairo_surface_t 	*surface,
+_cairo_paginated_surface_set_size (cairo_surface_t	*surface,
 				   int			 width,
 				   int			 height)
 {
     cairo_paginated_surface_t *paginated_surface;
+    cairo_status_t status;
 
     assert (_cairo_surface_is_paginated (surface));
 
@@ -145,8 +147,9 @@ _cairo_paginated_surface_set_size (cairo
     cairo_surface_destroy (paginated_surface->meta);
     paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
 							  width, height);
-    if (cairo_surface_status (paginated_surface->meta))
-	return cairo_surface_status (paginated_surface->meta);
+    status = cairo_surface_status (paginated_surface->meta);
+    if (status)
+	return status;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -284,6 +287,9 @@ _paint_page (cairo_paginated_surface_t *
     cairo_status_t status;
     cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
 
+    if (surface->target->status)
+	return surface->target->status;
+
     analysis = _cairo_analysis_surface_create (surface->target,
 					       surface->width, surface->height);
     if (analysis == NULL)
@@ -294,8 +300,7 @@ _paint_page (cairo_paginated_surface_t *
     if (status || analysis->status) {
 	if (status == CAIRO_STATUS_SUCCESS)
 	    status = analysis->status;
-	cairo_surface_destroy (analysis);
-	return status;
+	goto FAIL;
     }
 
      if (surface->backend->set_bounding_box) {
@@ -303,10 +308,8 @@ _paint_page (cairo_paginated_surface_t *
 
 	 _cairo_analysis_surface_get_bounding_box (analysis, &bbox);
 	 status = surface->backend->set_bounding_box (surface->target, &bbox);
-	 if (status) {
-	     cairo_surface_destroy (analysis);
-	     return status;
-	 }
+	 if (status)
+	     goto FAIL;
      }
 
     surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
@@ -339,7 +342,7 @@ _paint_page (cairo_paginated_surface_t *
 						    surface->target,
 						    CAIRO_META_REGION_NATIVE);
 	if (status)
-	    return status;
+	    goto FAIL;
     }
 
     if (has_page_fallback)
@@ -352,7 +355,7 @@ _paint_page (cairo_paginated_surface_t *
 	box.p2.y = surface->height;
 	status = _paint_fallback_image (surface, &box);
 	if (status)
-	    return status;
+	    goto FAIL;
     }
 
     if (has_finegrained_fallback)
@@ -368,34 +371,39 @@ _paint_page (cairo_paginated_surface_t *
 						     CAIRO_GSTATE_TOLERANCE_DEFAULT,
 						     CAIRO_ANTIALIAS_DEFAULT);
 	if (status)
-	    return status;
+	    goto FAIL;
 
 	region = _cairo_analysis_surface_get_unsupported (analysis);
 	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
 	if (status)
-	    return status;
+	    goto FAIL;
 	for (i = 0; i < num_boxes; i++) {
 	    status = _paint_fallback_image (surface, &boxes[i]);
 	    if (status) {
                 _cairo_region_boxes_fini (region, boxes);
-		return status;
+		goto FAIL;
             }
 	}
         _cairo_region_boxes_fini (region, boxes);
     }
 
+  FAIL:
     cairo_surface_destroy (analysis);
 
-    return status;
+    return _cairo_surface_set_error (surface->target, status);
 }
 
 static cairo_status_t
 _start_page (cairo_paginated_surface_t *surface)
 {
+    if (surface->target->status)
+	return surface->target->status;
+
     if (! surface->backend->start_page)
 	return CAIRO_STATUS_SUCCESS;
 
-    return (surface->backend->start_page) (surface->target);
+    return _cairo_surface_set_error (surface->target,
+	                        surface->backend->start_page (surface->target));
 }
 
 static cairo_int_status_t
@@ -442,15 +450,18 @@ _cairo_paginated_surface_show_page (void
     if (status)
 	return status;
 
-    if (cairo_surface_status (surface->meta))
-	return cairo_surface_status (surface->meta);
+    status = cairo_surface_status (surface->meta);
+    if (status)
+	return status;
 
     cairo_surface_destroy (surface->meta);
 
     surface->meta = _cairo_meta_surface_create (surface->content,
-						surface->width, surface->height);
-    if (cairo_surface_status (surface->meta))
-	return cairo_surface_status (surface->meta);
+						surface->width,
+						surface->height);
+    status = cairo_surface_status (surface->meta);
+    if (status)
+	return status;
 
     surface->page_num++;
     surface->page_is_blank = TRUE;
diff-tree 3da62fdd2848bd9d06b83534adfee2afa17828ba (from 737cbd25a6cb0bec87563926ad644da019fc9800)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 13:41:39 2007 +0100

    [cairo-xlib-display] Rescan the displays list during shutdown.
    
    As we drop the list mutex whilst calling the hooks during the
    XCloseDisplay callback, we must rescan the list when we reacquire the
    mutex in order to remove the display from the list.

diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 83170f5..d77b64f 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -158,6 +158,8 @@ _cairo_xlib_display_destroy (cairo_xlib_
     _cairo_freelist_fini (&display->wq_freelist);
     _cairo_freelist_fini (&display->hook_freelist);
 
+    CAIRO_MUTEX_FINI (display->mutex);
+
     free (display);
 }
 
@@ -171,6 +173,29 @@ static int
 _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
 {
     cairo_xlib_display_t *display, **prev, *next;
+    cairo_xlib_error_func_t old_handler;
+
+    CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);
+    for (display = _cairo_xlib_display_list; display; display = display->next)
+	if (display->display == dpy)
+	    break;
+    CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
+    if (display == NULL)
+	return 0;
+
+    /* protect the notifies from triggering XErrors */
+    XSync (dpy, False);
+    old_handler = XSetErrorHandler (_noop_error_handler);
+
+    _cairo_xlib_display_notify (display);
+    _cairo_xlib_call_close_display_hooks (display);
+    _cairo_xlib_display_discard_screens (display);
+
+    /* catch any that arrived before marking the display as closed */
+    _cairo_xlib_display_notify (display);
+
+    XSync (dpy, False);
+    XSetErrorHandler (old_handler);
 
     /*
      * Unhook from the global list
@@ -180,27 +205,6 @@ _cairo_xlib_close_display (Display *dpy,
     for (display = _cairo_xlib_display_list; display; display = next) {
 	next = display->next;
 	if (display->display == dpy) {
-	    cairo_xlib_error_func_t old_handler;
-
-	    /* drop the list mutex whilst triggering the hooks */
-	    CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
-
-	    /* protect the notifies from triggering XErrors */
-	    XSync (dpy, False);
-	    old_handler = XSetErrorHandler (_noop_error_handler);
-
-	    _cairo_xlib_display_notify (display);
-	    _cairo_xlib_call_close_display_hooks (display);
-	    _cairo_xlib_display_discard_screens (display);
-
-	    /* catch any that arrived before marking the display as closed */
-	    _cairo_xlib_display_notify (display);
-
-	    XSync (dpy, False);
-	    XSetErrorHandler (old_handler);
-
-	    CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex);
-	    _cairo_xlib_display_destroy (display);
 	    *prev = next;
 	    break;
 	} else
@@ -208,6 +212,8 @@ _cairo_xlib_close_display (Display *dpy,
     }
     CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
 
+    _cairo_xlib_display_destroy (display);
+
     /* Return value in accordance with requirements of
      * XESetCloseDisplay */
     return 0;
diff-tree 737cbd25a6cb0bec87563926ad644da019fc9800 (from 31b52779bad4122d101cdffdb03153baf6cd011e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 13:03:47 2007 +0100

    [cairo-ps-surface] Cleanup ps surface after creation failure.
    
    If we fail to create the paginated wrapper for the ps surface, cleanup
    the resources allocated for the surface.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 8265abd..9a774e2 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -813,7 +813,7 @@ _cairo_ps_surface_create_for_stream_inte
 					      double		     height)
 {
     cairo_status_t status;
-    cairo_ps_surface_t *surface = NULL;
+    cairo_ps_surface_t *surface;
 
     surface = malloc (sizeof (cairo_ps_surface_t));
     if (surface == NULL) {
@@ -853,12 +853,15 @@ _cairo_ps_surface_create_for_stream_inte
 
     surface->dsc_comment_target = &surface->dsc_header_comments;
 
-    surface->paginated_surface = _cairo_paginated_surface_create (&surface->base,
-								   CAIRO_CONTENT_COLOR_ALPHA,
-								   width, height,
-								   &cairo_ps_surface_paginated_backend);
-    return surface->paginated_surface;
+    surface->paginated_surface = _cairo_paginated_surface_create (
+	                                   &surface->base,
+					   CAIRO_CONTENT_COLOR_ALPHA,
+					   width, height,
+					   &cairo_ps_surface_paginated_backend);
+    if (surface->paginated_surface->status == CAIRO_STATUS_SUCCESS)
+	return surface->paginated_surface;
 
+    _cairo_scaled_font_subsets_destroy (surface->font_subsets);
  CLEANUP_OUTPUT_STREAM:
     status = _cairo_output_stream_destroy (surface->stream);
     /* Ignore status---we're already on a failure path. */
@@ -867,6 +870,8 @@ _cairo_ps_surface_create_for_stream_inte
  CLEANUP_SURFACE:
     free (surface);
  CLEANUP:
+    /* destroy stream on behalf of caller */
+    status = _cairo_output_stream_destroy (stream);
     _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
diff-tree 31b52779bad4122d101cdffdb03153baf6cd011e (from b210bea6c1867ef9d5c344747d17ca216f6071bd)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 12:55:13 2007 +0100

    [cairo-boilerplate-xlib] Cleanup fallback after creation failure.
    
    Cleanup the local resource if we fail to create the X window and
    surface for the xlib fallback test target.

diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index 781f8f9..28d1a2e 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -254,6 +254,7 @@ _cairo_boilerplate_xlib_fallback_create_
     xtc->dpy = dpy = XOpenDisplay (NULL);
     if (xtc->dpy == NULL) {
 	CAIRO_BOILERPLATE_LOG ("Failed to open display: %s\n", XDisplayName(0));
+	free (xtc);
 	return NULL;
     }
 
@@ -266,6 +267,8 @@ _cairo_boilerplate_xlib_fallback_create_
     if (! _cairo_boilerplate_xlib_check_screen_size (dpy, screen,
 		                                     width, height)) {
 	CAIRO_BOILERPLATE_LOG ("Surface is larger than the Screen.\n");
+	XCloseDisplay (dpy);
+	free (xtc);
 	return NULL;
     }
 
@@ -283,8 +286,10 @@ _cairo_boilerplate_xlib_fallback_create_
     surface = cairo_xlib_surface_create (dpy, xtc->drawable,
 					 DefaultVisual (dpy, screen),
 					 width, height);
-
-    cairo_boilerplate_xlib_surface_disable_render (surface);
+    if (cairo_surface_status (surface))
+	_cairo_boilerplate_xlib_cleanup (xtc);
+    else
+	cairo_boilerplate_xlib_surface_disable_render (surface);
 
     return surface;
 }
diff-tree b210bea6c1867ef9d5c344747d17ca216f6071bd (from 5ac7ba9821cba076d7f53f6b8836a8619661018c)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 12:45:36 2007 +0100

    [cairo-pdf-surface] Check for pdf_resource_t allocation failure.
    
    Check that the resources are actually allocated or propagate the error.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index da3fffe..bf99c40 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -986,6 +986,9 @@ _cairo_pdf_surface_close_group (cairo_pd
 						     surface->group_stream.mem_stream,
 						     &surface->group_stream.resources,
 						     surface->group_stream.is_knockout);
+    if (group->id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     return _cairo_output_stream_close (surface->group_stream.mem_stream);
 }
 
@@ -1122,6 +1125,9 @@ _cairo_pdf_surface_stop_content_stream (
 							surface->content_stream.mem_stream,
 							&surface->content_stream.resources,
 							FALSE);
+	if (group.id == 0)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	status = _cairo_pdf_surface_add_group_to_content_stream (surface, group);
 	if (status)
 	    return status;
@@ -1188,7 +1194,13 @@ _cairo_pdf_surface_finish (void *abstrac
     _cairo_pdf_surface_write_pages (surface);
 
     info = _cairo_pdf_surface_write_info (surface);
+    if (info.id == 0 && status == CAIRO_STATUS_SUCCESS)
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     catalog = _cairo_pdf_surface_write_catalog (surface);
+    if (catalog.id == 0 && status == CAIRO_STATUS_SUCCESS)
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     offset = _cairo_pdf_surface_write_xref (surface);
 
     _cairo_output_stream_printf (surface->output,
diff-tree 5ac7ba9821cba076d7f53f6b8836a8619661018c (from 63ddfa077c498780d46f752ec7f255b143c9f692)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 12:16:23 2007 +0100

    [cairo-pdf-surface] Destroy local resources on failed surface creation.
    
    During _cairo_pdf_surface_create_for_stream_internal() destroy all
    locally allocated resources and the output stream if we fail to create
    the pdf surface or its paginated wrapper.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 31bf7b2..da3fffe 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -302,9 +302,12 @@ _cairo_pdf_surface_create_for_stream_int
 					       double			 height)
 {
     cairo_pdf_surface_t *surface;
+    cairo_status_t status;
 
     surface = malloc (sizeof (cairo_pdf_surface_t));
     if (surface == NULL) {
+	/* destroy stream on behalf of caller */
+	status = _cairo_output_stream_destroy (output);
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
@@ -332,13 +335,13 @@ _cairo_pdf_surface_create_for_stream_int
     surface->font_subsets = _cairo_scaled_font_subsets_create_composite ();
     if (! surface->font_subsets) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	goto fail;
+	goto BAIL0;
     }
 
     surface->next_available_resource.id = 1;
     surface->pages_resource = _cairo_pdf_surface_new_object (surface);
     if (surface->pages_resource.id == 0)
-        goto fail;
+        goto BAIL1;
 
     surface->compress_content = TRUE;
     surface->pdf_stream.active = FALSE;
@@ -363,15 +366,23 @@ _cairo_pdf_surface_create_for_stream_int
     _cairo_output_stream_printf (surface->output,
 				 "%%%c%c%c%c\r\n", 181, 237, 174, 251);
 
-    surface->paginated_surface = _cairo_paginated_surface_create (&surface->base,
-								  CAIRO_CONTENT_COLOR_ALPHA,
-								  width, height,
-								  &cairo_pdf_surface_paginated_backend);
-    return surface->paginated_surface;
+    surface->paginated_surface =  _cairo_paginated_surface_create (
+	                                  &surface->base,
+					  CAIRO_CONTENT_COLOR_ALPHA,
+					  width, height,
+					  &cairo_pdf_surface_paginated_backend);
+    if (surface->paginated_surface->status == CAIRO_STATUS_SUCCESS)
+	return surface->paginated_surface;
 
-fail:
+BAIL1:
+    _cairo_scaled_font_subsets_destroy (surface->font_subsets);
+BAIL0:
+    _cairo_array_fini (&surface->objects);
     free (surface);
 
+    /* destroy stream on behalf of caller */
+    status = _cairo_output_stream_destroy (output);
+
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
 
diff-tree 63ddfa077c498780d46f752ec7f255b143c9f692 (from f1b6e2735c48d5a54190068c038047942f40f1d1)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 12:08:40 2007 +0100

    [cairo-pdf-surface] Propagate error status.
    
    Add a few missing propagations of error status.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 96c3e8f..31bf7b2 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -978,19 +978,22 @@ _cairo_pdf_surface_close_group (cairo_pd
     return _cairo_output_stream_close (surface->group_stream.mem_stream);
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_write_group_list (cairo_pdf_surface_t  *surface,
 				     cairo_array_t        *group_list)
 {
     int i, len;
     cairo_pdf_group_element_t *elem;
+    cairo_status_t status;
 
     _cairo_output_stream_printf (surface->output, "q\r\n");
     if (surface->group_stream.is_knockout) {
 	_cairo_output_stream_printf (surface->output,
 				     "/x%d Do\r\n",
 				     surface->group_stream.first_object.id);
-	_cairo_pdf_surface_add_xobject (surface, surface->group_stream.first_object);
+	status = _cairo_pdf_surface_add_xobject (surface, surface->group_stream.first_object);
+	if (status)
+	    return status;
     }
     len = _cairo_array_num_elements (group_list);
     for (i = 0; i < len; i++) {
@@ -999,12 +1002,18 @@ _cairo_pdf_surface_write_group_list (cai
 	    _cairo_output_stream_printf (surface->output,
 					 "/x%d Do\r\n",
 					 elem->group.id);
-	    _cairo_pdf_surface_add_xobject (surface, elem->group);
+	    status = _cairo_pdf_surface_add_xobject (surface, elem->group);
+	    if (status)
+		return status;
 	} else if (elem->type == ELEM_CLIP) {
-	    _cairo_pdf_surface_emit_clip (surface, elem->clip_path, elem->fill_rule);
+	    status = _cairo_pdf_surface_emit_clip (surface, elem->clip_path, elem->fill_rule);
+	    if (status)
+		return status;
 	}
     }
     _cairo_output_stream_printf (surface->output, "Q\r\n");
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -1102,7 +1111,9 @@ _cairo_pdf_surface_stop_content_stream (
 							surface->content_stream.mem_stream,
 							&surface->content_stream.resources,
 							FALSE);
-	_cairo_pdf_surface_add_group_to_content_stream (surface, group);
+	status = _cairo_pdf_surface_add_group_to_content_stream (surface, group);
+	if (status)
+	    return status;
     }
     surface->content_stream.active = FALSE;
 
@@ -1566,7 +1577,10 @@ _cairo_pdf_surface_emit_meta_surface (ca
     if (status)
 	return status;
 
-    _cairo_pdf_surface_write_group_list (surface, &group);
+    status = _cairo_pdf_surface_write_group_list (surface, &group);
+    if (status)
+	return status;
+
     status = _cairo_pdf_surface_close_group (surface, resource);
     if (status)
 	return status;
@@ -3338,6 +3352,7 @@ _cairo_pdf_surface_emit_outline_glyph (c
 					  _cairo_pdf_path_close_path,
 					  &info);
     if (status) {
+	/* ignore status return as we are on the error path... */
 	_cairo_pdf_surface_close_stream (surface);
 	return status;
     }
@@ -3785,7 +3800,10 @@ _cairo_pdf_surface_write_page (cairo_pdf
     if (status)
 	return status;
 
-    _cairo_pdf_surface_write_group_list (surface, &surface->content_group);
+    status = _cairo_pdf_surface_write_group_list (surface, &surface->content_group);
+    if (status)
+	return status;
+
     status = _cairo_pdf_surface_close_group (surface, &content_group);
     if (status)
 	return status;
@@ -3795,7 +3813,10 @@ _cairo_pdf_surface_write_page (cairo_pdf
 	if (status)
 	    return status;
 
-	_cairo_pdf_surface_write_group_list (surface, &surface->knockout_group);
+	status = _cairo_pdf_surface_write_group_list (surface, &surface->knockout_group);
+	if (status)
+	    return status;
+
 	status = _cairo_pdf_surface_close_group (surface, &knockout_group);
 	if (status)
 	    return status;
@@ -4578,9 +4599,11 @@ _cairo_pdf_surface_show_glyphs (void			*
 					 "/f-%d-%d 1 Tf\r\n",
 					 subset_glyph.font_id,
 					 subset_glyph.subset_id);
-	    _cairo_pdf_surface_add_font (surface,
-					 subset_glyph.font_id,
-					 subset_glyph.subset_id);
+	    status = _cairo_pdf_surface_add_font (surface,
+					          subset_glyph.font_id,
+						  subset_glyph.subset_id);
+	    if (status)
+		return status;
         }
 
         if (subset_glyph.subset_id != current_subset_id || !diagonal) {
diff-tree f1b6e2735c48d5a54190068c038047942f40f1d1 (from 709f3160368417d9a9a78974b16d93ec3e5e3c14)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Oct 5 11:59:13 2007 +0100

    [cairo-ps-surface] Propagate errors from emit_pattern().
    
    Do not discard the error status from _cairo_ps_surface_emit_pattern(),
    but propagate it back to the caller.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 06d0c82..8265abd 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1812,7 +1812,9 @@ _cairo_ps_surface_emit_surface_pattern (
 						      &image_extra);
 	assert (status == CAIRO_STATUS_SUCCESS);
 
-	_cairo_ps_surface_emit_image (surface, image, "MyPattern");
+	status = _cairo_ps_surface_emit_image (surface, image, "MyPattern");
+	if (status)
+	    return status;
 
 	bbox_width = image->width;
 	bbox_height = image->height;
@@ -2184,7 +2186,9 @@ _cairo_ps_surface_stroke (void			*abstra
 	}
     }
 
-    _cairo_ps_surface_emit_pattern (surface, source);
+    status = _cairo_ps_surface_emit_pattern (surface, source);
+    if (status)
+	return status;
 
     _cairo_output_stream_printf (stream,
 				 "gsave\n");
@@ -2253,11 +2257,15 @@ _cairo_ps_surface_fill (void		*abstract_
 				 "%% _cairo_ps_surface_fill\n");
 #endif
 
-    _cairo_ps_surface_emit_pattern (surface, source);
+    status = _cairo_ps_surface_emit_pattern (surface, source);
+    if (status)
+	return status;
 
     /* We're filling not stroking, so we pass CAIRO_LINE_CAP_ROUND. */
     status = _cairo_ps_surface_emit_path (surface, stream, path,
 					  CAIRO_LINE_CAP_ROUND);
+    if (status)
+	return status;
 
     switch (fill_rule) {
     case CAIRO_FILL_RULE_WINDING:
@@ -2273,7 +2281,7 @@ _cairo_ps_surface_fill (void		*abstract_
     _cairo_output_stream_printf (stream,
 				 "%s\n", ps_operator);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /* This size keeps the length of the hex encoded string of glyphs
@@ -2318,7 +2326,10 @@ _cairo_ps_surface_show_glyphs (void		   
 
     num_glyphs_unsigned = num_glyphs;
 
-    _cairo_ps_surface_emit_pattern (surface, source);
+    status = _cairo_ps_surface_emit_pattern (surface, source);
+    if (status)
+	return status;
+
     glyph_ids = _cairo_malloc_ab (num_glyphs_unsigned, sizeof (cairo_ps_glyph_id_t));
     if (glyph_ids == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);


More information about the cairo-commit mailing list