[cairo-svg-surface] Review error propagation during surface creation.

Track the error during surface creation so that it can be returned to
the user via _cairo_surface_create_in_error().
This commit is contained in:
Chris Wilson 2008-01-16 16:33:22 +00:00
parent 7111b18c27
commit 3daa63693c

View file

@ -118,11 +118,12 @@ typedef struct {
cairo_meta_surface_t *meta;
} cairo_meta_snapshot_t;
static cairo_svg_document_t *
_cairo_svg_document_create (cairo_output_stream_t *stream,
double width,
double height,
cairo_svg_version_t version);
static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *stream,
double width,
double height,
cairo_svg_version_t version,
cairo_svg_document_t **document_out);
static cairo_status_t
_cairo_svg_document_destroy (cairo_svg_document_t *document);
@ -173,13 +174,11 @@ cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
double width,
double height)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, NULL, closure);
status = _cairo_output_stream_get_status (stream);
if (status)
return _cairo_surface_create_in_error (status);
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
}
@ -208,13 +207,11 @@ cairo_svg_surface_create (const char *filename,
double width,
double height)
{
cairo_status_t status;
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_filename (filename);
status = _cairo_output_stream_get_status (stream);
if (status)
return _cairo_surface_create_in_error (status);
if (_cairo_output_stream_get_status (stream))
return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
}
@ -330,7 +327,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
{
cairo_svg_surface_t *surface;
cairo_surface_t *paginated;
cairo_status_t status;
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_svg_surface_t));
if (surface == NULL)
@ -351,8 +348,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->is_base_clip_emitted = FALSE;
surface->xml_node = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (surface->xml_node))
goto CLEANUP_DOCUMENT;
status = _cairo_output_stream_get_status (surface->xml_node);
if (status)
goto CLEANUP;
_cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t));
@ -362,8 +360,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
"style=\"opacity: 1; stroke: none; "
"fill: rgb(0,0,0);\"/>\n",
width, height);
if (_cairo_output_stream_get_status (surface->xml_node))
goto CLEANUP_STREAM;
status = _cairo_output_stream_get_status (surface->xml_node);
if (status)
goto CLEANUP;
}
surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
@ -375,17 +374,18 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->width,
surface->height,
&cairo_svg_surface_paginated_backend);
if (! paginated->status)
status = paginated->status;
if (status == CAIRO_STATUS_SUCCESS)
return paginated;
/* ignore status as we are on the error path */
CLEANUP_STREAM:
status = _cairo_output_stream_destroy (surface->xml_node);
CLEANUP_DOCUMENT:
status = _cairo_svg_document_destroy (document);
CLEANUP:
status_ignored = _cairo_output_stream_destroy (surface->xml_node);
status_ignored = _cairo_svg_document_destroy (document);
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return _cairo_surface_create_in_error (status);
}
static cairo_surface_t *
@ -394,15 +394,18 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double height,
cairo_svg_version_t version)
{
cairo_svg_document_t *document;
cairo_svg_document_t *document = NULL; /* silence compiler */
cairo_surface_t *surface;
cairo_status_t status;
document = _cairo_svg_document_create (stream, width, height, version);
if (document == NULL) {
status = _cairo_svg_document_create (stream,
width, height, version,
&document);
if (status) {
surface = _cairo_surface_create_in_error (status);
/* consume the output stream on behalf of caller */
status = _cairo_output_stream_destroy (stream);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
return surface;
}
surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA,
@ -426,20 +429,21 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
unsigned int i;
cairo_svg_page_t page;
cairo_output_stream_t *stream;
cairo_status_t status;
stream = _cairo_memory_stream_create ();
if (stream->status)
if (_cairo_output_stream_get_status (stream)) {
status = _cairo_output_stream_destroy (stream);
return NULL;
}
page.surface_id = surface->id;
page.clip_level = surface->clip_level;
page.xml_node = surface->xml_node;
if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS)
{
cairo_status_t status = _cairo_output_stream_destroy (stream);
if (_cairo_array_append (&surface->page_set, &page)) {
status = _cairo_output_stream_destroy (stream);
return NULL;
(void) status;
}
surface->xml_node = stream;
@ -1954,8 +1958,8 @@ _cairo_svg_surface_paint (void *abstract_surface,
}
surface->xml_node = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (surface->xml_node);
if (status) {
if (_cairo_output_stream_get_status (surface->xml_node)) {
status = _cairo_output_stream_destroy (surface->xml_node);
surface->xml_node = NULL;
return status;
}
@ -2000,9 +2004,8 @@ _cairo_svg_surface_mask (void *abstract_surface,
* document->xml_node_defs so we need to write the mask element to
* a temporary stream and then copy that to xml_node_defs. */
mask_stream = _cairo_memory_stream_create ();
status = _cairo_output_stream_get_status (mask_stream);
if (status)
return status;
if (_cairo_output_stream_get_status (mask_stream))
return _cairo_output_stream_destroy (mask_stream);
_cairo_output_stream_printf (mask_stream,
"<mask id=\"mask%d\">\n"
@ -2240,28 +2243,29 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
_cairo_svg_surface_fill_stroke
};
static cairo_svg_document_t *
_cairo_svg_document_create (cairo_output_stream_t *output_stream,
double width,
double height,
cairo_svg_version_t version)
static cairo_status_t
_cairo_svg_document_create (cairo_output_stream_t *output_stream,
double width,
double height,
cairo_svg_version_t version,
cairo_svg_document_t **document_out)
{
cairo_svg_document_t *document;
cairo_status_t status;
cairo_status_t status, status_ignored;
if (output_stream->status)
return NULL;
return output_stream->status;
document = malloc (sizeof (cairo_svg_document_t));
if (document == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
if (document == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* The use of defs for font glyphs imposes no per-subset limit. */
document->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
if (document->font_subsets == NULL)
if (document->font_subsets == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_DOCUMENT;
}
document->output_stream = output_stream;
document->refcount = 1;
@ -2279,12 +2283,14 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->mask_id = 0;
document->xml_node_defs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_defs))
goto CLEANUP_FONT_SUBSETS;
status = _cairo_output_stream_get_status (document->xml_node_defs);
if (status)
goto CLEANUP_NODE_DEFS;
document->xml_node_glyphs = _cairo_memory_stream_create ();
if (_cairo_output_stream_get_status (document->xml_node_glyphs))
goto CLEANUP_NODE_DEFS;
status = _cairo_output_stream_get_status (document->xml_node_glyphs);
if (status)
goto CLEANUP_NODE_GLYPHS;
document->alpha_filter = FALSE;
@ -2293,15 +2299,17 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->svg_version = version;
return document;
*document_out = document;
return CAIRO_STATUS_SUCCESS;
CLEANUP_NODE_GLYPHS:
status_ignored = _cairo_output_stream_destroy (document->xml_node_glyphs);
CLEANUP_NODE_DEFS:
status = _cairo_output_stream_destroy (document->xml_node_defs);
CLEANUP_FONT_SUBSETS:
status_ignored = _cairo_output_stream_destroy (document->xml_node_defs);
_cairo_scaled_font_subsets_destroy (document->font_subsets);
CLEANUP_DOCUMENT:
free (document);
return NULL;
return status;
}
static cairo_svg_document_t *