diff options
author | Søren Sandmann <sandmann@redhat.com> | 2008-12-11 15:29:23 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-03-28 17:58:48 -0400 |
commit | e3e1b35eb9eb3cf90d882a7452580f9efe00b89a (patch) | |
tree | 8b453b46051067c8745636960a55bea3b1ab1123 | |
parent | c2c637cf1d89fc8fdcced4467d602a55ef0b14e0 (diff) | |
download | cairo-e3e1b35eb9eb3cf90d882a7452580f9efe00b89a.tar.gz |
[region] Make cairo_region_t a malloced object.
-rw-r--r-- | src/cairo-analysis-surface.c | 26 | ||||
-rw-r--r-- | src/cairo-clip-private.h | 2 | ||||
-rw-r--r-- | src/cairo-clip.c | 99 | ||||
-rw-r--r-- | src/cairo-region-private.h | 42 | ||||
-rw-r--r-- | src/cairo-region.c | 168 | ||||
-rw-r--r-- | src/cairo-surface-fallback.c | 65 | ||||
-rw-r--r-- | src/cairo-surface.c | 29 | ||||
-rw-r--r-- | src/cairo-traps.c | 14 | ||||
-rw-r--r-- | src/cairo-xlib-surface.c | 16 | ||||
-rw-r--r-- | src/cairoint.h | 2 |
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, - ®ion); + if (clip->region) { + status = _cairo_region_intersect (clip->region, region); } else { - status = _cairo_region_copy (&clip->region, ®ion); - 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 (®ion); + _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 (®ion->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 (®ion->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 (®ion->rgn, pboxes, count)) - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + 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 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 (®ion->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 (©->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 (®ion->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 (®ion->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 (®ion->rgn); + pixman_box32_t *pextents; + + if (region->status || !extents) + return; + + pextents = pixman_region32_extents (®ion->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 (®ion->rgn); + pixman_region32_init (®ion->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 (®ion->rgn); } @@ -179,6 +271,9 @@ void _cairo_region_translate (cairo_region_t *region, int x, int y) { + if (region->status) + return; + pixman_region32_translate (®ion->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, |