[cairo-commit]
cairo/src cairo-array.c, 1.4, 1.5 cairo-atsui-font.c,
1.13, 1.14 cairo-font.c, 1.55, 1.56 cairo-ft-font.c, 1.78,
1.79 cairo-glitz-surface.c, 1.52, 1.53 cairo-gstate.c, 1.148,
1.149 cairo-image-surface.c, 1.50, 1.51 cairo-meta-surface.c,
1.4, 1.5 cairo-path-data.c, 1.7, 1.8 cairo-pattern.c, 1.50,
1.51 cairo-pdf-surface.c, 1.53, 1.54 cairo-png.c, 1.17,
1.18 cairo-ps-surface.c, 1.43, 1.44 cairo-quartz-surface.c,
1.14, 1.15 cairo-surface.c, 1.80, 1.81 cairo-win32-font.c,
1.26, 1.27 cairo-win32-surface.c, 1.29,
1.30 cairo-xcb-surface.c, 1.40, 1.41 cairo-xlib-surface.c,
1.97, 1.98 cairo.c, 1.114, 1.115 cairo.h, 1.139,
1.140 cairoint.h, 1.169, 1.170
Carl Worth
commit at pdx.freedesktop.org
Wed Jul 27 15:39:39 PDT 2005
Committed by: cworth
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv415/src
Modified Files:
cairo-array.c cairo-atsui-font.c cairo-font.c cairo-ft-font.c
cairo-glitz-surface.c cairo-gstate.c cairo-image-surface.c
cairo-meta-surface.c cairo-path-data.c cairo-pattern.c
cairo-pdf-surface.c cairo-png.c cairo-ps-surface.c
cairo-quartz-surface.c cairo-surface.c cairo-win32-font.c
cairo-win32-surface.c cairo-xcb-surface.c cairo-xlib-surface.c
cairo.c cairo.h cairoint.h
Log Message:
* src/cairo.h: Add CAIRO_STATUS_INVALID_CONTENT,
CAIRO_STATUS_INVALID_FORMAT, and CAIRO_STATUS_INVALID_VISUAL.
Change functions to return type of void:
cairo_scaled_font_extents
cairo_surface_finish
Add new functions to query object status:
cairo_scaled_font_status
cairo_surface_status
* doc/public/tmpl/cairo.sgml:
* src/cairo-array.c:
* src/cairo-atsui-font.c:
* src/cairo-font.c:
* src/cairo-ft-font.c:
* src/cairo-glitz-surface.c:
* src/cairo-gstate.c:
* src/cairo-image-surface.c:
* src/cairo-meta-surface.c:
* src/cairo-path-data.c:
* src/cairo-pattern.c:
* src/cairo-pdf-surface.c:
* src/cairo-png.c:
* src/cairo-ps-surface.c:
* src/cairo-quartz-surface.c:
* src/cairo-surface.c:
* src/cairo-win32-font.c:
* src/cairo-win32-surface.c:
* src/cairo-xcb-surface.c:
* src/cairo-xlib-surface.c:
* src/cairo.c:
* src/cairoint.h: Implementation of new error handling scheme for
cairo_surface_t and cairo_scaled_font_t.
* test/surface-finish-twice.c: Track change in return value of
cairo_surface_finish.
Index: cairo-array.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-array.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cairo-array.c 3 Jun 2005 23:16:44 -0000 1.4
+++ cairo-array.c 27 Jul 2005 22:39:35 -0000 1.5
@@ -198,6 +198,11 @@
int i, num_slots;
cairo_user_data_slot_t *slots;
+ /* We allow this to support degenerate objects such as
+ * cairo_image_surface_nil. */
+ if (array == NULL)
+ return NULL;
+
num_slots = array->num_elements;
slots = (cairo_user_data_slot_t *) array->elements;
for (i = 0; i < num_slots; i++) {
Index: cairo-atsui-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-atsui-font.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- cairo-atsui-font.c 28 Jun 2005 18:52:42 -0000 1.13
+++ cairo-atsui-font.c 27 Jul 2005 22:39:35 -0000 1.14
@@ -68,7 +68,6 @@
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend;
-
static CGAffineTransform
CGAffineTransformMakeWithCairoFontScale(cairo_matrix_t *scale)
{
@@ -77,7 +76,6 @@
0, 0);
}
-
static ATSUStyle
CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale)
{
@@ -691,7 +689,6 @@
return CAIRO_STATUS_SUCCESS;
}
-
const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
_cairo_atsui_font_create,
_cairo_atsui_font_destroy_font,
Index: cairo-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-font.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- cairo-font.c 25 Jul 2005 23:23:05 -0000 1.55
+++ cairo-font.c 27 Jul 2005 22:39:35 -0000 1.56
@@ -421,6 +421,56 @@
/* cairo_scaled_font_t */
+const cairo_scaled_font_t _cairo_scaled_font_nil = {
+ CAIRO_STATUS_NO_MEMORY, /* status */
+ -1, /* ref_count */
+ { 1., 0., 0., 1., 0, 0}, /* font_matrix */
+ { 1., 0., 0., 1., 0, 0}, /* ctm */
+ { 1., 0., 0., 1., 0, 0}, /* scale */
+ NULL, /* font_face */
+ CAIRO_SCALED_FONT_BACKEND_DEFAULT,
+};
+
+/**
+ * _cairo_scaled_font_set_error:
+ * @scaled_font: a scaled_font
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
+ * Sets scaled_font->status to @status and calls _cairo_error;
+ *
+ * All assignments of an error status to scaled_font->status should happen
+ * through _cairo_scaled_font_set_error() or else _cairo_error() should be
+ * called immediately after the assignment.
+ *
+ * The purpose of this function is to allow the user to set a
+ * breakpoint in _cairo_error() to generate a stack trace for when the
+ * user causes cairo to detect an error.
+ **/
+void
+_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
+ cairo_status_t status)
+{
+ scaled_font->status = status;
+
+ _cairo_error (status);
+}
+
+/**
+ * cairo_scaled_font_status:
+ * @surface: a #cairo_scaled_font_t
+ *
+ * Checks whether an error has previously occurred for this
+ * scaled_font.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NULL_POINTER.
+ **/
+cairo_status_t
+cairo_scaled_font_status (cairo_scaled_font_t *scaled_font)
+{
+ return scaled_font->status;
+}
+
/* Here we keep a cache from cairo_font_face_t/matrix/ctm => cairo_scaled_font_t.
*
* The implementation is messy because we want
@@ -750,7 +800,8 @@
cache = _get_outer_font_cache ();
if (cache == NULL) {
_unlock_global_font_cache ();
- return NULL;
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
}
status = _cairo_cache_lookup (cache, &key, (void **) &entry, NULL);
@@ -758,8 +809,10 @@
cairo_scaled_font_reference (entry->scaled_font);
_unlock_global_font_cache ();
- if (status)
- return NULL;
+ if (status) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
+ }
return entry->scaled_font;
}
@@ -770,6 +823,8 @@
const cairo_matrix_t *ctm,
const cairo_scaled_font_backend_t *backend)
{
+ scaled_font->status = CAIRO_STATUS_SUCCESS;
+
scaled_font->font_matrix = *font_matrix;
scaled_font->ctm = *ctm;
cairo_matrix_multiply (&scaled_font->scale, &scaled_font->font_matrix, &scaled_font->ctm);
@@ -784,6 +839,9 @@
cairo_glyph_t **glyphs,
int *num_glyphs)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
return scaled_font->backend->text_to_glyphs (scaled_font, utf8, glyphs, num_glyphs);
}
@@ -793,6 +851,9 @@
int num_glyphs,
cairo_text_extents_t *extents)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
return scaled_font->backend->glyph_extents (scaled_font, glyphs, num_glyphs, extents);
}
@@ -803,6 +864,9 @@
int num_glyphs,
cairo_box_t *bbox)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
return scaled_font->backend->glyph_bbox (scaled_font, glyphs, num_glyphs, bbox);
}
@@ -822,6 +886,9 @@
{
cairo_status_t status;
+ if (scaled_font->status)
+ return scaled_font->status;
+
status = _cairo_surface_show_glyphs (scaled_font, operator, pattern,
surface,
source_x, source_y,
@@ -846,20 +913,31 @@
int num_glyphs,
cairo_path_fixed_t *path)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
return scaled_font->backend->glyph_path (scaled_font, glyphs, num_glyphs, path);
}
-void
+cairo_status_t
_cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t *scaled_font,
cairo_glyph_cache_key_t *key)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
scaled_font->backend->get_glyph_cache_key (scaled_font, key);
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents)
{
+ if (scaled_font->status)
+ return scaled_font->status;
+
return scaled_font->backend->font_extents (scaled_font, extents);
}
@@ -913,6 +991,9 @@
if (scaled_font == NULL)
return;
+ if (scaled_font->ref_count == (unsigned int)-1)
+ return;
+
scaled_font->ref_count++;
}
@@ -933,6 +1014,9 @@
if (scaled_font == NULL)
return;
+ if (scaled_font->ref_count == (unsigned int)-1)
+ return;
+
if (--(scaled_font->ref_count) > 0)
return;
@@ -966,17 +1050,23 @@
* Return value: %CAIRO_STATUS_SUCCESS on success. Otherwise, an
* error such as %CAIRO_STATUS_NO_MEMORY.
**/
-cairo_status_t
+void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents)
{
cairo_int_status_t status;
double font_scale_x, font_scale_y;
+
+ if (scaled_font->status) {
+ _cairo_scaled_font_set_error (scaled_font, scaled_font->status);
+ return;
+ }
status = _cairo_scaled_font_font_extents (scaled_font, extents);
-
- if (status)
- return status;
+ if (status) {
+ _cairo_scaled_font_set_error (scaled_font, status);
+ return;
+ }
_cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
&font_scale_x, &font_scale_y,
@@ -992,8 +1082,6 @@
extents->height *= font_scale_y;
extents->max_x_advance *= font_scale_x;
extents->max_y_advance *= font_scale_y;
-
- return status;
}
/**
@@ -1020,6 +1108,11 @@
double x_pos = 0.0, y_pos = 0.0;
int set = 0;
+ if (scaled_font->status) {
+ _cairo_scaled_font_set_error (scaled_font, scaled_font->status);
+ return;
+ }
+
if (!num_glyphs)
{
extents->x_bearing = 0.0;
Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- cairo-ft-font.c 27 Jul 2005 11:07:46 -0000 1.78
+++ cairo-ft-font.c 27 Jul 2005 22:39:35 -0000 1.79
@@ -88,7 +88,6 @@
* just create a one-off version with a permanent face value.
*/
-
typedef struct _ft_font_face ft_font_face_t;
typedef struct {
@@ -796,10 +795,9 @@
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
- if (val->image == NULL) {
+ if (val->image->base.status) {
free (data);
-
- return CAIRO_STATUS_NO_MEMORY;
+ return val->image->base.status;
}
if (subpixel)
@@ -1063,8 +1061,8 @@
/* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
width = (width + 3) & ~3;
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
- if (!image)
- return CAIRO_STATUS_NO_MEMORY;
+ if (image->status)
+ return image->status;
/* Initialize it to empty
*/
@@ -1380,7 +1378,7 @@
f = malloc (sizeof(cairo_ft_scaled_font_t));
if (f == NULL)
- return NULL;
+ return (cairo_scaled_font_t*) &_cairo_scaled_font_nil;
f->unscaled = unscaled;
_cairo_unscaled_font_reference (&unscaled->base);
@@ -1875,7 +1873,7 @@
static int
-_move_to (FT_Vector *to, void *closure)
+_move_to (const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
@@ -1890,7 +1888,7 @@
}
static int
-_line_to (FT_Vector *to, void *closure)
+_line_to (const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
@@ -1904,7 +1902,7 @@
}
static int
-_conic_to (FT_Vector *control, FT_Vector *to, void *closure)
+_conic_to (const FT_Vector *control, const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
@@ -1937,7 +1935,8 @@
}
static int
-_cubic_to (FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *closure)
+_cubic_to (const FT_Vector *control1, const FT_Vector *control2,
+ const FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x0, y0;
@@ -2351,7 +2350,9 @@
* implemented, so this function cannot be currently safely used in a
* threaded application.)
- * Return value: The #FT_Face object for @font, scaled appropriately.
+ * Return value: The #FT_Face object for @font, scaled appropriately,
+ * or %NULL if @scaled_font is in an error state (see
+ * cairo_scaled_font_status()) or there is insufficient memory.
**/
FT_Face
cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
@@ -2359,9 +2360,14 @@
cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
FT_Face face;
+ if (scaled_font->base.status)
+ return NULL;
+
face = _ft_unscaled_font_lock_face (scaled_font->unscaled);
- if (!face)
+ if (face == NULL) {
+ _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
+ }
_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
@@ -2383,6 +2389,9 @@
{
cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
+ if (scaled_font->base.status)
+ return;
+
_ft_unscaled_font_unlock_face (scaled_font->unscaled);
}
Index: cairo-glitz-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-glitz-surface.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- cairo-glitz-surface.c 25 Jul 2005 23:23:05 -0000 1.52
+++ cairo-glitz-surface.c 27 Jul 2005 22:39:35 -0000 1.53
@@ -83,12 +83,16 @@
gformat = glitz_find_standard_format (drawable,
_glitz_format_from_content (content));
- if (!gformat)
- return NULL;
+ if (!gformat) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = glitz_surface_create (drawable, gformat, width, height, 0, NULL);
- if (!surface)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
crsurface = cairo_glitz_surface_create (surface);
@@ -206,11 +210,10 @@
&format,
width, height,
pf.bytes_per_line);
-
- if (!image)
+ if (image->base.status)
{
free (pixels);
- return CAIRO_STATUS_NO_MEMORY;
+ return image->base.status;
}
_cairo_image_surface_assume_ownership_of_data (image);
@@ -341,6 +344,9 @@
cairo_glitz_surface_t *surface = abstract_surface;
cairo_glitz_surface_t *clone;
+ if (surface->base.status)
+ return surface->base.status;
+
if (src->backend == surface->base.backend)
{
*clone_out = src;
@@ -357,8 +363,8 @@
_cairo_glitz_surface_create_similar (surface, content,
image_src->width,
image_src->height);
- if (!clone)
- return CAIRO_STATUS_NO_MEMORY;
+ if (clone->base.status)
+ return clone->base.status;
_cairo_glitz_surface_set_image (clone, image_src, 0, 0);
@@ -570,11 +576,11 @@
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_COLOR_ALPHA,
gradient->n_stops, 1);
- if (!src)
+ if (src->base.status)
{
glitz_buffer_destroy (buffer);
free (data);
- return CAIRO_STATUS_NO_MEMORY;
+ return src->base.status;
}
for (i = 0; i < gradient->n_stops; i++)
@@ -900,8 +906,8 @@
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
(cairo_color_t *) color);
- if (!src)
- return CAIRO_STATUS_NO_MEMORY;
+ if (src->base.status)
+ return src->base.status;
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
@@ -951,6 +957,9 @@
cairo_int_status_t status;
unsigned short alpha;
+ if (dst->base.status)
+ return dst->base.status;
+
if (op == CAIRO_OPERATOR_SATURATE)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1002,13 +1011,13 @@
_cairo_glitz_surface_create_similar (&dst->base,
CAIRO_CONTENT_ALPHA,
2, 1);
- if (!mask)
+ if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
if (src_pattern == &tmp_src_pattern.base)
_cairo_pattern_fini (&tmp_src_pattern.base);
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return mask->base.status;
}
color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1097,11 +1106,11 @@
CAIRO_FORMAT_A8,
width, height,
-stride);
- if (!image)
+ if (image->base.status)
{
cairo_surface_destroy (&src->base);
free (data);
- return CAIRO_STATUS_NO_MEMORY;
+ return image->base.status;
}
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@@ -1111,12 +1120,12 @@
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_ALPHA,
width, height);
- if (!mask)
+ if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
free (data);
cairo_surface_destroy (&image->base);
- return CAIRO_STATUS_NO_MEMORY;
+ return mask->base.status;
}
_cairo_glitz_surface_set_image (mask, image, 0, 0);
@@ -1694,7 +1703,7 @@
GLYPH_CACHE_TEXTURE_SIZE,
GLYPH_CACHE_TEXTURE_SIZE,
0, NULL);
- if (!cache->surface)
+ if (cache->surface == NULL)
{
free (cache);
return NULL;
@@ -1898,7 +1907,9 @@
goto UNLOCK;
}
- _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
+ status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
+ if (status)
+ goto UNLOCK;
for (i = 0; i < num_glyphs; i++)
{
@@ -2123,12 +2134,14 @@
{
cairo_glitz_surface_t *crsurface;
- if (!surface)
- return NULL;
+ if (surface == NULL)
+ return _cairo_surface_create_in_error (CAIRO_STATUS_NULL_POINTER);
crsurface = malloc (sizeof (cairo_glitz_surface_t));
- if (crsurface == NULL)
- return NULL;
+ if (crsurface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend);
Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.148
retrieving revision 1.149
diff -u -d -r1.148 -r1.149
--- cairo-gstate.c 25 Jul 2005 19:29:24 -0000 1.148
+++ cairo-gstate.c 27 Jul 2005 22:39:35 -0000 1.149
@@ -282,8 +282,8 @@
return CAIRO_STATUS_NO_MEMORY;
gstate->target = cairo_surface_create (gstate->dpy);
- if (gstate->target == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (gstate->target->status)
+ return gstate->target->status;
_cairo_surface_set_drawableWH (gstate->target, pix, width, height);
@@ -904,12 +904,15 @@
*/
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 == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (intermediate->status)
+ return intermediate->status;
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
mask, NULL, intermediate,
@@ -1244,13 +1247,16 @@
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 == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (intermediate->status)
+ return intermediate->status;
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
@@ -1720,13 +1726,16 @@
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 == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (surface->status)
+ return surface->status;
/* Render the new clipping path into the new mask surface. */
@@ -2025,7 +2034,9 @@
if (status)
return status;
- return cairo_scaled_font_extents (gstate->scaled_font, extents);
+ cairo_scaled_font_extents (gstate->scaled_font, extents);
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
@@ -2156,13 +2167,18 @@
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 == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
+ if (intermediate->status) {
+ status = intermediate->status;
goto BAIL1;
}
Index: cairo-image-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-image-surface.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- cairo-image-surface.c 14 Jul 2005 22:10:48 -0000 1.50
+++ cairo-image-surface.c 27 Jul 2005 22:39:35 -0000 1.51
@@ -36,8 +36,6 @@
#include "cairoint.h"
-static const cairo_surface_backend_t cairo_image_surface_backend;
-
static int
_cairo_format_bpp (cairo_format_t format)
{
@@ -53,15 +51,17 @@
}
}
-static cairo_image_surface_t *
+static cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format)
{
cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&surface->base, &cairo_image_surface_backend);
@@ -76,17 +76,17 @@
surface->stride = pixman_image_get_stride (pixman_image);
surface->depth = pixman_image_get_depth (pixman_image);
- return surface;
+ return &surface->base;
}
-cairo_image_surface_t *
+cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
cairo_format_masks_t *format,
int width,
int height,
int stride)
{
- cairo_image_surface_t *surface;
+ cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
@@ -96,16 +96,20 @@
format->green_mask,
format->blue_mask);
- if (pixman_format == NULL)
- return NULL;
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height, format->bpp, stride);
pixman_format_destroy (pixman_format);
- if (pixman_image == NULL)
- return NULL;
+ if (pixman_image == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
(cairo_format_t)-1);
@@ -152,28 +156,31 @@
int width,
int height)
{
- cairo_image_surface_t *surface;
+ cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
- /* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_FORMAT_VALID (format))
- return NULL;
+ return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
pixman_format = _create_pixman_format (format);
- if (pixman_format == NULL)
- return NULL;
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
pixman_image = pixman_image_create (pixman_format, width, height);
pixman_format_destroy (pixman_format);
- if (pixman_image == NULL)
- return NULL;
+ if (pixman_image == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
- return &surface->base;
+ return surface;
}
/**
@@ -205,17 +212,18 @@
int height,
int stride)
{
- cairo_image_surface_t *surface;
+ cairo_surface_t *surface;
pixman_format_t *pixman_format;
pixman_image_t *pixman_image;
- /* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_FORMAT_VALID (format))
- return NULL;
+ return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
pixman_format = _create_pixman_format (format);
- if (pixman_format == NULL)
- return NULL;
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
width, height,
@@ -224,12 +232,14 @@
pixman_format_destroy (pixman_format);
- if (pixman_image == NULL)
- return NULL;
+ if (pixman_image == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
- return &surface->base;
+ return surface;
}
/**
@@ -303,9 +313,7 @@
int width,
int height)
{
- /* XXX: Really need to make this kind of thing pass through _cairo_error. */
- if (! CAIRO_CONTENT_VALID (content))
- return NULL;
+ assert (CAIRO_CONTENT_VALID (content));
return cairo_image_surface_create (_cairo_format_from_content (content),
width, height);
@@ -724,15 +732,15 @@
*
* Checks if a surface is an #cairo_image_surface_t
*
- * Return value: True if the surface is an image surface
+ * Return value: TRUE if the surface is an image surface
**/
-int
+cairo_bool_t
_cairo_surface_is_image (cairo_surface_t *surface)
{
return surface->backend == &cairo_image_surface_backend;
}
-static const cairo_surface_backend_t cairo_image_surface_backend = {
+const cairo_surface_backend_t cairo_image_surface_backend = {
_cairo_image_surface_create_similar,
_cairo_image_abstract_surface_finish,
_cairo_image_surface_acquire_source_image,
Index: cairo-meta-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cairo-meta-surface.c 13 Jul 2005 19:32:51 -0000 1.4
+++ cairo-meta-surface.c 27 Jul 2005 22:39:35 -0000 1.5
@@ -53,8 +53,10 @@
cairo_meta_surface_t *meta;
meta = malloc (sizeof (cairo_meta_surface_t));
- if (meta == NULL)
- return NULL;
+ if (meta == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
meta->width = width;
meta->height = height;
Index: cairo-path-data.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-path-data.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cairo-path-data.c 13 Jun 2005 23:29:26 -0000 1.7
+++ cairo-path-data.c 27 Jul 2005 22:39:35 -0000 1.8
@@ -460,6 +460,8 @@
path->data = NULL;
path->num_data = 0;
+ _cairo_error (status);
+
return path;
}
Index: cairo-pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pattern.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- cairo-pattern.c 14 Jul 2005 22:47:18 -0000 1.50
+++ cairo-pattern.c 27 Jul 2005 22:39:35 -0000 1.51
@@ -96,6 +96,31 @@
1.0, 1.0, /* radius0, radius1 */
};
+/**
+ * _cairo_pattern_set_error:
+ * @pattern: a pattern
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
+ * Sets pattern->status to @status and calls _cairo_error;
+ *
+ * All assignments of an error status to pattern->status should happen
+ * through _cairo_pattern_set_error() or else _cairo_error() should be
+ * called immediately after the assignment.
+ *
+ * The purpose of this function is to allow the user to set a
+ * breakpoint in _cairo_error() to generate a stack trace for when the
+ * user causes cairo to detect an error.
+ **/
+static void
+_cairo_pattern_set_error (cairo_pattern_t *pattern,
+ cairo_status_t status)
+{
+ pattern->status = status;
+
+ _cairo_error (status);
+}
+
static void
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
{
@@ -127,10 +152,13 @@
*dst = *src;
}
+ if (other->base.status)
+ _cairo_pattern_set_error (&pattern->base, other->base.status);
+
if (other->n_stops)
{
pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
- if (!pattern->stops) {
+ if (pattern->stops == NULL) {
if (other->base.type == CAIRO_PATTERN_LINEAR)
_cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base);
else
@@ -289,7 +317,7 @@
_cairo_pattern_init_solid (pattern, CAIRO_COLOR_BLACK);
- pattern->base.status = status;
+ _cairo_pattern_set_error (&pattern->base, status);
return &pattern->base;
}
@@ -317,6 +345,7 @@
cairo_pattern_t *
cairo_pattern_create_rgb (double red, double green, double blue)
{
+ cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@@ -325,7 +354,11 @@
_cairo_color_init_rgb (&color, red, green, blue);
- return _cairo_pattern_create_solid (&color);
+ pattern = _cairo_pattern_create_solid (&color);
+ if (pattern->status)
+ _cairo_pattern_set_error (pattern, pattern->status);
+
+ return pattern;
}
/**
@@ -353,6 +386,7 @@
cairo_pattern_create_rgba (double red, double green, double blue,
double alpha)
{
+ cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@@ -362,7 +396,11 @@
_cairo_color_init_rgba (&color, red, green, blue, alpha);
- return _cairo_pattern_create_solid (&color);
+ pattern = _cairo_pattern_create_solid (&color);
+ if (pattern->status)
+ _cairo_pattern_set_error (pattern, pattern->status);
+
+ return pattern;
}
/**
@@ -386,8 +424,10 @@
cairo_surface_pattern_t *pattern;
pattern = malloc (sizeof (cairo_surface_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&cairo_surface_pattern_nil.base;
+ }
_cairo_pattern_init_for_surface (pattern, surface);
@@ -422,8 +462,10 @@
cairo_linear_pattern_t *pattern;
pattern = malloc (sizeof (cairo_linear_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_linear_pattern_nil.base;
+ }
_cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
@@ -461,8 +503,10 @@
cairo_radial_pattern_t *pattern;
pattern = malloc (sizeof (cairo_radial_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_radial_pattern_nil.base;
+ }
_cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
@@ -541,7 +585,7 @@
new_stops = realloc (pattern->stops,
pattern->n_stops * sizeof (cairo_color_stop_t));
if (new_stops == NULL) {
- pattern->base.status = CAIRO_STATUS_NO_MEMORY;
+ _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
@@ -568,7 +612,7 @@
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
- pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+ _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@@ -599,7 +643,7 @@
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
- pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+ _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@@ -619,8 +663,10 @@
cairo_pattern_set_matrix (cairo_pattern_t *pattern,
const cairo_matrix_t *matrix)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->matrix = *matrix;
}
@@ -634,8 +680,10 @@
void
cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->filter = filter;
}
@@ -649,8 +697,10 @@
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->extend = extend;
}
@@ -1164,7 +1214,7 @@
}
data = malloc (width * height * 4);
- if (!data)
+ if (data == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
@@ -1228,9 +1278,8 @@
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
&pattern->color);
-
- if (*out == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if ((*out)->status)
+ return (*out)->status;
attribs->x_offset = attribs->y_offset = 0;
cairo_matrix_init_identity (&attribs->matrix);
Index: cairo-pdf-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pdf-surface.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- cairo-pdf-surface.c 25 Jul 2005 23:23:05 -0000 1.53
+++ cairo-pdf-surface.c 27 Jul 2005 22:39:35 -0000 1.54
@@ -290,8 +290,10 @@
cairo_surface_t *surface;
document = _cairo_pdf_document_create (stream, width, height);
- if (document == NULL)
- return NULL;
+ if (document == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = _cairo_pdf_surface_create_for_document (document, width, height);
@@ -310,8 +312,10 @@
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write, closure);
- if (stream == NULL)
- return NULL;
+ if (stream == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}
@@ -324,8 +328,10 @@
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_file (filename);
- if (stream == NULL)
- return NULL;
+ if (stream == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}
@@ -349,8 +355,10 @@
cairo_pdf_surface_t *surface;
surface = malloc (sizeof (cairo_pdf_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);
Index: cairo-png.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-png.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cairo-png.c 27 Jul 2005 16:23:29 -0000 1.17
+++ cairo-png.c 27 Jul 2005 22:39:35 -0000 1.18
@@ -36,6 +36,7 @@
*/
#include <png.h>
+#include <errno.h>
#include "cairoint.h"
/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
@@ -315,19 +316,15 @@
read_png (png_rw_ptr read_func,
void *closure)
{
- cairo_surface_t *surface;
- png_byte *data;
+ cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil;
+ png_byte *data = NULL;
int i;
- png_struct *png;
+ png_struct *png = NULL;
png_info *info;
png_uint_32 png_width, png_height, stride;
int depth, color_type, interlace;
unsigned int pixel_size;
- png_byte **row_pointers;
-
- surface = NULL;
- data = NULL;
- row_pointers = NULL;
+ png_byte **row_pointers = NULL;
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
@@ -335,7 +332,7 @@
NULL,
NULL);
if (png == NULL)
- return NULL;
+ goto BAIL;
info = png_create_info_struct (png);
if (info == NULL)
@@ -402,13 +399,22 @@
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
png_width, png_height, stride);
+ if (surface->status)
+ goto BAIL;
+
_cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
data = NULL;
BAIL:
- free (row_pointers);
- free (data);
- png_destroy_read_struct (&png, &info, NULL);
+ if (row_pointers)
+ free (row_pointers);
+ if (data)
+ free (data);
+ if (png)
+ png_destroy_read_struct (&png, &info, NULL);
+
+ if (surface == &_cairo_surface_nil)
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return surface;
}
@@ -441,8 +447,12 @@
cairo_surface_t *surface;
fp = fopen (filename, "rb");
- if (fp == NULL)
- return NULL;
+ if (fp == NULL) {
+ if (errno == ENOMEM)
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ else
+ return _cairo_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+ }
surface = read_png (stdio_read_func, fp);
Index: cairo-ps-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ps-surface.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- cairo-ps-surface.c 14 Jul 2005 18:48:40 -0000 1.43
+++ cairo-ps-surface.c 27 Jul 2005 22:39:35 -0000 1.44
@@ -89,8 +89,10 @@
cairo_ps_surface_t *surface;
surface = malloc (sizeof (cairo_ps_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&surface->base, &cairo_ps_surface_backend);
@@ -103,9 +105,10 @@
surface->current_page = _cairo_meta_surface_create (width,
height);
- if (surface->current_page == NULL) {
+ if (surface->current_page->status) {
free (surface);
- return NULL;
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
}
_cairo_array_init (&surface->pages, sizeof (cairo_surface_t *));
@@ -122,8 +125,10 @@
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create_for_file (filename);
- if (stream == NULL)
- return NULL;
+ if (stream == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points,
@@ -139,23 +144,16 @@
cairo_output_stream_t *stream;
stream = _cairo_output_stream_create (write_func, closure);
- if (stream == NULL)
- return NULL;
+ if (stream == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
return _cairo_ps_surface_create_for_stream_internal (stream,
width_in_points,
height_in_points);
}
-static cairo_surface_t *
-_cairo_ps_surface_create_similar (void *abstract_src,
- cairo_content_t content,
- int width,
- int height)
-{
- return NULL;
-}
-
static cairo_status_t
_cairo_ps_surface_finish (void *abstract_surface)
{
@@ -316,8 +314,8 @@
_cairo_array_append (&surface->pages, &surface->current_page, 1);
surface->current_page = _cairo_meta_surface_create (surface->width,
surface->height);
- if (surface->current_page == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (surface->current_page->status)
+ return surface->current_page->status;
return CAIRO_STATUS_SUCCESS;
}
@@ -453,7 +451,7 @@
}
static const cairo_surface_backend_t cairo_ps_surface_backend = {
- _cairo_ps_surface_create_similar,
+ NULL, /* create_similar */
_cairo_ps_surface_finish,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
@@ -652,7 +650,7 @@
cairo_image_surface_t *image,
cairo_matrix_t *matrix)
{
- cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
+ cairo_status_t status;
unsigned char *rgb, *compressed;
unsigned long rgb_size, compressed_size;
cairo_surface_t *opaque;
@@ -663,13 +661,18 @@
/* PostScript can not represent the alpha channel, so we blend the
current image over a white RGB surface to eliminate it. */
+ if (image->base.status)
+ return image->base.status;
+
opaque = _cairo_surface_create_similar_solid (&image->base,
CAIRO_CONTENT_COLOR,
image->width,
image->height,
CAIRO_COLOR_WHITE);
- if (opaque == NULL)
+ if (opaque->status) {
+ status = opaque->status;
goto bail0;
+ }
_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
@@ -687,8 +690,10 @@
rgb_size = 3 * image->width * image->height;
rgb = malloc (rgb_size);
- if (rgb == NULL)
+ if (rgb == NULL) {
+ status = CAIRO_STATUS_NO_MEMORY;
goto bail1;
+ }
i = 0;
for (y = 0; y < image->height; y++) {
@@ -701,8 +706,10 @@
}
compressed = compress_dup (rgb, rgb_size, &compressed_size);
- if (compressed == NULL)
+ if (compressed == NULL) {
+ status = CAIRO_STATUS_NO_MEMORY;
goto bail2;
+ }
/* matrix transforms from user space to image space. We need to
* transform from device space to image space to compensate for
@@ -1242,8 +1249,8 @@
height = ps_output->parent->height * ps_output->parent->y_dpi / 72;
image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
- if (image == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (image->status)
+ return image->status;
status = _cairo_surface_fill_rectangle (image,
CAIRO_OPERATOR_SOURCE,
@@ -1278,8 +1285,10 @@
ps_output_surface_t *ps_output;
ps_output = malloc (sizeof (ps_output_surface_t));
- if (ps_output == NULL)
- return NULL;
+ if (ps_output == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&ps_output->base, &ps_output_backend);
ps_output->parent = parent;
@@ -1301,8 +1310,8 @@
page_number);
ps_output = _ps_output_surface_create (surface);
- if (ps_output == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (ps_output->status)
+ return ps_output->status;
status = _cairo_meta_surface_replay (page, ps_output);
Index: cairo-quartz-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-quartz-surface.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- cairo-quartz-surface.c 18 Jul 2005 16:23:34 -0000 1.14
+++ cairo-quartz-surface.c 27 Jul 2005 22:39:35 -0000 1.15
@@ -58,15 +58,6 @@
}
}
-static cairo_surface_t *
-_cairo_quartz_surface_create_similar (void *abstract_src,
- cairo_content_t content,
- int width,
- int height)
-{
- return NULL;
-}
-
static cairo_status_t
_cairo_quartz_surface_finish(void *abstract_surface)
{
@@ -209,7 +200,7 @@
}
static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
- _cairo_quartz_surface_create_similar,
+ NULL, /* create_similar */
_cairo_quartz_surface_finish,
_cairo_quartz_surface_acquire_source_image,
NULL, /* release_source_image */
@@ -234,8 +225,10 @@
cairo_quartz_surface_t *surface;
surface = malloc(sizeof(cairo_quartz_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_surface_nil;
+ }
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);
Index: cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- cairo-surface.c 21 Jul 2005 13:52:13 -0000 1.80
+++ cairo-surface.c 27 Jul 2005 22:39:35 -0000 1.81
@@ -40,6 +40,65 @@
#include "cairoint.h"
#include "cairo-gstate-private.h"
+const cairo_surface_t _cairo_surface_nil = {
+ &cairo_image_surface_backend, /* backend */
+ -1, /* ref_count */
+ CAIRO_STATUS_NO_MEMORY, /* status */
+ FALSE, /* finished */
+ { 0, /* size */
+ 0, /* num_elements */
+ 0, /* element_size */
+ NULL, /* elements */
+ }, /* user_data */
+ 0.0, /* device_x_offset */
+ 0.0, /* device_y_offset */
+ 0, /* next_clip_serial */
+ 0 /* current_clip_serial */
+};
+
+/**
+ * _cairo_surface_set_error:
+ * @surface: a surface
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
+ * Sets surface->status to @status and calls _cairo_error;
+ *
+ * All assignments of an error status to surface->status should happen
+ * through _cairo_surface_set_error() or else _cairo_error() should be
+ * called immediately after the assignment.
+ *
+ * The purpose of this function is to allow the user to set a
+ * breakpoint in _cairo_error() to generate a stack trace for when the
+ * user causes cairo to detect an error.
+ **/
+static void
+_cairo_surface_set_error (cairo_surface_t *surface,
+ cairo_status_t status)
+{
+ surface->status = status;
+
+ _cairo_error (status);
+}
+
+/**
+ * cairo_surface_status:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks whether an error has previously occurred for this
+ * surface.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
+ * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
+ * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALUE_FORMAT, or
+ * %CAIRO_STATUS_INVALID_VISUAL.
+ **/
+cairo_status_t
+cairo_surface_status (cairo_surface_t *surface)
+{
+ return surface->status;
+}
+
void
_cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend)
@@ -47,6 +106,7 @@
surface->backend = backend;
surface->ref_count = 1;
+ surface->status = CAIRO_STATUS_SUCCESS;
surface->finished = FALSE;
_cairo_user_data_array_init (&surface->user_data);
@@ -64,10 +124,15 @@
int width,
int height)
{
- if (other == NULL)
- return NULL;
+ cairo_format_t format = _cairo_format_from_content (content);
- return other->backend->create_similar (other, content, width, height);
+ if (other->status)
+ return _cairo_surface_create_in_error (other->status);
+
+ if (other->backend->create_similar)
+ return other->backend->create_similar (other, content, width, height);
+ else
+ return cairo_image_surface_create (format, width, height);
}
/**
@@ -91,12 +156,11 @@
int width,
int height)
{
- if (other == NULL)
- return NULL;
+ if (other->status)
+ return _cairo_surface_create_in_error (other->status);
- /* XXX: Really need to make this kind of thing pass through _cairo_error. */
if (! CAIRO_CONTENT_VALID (content))
- return NULL;
+ return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
return _cairo_surface_create_similar_solid (other, content,
width, height,
@@ -112,25 +176,40 @@
{
cairo_status_t status;
cairo_surface_t *surface;
- cairo_format_t format = _cairo_format_from_content (content);
surface = _cairo_surface_create_similar_scratch (other, content,
width, height);
- if (surface == NULL)
- surface = cairo_image_surface_create (format, width, height);
-
status = _cairo_surface_fill_rectangle (surface,
CAIRO_OPERATOR_SOURCE, color,
0, 0, width, height);
if (status) {
cairo_surface_destroy (surface);
- return NULL;
+ return _cairo_surface_create_in_error (status);
}
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)
{
@@ -148,6 +227,9 @@
if (surface == NULL)
return;
+ if (surface->ref_count == (unsigned int)-1)
+ return;
+
surface->ref_count++;
}
@@ -157,6 +239,9 @@
if (surface == NULL)
return;
+ if (surface->ref_count == (unsigned int)-1)
+ return;
+
surface->ref_count--;
if (surface->ref_count)
return;
@@ -178,36 +263,37 @@
* that cairo will no longer access the drawable, which can be freed.
* After calling cairo_surface_finish() the only valid operations on a
* surface are getting and setting user data and referencing and
- * destroying it. Further drawing the the surface will not affect the
- * surface but set the surface status to
- * CAIRO_STATUS_SURFACE_FINISHED.
+ * destroying it. Further drawing to the surface will not affect the
+ * surface but will instead trigger a CAIRO_STATUS_SURFACE_FINISHED
+ * error.
*
* When the last call to cairo_surface_destroy() decreases the
* reference count to zero, cairo will call cairo_surface_finish() if
* it hasn't been called already, before freeing the resources
* associated with the surface.
- *
- * Return value: CAIRO_STATUS_SUCCESS if the surface was finished
- * successfully, otherwise CAIRO_STATUS_NO_MEMORY or
- * CAIRO_STATUS_WRITE_ERROR.
**/
-cairo_status_t
+void
cairo_surface_finish (cairo_surface_t *surface)
{
cairo_status_t status;
- if (surface->finished)
- return CAIRO_STATUS_SURFACE_FINISHED;
+ if (surface->finished) {
+ _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+ return;
+ }
- if (surface->backend->finish) {
- status = surface->backend->finish (surface);
- if (status)
- return status;
+ if (surface->backend->finish == NULL) {
+ surface->finished = TRUE;
+ return;
+ }
+
+ status = surface->backend->finish (surface);
+ if (status) {
+ _cairo_surface_set_error (surface, status);
+ return;
}
surface->finished = TRUE;
-
- return CAIRO_STATUS_SUCCESS;
}
/**
@@ -272,14 +358,10 @@
cairo_surface_get_font_options (cairo_surface_t *surface,
cairo_font_options_t *options)
{
-
if (!surface->finished && surface->backend->get_font_options) {
surface->backend->get_font_options (surface, options);
} else {
- options->antialias = CAIRO_ANTIALIAS_DEFAULT;
- options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
- options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
- options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
+ _cairo_font_options_init_default (options);
}
}
@@ -306,6 +388,16 @@
double x_offset,
double y_offset)
{
+ if (surface->status) {
+ _cairo_surface_set_error (surface, surface->status);
+ return;
+ }
+
+ if (surface->finished) {
+ _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+ return;
+ }
+
surface->device_x_offset = x_offset;
surface->device_y_offset = y_offset;
}
@@ -480,7 +572,17 @@
void *image_extra;
} fallback_state_t;
-static cairo_status_t
+/**
+ * _fallback_init:
+ *
+ * Acquire destination image surface needed for an image-based
+ * fallback.
+ *
+ * Return value: CAIRO_INT_STATUS_NOTHING_TO_DO if the extents are not
+ * visible, CAIRO_STATUS_SUCCESS if some portion is visible and all
+ * went well, or some error status otherwise.
+ **/
+static cairo_int_status_t
_fallback_init (fallback_state_t *state,
cairo_surface_t *dst,
int x,
@@ -488,6 +590,8 @@
int width,
int height)
{
+ cairo_status_t status;
+
state->extents.x = x;
state->extents.y = y;
state->extents.width = width;
@@ -495,15 +599,29 @@
state->dst = dst;
- return _cairo_surface_acquire_dest_image (dst, &state->extents,
- &state->image, &state->image_rect, &state->image_extra);
+ status = _cairo_surface_acquire_dest_image (dst, &state->extents,
+ &state->image, &state->image_rect,
+ &state->image_extra);
+ if (status)
+ return status;
+
+ /* XXX: This NULL value tucked away in state->image is a rather
+ * ugly interface. Cleaner would be to push the
+ * CAIRO_INT_STATUS_NOTHING_TO_DO value down into
+ * _cairo_surface_acquire_dest_image and its backend
+ * counterparts. */
+ if (state->image == NULL)
+ return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
+ return CAIRO_STATUS_SUCCESS;
}
static void
-_fallback_cleanup (fallback_state_t *state)
+_fallback_fini (fallback_state_t *state)
{
_cairo_surface_release_dest_image (state->dst, &state->extents,
- state->image, &state->image_rect, state->image_extra);
+ state->image, &state->image_rect,
+ state->image_extra);
}
static cairo_status_t
@@ -524,18 +642,20 @@
cairo_status_t status;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
- if (status || !state.image)
+ if (status) {
+ if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
+ return CAIRO_STATUS_SUCCESS;
return status;
+ }
- state.image->base.backend->composite (operator, src, mask,
- &state.image->base,
- src_x, src_y, mask_x, mask_y,
- dst_x - state.image_rect.x,
- dst_y - state.image_rect.y,
- width, height);
+ status = state.image->base.backend->composite (operator, src, mask,
+ &state.image->base,
+ src_x, src_y, mask_x, mask_y,
+ dst_x - state.image_rect.x,
+ dst_y - state.image_rect.y,
+ width, height);
+ _fallback_fini (&state);
- _fallback_cleanup (&state);
-
return status;
}
@@ -555,6 +675,9 @@
{
cairo_int_status_t status;
+ if (dst->status)
+ return dst->status;
+
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -588,6 +711,9 @@
{
cairo_rectangle_t rect;
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -636,16 +762,19 @@
}
status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1);
- if (status || !state.image)
+ if (status) {
+ if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
+ return CAIRO_STATUS_SUCCESS;
return status;
+ }
/* If the fetched image isn't at 0,0, we need to offset the rectangles */
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
offset_rects = malloc (sizeof (cairo_rectangle_t) * num_rects);
- if (!offset_rects) {
+ if (offset_rects == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
- goto FAIL;
+ goto DONE;
}
for (i = 0; i < num_rects; i++) {
@@ -658,15 +787,15 @@
rects = offset_rects;
}
- state.image->base.backend->fill_rectangles (&state.image->base, operator, color,
- rects, num_rects);
+ status = state.image->base.backend->fill_rectangles (&state.image->base,
+ operator, color,
+ rects, num_rects);
- if (offset_rects)
- free (offset_rects);
+ free (offset_rects);
+
+ DONE:
+ _fallback_fini (&state);
- FAIL:
- _fallback_cleanup (&state);
-
return status;
}
@@ -679,6 +808,9 @@
{
cairo_int_status_t status;
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -705,11 +837,11 @@
cairo_fill_rule_t fill_rule,
double tolerance)
{
- if (dst->backend->fill_path)
- return dst->backend->fill_path (operator, pattern, dst, path,
- fill_rule, tolerance);
- else
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ if (dst->backend->fill_path)
+ return dst->backend->fill_path (operator, pattern, dst, path,
+ fill_rule, tolerance);
+ else
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -732,8 +864,11 @@
int i;
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
- if (status || !state.image)
+ if (status) {
+ if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
+ return CAIRO_STATUS_SUCCESS;
return status;
+ }
/* If the destination image isn't at 0,0, we need to offset the trapezoids */
@@ -745,7 +880,7 @@
offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
if (!offset_traps) {
status = CAIRO_STATUS_NO_MEMORY;
- goto FAIL;
+ goto DONE;
}
for (i = 0; i < num_traps; i++) {
@@ -773,13 +908,12 @@
if (offset_traps)
free (offset_traps);
- FAIL:
- _fallback_cleanup (&state);
+ DONE:
+ _fallback_fini (&state);
return status;
}
-
cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
cairo_pattern_t *pattern,
@@ -795,6 +929,9 @@
{
cairo_int_status_t status;
+ if (dst->status)
+ return dst->status;
+
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -809,16 +946,19 @@
return status;
}
- return _fallback_composite_trapezoids (operator, pattern, dst,
- src_x, src_y,
- dst_x, dst_y,
- width, height,
- traps, num_traps);
+ return _fallback_composite_trapezoids (operator, pattern, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ traps, num_traps);
}
cairo_status_t
_cairo_surface_copy_page (cairo_surface_t *surface)
{
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -826,12 +966,15 @@
if (surface->backend->copy_page == NULL)
return CAIRO_STATUS_SUCCESS;
- return surface->backend->copy_page (surface);
+ return surface->backend->copy_page (surface);
}
cairo_status_t
_cairo_surface_show_page (cairo_surface_t *surface)
{
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -861,15 +1004,19 @@
* _cairo_surface_allocate_clip_serial:
* @surface: the #cairo_surface_t to allocate a serial number from
*
- * Each surface has a separate set of clipping serial numbers,
- * and this function allocates one from the specified surface.
- * As zero is reserved for the special no-clipping case,
- * this function will not return that.
+ * Each surface has a separate set of clipping serial numbers, and
+ * this function allocates one from the specified surface. As zero is
+ * reserved for the special no-clipping case, this function will not
+ * return that except for an in-error surface, (ie. surface->status !=
+ * CAIRO_STATUS_SUCCESS).
*/
unsigned int
_cairo_surface_allocate_clip_serial (cairo_surface_t *surface)
{
unsigned int serial;
+
+ if (surface->status)
+ return 0;
if ((serial = ++(surface->next_clip_serial)) == 0)
serial = ++(surface->next_clip_serial);
@@ -890,6 +1037,9 @@
{
cairo_status_t status;
+ if (surface->status)
+ return status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -909,6 +1059,7 @@
if (status)
return status;
}
+
return CAIRO_STATUS_SUCCESS;
}
@@ -927,12 +1078,16 @@
pixman_region16_t *region,
unsigned int serial)
{
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
assert (surface->backend->set_clip_region != NULL);
surface->current_clip_serial = serial;
+
return surface->backend->set_clip_region (surface, region);
}
@@ -942,6 +1097,9 @@
cairo_fill_rule_t fill_rule,
double tolerance)
{
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -972,7 +1130,6 @@
clip_path->tolerance);
}
-
/**
* _cairo_surface_set_clip_path:
* @surface: the #cairo_surface_t to reset the clip on
@@ -991,6 +1148,9 @@
{
cairo_status_t status;
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -1031,6 +1191,9 @@
_cairo_surface_get_extents (cairo_surface_t *surface,
cairo_rectangle_t *rectangle)
{
+ if (surface->status)
+ return surface->status;
+
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
@@ -1053,6 +1216,9 @@
{
cairo_status_t status;
+ if (dst->status)
+ return dst->status;
+
if (dst->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
Index: cairo-win32-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-font.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- cairo-win32-font.c 22 Jul 2005 14:15:57 -0000 1.26
+++ cairo-win32-font.c 27 Jul 2005 22:39:35 -0000 1.27
@@ -223,8 +223,10 @@
cairo_matrix_t scale;
f = malloc (sizeof(cairo_win32_scaled_font_t));
- if (f == NULL)
- return NULL;
+ if (f == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_scaled_font_nil;
+ }
f->logfont = *logfont;
f->options = *options;
@@ -1009,7 +1011,7 @@
image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,
image24->width, image24->height);
- if (!image8)
+ if (image8->status)
return NULL;
for (i = 0; i < image24->height; i++) {
@@ -1082,8 +1084,8 @@
RECT r;
tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
- if (!tmp_surface)
- return CAIRO_STATUS_NO_MEMORY;
+ if (tmp_surface->status)
+ return tmp_surface->status;
r.left = 0;
r.top = 0;
@@ -1387,6 +1389,11 @@
HFONT old_hfont = NULL;
int old_mode;
+ if (scaled_font->status) {
+ _cairo_scaled_font_set_error (scaled_font, scaled_font->status);
+ return scaled_font->status;
+ }
+
hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
if (!hfont)
return CAIRO_STATUS_NO_MEMORY;
Index: cairo-win32-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-surface.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- cairo-win32-surface.c 14 Jul 2005 23:50:58 -0000 1.29
+++ cairo-win32-surface.c 27 Jul 2005 22:39:35 -0000 1.30
@@ -243,23 +243,29 @@
int width,
int height)
{
+ cairo_status_t status;
cairo_win32_surface_t *surface;
char *bits;
int rowstride;
surface = malloc (sizeof (cairo_win32_surface_t));
- if (!surface)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_surface_nil;
+ }
- if (_create_dc_and_bitmap (surface, original_dc, format,
- width, height,
- &bits, &rowstride) != CAIRO_STATUS_SUCCESS)
+ status = _create_dc_and_bitmap (surface, original_dc, format,
+ width, height,
+ &bits, &rowstride);
+ if (status)
goto FAIL;
surface->image = cairo_image_surface_create_for_data (bits, format,
width, height, rowstride);
- if (!surface->image)
+ if (surface->image->status) {
+ status = surface->image->status;
goto FAIL;
+ }
surface->format = format;
@@ -283,9 +289,13 @@
}
if (surface)
free (surface);
-
- return NULL;
-
+
+ if (status == CAIRO_STATUS_NO_MEMORY) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_surface_nil;
+ } else {
+ return _cairo_surface_create_in_error (status);
+ }
}
static cairo_surface_t *
@@ -359,8 +369,8 @@
content,
width,
height);
- if (!local)
- return CAIRO_STATUS_NO_MEMORY;
+ if (local->status)
+ return local->status;
if (!BitBlt (local->dc,
0, 0,
@@ -892,12 +902,16 @@
*/
if (GetClipBox (hdc, &rect) == ERROR) {
_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
- return NULL;
+ /* XXX: Can we make a more reasonable guess at the error cause here? */
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_surface_nil;
}
surface = malloc (sizeof (cairo_win32_surface_t));
- if (!surface)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return &_cairo_surface_nil;
+ }
surface->image = NULL;
surface->format = CAIRO_FORMAT_RGB24;
Index: cairo-xcb-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xcb-surface.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- cairo-xcb-surface.c 21 Jul 2005 06:30:08 -0000 1.40
+++ cairo-xcb-surface.c 27 Jul 2005 22:39:35 -0000 1.41
@@ -503,6 +503,8 @@
x2 - x1,
y2 - y1,
bytes_per_line);
+ if (image->base.status)
+ goto FAIL;
} else {
/*
* XXX This can't work. We must convert the data to one of the
@@ -510,12 +512,14 @@
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
- image = _cairo_image_surface_create_with_masks (data,
- &masks,
- x2 - x1,
- y2 - y1,
- bytes_per_line);
-
+ image = (cairo_image_surface_t *)
+ _cairo_image_surface_create_with_masks (data,
+ &masks,
+ x2 - x1,
+ y2 - y1,
+ bytes_per_line);
+ if (image->base.status)
+ goto FAIL;
}
/* Let the surface take ownership of the data */
@@ -523,6 +527,10 @@
*image_out = image;
return CAIRO_STATUS_SUCCESS;
+
+ FAIL:
+ free (data);
+ return CAIRO_STATUS_NO_MEMORY;
}
static void
@@ -637,12 +645,15 @@
} else if (_cairo_surface_is_image (src)) {
cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
cairo_content_t content = _cairo_content_from_format (image_src->format);
+
+ if (surface->base.status)
+ return surface->base.status;
clone = (cairo_xcb_surface_t *)
_cairo_xcb_surface_create_similar (surface, content,
image_src->width, image_src->height);
- if (clone == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (clone->base.status)
+ return clone->base.status;
_draw_image_surface (clone, image_src, 0, 0);
@@ -1062,8 +1073,10 @@
cairo_xcb_surface_t *surface;
surface = malloc (sizeof (cairo_xcb_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&surface->base, &cairo_xcb_surface_backend);
Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- cairo-xlib-surface.c 27 Jul 2005 22:04:04 -0000 1.97
+++ cairo-xlib-surface.c 27 Jul 2005 22:39:35 -0000 1.98
@@ -430,11 +430,14 @@
*/
if (_CAIRO_MASK_FORMAT (&masks, &format))
{
- image = (cairo_image_surface_t *) cairo_image_surface_create_for_data ((unsigned char *) ximage->data,
- format,
- ximage->width,
- ximage->height,
- ximage->bytes_per_line);
+ image = (cairo_image_surface_t*)
+ cairo_image_surface_create_for_data ((unsigned char *) ximage->data,
+ format,
+ ximage->width,
+ ximage->height,
+ ximage->bytes_per_line);
+ if (image->base.status)
+ goto FAIL;
}
else
{
@@ -444,11 +447,14 @@
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
- image = _cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
- &masks,
- ximage->width,
- ximage->height,
- ximage->bytes_per_line);
+ image = (cairo_image_surface_t*)
+ _cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
+ &masks,
+ ximage->width,
+ ximage->height,
+ ximage->bytes_per_line);
+ if (image->base.status)
+ goto FAIL;
}
/* Let the surface take ownership of the data */
@@ -458,6 +464,10 @@
*image_out = image;
return CAIRO_STATUS_SUCCESS;
+
+ FAIL:
+ XDestroyImage (ximage);
+ return CAIRO_STATUS_NO_MEMORY;
}
static void
@@ -658,8 +668,8 @@
clone = (cairo_xlib_surface_t *)
_cairo_xlib_surface_create_similar (surface, content,
image_src->width, image_src->height);
- if (clone == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (clone->base.status)
+ return clone->base.status;
_draw_image_surface (clone, image_src, 0, 0);
@@ -1400,12 +1410,16 @@
cairo_xlib_screen_info_t *screen_info;
screen_info = _cairo_xlib_screen_info_get (dpy, screen);
- if (!screen_info)
- return NULL;
+ if (screen_info == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
surface = malloc (sizeof (cairo_xlib_surface_t));
- if (surface == NULL)
- return NULL;
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend);
@@ -1534,7 +1548,7 @@
Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
if (screen == NULL)
- return NULL;
+ return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_VISUAL);
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
visual, NULL, width, height, 0);
@@ -2376,7 +2390,9 @@
/* Work out the index size to use. */
elt_size = 8;
- _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
+ status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
+ if (status)
+ goto UNLOCK;
for (i = 0; i < num_glyphs; ++i) {
key.index = glyphs[i].index;
Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.114
retrieving revision 1.115
diff -u -d -r1.114 -r1.115
--- cairo.c 25 Jul 2005 19:29:24 -0000 1.114
+++ cairo.c 27 Jul 2005 22:39:35 -0000 1.115
@@ -62,34 +62,52 @@
* a bit of a pain, but it should be easy to always catch as long as
* one adds a new test case to test a trigger of the new status value.
*/
-#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_PATTERN_TYPE_MISMATCH
+#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_VISUAL
/**
* _cairo_error:
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
[...1174 lines suppressed...]
return "invalid matrix (not invertible)";
case CAIRO_STATUS_INVALID_STATUS:
- return " invalid value for an input cairo_status_t";
+ return "invalid value for an input cairo_status_t";
case CAIRO_STATUS_NULL_POINTER:
return "NULL pointer";
case CAIRO_STATUS_INVALID_STRING:
@@ -2374,6 +2389,12 @@
return "the surface type is not appropriate for the operation";
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
return "the pattern type is not appropriate for the operation";
+ case CAIRO_STATUS_INVALID_CONTENT:
+ return "invalid value for an input cairo_content_t";
+ case CAIRO_STATUS_INVALID_FORMAT:
+ return "invalid value for an input cairo_format_t";
+ case CAIRO_STATUS_INVALID_VISUAL:
+ return "invalid value for an input Visual*";
}
return "<unknown error status>";
Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- cairo.h 25 Jul 2005 19:29:24 -0000 1.139
+++ cairo.h 27 Jul 2005 22:39:35 -0000 1.140
@@ -154,6 +154,9 @@
* @CAIRO_STATUS_SURFACE_FINISHED: target surface has been finished
* @CAIRO_STATUS_SURFACE_TYPE_MISMATCH: the surface type is not appropriate for the operation
* @CAIRO_STATUS_PATTERN_TYPE_MISMATCH: the pattern type is not appropriate for the operation
+ * @CAIRO_STATUS_INVALID_CONTENT: invalid value for an input cairo_content_t
+ * @CAIRO_STATUS_INVALID_FORMAT: invalid value for an input cairo_format_t
+ * @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual*
*
* #cairo_status_t is used to indicate errors that can occur when
* using Cairo. In some cases it is returned directly by functions.
@@ -175,7 +178,10 @@
CAIRO_STATUS_WRITE_ERROR,
CAIRO_STATUS_SURFACE_FINISHED,
CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
- CAIRO_STATUS_PATTERN_TYPE_MISMATCH
+ CAIRO_STATUS_PATTERN_TYPE_MISMATCH,
+ CAIRO_STATUS_INVALID_CONTENT,
+ CAIRO_STATUS_INVALID_FORMAT,
+ CAIRO_STATUS_INVALID_VISUAL
} cairo_status_t;
/**
@@ -894,6 +900,9 @@
cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
cairo_status_t
+cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
+
+void
cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *extents);
@@ -1102,6 +1111,9 @@
cairo_surface_destroy (cairo_surface_t *surface);
cairo_status_t
+cairo_surface_status (cairo_surface_t *surface);
+
+void
cairo_surface_finish (cairo_surface_t *surface);
#if CAIRO_HAS_PNG_FUNCTIONS
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -d -r1.169 -r1.170
--- cairoint.h 25 Jul 2005 23:23:05 -0000 1.169
+++ cairoint.h 27 Jul 2005 22:39:35 -0000 1.170
@@ -229,7 +229,8 @@
offset */
typedef enum cairo_int_status {
CAIRO_INT_STATUS_DEGENERATE = 1000,
- CAIRO_INT_STATUS_UNSUPPORTED
+ CAIRO_INT_STATUS_UNSUPPORTED,
+ CAIRO_INT_STATUS_NOTHING_TO_DO
} cairo_int_status_t;
typedef enum cairo_direction {
@@ -458,6 +459,7 @@
};
struct _cairo_scaled_font {
+ cairo_status_t status;
int ref_count;
cairo_matrix_t font_matrix; /* font space => user space */
cairo_matrix_t ctm; /* user space => device space */
@@ -794,6 +796,7 @@
const cairo_surface_backend_t *backend;
unsigned int ref_count;
+ cairo_status_t status;
cairo_bool_t finished;
cairo_user_data_array_t user_data;
@@ -833,6 +836,8 @@
pixman_image_t *pixman_image;
};
+extern const cairo_surface_backend_t cairo_image_surface_backend;
+
/* XXX: Right now, the cairo_color structure puts unpremultiplied
color in the doubles and premultiplied color in the shorts. Yes,
this is crazy insane, (but at least we don't export this
@@ -1294,6 +1299,10 @@
/* cairo-font.c */
cairo_private void
+_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
+ cairo_status_t status);
+
+cairo_private void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend);
@@ -1302,6 +1311,8 @@
cairo_font_slant_t slant,
cairo_font_weight_t weight);
+extern const cairo_scaled_font_t _cairo_scaled_font_nil;
+
cairo_private void
_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
const cairo_matrix_t *font_matrix,
@@ -1360,7 +1371,7 @@
int num_glyphs,
cairo_path_fixed_t *path);
-cairo_private void
+cairo_private cairo_status_t
_cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t *scaled_font,
cairo_glyph_cache_key_t *key);
@@ -1468,6 +1479,9 @@
cairo_traps_t *traps);
/* cairo-surface.c */
+
+extern const cairo_surface_t _cairo_surface_nil;
+
cairo_private cairo_surface_t *
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
cairo_content_t content,
@@ -1481,6 +1495,9 @@
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);
@@ -1627,7 +1644,7 @@
cairo_private cairo_content_t
_cairo_content_from_format (cairo_format_t format);
-cairo_private cairo_image_surface_t *
+cairo_private cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
cairo_format_masks_t *format,
int width,
@@ -1641,7 +1658,7 @@
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
pixman_region16_t *region);
-cairo_private int
+cairo_private cairo_bool_t
_cairo_surface_is_image (cairo_surface_t *surface);
/* cairo_pen.c */
@@ -1909,6 +1926,9 @@
cairo_output_stream_t *
_cairo_output_stream_create_for_file (const char *filename);
+cairo_private void
+_cairo_error (cairo_status_t status);
+
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(cairo_get_current_point)
More information about the cairo-commit
mailing list