diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-03-28 03:04:28 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-03-28 18:02:58 -0400 |
commit | 980e9f0dbd4f21c0ccf4cc33b0b0f2f370667290 (patch) | |
tree | a4e5f58d17aa3eb93ebcfb1d0026738c3c069bd8 /src/cairo-region.c | |
parent | 64e490a464472cfe06d779503601d41972ed4518 (diff) | |
download | cairo-980e9f0dbd4f21c0ccf4cc33b0b0f2f370667290.tar.gz |
[region] Fix status propagation for regions
When an operation fails, store the status code in the destination
region rather than leaving it unchanged.
Diffstat (limited to 'src/cairo-region.c')
-rw-r--r-- | src/cairo-region.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/src/cairo-region.c b/src/cairo-region.c index 55898d9c9..aec1bdf15 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -42,6 +42,40 @@ const cairo_region_t _cairo_region_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ }; +/** + * cairo_region_set_error: + * @region: a region + * @status: a status value indicating an error + * + * Atomically sets region->status to @status and calls _cairo_error; + * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal + * status values. + * + * All assignments of an error status to region->status should happen + * through cairo_region_set_error(). Note that due to the nature of + * the atomic operation, it is not safe to call this function on the + * nil objects. + * + * 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. + * + * Return value: the error status. + **/ +static cairo_status_t +cairo_region_set_error (cairo_region_t *region, + cairo_status_t status) +{ + if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED) + return status; + + /* Don't overwrite an existing error. This preserves the first + * error, which is the most significant. */ + _cairo_status_set_error (®ion->status, status); + + return _cairo_error (status); +} + cairo_region_t * cairo_region_create (void) { @@ -172,7 +206,7 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return other->status; if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -207,9 +241,9 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) if (other->status) return other->status; - + if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -218,7 +252,7 @@ cairo_status_t cairo_region_intersect_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rect) { - cairo_status_t result = CAIRO_STATUS_SUCCESS; + cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; if (dst->status) @@ -228,11 +262,11 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, rect->x, rect->y, rect->width, rect->height); if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) - result = _cairo_error (CAIRO_STATUS_NO_MEMORY); + status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); - return result; + return status; } cairo_status_t @@ -246,7 +280,7 @@ cairo_region_union (cairo_region_t *dst, return other->status; if (!pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -255,14 +289,18 @@ cairo_status_t cairo_region_union_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rect) { - if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, - rect->x, rect->y, - rect->width, rect->height)) - { - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } + cairo_status_t status = CAIRO_STATUS_SUCCESS; + pixman_region32_t region; - return CAIRO_STATUS_SUCCESS; + pixman_region32_init_rect (®ion, + rect->x, rect->y, rect->width, rect->height); + + if (!pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) + status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (®ion); + + return status; } cairo_bool_t |