summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2005-07-28 09:46:38 +0000
committerCarl Worth <cworth@cworth.org>2005-07-28 09:46:38 +0000
commit5d7c796c1830663772dd681026e2d5dd952826b8 (patch)
treebd607774fcdb25ba94f295905035fe0b2a631d18
parentb9fe1b74665e528e6114bd833028a8f62ecfa869 (diff)
Remove all create_in_error functions as they were just muddling up the memory management semantics:
_cairo_path_data_create_in_error _cairo_pattern_create_in_error _cairo_surface_create_in_error Don't bother with extra check of other->status to anticipate and try to prevent cairo_surface_create_similar from returning through cairo_surface_create_in_error. Just return &_cairo_surface|pattern|path_nil rather than _cairo_surface|pattern|path_create_in_error. After checking surface->status from a cairo_<foo>_surface_create function, just return CAIRO_STATUS_NO_MEMORY since that's the only error we'll get from one of these create functions. Remove unnecessary check for gstate == NULL; Fix old check for image == NULL instead of image->base.status. Add missing check of surface->image_base.status after creating surface->image. Add missing check of surface->base.status after creating surface.
-rw-r--r--ChangeLog67
-rw-r--r--doc/public/tmpl/cairo-font.sgml1
-rw-r--r--src/cairo-ft-font.c6
-rw-r--r--src/cairo-glitz-surface.c16
-rw-r--r--src/cairo-gstate.c25
-rw-r--r--src/cairo-image-surface.c4
-rw-r--r--src/cairo-path-data-private.h5
-rw-r--r--src/cairo-path-data.c34
-rw-r--r--src/cairo-pattern.c37
-rw-r--r--src/cairo-png.c20
-rw-r--r--src/cairo-ps-surface.c8
-rw-r--r--src/cairo-quartz-surface.c5
-rw-r--r--src/cairo-surface.c46
-rw-r--r--src/cairo-win32-font.c2
-rw-r--r--src/cairo-win32-surface.c7
-rw-r--r--src/cairo-xcb-surface.c6
-rw-r--r--src/cairo-xlib-surface.c12
-rw-r--r--src/cairo.c44
-rw-r--r--src/cairoint.h8
19 files changed, 173 insertions, 180 deletions
diff --git a/ChangeLog b/ChangeLog
index 54dfbd48a..2d4290da1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+2005-07-27 Carl Worth <cworth@cworth.org>
+
+ * src/cairoint.h:
+ * src/cairo-path-data-private.h:
+ * src/cairo-path-data.c:
+ * src/cairo-pattern.c:
+ * src/cairo-surface.c:
+ Remove all create_in_error functions as they were just muddling up
+ the memory management semantics:
+
+ _cairo_path_data_create_in_error
+ _cairo_pattern_create_in_error
+ _cairo_surface_create_in_error
+
+ * src/cairo-gstate.c: (_cairo_gstate_mask),
+ (_composite_traps_intermediate_surface),
+ (_cairo_gstate_intersect_clip_mask), (_cairo_gstate_show_glyphs):
+
+ Don't bother with extra check of other->status to anticipate and
+ try to prevent cairo_surface_create_similar from returning through
+ cairo_surface_create_in_error.
+
+ * src/cairo-glitz-surface.c: (cairo_glitz_surface_create):
+ * src/cairo-image-surface.c: (cairo_image_surface_create),
+ (cairo_image_surface_create_for_data):
+ * src/cairo-png.c: (cairo_image_surface_create_from_png):
+ * src/cairo-surface.c: (_cairo_surface_create_similar_scratch),
+ (cairo_surface_create_similar),
+ (_cairo_surface_create_similar_solid):
+ * src/cairo-win32-surface.c: (_cairo_win32_surface_create_for_dc):
+ * src/cairo-xlib-surface.c: (cairo_xlib_surface_create):
+ * src/cairo.c: (cairo_get_source), (cairo_get_font_face):
+ (cairo_get_target), (cairo_copy_path), (cairo_copy_path_flat):
+
+ Just return &_cairo_surface|pattern|path_nil rather than
+ _cairo_surface|pattern|path_create_in_error.
+
+ * src/cairo-ft-font.c:
+ * src/cairo-glitz-surface.c:
+ * src/cairo-gstate.c:
+ * src/cairo-pattern.c:
+ * src/cairo-ps-surface.c:
+ * src/cairo-win32-font.c:
+ * src/cairo-win32-surface.c:
+ * src/cairo-xcb-surface.c:
+ * src/cairo-xlib-surface.c:
+ After checking surface->status from a cairo_<foo>_surface_create
+ function, just return CAIRO_STATUS_NO_MEMORY since that's the only
+ error we'll get from one of these create functions.
+
+ * src/cairo-gstate.c: (_cairo_gstate_get_target):
+ Remove unnecessary check for gstate == NULL;
+
+ * src/cairo-pattern.c:
+ (_cairo_pattern_acquire_surface_for_gradient): Fix old check for
+ image == NULL instead of image->base.status.
+
+ * src/cairo-quartz-surface.c:
+ (_cairo_quartz_surface_acquire_source_image):
+
+ Add missing check of surface->image_base.status after creating
+ surface->image.
+
+ * src/cairo-xcb-surface.c: (_cairo_xcb_surface_create_similar):
+ * src/cairo-xlib-surface.c: (_cairo_xlib_surface_create_similar):
+ Add missing check of surface->base.status after creating surface.
+
2005-07-27 Owen Taylor <otaylor@redhat.com>
* src/cairo-font.c src/cairoint.h: Define _cairo_font_face_nil.
diff --git a/doc/public/tmpl/cairo-font.sgml b/doc/public/tmpl/cairo-font.sgml
index 0c81b7ae5..a41b7ccea 100644
--- a/doc/public/tmpl/cairo-font.sgml
+++ b/doc/public/tmpl/cairo-font.sgml
@@ -113,6 +113,7 @@ Font Handling
@scaled_font:
@extents:
+<!-- # Unused Parameters # -->
@Returns:
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 929ce58b7..3a762c205 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -797,7 +797,7 @@ _get_bitmap_surface (cairo_image_glyph_cache_entry_t *val,
width, height, stride);
if (val->image->base.status) {
free (data);
- return val->image->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
if (subpixel)
@@ -867,6 +867,8 @@ _render_glyph_outline (FT_Face face,
val->image = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
+ if (val->image->base.status)
+ return CAIRO_STATUS_NO_MEMORY;
} else {
matrix.xx = matrix.yy = 0x10000L;
@@ -1062,7 +1064,7 @@ _transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val)
width = (width + 3) & ~3;
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
if (image->status)
- return image->status;
+ return CAIRO_STATUS_NO_MEMORY;
/* Initialize it to empty
*/
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 06faaecc3..96e920339 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -213,7 +213,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
if (image->base.status)
{
free (pixels);
- return image->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
_cairo_image_surface_assume_ownership_of_data (image);
@@ -364,7 +364,7 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
image_src->width,
image_src->height);
if (clone->base.status)
- return clone->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
_cairo_glitz_surface_set_image (clone, image_src, 0, 0);
@@ -580,7 +580,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
{
glitz_buffer_destroy (buffer);
free (data);
- return src->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
for (i = 0; i < gradient->n_stops; i++)
@@ -907,7 +907,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
1, 1,
(cairo_color_t *) color);
if (src->base.status)
- return src->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
@@ -1017,7 +1017,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
- return mask->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1110,7 +1110,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
{
cairo_surface_destroy (&src->base);
free (data);
- return image->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@@ -1125,7 +1125,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
free (data);
cairo_surface_destroy (&image->base);
- return mask->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
}
_cairo_glitz_surface_set_image (mask, image, 0, 0);
@@ -2135,7 +2135,7 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
cairo_glitz_surface_t *crsurface;
if (surface == NULL)
- return _cairo_surface_create_in_error (CAIRO_STATUS_NULL_POINTER);
+ return (cairo_surface_t*) &_cairo_surface_nil;
crsurface = malloc (sizeof (cairo_glitz_surface_t));
if (crsurface == NULL) {
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 0cca756f3..ed3359b99 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -401,9 +401,6 @@ _cairo_gstate_get_clip_extents (cairo_gstate_t *gstate,
cairo_surface_t *
_cairo_gstate_get_target (cairo_gstate_t *gstate)
{
- if (gstate == NULL)
- return NULL;
-
return gstate->target;
}
@@ -904,15 +901,12 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
*/
cairo_surface_t *intermediate;
- if (gstate->clip.surface->status)
- return gstate->clip.surface->status;
-
intermediate = cairo_surface_create_similar (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents.width,
extents.height);
if (intermediate->status)
- return intermediate->status;
+ return CAIRO_STATUS_NO_MEMORY;
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
mask, NULL, intermediate,
@@ -1247,16 +1241,13 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate,
translate_traps (traps, -extents->x, -extents->y);
- if (gstate->clip.surface->status)
- return gstate->clip.surface->status;
-
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents->width,
extents->height,
CAIRO_COLOR_TRANSPARENT);
if (intermediate->status)
- return intermediate->status;
+ return CAIRO_STATUS_NO_MEMORY;
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
@@ -1726,16 +1717,13 @@ _cairo_gstate_intersect_clip_mask (cairo_gstate_t *gstate,
if (gstate->clip.surface != NULL)
_cairo_rectangle_intersect (&surface_rect, &gstate->clip.surface_rect);
- if (gstate->target->status)
- return gstate->target->status;
-
surface = _cairo_surface_create_similar_solid (gstate->target,
CAIRO_CONTENT_ALPHA,
surface_rect.width,
surface_rect.height,
CAIRO_COLOR_WHITE);
if (surface->status)
- return surface->status;
+ return CAIRO_STATUS_NO_MEMORY;
/* Render the new clipping path into the new mask surface. */
@@ -2174,18 +2162,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
goto BAIL1;
}
- if (gstate->clip.surface->status) {
- status = gstate->clip.surface->status;
- goto BAIL1;
- }
-
intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
CAIRO_CONTENT_ALPHA,
extents.width,
extents.height,
CAIRO_COLOR_TRANSPARENT);
if (intermediate->status) {
- status = intermediate->status;
+ status = CAIRO_STATUS_NO_MEMORY;
goto BAIL1;
}
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6576e874d..4d0a3d319 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -161,7 +161,7 @@ cairo_image_surface_create (cairo_format_t format,
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
- return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
+ return (cairo_surface_t*) &_cairo_surface_nil;
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL) {
@@ -217,7 +217,7 @@ cairo_image_surface_create_for_data (unsigned char *data,
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
- return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
+ return (cairo_surface_t*) &_cairo_surface_nil;
pixman_format = _create_pixman_format (format);
if (pixman_format == NULL) {
diff --git a/src/cairo-path-data-private.h b/src/cairo-path-data-private.h
index f7f429437..d680f901e 100644
--- a/src/cairo-path-data-private.h
+++ b/src/cairo-path-data-private.h
@@ -38,6 +38,8 @@
#include "cairoint.h"
+extern cairo_path_t cairo_path_nil;
+
cairo_private cairo_path_t *
_cairo_path_data_create (cairo_path_fixed_t *path,
cairo_gstate_t *gstate);
@@ -46,9 +48,6 @@ cairo_private cairo_path_t *
_cairo_path_data_create_flat (cairo_path_fixed_t *path,
cairo_gstate_t *gstate);
-cairo_private cairo_path_t *
-_cairo_path_data_create_in_error (cairo_status_t status);
-
cairo_private cairo_status_t
_cairo_path_data_append_to_context (cairo_path_t *path,
cairo_t *cr);
diff --git a/src/cairo-path-data.c b/src/cairo-path-data.c
index cbfa2b71b..b3bd31232 100644
--- a/src/cairo-path-data.c
+++ b/src/cairo-path-data.c
@@ -37,8 +37,7 @@
#include "cairo-path-fixed-private.h"
#include "cairo-gstate-private.h"
-static cairo_path_t
-cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
+cairo_path_t cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
/* Closure for path interpretation. */
typedef struct cairo_path_data_count {
@@ -435,37 +434,6 @@ _cairo_path_data_create_flat (cairo_path_fixed_t *path,
}
/**
- * _cairo_path_data_create_in_error:
- * @status: an error status
- *
- * Create an empty #cairo_path_t object to hold an error status. This
- * is useful for propagating status values from an existing object to
- * a new #cairo_path_t.
- *
- * Return value: a #cairo_path_t object with status of @status, NULL
- * data, and 0 num_data. If there is insufficient memory a pointer to
- * a special static cairo_path_nil will be returned instead with
- * status==CAIRO_STATUS_NO_MEMORY rather than @status.
- **/
-cairo_path_t *
-_cairo_path_data_create_in_error (cairo_status_t status)
-{
- cairo_path_t *path;
-
- path = malloc (sizeof (cairo_path_t));
- if (path == NULL)
- return &cairo_path_nil;
-
- path->status = status;
- path->data = NULL;
- path->num_data = 0;
-
- _cairo_error (status);
-
- return path;
-}
-
-/**
* _cairo_path_data_append_to_context:
* @path: the path data to be appended
* @cr: a cairo context
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a224d8a14..1fb172179 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -50,7 +50,7 @@ typedef struct _cairo_shader_op {
((unsigned char) \
((((unsigned char) (c1)) * (int) ((unsigned char) (c2))) / 0xff))
-static const cairo_solid_pattern_t cairo_solid_pattern_nil = {
+const cairo_solid_pattern_t cairo_solid_pattern_nil = {
{ CAIRO_PATTERN_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
@@ -292,37 +292,6 @@ _cairo_pattern_create_solid (const cairo_color_t *color)
}
/**
- * _cairo_pattern_create_in_error:
- * @status: an error status
- *
- * Create an empty #cairo_pattern_t object to hold an error
- * status. This is useful for propagating status values from an
- * existing object to a new #cairo_pattern_t.
- *
- * Return value: a (solid, black) #cairo_pattern_t object with status
- * of @status. If there is insufficient memory a pointer to a special,
- * static cairo_solid_pattern_nil will be returned instead with a
- * status of CAIRO_STATUS_NO_MEMORY rather than @status.
- *
- * Return value:
- **/
-cairo_pattern_t *
-_cairo_pattern_create_in_error (cairo_status_t status)
-{
- cairo_solid_pattern_t *pattern;
-
- pattern = malloc (sizeof (cairo_solid_pattern_t));
- if (pattern == NULL)
- return (cairo_pattern_t *) &cairo_solid_pattern_nil.base;
-
- _cairo_pattern_init_solid (pattern, CAIRO_COLOR_BLACK);
-
- _cairo_pattern_set_error (&pattern->base, status);
-
- return &pattern->base;
-}
-
-/**
* cairo_pattern_create_rgb:
* @red: red component of the color
* @green: green component of the color
@@ -1243,7 +1212,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
width, height,
width * 4);
- if (image == NULL) {
+ if (image->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
@@ -1279,7 +1248,7 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
1, 1,
&pattern->color);
if ((*out)->status)
- return (*out)->status;
+ return CAIRO_STATUS_NO_MEMORY;
attribs->x_offset = attribs->y_offset = 0;
cairo_matrix_init_identity (&attribs->matrix);
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 0dabbd676..bd55d4bbc 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -437,8 +437,16 @@ stdio_read_func (png_structp png, png_bytep data, png_size_t size)
* given PNG file.
*
* Return value: a new #cairo_surface_t initialized with the contents
- * of the PNG file or %NULL if the file is not a valid PNG file or
- * memory could not be allocated for the operation.
+ * of the PNG file, or a "nil" surface if any error occured. A nil
+ * surface can be checked for with cairo_surface_status(surface) which
+ * may return one of the following values:
+ *
+ * CAIRO_STATUS_NO_MEMORY
+ *
+ * XXX: We may want to add a few more error values here, (file not
+ * found? permission denied? file not png?). One way to do this would
+ * be to create several variations on cairo_surface_nil to house the
+ * status values we care about.
**/
cairo_surface_t *
cairo_image_surface_create_from_png (const char *filename)
@@ -447,12 +455,8 @@ cairo_image_surface_create_from_png (const char *filename)
cairo_surface_t *surface;
fp = fopen (filename, "rb");
- if (fp == NULL) {
- if (errno == ENOMEM)
- return (cairo_surface_t*) &_cairo_surface_nil;
- else
- return _cairo_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
- }
+ if (fp == NULL)
+ return (cairo_surface_t*) &_cairo_surface_nil;
surface = read_png (stdio_read_func, fp);
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 2817cc85a..0b2962c28 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -315,7 +315,7 @@ _cairo_ps_surface_show_page (void *abstract_surface)
surface->current_page = _cairo_meta_surface_create (surface->width,
surface->height);
if (surface->current_page->status)
- return surface->current_page->status;
+ return CAIRO_STATUS_NO_MEMORY;
return CAIRO_STATUS_SUCCESS;
}
@@ -670,7 +670,7 @@ emit_image (cairo_ps_surface_t *surface,
image->height,
CAIRO_COLOR_WHITE);
if (opaque->status) {
- status = opaque->status;
+ status = CAIRO_STATUS_NO_MEMORY;
goto bail0;
}
@@ -1250,7 +1250,7 @@ _ps_output_render_fallbacks (cairo_surface_t *surface,
image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
if (image->status)
- return image->status;
+ return CAIRO_STATUS_NO_MEMORY;
status = _cairo_surface_fill_rectangle (image,
CAIRO_OPERATOR_SOURCE,
@@ -1311,7 +1311,7 @@ _cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
ps_output = _ps_output_surface_create (surface);
if (ps_output->status)
- return ps_output->status;
+ return CAIRO_STATUS_NO_MEMORY;
status = _cairo_meta_surface_replay (page, ps_output);
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 5b6faf6f1..092c0cd0d 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -124,6 +124,11 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
CAIRO_FORMAT_ARGB32,
surface->width,
surface->height, rowBytes);
+ if (surface->image->base.status) {
+ /* XXX: I assume we're leaking memory here, but I don't know
+ * the right call to use to clean up from CGImageCreate. */
+ return CAIRO_STATUS_NO_MEMORY;
+ }
*image_out = surface->image;
*image_extra = NULL;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 59dfbad1c..83eb6f26a 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -127,7 +127,7 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
cairo_format_t format = _cairo_format_from_content (content);
if (other->status)
- return _cairo_surface_create_in_error (other->status);
+ return (cairo_surface_t*) &_cairo_surface_nil;
if (other->backend->create_similar)
return other->backend->create_similar (other, content, width, height);
@@ -146,9 +146,13 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
* existing surface. The new surface will use the same backend as
* @other unless that is not possible for some reason.
*
- * Return value: a pointer to the newly allocated surface, or NULL in
- * the case of errors. The caller owns the surface and should call
- * cairo_surface_destroy when done with it.
+ * Return value: a pointer to the newly allocated surface. The caller
+ * owns the surface and should call cairo_surface_destroy when done
+ * with it.
+ *
+ * This function always returns a valid pointer, but it will return a
+ * pointer to a "nil" surface if @other is already in an error state
+ * or any other error occurs.
**/
cairo_surface_t *
cairo_surface_create_similar (cairo_surface_t *other,
@@ -157,10 +161,12 @@ cairo_surface_create_similar (cairo_surface_t *other,
int height)
{
if (other->status)
- return _cairo_surface_create_in_error (other->status);
+ return (cairo_surface_t*) &_cairo_surface_nil;
- if (! CAIRO_CONTENT_VALID (content))
- return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
+ if (! CAIRO_CONTENT_VALID (content)) {
+ _cairo_error (CAIRO_STATUS_INVALID_CONTENT);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_surface_create_similar_solid (other, content,
width, height,
@@ -179,37 +185,23 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
surface = _cairo_surface_create_similar_scratch (other, content,
width, height);
+ if (surface->status) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
status = _cairo_surface_fill_rectangle (surface,
CAIRO_OPERATOR_SOURCE, color,
0, 0, width, height);
if (status) {
cairo_surface_destroy (surface);
- return _cairo_surface_create_in_error (status);
+ _cairo_error (status);
+ return (cairo_surface_t*) &_cairo_surface_nil;
}
return surface;
}
-cairo_surface_t *
-_cairo_surface_create_in_error (cairo_status_t status)
-{
- cairo_surface_t *surface;
-
- /* The format here is totally arbitrary. */
- surface = cairo_image_surface_create_for_data (NULL, CAIRO_FORMAT_ARGB32,
- 0, 0, 0);
- /* If that failed, then there are bigger problems than the error
- * we want to stash here. */
- if (surface->ref_count == -1)
- return surface;
-
- _cairo_surface_set_error (surface, status);
-
- return surface;
-}
-
-
cairo_clip_mode_t
_cairo_surface_get_clip_mode (cairo_surface_t *surface)
{
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 9828ea5f3..a534fa21e 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1083,7 +1083,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
if (tmp_surface->status)
- return tmp_surface->status;
+ return CAIRO_STATUS_NO_MEMORY;
r.left = 0;
r.top = 0;
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index e991eb9b4..20e9e3608 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -263,7 +263,7 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->image = cairo_image_surface_create_for_data (bits, format,
width, height, rowstride);
if (surface->image->status) {
- status = surface->image->status;
+ status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
}
@@ -294,7 +294,8 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return &_cairo_surface_nil;
} else {
- return _cairo_surface_create_in_error (status);
+ _cairo_error (status);
+ return &_cairo_surface_nil;
}
}
@@ -370,7 +371,7 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
width,
height);
if (local->status)
- return local->status;
+ return CAIRO_STATUS_NO_MEMORY;
if (!BitBlt (local->dc,
0, 0,
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 427345ae4..40a4ec835 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -256,6 +256,10 @@ _cairo_xcb_surface_create_similar (void *abstract_src,
cairo_xcb_surface_create_with_xrender_format (dpy, d,
&xrender_format,
width, height);
+ if (surface->base.status) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface->owns_pixmap = TRUE;
@@ -653,7 +657,7 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface,
_cairo_xcb_surface_create_similar (surface, content,
image_src->width, image_src->height);
if (clone->base.status)
- return clone->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
_draw_image_surface (clone, image_src, 0, 0);
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index ee3e93076..a9b20a2c9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -213,6 +213,10 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
xrender_format,
width, height);
+ if (surface->base.status) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface->owns_pixmap = TRUE;
@@ -669,7 +673,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
_cairo_xlib_surface_create_similar (surface, content,
image_src->width, image_src->height);
if (clone->base.status)
- return clone->base.status;
+ return CAIRO_STATUS_NO_MEMORY;
_draw_image_surface (clone, image_src, 0, 0);
@@ -1547,8 +1551,10 @@ cairo_xlib_surface_create (Display *dpy,
{
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
- if (screen == NULL)
- return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_VISUAL);
+ if (screen == NULL) {
+ _cairo_error (CAIRO_STATUS_INVALID_VISUAL);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
visual, NULL, width, height, 0);
diff --git a/src/cairo.c b/src/cairo.c
index ee4d75daf..8515dec7c 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -497,12 +497,8 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
cairo_pattern_t *
cairo_get_source (cairo_t *cr)
{
- if (cr->status) {
- cairo_pattern_t *pattern;
- pattern = _cairo_pattern_create_in_error (cr->status);
- _cairo_set_error (cr, cr->status);
- return pattern;
- }
+ if (cr->status)
+ return (cairo_pattern_t*) &cairo_solid_pattern_nil.base;
return _cairo_gstate_get_source (cr->gstate);
}
@@ -1692,7 +1688,7 @@ cairo_get_font_face (cairo_t *cr)
if (cr->status) {
_cairo_set_error (cr, cr->status);
/* XXX: When available:
- return _cairo_font_face_create_in_error (cr->status);
+ return _cairo_font_face_nil;
*/
return NULL;
}
@@ -2217,17 +2213,19 @@ cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
* Gets the target surface for the cairo context as passed to
* cairo_create().
*
- * Return value: the target surface, (or NULL if @cr is in an error
- * state). This object is owned by cairo. To keep a reference to it,
- * you must call cairo_surface_reference().
+ * Return value: the target surface. This object is owned by cairo. To
+ * keep a reference to it, you must call cairo_surface_reference().
+ *
+ * This function will always return a valid pointer, but the result
+ * can be a "nil" surface if @cr is already in an error state,
+ * (ie. cairo_status(cr) != CAIRO_STATUS_SUCCESS). A nil surface is
+ * indicated by cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS.
**/
cairo_surface_t *
cairo_get_target (cairo_t *cr)
{
- if (cr->status) {
- _cairo_set_error (cr, cr->status);
- return _cairo_surface_create_in_error (cr->status);
- }
+ if (cr->status)
+ return (cairo_surface_t*) &_cairo_surface_nil;
return _cairo_gstate_get_target (cr->gstate);
}
@@ -2248,20 +2246,18 @@ cairo_get_target (cairo_t *cr)
* will have no data, (data==NULL and num_data==0), if either of the
* following conditions hold:
*
- * 1) If there is insufficient memory to copy the path. In this case
- * path->status will be set to CAIRO_STATUS_NO_MEMORY.
+ * 1) If there is insufficient memory to copy the path.
*
- * 2) If @cr is already in an error state. In this case path->status
- * will contain the same status that would be returned by
- * cairo_status(cr).
+ * 2) If @cr is already in an error state.
+ *
+ * In either case, path->status will be set to CAIRO_STATUS_NO_MEMORY,
+ * (regardless of what the error status in @cr might have been).
**/
cairo_path_t *
cairo_copy_path (cairo_t *cr)
{
- if (cr->status) {
- _cairo_set_error (cr, cr->status);
- return _cairo_path_data_create_in_error (cr->status);
- }
+ if (cr->status)
+ return &cairo_path_nil;
return _cairo_path_data_create (&cr->path, cr->gstate);
}
@@ -2300,7 +2296,7 @@ cairo_path_t *
cairo_copy_path_flat (cairo_t *cr)
{
if (cr->status)
- return _cairo_path_data_create_in_error (cr->status);
+ return &cairo_path_nil;
else
return _cairo_path_data_create_flat (&cr->path, cr->gstate);
}
diff --git a/src/cairoint.h b/src/cairoint.h
index d10812191..3cbae5107 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -892,6 +892,8 @@ typedef struct _cairo_solid_pattern {
cairo_color_t color;
} cairo_solid_pattern_t;
+extern const cairo_solid_pattern_t cairo_solid_pattern_nil;
+
typedef struct _cairo_surface_pattern {
cairo_pattern_t base;
@@ -1496,9 +1498,6 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
int height,
const cairo_color_t *color);
-cairo_surface_t *
-_cairo_surface_create_in_error (cairo_status_t status);
-
cairo_private void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend);
@@ -1835,9 +1834,6 @@ _cairo_pattern_fini (cairo_pattern_t *pattern);
cairo_private cairo_pattern_t *
_cairo_pattern_create_solid (const cairo_color_t *color);
-cairo_pattern_t *
-_cairo_pattern_create_in_error (cairo_status_t status);
-
cairo_private void
_cairo_pattern_transform (cairo_pattern_t *pattern,
const cairo_matrix_t *ctm_inverse);