diff options
author | Carl Worth <cworth@cworth.org> | 2005-06-13 16:36:40 +0000 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2005-06-13 16:36:40 +0000 |
commit | 14ae3ce3ade3448f3c3d6ae0344ab4785afa96aa (patch) | |
tree | e86cd9770002970097b5acbb5ddfef855ba26aeb | |
parent | 15fb5e0d27a1fc7743894792a168980363df5d71 (diff) |
No longer need to check for NULL after creating a pattern.
Propagate status errors from pattern->status to cr->status.
Originally 2005-05-08 Owen Taylor <otaylor@redhat.com>:
src/cairo-pattern.c src/cairoint.h: If allocation of pattern objects fails, return special static nil pattern objects.
If adding a color stop fails to allocate memory, set pattern->status. (And fix a memory leak.) Make public functions return when pattern->status is set, (and no longer return a cairo_status_t).
src/cairo-pattern.c src/cairo.h doc/public/cairo-sections.txt: Add cairo_pattern_status()
Check the status of gstate->source and of mask patterns passed in.
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | doc/public/cairo-sections.txt | 1 | ||||
-rw-r--r-- | src/cairo-gstate.c | 24 | ||||
-rw-r--r-- | src/cairo-pattern.c | 188 | ||||
-rw-r--r-- | src/cairo.c | 34 | ||||
-rw-r--r-- | src/cairo.h | 16 | ||||
-rw-r--r-- | src/cairoint.h | 6 |
7 files changed, 219 insertions, 75 deletions
@@ -1,5 +1,30 @@ 2005-06-13 Carl Worth <cworth@cworth.org> + * src/cairo.c (_cairo_set_source_solid), + (cairo_set_source_surface), (cairo_mask_surface): No longer need + to check for NULL after creating a pattern. + + * src/cairo.c (cairo_set_source), (cairo_mask): Propagate status + errors from pattern->status to cr->status. + + Originally 2005-05-08 Owen Taylor <otaylor@redhat.com>: + + * src/cairo-pattern.c src/cairoint.h: If allocation of pattern + objects fails, return special static nil pattern objects. + + * src/cairo-pattern.c: If adding a color stop fails to allocate + memory, set pattern->status. (And fix a memory leak.) Make public + functions return when pattern->status is set, (and no longer + return a cairo_status_t). + + * src/cairo-pattern.c src/cairo.h doc/public/cairo-sections.txt: + Add cairo_pattern_status() + + * src/cairo-gstate.c: Check the status of gstate->source and + of mask patterns passed in. + +2005-06-13 Carl Worth <cworth@cworth.org> + Originally 2005-05-08 Owen Taylor <otaylor@redhat.com>: * src/cairo.c (cairo_create): If cairo_create() fails, return diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 785af878e..204cc8bdd 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -109,6 +109,7 @@ cairo_pattern_create_linear cairo_pattern_create_radial cairo_pattern_reference cairo_pattern_destroy +cairo_pattern_status cairo_pattern_add_color_stop_rgb cairo_pattern_add_color_stop_rgba cairo_pattern_set_matrix diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 0c35a3a9a..90ef78f53 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -128,7 +128,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, cairo_surface_reference (gstate->target); gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK); - if (gstate->source == NULL) + if (gstate->source->status) return CAIRO_STATUS_NO_MEMORY; gstate->next = NULL; @@ -393,8 +393,8 @@ cairo_status_t _cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source) { - if (source == NULL) - return CAIRO_STATUS_NULL_POINTER; + if (source->status) + return source->status; cairo_pattern_reference (source); cairo_pattern_destroy (gstate->source); @@ -723,6 +723,9 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) cairo_box_t box; cairo_traps_t traps; + if (gstate->source->status) + return gstate->source->status; + status = _cairo_gstate_set_clip (gstate); if (status) return status; @@ -865,6 +868,12 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, cairo_status_t status; int mask_x, mask_y; + if (mask->status) + return mask->status; + + if (gstate->source->status) + return gstate->source->status; + status = _cairo_gstate_set_clip (gstate); if (status) return status; @@ -937,6 +946,9 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) cairo_status_t status; cairo_traps_t traps; + if (gstate->source->status) + return gstate->source->status; + if (gstate->line_width <= 0.0) return CAIRO_STATUS_SUCCESS; @@ -1416,6 +1428,9 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) cairo_status_t status; cairo_traps_t traps; + if (gstate->source->status) + return gstate->source->status; + status = _cairo_gstate_set_clip (gstate); if (status) return status; @@ -1989,6 +2004,9 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, cairo_box_t bbox; cairo_rectangle_t extents; + if (gstate->source->status) + return gstate->source->status; + status = _cairo_gstate_set_clip (gstate); if (status) return status; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 8768ca9cf..b3ab94645 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -50,20 +50,67 @@ 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 = { + { CAIRO_PATTERN_SOLID, /* type */ + (unsigned int)-1, /* ref_count */ + CAIRO_STATUS_NO_MEMORY, /* status */ + { 1., 0., 0., 1., 0., 0., }, /* matrix */ + CAIRO_FILTER_DEFAULT, /* filter */ + CAIRO_EXTEND_DEFAULT }, /* extend */ + { 0.0, 0.0, 0.0, 1.0, /* solid black */ + 0x0, 0x0, 0x0, 0xffff } +}; + +static const cairo_surface_pattern_t cairo_surface_pattern_nil = { + { CAIRO_PATTERN_SURFACE, /* type */ + (unsigned int)-1, /* ref_count */ + CAIRO_STATUS_NO_MEMORY, /* status */ + { 1., 0., 0., 1., 0., 0., }, /* matrix */ + CAIRO_FILTER_DEFAULT, /* filter */ + CAIRO_EXTEND_DEFAULT }, /* extend */ + NULL /* surface */ +}; + +static const cairo_linear_pattern_t cairo_linear_pattern_nil = { + { { CAIRO_PATTERN_LINEAR, /* type */ + (unsigned int)-1, /* ref_count */ + CAIRO_STATUS_NO_MEMORY, /* status */ + { 1., 0., 0., 1., 0., 0., }, /* matrix */ + CAIRO_FILTER_DEFAULT, /* filter */ + CAIRO_EXTEND_DEFAULT }, /* extend */ + NULL, /* stops */ + 0 }, /* n_stops */ + { 0., 0. }, { 1.0, 1.0 } /* point0, point1 */ +}; + +static const cairo_radial_pattern_t cairo_radial_pattern_nil = { + { { CAIRO_PATTERN_RADIAL, /* type */ + (unsigned int)-1, /* ref_count */ + CAIRO_STATUS_NO_MEMORY, /* status */ + { 1., 0., 0., 1., 0., 0., }, /* matrix */ + CAIRO_FILTER_DEFAULT, /* filter */ + CAIRO_EXTEND_DEFAULT }, /* extend */ + NULL, /* stops */ + 0 }, /* n_stops */ + { 0., 0. }, { 0.0, 0.0 }, /* center0, center1 */ + 1.0, 1.0, /* radius0, radius1 */ +}; + static void _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) { pattern->type = type; pattern->ref_count = 1; + pattern->status = CAIRO_STATUS_SUCCESS; pattern->extend = CAIRO_EXTEND_DEFAULT; pattern->filter = CAIRO_FILTER_DEFAULT; cairo_matrix_init_identity (&pattern->matrix); } -static cairo_status_t -_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, - cairo_gradient_pattern_t *other) +static void +_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, + const cairo_gradient_pattern_t *other) { if (other->base.type == CAIRO_PATTERN_LINEAR) { @@ -83,18 +130,22 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, if (other->n_stops) { pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t)); - if (!pattern->stops) - return CAIRO_STATUS_NO_MEMORY; + if (!pattern->stops) { + if (other->base.type == CAIRO_PATTERN_LINEAR) + _cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base); + else + _cairo_gradient_pattern_init_copy (pattern, &cairo_radial_pattern_nil.base); + return; + } memcpy (pattern->stops, other->stops, other->n_stops * sizeof (cairo_color_stop_t)); } - - return CAIRO_STATUS_SUCCESS; } -cairo_status_t -_cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other) +void +_cairo_pattern_init_copy (cairo_pattern_t *pattern, + const cairo_pattern_t *other) { switch (other->type) { case CAIRO_PATTERN_SOLID: { @@ -114,17 +165,12 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other) case CAIRO_PATTERN_RADIAL: { cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern; cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other; - cairo_status_t status; - status = _cairo_gradient_pattern_init_copy (dst, src); - if (status) - return status; + _cairo_gradient_pattern_init_copy (dst, src); } break; } pattern->ref_count = 1; - - return CAIRO_STATUS_SUCCESS; } void @@ -210,7 +256,7 @@ _cairo_pattern_create_solid (const cairo_color_t *color) pattern = malloc (sizeof (cairo_solid_pattern_t)); if (pattern == NULL) - return NULL; + return (cairo_pattern_t *) &cairo_solid_pattern_nil.base; _cairo_pattern_init_solid (pattern, color); @@ -224,7 +270,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface) pattern = malloc (sizeof (cairo_surface_pattern_t)); if (pattern == NULL) - return NULL; + return (cairo_pattern_t *)&cairo_surface_pattern_nil.base; _cairo_pattern_init_for_surface (pattern, surface); @@ -244,7 +290,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1) pattern = malloc (sizeof (cairo_linear_pattern_t)); if (pattern == NULL) - return NULL; + return (cairo_pattern_t *) &cairo_linear_pattern_nil.base; _cairo_pattern_init_linear (pattern, x0, y0, x1, y1); @@ -259,7 +305,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0, pattern = malloc (sizeof (cairo_radial_pattern_t)); if (pattern == NULL) - return NULL; + return (cairo_pattern_t *) &cairo_radial_pattern_nil.base; _cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1); @@ -272,15 +318,36 @@ cairo_pattern_reference (cairo_pattern_t *pattern) if (pattern == NULL) return; + if (pattern->ref_count == (unsigned int)-1) + return; + pattern->ref_count++; } +/** + * cairo_pattern_status: + * @pattern: a #cairo_pattern_t + * + * Checks whether an error has previously occurred for this + * pattern. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + **/ +cairo_status_t +cairo_pattern_status (cairo_pattern_t *pattern) +{ + return pattern->status; +} + void cairo_pattern_destroy (cairo_pattern_t *pattern) { if (pattern == NULL) return; + if (pattern->ref_count == (unsigned int)-1) + return; + pattern->ref_count--; if (pattern->ref_count) return; @@ -289,31 +356,31 @@ cairo_pattern_destroy (cairo_pattern_t *pattern) free (pattern); } -static cairo_status_t +static void _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern, double offset, cairo_color_t *color) { cairo_color_stop_t *stop; + cairo_color_stop_t *new_stops; pattern->n_stops++; - pattern->stops = realloc (pattern->stops, - pattern->n_stops * sizeof (cairo_color_stop_t)); - if (pattern->stops == NULL) { - pattern->n_stops = 0; - - return CAIRO_STATUS_NO_MEMORY; + new_stops = realloc (pattern->stops, + pattern->n_stops * sizeof (cairo_color_stop_t)); + if (new_stops == NULL) { + pattern->base.status = CAIRO_STATUS_NO_MEMORY; + return; } + + pattern->stops = new_stops; stop = &pattern->stops[pattern->n_stops - 1]; stop->offset = _cairo_fixed_from_double (offset); stop->color = *color; - - return CAIRO_STATUS_SUCCESS; } -cairo_status_t +void cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, double offset, double red, @@ -322,11 +389,14 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, { cairo_color_t color; + if (pattern->status) + return; + if (pattern->type != CAIRO_PATTERN_LINEAR && pattern->type != CAIRO_PATTERN_RADIAL) { - /* XXX: CAIRO_STATUS_INVALID_PATTERN? */ - return CAIRO_STATUS_SUCCESS; + pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH; + return; } _cairo_restrict_value (&offset, 0.0, 1.0); @@ -335,12 +405,12 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, _cairo_restrict_value (&blue, 0.0, 1.0); _cairo_color_init_rgb (&color, red, green, blue); - return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, - offset, - &color); + _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, + offset, + &color); } -cairo_status_t +void cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, double offset, double red, @@ -350,11 +420,14 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, { cairo_color_t color; + if (pattern->status) + return; + if (pattern->type != CAIRO_PATTERN_LINEAR && pattern->type != CAIRO_PATTERN_RADIAL) { - /* XXX: CAIRO_STATUS_INVALID_PATTERN? */ - return CAIRO_STATUS_SUCCESS; + pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH; + return; } _cairo_restrict_value (&offset, 0.0, 1.0); @@ -364,34 +437,34 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, _cairo_restrict_value (&alpha, 0.0, 1.0); _cairo_color_init_rgba (&color, red, green, blue, alpha); - return _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, - offset, - &color); + _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, + offset, + &color); } -cairo_status_t +void cairo_pattern_set_matrix (cairo_pattern_t *pattern, const cairo_matrix_t *matrix) { - pattern->matrix = *matrix; + if (pattern->status) + return; - return CAIRO_STATUS_SUCCESS; + pattern->matrix = *matrix; } -cairo_status_t +void cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix) { *matrix = pattern->matrix; - - return CAIRO_STATUS_SUCCESS; } -cairo_status_t +void cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter) { - pattern->filter = filter; + if (pattern->status) + return; - return CAIRO_STATUS_SUCCESS; + pattern->filter = filter; } cairo_filter_t @@ -400,12 +473,13 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern) return pattern->filter; } -cairo_status_t +void cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend) { - pattern->extend = extend; + if (pattern->status) + return; - return CAIRO_STATUS_SUCCESS; + pattern->extend = extend; } cairo_extend_t @@ -418,6 +492,8 @@ void _cairo_pattern_transform (cairo_pattern_t *pattern, const cairo_matrix_t *ctm_inverse) { + assert (pattern->status == CAIRO_STATUS_SUCCESS); + cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix); } @@ -1098,6 +1174,9 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern, { cairo_status_t status; + if (pattern->status) + return pattern->status; + switch (pattern->type) { case CAIRO_PATTERN_SOLID: { cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) pattern; @@ -1197,6 +1276,11 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src, cairo_int_status_t status; cairo_pattern_union_t tmp; + if (src->status) + return src->status; + if (mask && mask->status) + return mask->status; + /* If src and mask are both solid, then the mask alpha can be * combined into src and mask can be ignored. */ diff --git a/src/cairo.c b/src/cairo.c index a548ac8f0..3191cf545 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -328,10 +328,6 @@ _cairo_set_source_solid (cairo_t *cr, const cairo_color_t *color) cairo_pattern_t *source; source = _cairo_pattern_create_solid (color); - if (source == NULL) { - cr->status = CAIRO_STATUS_NO_MEMORY; - return; - } cairo_set_source (cr, source); @@ -426,10 +422,6 @@ cairo_set_source_surface (cairo_t *cr, return; pattern = cairo_pattern_create_for_surface (surface); - if (!pattern) { - cr->status = CAIRO_STATUS_NO_MEMORY; - return; - } cairo_matrix_init_translate (&matrix, -x, -y); cairo_pattern_set_matrix (pattern, &matrix); @@ -461,6 +453,16 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source) if (cr->status) return; + if (source == NULL) { + cr->status = CAIRO_STATUS_NULL_POINTER; + return; + } + + if (source->status) { + cr->status = source->status; + return; + } + cr->status = _cairo_gstate_set_source (cr->gstate, source); CAIRO_CHECK_SANITY (cr); } @@ -1235,6 +1237,16 @@ cairo_mask (cairo_t *cr, if (cr->status) return; + if (pattern == NULL) { + cr->status = CAIRO_STATUS_NULL_POINTER; + return; + } + + if (pattern->status) { + cr->status = pattern->status; + return; + } + cr->status = _cairo_gstate_mask (cr->gstate, pattern); CAIRO_CHECK_SANITY (cr); @@ -1266,10 +1278,6 @@ cairo_mask_surface (cairo_t *cr, return; pattern = cairo_pattern_create_for_surface (surface); - if (!pattern) { - cr->status = CAIRO_STATUS_NO_MEMORY; - return; - } cairo_matrix_init_translate (&matrix, - surface_x, - surface_y); cairo_pattern_set_matrix (pattern, &matrix); @@ -2229,6 +2237,8 @@ cairo_status_to_string (cairo_status_t status) return "the target surface has been finished"; case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: 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"; } return "<unknown error status>"; diff --git a/src/cairo.h b/src/cairo.h index b3c8183e2..4448fd455 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -160,7 +160,8 @@ typedef enum cairo_status { CAIRO_STATUS_READ_ERROR, CAIRO_STATUS_WRITE_ERROR, CAIRO_STATUS_SURFACE_FINISHED, - CAIRO_STATUS_SURFACE_TYPE_MISMATCH + CAIRO_STATUS_SURFACE_TYPE_MISMATCH, + CAIRO_STATUS_PATTERN_TYPE_MISMATCH } cairo_status_t; /** @@ -1014,21 +1015,24 @@ void cairo_pattern_destroy (cairo_pattern_t *pattern); cairo_status_t +cairo_pattern_status (cairo_pattern_t *pattern); + +void cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, double offset, double red, double green, double blue); -cairo_status_t +void cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, double offset, double red, double green, double blue, double alpha); -cairo_status_t +void cairo_pattern_set_matrix (cairo_pattern_t *pattern, const cairo_matrix_t *matrix); -cairo_status_t +void cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix); @@ -1038,7 +1042,7 @@ typedef enum { CAIRO_EXTEND_REFLECT } cairo_extend_t; -cairo_status_t +void cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend); cairo_extend_t @@ -1053,7 +1057,7 @@ typedef enum { CAIRO_FILTER_GAUSSIAN } cairo_filter_t; -cairo_status_t +void cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter); cairo_filter_t diff --git a/src/cairoint.h b/src/cairoint.h index 24c3ee29c..6430b3895 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -785,6 +785,7 @@ typedef struct _cairo_color_stop { struct _cairo_pattern { cairo_pattern_type_t type; unsigned int ref_count; + cairo_status_t status; cairo_matrix_t matrix; cairo_filter_t filter; cairo_extend_t extend; @@ -1689,8 +1690,9 @@ _cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b); /* cairo_pattern.c */ -cairo_private cairo_status_t -_cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_pattern_t *other); +cairo_private void +_cairo_pattern_init_copy (cairo_pattern_t *pattern, + const cairo_pattern_t *other); cairo_private void _cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, |