diff options
author | Benjamin Otte <otte@redhat.com> | 2010-07-06 17:27:18 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-07-06 17:27:18 +0200 |
commit | 4c91bb9a221bc8e3d65a96365bbd1157b3f4e612 (patch) | |
tree | 84de58b59ee99f29e45a6b598e015a003ea0a5e0 /src/cairo-region.c | |
parent | 82de6336d88be43de759b94634e87b9e4a8391b1 (diff) | |
download | cairo-4c91bb9a221bc8e3d65a96365bbd1157b3f4e612.tar.gz |
region: Add cairo_region_xor() and cairo_region_xor_rectangle()
gdk_region_xor() was a quite often used function in GDK and now that
GDKe uses cairo regions, it seems like a worthwhile addition to Cairo.
Diffstat (limited to 'src/cairo-region.c')
-rw-r--r-- | src/cairo-region.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/cairo-region.c b/src/cairo-region.c index 565a7de62..85d7c0900 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -652,6 +652,86 @@ cairo_region_union_rectangle (cairo_region_t *dst, slim_hidden_def (cairo_region_union_rectangle); /** + * cairo_region_xor: + * @dst: a #cairo_region_t + * @other: another #cairo_region_t + * + * Computes the exclusive difference of @dst with @other and places the + * result in @dst. That is, @dst will be set to contain all areas that + * are either in @dst or in @other, but not in both. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ +cairo_status_t +cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + pixman_region32_t tmp; + + if (dst->status) + return dst->status; + + if (other->status) + return _cairo_region_set_error (dst, other->status); + + pixman_region32_init (&tmp); + + /* XXX: get an xor function into pixman */ + if (! pixman_region32_subtract (&tmp, CONST_CAST &other->rgn, &dst->rgn) || + ! pixman_region32_subtract (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn) || + ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp)) + status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (&tmp); + + return status; +} +slim_hidden_def (cairo_region_xor); + +/** + * cairo_region_xor_rectangle: + * @dst: a #cairo_region_t + * @rectangle: a #cairo_rectangle_int_t + * + * Computes the exclusive difference of @dst with @rectangle and places the + * result in @dst. That is, @dst will be set to contain all areas that are + * either in @dst or in @rectangle, but not in both. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ +cairo_status_t +cairo_region_xor_rectangle (cairo_region_t *dst, + const cairo_rectangle_int_t *rectangle) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + pixman_region32_t region, tmp; + + if (dst->status) + return dst->status; + + pixman_region32_init_rect (®ion, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); + pixman_region32_init (&tmp); + + /* XXX: get an xor function into pixman */ + if (! pixman_region32_subtract (&tmp, ®ion, &dst->rgn) || + ! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion) || + ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp)) + status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (&tmp); + pixman_region32_fini (®ion); + + return status; +} +slim_hidden_def (cairo_region_xor_rectangle); + +/** * cairo_region_is_empty: * @region: a #cairo_region_t * |