From 5d7c796c1830663772dd681026e2d5dd952826b8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 09:46:38 +0000 Subject: 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__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. --- ChangeLog | 67 +++++++++++++++++++++++++++++++++++++++++ doc/public/tmpl/cairo-font.sgml | 1 + src/cairo-ft-font.c | 6 ++-- src/cairo-glitz-surface.c | 16 +++++----- src/cairo-gstate.c | 25 +++------------ src/cairo-image-surface.c | 4 +-- src/cairo-path-data-private.h | 5 ++- src/cairo-path-data.c | 34 +-------------------- src/cairo-pattern.c | 37 ++--------------------- src/cairo-png.c | 20 +++++++----- src/cairo-ps-surface.c | 8 ++--- src/cairo-quartz-surface.c | 5 +++ src/cairo-surface.c | 46 ++++++++++++---------------- src/cairo-win32-font.c | 2 +- src/cairo-win32-surface.c | 7 +++-- src/cairo-xcb-surface.c | 6 +++- src/cairo-xlib-surface.c | 12 ++++++-- src/cairo.c | 44 ++++++++++++--------------- src/cairoint.h | 8 ++--- 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 + + * 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__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 * 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: + @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 { @@ -434,37 +433,6 @@ _cairo_path_data_create_flat (cairo_path_fixed_t *path, return _cairo_path_data_create_real (path, gstate, TRUE); } -/** - * _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 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 */ @@ -291,37 +291,6 @@ _cairo_pattern_create_solid (const cairo_color_t *color) return &pattern->base; } -/** - * _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 @@ -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); -- cgit v1.2.3