summaryrefslogtreecommitdiff
path: root/src/cairo-region.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-07-06 17:27:18 +0200
committerBenjamin Otte <otte@redhat.com>2010-07-06 17:27:18 +0200
commit4c91bb9a221bc8e3d65a96365bbd1157b3f4e612 (patch)
tree84de58b59ee99f29e45a6b598e015a003ea0a5e0 /src/cairo-region.c
parent82de6336d88be43de759b94634e87b9e4a8391b1 (diff)
downloadcairo-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.c80
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 (&region,
+ rectangle->x, rectangle->y,
+ rectangle->width, rectangle->height);
+ pixman_region32_init (&tmp);
+
+ /* XXX: get an xor function into pixman */
+ if (! pixman_region32_subtract (&tmp, &region, &dst->rgn) ||
+ ! pixman_region32_subtract (&dst->rgn, &dst->rgn, &region) ||
+ ! 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 (&region);
+
+ return status;
+}
+slim_hidden_def (cairo_region_xor_rectangle);
+
+/**
* cairo_region_is_empty:
* @region: a #cairo_region_t
*