diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-05-26 17:53:37 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-06-15 05:48:51 -0400 |
commit | 5d57aeaa23566739ba01a0fac1c3b90ce27b28cd (patch) | |
tree | d60e06bb812f0e1652a67a5c96701011cb5160f6 /src/cairo-region.c | |
parent | 216a2e24c7375e48677ce30f9fe8fb3d8bbdd10d (diff) | |
download | cairo-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.c | 44 |
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 (®ion->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 |