summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2008-12-11 15:29:23 -0500
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-03-28 17:58:48 -0400
commite3e1b35eb9eb3cf90d882a7452580f9efe00b89a (patch)
tree8b453b46051067c8745636960a55bea3b1ab1123
parentc2c637cf1d89fc8fdcced4467d602a55ef0b14e0 (diff)
downloadcairo-e3e1b35eb9eb3cf90d882a7452580f9efe00b89a.tar.gz
[region] Make cairo_region_t a malloced object.
-rw-r--r--src/cairo-analysis-surface.c26
-rw-r--r--src/cairo-clip-private.h2
-rw-r--r--src/cairo-clip.c99
-rw-r--r--src/cairo-region-private.h42
-rw-r--r--src/cairo-region.c168
-rw-r--r--src/cairo-surface-fallback.c65
-rw-r--r--src/cairo-surface.c29
-rw-r--r--src/cairo-traps.c14
-rw-r--r--src/cairo-xlib-surface.c16
-rw-r--r--src/cairoint.h2
10 files changed, 280 insertions, 183 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 1be592e9e..9c97c1117 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -52,8 +52,8 @@ typedef struct {
cairo_bool_t has_supported;
cairo_bool_t has_unsupported;
- cairo_region_t supported_region;
- cairo_region_t fallback_region;
+ cairo_region_t *supported_region;
+ cairo_region_t *fallback_region;
cairo_rectangle_int_t current_clip;
cairo_box_t page_bbox;
@@ -215,7 +215,7 @@ _add_operation (cairo_analysis_surface_t *surface,
* region there is no benefit in emitting a native operation as
* the fallback image will be painted on top.
*/
- if (_cairo_region_contains_rectangle (&surface->fallback_region, rect) == PIXMAN_REGION_IN)
+ if (_cairo_region_contains_rectangle (surface->fallback_region, rect) == PIXMAN_REGION_IN)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) {
@@ -226,7 +226,7 @@ _add_operation (cairo_analysis_surface_t *surface,
* natively supported and the backend will blend the
* transparency into the white background.
*/
- if (_cairo_region_contains_rectangle (&surface->supported_region, rect) == PIXMAN_REGION_OUT)
+ if (_cairo_region_contains_rectangle (surface->supported_region, rect) == PIXMAN_REGION_OUT)
backend_status = CAIRO_STATUS_SUCCESS;
}
@@ -235,8 +235,7 @@ _add_operation (cairo_analysis_surface_t *surface,
* this region will be emitted as native operations.
*/
surface->has_supported = TRUE;
- status = _cairo_region_union_rect (&surface->supported_region,
- &surface->supported_region,
+ status = _cairo_region_union_rect (surface->supported_region,
rect);
return status;
}
@@ -246,8 +245,7 @@ _add_operation (cairo_analysis_surface_t *surface,
* emitted.
*/
surface->has_unsupported = TRUE;
- status = _cairo_region_union_rect (&surface->fallback_region,
- &surface->fallback_region,
+ status = _cairo_region_union_rect (surface->fallback_region,
rect);
/* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
@@ -267,8 +265,8 @@ _cairo_analysis_surface_finish (void *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
- _cairo_region_fini (&surface->supported_region);
- _cairo_region_fini (&surface->fallback_region);
+ _cairo_region_destroy (surface->supported_region);
+ _cairo_region_destroy (surface->fallback_region);
cairo_surface_destroy (surface->target);
@@ -783,8 +781,8 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface->page_bbox.p2.x = 0;
surface->page_bbox.p2.y = 0;
- _cairo_region_init (&surface->supported_region);
- _cairo_region_init (&surface->fallback_region);
+ surface->supported_region = _cairo_region_create ();
+ surface->fallback_region = _cairo_region_create ();
if (width == -1 && height == -1) {
surface->current_clip.x = CAIRO_RECT_INT_MIN;
@@ -831,7 +829,7 @@ _cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
- return &surface->supported_region;
+ return surface->supported_region;
}
cairo_region_t *
@@ -839,7 +837,7 @@ _cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
- return &surface->fallback_region;
+ return surface->fallback_region;
}
cairo_bool_t
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 36c0fbdcf..517c28cfd 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -78,7 +78,7 @@ struct _cairo_clip {
/*
* A clip region that can be placed in the surface
*/
- cairo_region_t region;
+ cairo_region_t *region;
cairo_bool_t has_region;
/*
* If the surface supports path clipping, we store the list of
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 9455c2889..095af10b8 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -64,8 +64,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
clip->serial = 0;
- _cairo_region_init (&clip->region);
- clip->has_region = FALSE;
+ clip->region = NULL;
clip->path = NULL;
}
@@ -73,6 +72,8 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
cairo_status_t
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
{
+ cairo_status_t status;
+
clip->mode = other->mode;
clip->all_clipped = other->all_clipped;
@@ -82,22 +83,25 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
clip->serial = other->serial;
- _cairo_region_init (&clip->region);
-
if (other->has_region) {
- cairo_status_t status;
-
- status = _cairo_region_copy (&clip->region, &other->region);
- if (unlikely (status)) {
- _cairo_region_fini (&clip->region);
- cairo_surface_destroy (clip->surface);
- return status;
- }
clip->has_region = TRUE;
+
+ clip->region = _cairo_region_copy (other->region);
} else {
clip->has_region = FALSE;
+
+ clip->region = _cairo_region_create ();
}
+ status = _cairo_region_status (clip->region);
+ if (unlikely (status)) {
+ cairo_surface_destroy (clip->surface);
+ _cairo_region_destroy (clip->region);
+ clip->region = NULL;
+
+ return status;
+ }
+
clip->path = _cairo_clip_path_reference (other->path);
return CAIRO_STATUS_SUCCESS;
@@ -115,11 +119,7 @@ _cairo_clip_reset (cairo_clip_t *clip)
clip->serial = 0;
if (clip->has_region) {
- /* _cairo_region_fini just releases the resources used but
- * doesn't bother with leaving the region in a valid state.
- * So _cairo_region_init has to be called afterwards. */
- _cairo_region_fini (&clip->region);
- _cairo_region_init (&clip->region);
+ _cairo_region_clear (clip->region);
clip->has_region = FALSE;
}
@@ -178,10 +178,10 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
return status;
}
- if (clip->has_region) {
+ if (clip->region) {
cairo_rectangle_int_t extents;
- _cairo_region_get_extents (&clip->region, &extents);
+ _cairo_region_get_extents (clip->region, &extents);
is_empty = _cairo_rectangle_intersect (rectangle, &extents);
if (is_empty)
return CAIRO_STATUS_SUCCESS;
@@ -194,7 +194,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
}
cairo_status_t
-_cairo_clip_intersect_to_region (cairo_clip_t *clip,
+_cairo_clip_intersect_to_region (cairo_clip_t *clip,
cairo_region_t *region)
{
cairo_status_t status;
@@ -203,13 +203,13 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
return CAIRO_STATUS_SUCCESS;
if (clip->all_clipped) {
- cairo_region_t clip_rect;
+ cairo_region_t *clip_rect;
- _cairo_region_init_rect (&clip_rect, &clip->surface_rect);
+ clip_rect = _cairo_region_create_rect (&clip->surface_rect);
- status = _cairo_region_intersect (region, &clip_rect, region);
+ status = _cairo_region_intersect (region, clip_rect);
- _cairo_region_fini (&clip_rect);
+ _cairo_region_destroy (clip_rect);
return status;
}
@@ -218,20 +218,20 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
/* Intersect clip path into region. */
}
- if (clip->has_region) {
- status = _cairo_region_intersect (region, &clip->region, region);
+ if (clip->region) {
+ status = _cairo_region_intersect (region, clip->region);
if (unlikely (status))
return status;
}
if (clip->surface) {
- cairo_region_t clip_rect;
+ cairo_region_t *clip_rect;
- _cairo_region_init_rect (&clip_rect, &clip->surface_rect);
+ clip_rect = _cairo_region_create_rect (&clip->surface_rect);
- status = _cairo_region_intersect (region, &clip_rect, region);
+ status = _cairo_region_intersect (region, clip_rect);
- _cairo_region_fini (&clip_rect);
+ _cairo_region_destroy (clip_rect);
if (unlikely (status))
return status;
@@ -344,7 +344,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_surface_t *target)
{
- cairo_region_t region;
+ cairo_region_t *region;
cairo_int_status_t status;
if (clip->all_clipped)
@@ -357,20 +357,19 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
if (status)
return status;
- if (clip->has_region) {
- status = _cairo_region_intersect (&clip->region,
- &clip->region,
- &region);
+ if (clip->region) {
+ status = _cairo_region_intersect (clip->region, region);
} else {
- status = _cairo_region_copy (&clip->region, &region);
- if (status == CAIRO_STATUS_SUCCESS)
- clip->has_region = TRUE;
+ clip->region = _cairo_region_copy (region);
+
+ if ((status = _cairo_region_status (clip->region)))
+ clip->region = NULL;
}
clip->serial = _cairo_surface_allocate_clip_serial (target);
- _cairo_region_fini (&region);
+ _cairo_region_destroy (region);
- if (! _cairo_region_not_empty (&clip->region))
+ if (!clip->region || ! _cairo_region_not_empty (clip->region))
_cairo_clip_set_all_clipped (clip, target);
return status;
@@ -727,8 +726,8 @@ _cairo_clip_translate (cairo_clip_t *clip,
if (clip->all_clipped)
return;
- if (clip->has_region) {
- _cairo_region_translate (&clip->region,
+ if (clip->region) {
+ _cairo_region_translate (clip->region,
_cairo_fixed_integer_part (tx),
_cairo_fixed_integer_part (ty));
}
@@ -785,9 +784,9 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
/* We should reapply the original clip path in this case, and let
* whatever the right handling is happen */
} else {
- if (other->has_region) {
- status = _cairo_region_copy (&clip->region, &other->region);
- if (unlikely (status))
+ if (other->region) {
+ clip->region = _cairo_region_copy (other->region);
+ if (unlikely ((status = _cairo_region_status (clip->region))))
goto BAIL;
clip->has_region = TRUE;
@@ -822,8 +821,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
return CAIRO_STATUS_SUCCESS;
BAIL:
- if (clip->has_region)
- _cairo_region_fini (&clip->region);
+ if (clip->region)
+ _cairo_region_destroy (clip->region);
if (clip->surface)
cairo_surface_destroy (clip->surface);
@@ -874,10 +873,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
}
- if (clip->has_region) {
+ if (clip->region) {
int i;
- n_boxes = _cairo_region_num_boxes (&clip->region);
+ n_boxes = _cairo_region_num_boxes (clip->region);
if (n_boxes) {
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
@@ -890,7 +889,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
cairo_box_int_t box;
cairo_rectangle_int_t clip_rect;
- _cairo_region_get_box (&clip->region, i, &box);
+ _cairo_region_get_box (clip->region, i, &box);
clip_rect.x = box.p1.x;
clip_rect.y = box.p1.y;
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index d969116a9..f762fea70 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -47,27 +47,32 @@ CAIRO_BEGIN_DECLS
/* #cairo_region_t is defined in cairoint.h */
struct _cairo_region {
+ cairo_status_t status;
+
pixman_region32_t rgn;
};
-cairo_private void
-_cairo_region_init (cairo_region_t *region);
+cairo_private cairo_region_t *
+_cairo_region_create (void);
+
+cairo_private cairo_region_t *
+_cairo_region_create_rect (cairo_rectangle_int_t *rect);
+
+cairo_private cairo_status_t
+_cairo_region_status (cairo_region_t *region);
cairo_private void
-_cairo_region_init_rect (cairo_region_t *region,
- cairo_rectangle_int_t *rect);
+_cairo_region_clear (cairo_region_t *region);
-cairo_private cairo_int_status_t
-_cairo_region_init_boxes (cairo_region_t *region,
- cairo_box_int_t *boxes,
- int count);
+cairo_private cairo_region_t *
+_cairo_region_create_boxes (cairo_box_int_t *boxes,
+ int count);
cairo_private void
-_cairo_region_fini (cairo_region_t *region);
+_cairo_region_destroy (cairo_region_t *region);
-cairo_private cairo_int_status_t
-_cairo_region_copy (cairo_region_t *dst,
- cairo_region_t *src);
+cairo_private cairo_region_t *
+_cairo_region_copy (cairo_region_t *original);
cairo_private int
_cairo_region_num_boxes (cairo_region_t *region);
@@ -81,19 +86,16 @@ cairo_private void
_cairo_region_get_extents (cairo_region_t *region,
cairo_rectangle_int_t *extents);
-cairo_private cairo_int_status_t
+cairo_private cairo_status_t
_cairo_region_subtract (cairo_region_t *dst,
- cairo_region_t *a,
- cairo_region_t *b);
+ cairo_region_t *other);
-cairo_private cairo_int_status_t
+cairo_private cairo_status_t
_cairo_region_intersect (cairo_region_t *dst,
- cairo_region_t *a,
- cairo_region_t *b);
+ cairo_region_t *other);
-cairo_private cairo_int_status_t
+cairo_private cairo_status_t
_cairo_region_union_rect (cairo_region_t *dst,
- cairo_region_t *src,
cairo_rectangle_int_t *rect);
cairo_private cairo_bool_t
diff --git a/src/cairo-region.c b/src/cairo-region.c
index d32805e82..804c64d74 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -33,39 +33,68 @@
* Contributor(s):
* Owen Taylor <otaylor@redhat.com>
* Vladimir Vukicevic <vladimir@pobox.com>
+ * Søren Sandmann <sandmann@daimi.au.dk>
*/
#include "cairoint.h"
-void
-_cairo_region_init (cairo_region_t *region)
+const cairo_region_t _cairo_region_nil = {
+ CAIRO_STATUS_NO_MEMORY, /* status */
+};
+
+cairo_region_t *
+_cairo_region_create (void)
{
+ cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t));
+
+ if (!region)
+ return (cairo_region_t *)&_cairo_region_nil;
+
+ region->status = CAIRO_STATUS_SUCCESS;
+
pixman_region32_init (&region->rgn);
+
+ return region;
}
-void
-_cairo_region_init_rect (cairo_region_t *region,
- cairo_rectangle_int_t *rect)
+cairo_region_t *
+_cairo_region_create_rect (cairo_rectangle_int_t *rect)
{
+ cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t));
+
+ if (!region)
+ return (cairo_region_t *)&_cairo_region_nil;
+
+ region->status = CAIRO_STATUS_SUCCESS;
+
pixman_region32_init_rect (&region->rgn,
- rect->x, rect->y,
- rect->width, rect->height);
+ rect->x, rect->y,
+ rect->width, rect->height);
+
+ return region;
}
-cairo_int_status_t
-_cairo_region_init_boxes (cairo_region_t *region,
- cairo_box_int_t *boxes,
- int count)
+cairo_region_t *
+_cairo_region_create_boxes (cairo_box_int_t *boxes,
+ int count)
{
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
pixman_box32_t *pboxes = stack_pboxes;
- cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_region_t *region;
int i;
+ region = _cairo_malloc (sizeof (cairo_region_t));
+
+ if (!region)
+ return (cairo_region_t *)&_cairo_region_nil;
+
if (count > ARRAY_LENGTH (stack_pboxes)) {
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
- if (unlikely (pboxes == NULL))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ if (unlikely (pboxes == NULL)) {
+ free (region);
+ return (cairo_region_t *)&_cairo_region_nil;
+ }
}
for (i = 0; i < count; i++) {
@@ -75,26 +104,45 @@ _cairo_region_init_boxes (cairo_region_t *region,
pboxes[i].y2 = boxes[i].p2.y;
}
- if (! pixman_region32_init_rects (&region->rgn, pboxes, count))
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ 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 status;
+ return region;
}
void
-_cairo_region_fini (cairo_region_t *region)
+_cairo_region_destroy (cairo_region_t *region)
{
+ if (region->status)
+ return;
+
pixman_region32_fini (&region->rgn);
+ free (region);
}
-cairo_int_status_t
-_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
+cairo_region_t *
+_cairo_region_copy (cairo_region_t *original)
{
- if (!pixman_region32_copy (&dst->rgn, &src->rgn))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ cairo_region_t *copy;
+
+ if (original->status)
+ return (cairo_region_t *)&_cairo_region_nil;
+
+ copy = _cairo_region_create ();
+ if (!copy)
+ return (cairo_region_t *)&_cairo_region_nil;
+
+ if (!pixman_region32_copy (&copy->rgn, &original->rgn)) {
+ _cairo_region_destroy (copy);
+
+ return (cairo_region_t *)&_cairo_region_nil;
+ }
return CAIRO_STATUS_SUCCESS;
}
@@ -102,6 +150,9 @@ _cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
int
_cairo_region_num_boxes (cairo_region_t *region)
{
+ if (region->status)
+ return 0;
+
return pixman_region32_n_rects (&region->rgn);
}
@@ -112,6 +163,9 @@ _cairo_region_get_box (cairo_region_t *region,
{
pixman_box32_t *pbox;
+ if (region->status)
+ return;
+
pbox = pixman_region32_rectangles (&region->rgn, NULL) + nth_box;
box->p1.x = pbox->x1;
@@ -128,9 +182,15 @@ _cairo_region_get_box (cairo_region_t *region,
* Gets the bounding box of a region as a #cairo_rectangle_int_t
**/
void
-_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
+_cairo_region_get_extents (cairo_region_t *region,
+ cairo_rectangle_int_t *extents)
{
- pixman_box32_t *pextents = pixman_region32_extents (&region->rgn);
+ pixman_box32_t *pextents;
+
+ if (region->status || !extents)
+ return;
+
+ pextents = pixman_region32_extents (&region->rgn);
extents->x = pextents->x1;
extents->y = pextents->y1;
@@ -138,33 +198,62 @@ _cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extent
extents->height = pextents->y2 - pextents->y1;
}
-cairo_int_status_t
-_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
+cairo_status_t
+_cairo_region_status (cairo_region_t *region)
+{
+ return region->status;
+}
+
+void
+_cairo_region_clear (cairo_region_t *region)
+{
+ if (region->status)
+ return;
+
+ pixman_region32_fini (&region->rgn);
+ pixman_region32_init (&region->rgn);
+}
+
+cairo_status_t
+_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other)
{
- if (!pixman_region32_subtract (&dst->rgn, &a->rgn, &b->rgn))
+ if (dst->status)
+ return dst->status;
+
+ if (other->status)
+ return other->status;
+
+ if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
}
-cairo_int_status_t
-_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
+cairo_status_t
+_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other)
{
- if (!pixman_region32_intersect (&dst->rgn, &a->rgn, &b->rgn))
+ if (dst->status)
+ return dst->status;
+
+ 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_STATUS_SUCCESS;
}
-cairo_int_status_t
+cairo_status_t
_cairo_region_union_rect (cairo_region_t *dst,
- cairo_region_t *src,
cairo_rectangle_int_t *rect)
{
- if (!pixman_region32_union_rect (&dst->rgn, &src->rgn,
- rect->x, rect->y,
- rect->width, rect->height))
+ if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn,
+ rect->x, rect->y,
+ rect->width, rect->height))
+ {
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
return CAIRO_STATUS_SUCCESS;
}
@@ -172,6 +261,9 @@ _cairo_region_union_rect (cairo_region_t *dst,
cairo_bool_t
_cairo_region_not_empty (cairo_region_t *region)
{
+ if (region->status)
+ return FALSE;
+
return (cairo_bool_t) pixman_region32_not_empty (&region->rgn);
}
@@ -179,6 +271,9 @@ void
_cairo_region_translate (cairo_region_t *region,
int x, int y)
{
+ if (region->status)
+ return;
+
pixman_region32_translate (&region->rgn, x, y);
}
@@ -188,6 +283,9 @@ _cairo_region_contains_rectangle (cairo_region_t *region,
{
pixman_box32_t pbox;
+ if (region->status)
+ return PIXMAN_REGION_OUT;
+
pbox.x1 = rect->x;
pbox.y1 = rect->y;
pbox.x2 = rect->x + rect->width;
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 7c38cbdfe..da2f9438b 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -520,10 +520,8 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
cairo_antialias_t antialias)
{
cairo_status_t status;
- cairo_region_t trap_region;
- cairo_region_t clear_region;
- cairo_bool_t has_trap_region = FALSE;
- cairo_bool_t has_clear_region = FALSE;
+ cairo_region_t *trap_region = NULL;
+ cairo_region_t *clear_region = NULL;
cairo_rectangle_int_t extents;
cairo_composite_traps_info_t traps_info;
@@ -535,23 +533,18 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
return status;
status = _cairo_traps_extract_region (traps, &trap_region);
- if (CAIRO_INT_STATUS_UNSUPPORTED == status) {
- has_trap_region = FALSE;
- } else if (status) {
- return status;
- } else {
- has_trap_region = TRUE;
- }
+ if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t trap_extents;
- if (has_trap_region) {
- status = _cairo_clip_intersect_to_region (clip, &trap_region);
+ if (trap_region) {
+ status = _cairo_clip_intersect_to_region (clip, trap_region);
if (unlikely (status))
goto out;
- _cairo_region_get_extents (&trap_region, &trap_extents);
+ _cairo_region_get_extents (trap_region, &trap_extents);
} else {
cairo_box_t trap_box;
_cairo_traps_extents (traps, &trap_box);
@@ -569,27 +562,30 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
} else {
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
- if (has_trap_region && !clip_surface) {
+ if (trap_region && !clip_surface) {
/* If we optimize drawing with an unbounded operator to
* _cairo_surface_fill_rectangles() or to drawing with a
* clip region, then we have an additional region to clear.
*/
- _cairo_region_init_rect (&clear_region, &extents);
+ clear_region = _cairo_region_create_rect (&extents);
+
+ status = _cairo_region_status (clear_region);
+ if (unlikely (status))
+ goto out;
- has_clear_region = TRUE;
- status = _cairo_clip_intersect_to_region (clip, &clear_region);
+ status = _cairo_clip_intersect_to_region (clip, clear_region);
if (unlikely (status))
goto out;
- _cairo_region_get_extents (&clear_region, &extents);
+ _cairo_region_get_extents (clear_region, &extents);
- status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
+ status = _cairo_region_subtract (clear_region, trap_region);
if (unlikely (status))
goto out;
- if (!_cairo_region_not_empty (&clear_region)) {
- _cairo_region_fini (&clear_region);
- has_clear_region = FALSE;
+ if (!_cairo_region_not_empty (clear_region)) {
+ _cairo_region_destroy (clear_region);
+ clear_region = NULL;
}
} else {
status = _cairo_clip_intersect_to_rectangle (clip, &extents);
@@ -599,7 +595,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
if (unlikely (status))
goto out;
- if (has_trap_region) {
+ if (trap_region) {
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
if ((src->type == CAIRO_PATTERN_TYPE_SOLID ||
@@ -613,12 +609,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
}
/* Solid rectangles special case */
- status = _cairo_surface_fill_region (dst, op, color, &trap_region);
+ status = _cairo_surface_fill_region (dst, op, color, trap_region);
- if (!status && has_clear_region)
+ if (!status && clear_region) {
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
- &clear_region);
+ clear_region);
+ }
goto out;
}
@@ -641,13 +638,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
* regions. In that case, we fall through.
*/
status = _composite_trap_region (clip, src, op, dst,
- &trap_region, &extents);
+ trap_region, &extents);
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
- if (!status && has_clear_region)
+ if (!status && clear_region)
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
- &clear_region);
+ clear_region);
goto out;
}
}
@@ -661,10 +658,10 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
&traps_info, dst, &extents);
out:
- if (has_trap_region)
- _cairo_region_fini (&trap_region);
- if (has_clear_region)
- _cairo_region_fini (&clear_region);
+ if (trap_region)
+ _cairo_region_destroy (trap_region);
+ if (clear_region)
+ _cairo_region_destroy (clear_region);
return status;
}
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 456f85182..22e67f71e 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2201,10 +2201,10 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
cairo_status_t
_cairo_surface_set_clip_region (cairo_surface_t *surface,
cairo_region_t *region,
- unsigned int serial)
+ unsigned int serial)
{
cairo_status_t status;
-
+
if (surface->status)
return surface->status;
@@ -2381,7 +2381,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
if (surface->backend->set_clip_region != NULL)
return _cairo_surface_set_clip_region (surface,
- &clip->region,
+ clip->region,
clip->serial);
} else {
if (clip->path)
@@ -2391,7 +2391,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
if (clip->has_region)
return _cairo_surface_set_clip_region (surface,
- &clip->region,
+ clip->region,
clip->serial);
}
}
@@ -2689,8 +2689,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
cairo_rectangle_int_t dst_rectangle;
cairo_rectangle_int_t drawn_rectangle;
cairo_bool_t has_drawn_region = FALSE;
- cairo_region_t drawn_region;
- cairo_region_t clear_region;
+ cairo_region_t *drawn_region = NULL;
+ cairo_region_t *clear_region = NULL;
cairo_status_t status;
/* The area that was drawn is the area in the destination rectangle but not within
@@ -2700,7 +2700,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
dst_rectangle.y = dst_y;
dst_rectangle.width = width;
dst_rectangle.height = height;
- _cairo_region_init_rect (&clear_region, &dst_rectangle);
+
+ clear_region = _cairo_region_create_rect (&dst_rectangle);
drawn_rectangle = dst_rectangle;
@@ -2716,24 +2717,22 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
/* Now compute the area that is in dst_rectangle but not in drawn_rectangle
*/
- _cairo_region_init_rect (&drawn_region, &drawn_rectangle);
+ drawn_region = _cairo_region_create_rect (&drawn_rectangle);
has_drawn_region = TRUE;
- status = _cairo_region_subtract (&clear_region,
- &clear_region,
- &drawn_region);
+ status = _cairo_region_subtract (clear_region, drawn_region);
if (unlikely (status))
goto CLEANUP_REGIONS;
EMPTY:
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
CAIRO_COLOR_TRANSPARENT,
- &clear_region);
+ clear_region);
CLEANUP_REGIONS:
- if (has_drawn_region)
- _cairo_region_fini (&drawn_region);
- _cairo_region_fini (&clear_region);
+ if (drawn_region)
+ _cairo_region_destroy (drawn_region);
+ _cairo_region_destroy (clear_region);
return _cairo_surface_set_error (dst, status);
}
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 0afdce23a..3b6dedf7c 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -608,7 +608,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
**/
cairo_int_status_t
_cairo_traps_extract_region (const cairo_traps_t *traps,
- cairo_region_t *region)
+ cairo_region_t **region)
{
cairo_box_int_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_int_t)];
cairo_box_int_t *boxes = stack_boxes;
@@ -616,7 +616,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
cairo_int_status_t status;
if (traps->num_traps == 0) {
- _cairo_region_init (region);
+ *region = _cairo_region_create ();
return CAIRO_STATUS_SUCCESS;
}
@@ -661,13 +661,17 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
box_count++;
}
- status = _cairo_region_init_boxes (region, boxes, box_count);
-
+ *region = _cairo_region_create_boxes (boxes, box_count);
+ status = _cairo_region_status (*region);
+
if (boxes != stack_boxes)
free (boxes);
if (unlikely (status))
- _cairo_region_fini (region);
+ {
+ _cairo_region_destroy (*region);
+ *region = NULL;
+ }
return status;
}
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index f86a133ef..e3a1417ab 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2293,7 +2293,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
XRectangle *rects = NULL;
int n_boxes, i;
cairo_rectangle_int_t rect;
- cairo_region_t bounded;
+ cairo_region_t *bounded;
rect.x = rect.y = 0;
rect.width = surface->width;
@@ -2303,19 +2303,19 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
* is necessary so we don't wrap around when we convert cairo's
* 32 bit region into 16 bit rectangles.
*/
- _cairo_region_init_rect (&bounded, &rect);
- status = _cairo_region_intersect (&bounded, &bounded, region);
+ bounded = _cairo_region_create_rect (&rect);
+ status = _cairo_region_intersect (bounded, region);
if (unlikely (status)) {
- _cairo_region_fini (&bounded);
+ _cairo_region_destroy (bounded);
return status;
}
- n_boxes = _cairo_region_num_boxes (&bounded);
+ n_boxes = _cairo_region_num_boxes (bounded);
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
if (unlikely (rects == NULL)) {
- _cairo_region_fini (&bounded);
+ _cairo_region_destroy (bounded);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
} else {
@@ -2325,7 +2325,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
for (i = 0; i < n_boxes; i++) {
cairo_box_int_t box;
- _cairo_region_get_box (&bounded, i, &box);
+ _cairo_region_get_box (bounded, i, &box);
rects[i].x = box.p1.x;
rects[i].y = box.p1.y;
@@ -2333,7 +2333,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
rects[i].height = box.p2.y - rects[i].y;
}
- _cairo_region_fini (&bounded);
+ _cairo_region_destroy (bounded);
surface->have_clip_rects = TRUE;
surface->clip_rects = rects;
diff --git a/src/cairoint.h b/src/cairoint.h
index 66a9726ed..30273c224 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2408,7 +2408,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
cairo_private cairo_int_status_t
_cairo_traps_extract_region (const cairo_traps_t *tr,
- cairo_region_t *region);
+ cairo_region_t **region);
cairo_private cairo_status_t
_cairo_traps_path (const cairo_traps_t *traps,