summaryrefslogtreecommitdiff
path: root/src/cairo-region.c
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2009-05-26 17:53:37 -0400
committerSøren Sandmann Pedersen <sandmann@redhat.com>2009-06-15 05:48:51 -0400
commit5d57aeaa23566739ba01a0fac1c3b90ce27b28cd (patch)
treed60e06bb812f0e1652a67a5c96701011cb5160f6 /src/cairo-region.c
parent216a2e24c7375e48677ce30f9fe8fb3d8bbdd10d (diff)
downloadcairo-5d57aeaa23566739ba01a0fac1c3b90ce27b28cd.tar.gz
Reinstate cairo_region_create_rectangles()
cairo_region_union_rectangle() is linear in the number of rectangles in the region. There is no way to make it significantly faster without losing the ability to return errors synchronously, so a cairo_region_create_rectangles() is needed to avoid a large performance regression.
Diffstat (limited to 'src/cairo-region.c')
-rw-r--r--src/cairo-region.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/cairo-region.c b/src/cairo-region.c
index c355b4ad7..aeb2ef22d 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -134,6 +134,50 @@ cairo_region_create (void)
}
slim_hidden_def (cairo_region_create);
+cairo_region_t *
+cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
+ int count)
+{
+ pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
+ pixman_box32_t *pboxes = stack_pboxes;
+ cairo_region_t *region;
+ int i;
+
+ region = _cairo_malloc (sizeof (cairo_region_t));
+
+ if (!region)
+ return (cairo_region_t *)&_cairo_region_nil;
+
+ region->status = CAIRO_STATUS_SUCCESS;
+
+ if (count > ARRAY_LENGTH (stack_pboxes)) {
+ pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
+
+ if (unlikely (pboxes == NULL)) {
+ free (region);
+ return (cairo_region_t *)&_cairo_region_nil;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ pboxes[i].x1 = rects[i].x;
+ pboxes[i].y1 = rects[i].y;
+ pboxes[i].x2 = rects[i].x + rects[i].width;
+ pboxes[i].y2 = rects[i].y + rects[i].height;
+ }
+
+ if (! pixman_region32_init_rects (&region->rgn, pboxes, count)) {
+ free (region);
+
+ region = (cairo_region_t *)&_cairo_region_nil;
+ }
+
+ if (pboxes != stack_pboxes)
+ free (pboxes);
+
+ return region;
+}
+
/**
* cairo_region_create_rectangle:
* @rectangle: a #cairo_rectangle_int_t