mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-03-07 01:40:31 +01:00
[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:
parent
7111b18c27
commit
3daa63693c
1 changed files with 66 additions and 58 deletions
|
|
@ -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 *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue