[cairo] Cairo and layered application
Mathias Hasselmann
mathias.hasselmann at gmx.de
Thu Mar 8 21:50:16 PST 2007
Hi,
Resending as I was using the wrong sender address. I really start
hating Evo for not properly supporting mailing lists... :-(
> > pixman_region_create_simple
> > pixman_region_create
> > cairo_traps_extract_region
> > clip_and_composite_trapezoids
> > cairo_surface_fallback_fill
> > cairo_traps_extract_region
> > clip_and_composite_trapezoids
> > cairo_surface_fallback_fill
Behdad: Attached there is a patch removing malloc in this case.
Still needs testing and at some places I accidently removed
pixman_region_destroy instead of replacing it by pixman_region_uninit by
accident. But it is too late here, to fix and test it now, so I defer to
tomorrow. Usually work better when my mind is fresh.
Ciao,
Mathias
-------------- next part --------------
>From b1db42d981705867cc917000d0743845c1fe1716 Mon Sep 17 00:00:00 2001
From: (null) <(null)>
Date: Fri, 9 Mar 2007 01:41:08 +0100
Subject: [PATCH] Avoid alloc in _cairo_pixman_region_create_simple
---
pixman/src/pixman.h | 12 ++-
pixman/src/pixregion.c | 18 +--
pixman/src/pixregionint.h | 7 +-
src/cairo-clip-private.h | 3 +-
src/cairo-clip.c | 125 +++++++++------------
src/cairo-region.c | 34 +++---
src/cairo-surface-fallback.c | 249 +++++++++++++++++++++---------------------
src/cairo-surface.c | 42 +++-----
src/cairo-traps.c | 15 +--
src/cairoint.h | 11 +-
10 files changed, 241 insertions(+), 275 deletions(-)
diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h
index 7f0ef32..8428543 100644
--- a/pixman/src/pixman.h
+++ b/pixman/src/pixman.h
@@ -113,12 +113,17 @@ extern "C" {
/* pixregion.h */
-typedef struct pixman_region16 pixman_region16_t;
+typedef struct pixman_region16_data pixman_region16_data_t;
typedef struct pixman_box16 {
short x1, y1, x2, y2;
} pixman_box16_t;
+typedef struct pixman_region16 {
+ pixman_box16_t extents;
+ pixman_region16_data_t *data;
+} pixman_region16_t;
+
typedef enum {
PIXMAN_REGION_STATUS_FAILURE,
PIXMAN_REGION_STATUS_SUCCESS
@@ -133,6 +138,11 @@ pixman_private pixman_region16_t *
pixman_region_create_simple (pixman_box16_t *extents);
pixman_private void
+pixman_region_init(pixman_region16_t *region, pixman_box16_t *extents);
+pixman_private void
+pixman_region_uninit (pixman_region16_t *region);
+
+pixman_private void
pixman_region_destroy (pixman_region16_t *region);
/* manipulation */
diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c
index 0404dff..f710294 100644
--- a/pixman/src/pixregion.c
+++ b/pixman/src/pixregion.c
@@ -82,12 +82,6 @@ static pixman_region16_t pixman_brokenregion = { { 0, 0, 0, 0 }, &pixman_broke
static pixman_region_status_t
pixman_break (pixman_region16_t *pReg);
-static void
-pixman_init (pixman_region16_t *region, pixman_box16_t *rect);
-
-static void
-pixman_uninit (pixman_region16_t *region);
-
/*
* The functions in this file implement the Region abstraction used extensively
* throughout the X11 sample server. A Region is simply a set of disjoint
@@ -318,7 +312,7 @@ pixman_region_create_simple (pixman_box16_t *extents)
if (region == NULL)
return &pixman_brokenregion;
- pixman_init (region, extents);
+ pixman_region_init (region, extents);
return region;
}
@@ -328,8 +322,8 @@ pixman_region_create_simple (pixman_box16_t *extents)
* Outer region rect is statically allocated.
*****************************************************************/
-static void
-pixman_init(pixman_region16_t *region, pixman_box16_t *extents)
+void
+pixman_region_init(pixman_region16_t *region, pixman_box16_t *extents)
{
if (extents)
{
@@ -343,8 +337,8 @@ pixman_init(pixman_region16_t *region, pixman_box16_t *extents)
}
}
-static void
-pixman_uninit (pixman_region16_t *region)
+void
+pixman_region_uninit (pixman_region16_t *region)
{
good (region);
freeData (region);
@@ -353,7 +347,7 @@ pixman_uninit (pixman_region16_t *region)
void
pixman_region_destroy (pixman_region16_t *region)
{
- pixman_uninit (region);
+ pixman_region_uninit (region);
if (region != &pixman_brokenregion)
free (region);
diff --git a/pixman/src/pixregionint.h b/pixman/src/pixregionint.h
index b5b53fd..385a7f2 100644
--- a/pixman/src/pixregionint.h
+++ b/pixman/src/pixregionint.h
@@ -48,16 +48,11 @@ SOFTWARE.
#include "pixman.h"
-typedef struct pixman_region16_data {
+struct pixman_region16_data {
long size;
long numRects;
/* XXX: And why, exactly, do we have this bogus struct definition? */
/* pixman_box16_t rects[size]; in memory but not explicitly declared */
-} pixman_region16_data_t;
-
-struct pixman_region16 {
- pixman_box16_t extents;
- pixman_region16_data_t *data;
};
typedef struct pixman_region16_point {
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 3c4ff0d..381c003 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -72,7 +72,8 @@ struct _cairo_clip {
/*
* A clip region that can be placed in the surface
*/
- pixman_region16_t *region;
+ pixman_region16_t region;
+ cairo_bool_t has_region;
/*
* If the surface supports path clipping, we store the list of
* clipping paths that has been set here as a linked list.
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 605589b..a1d4d0a 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -58,7 +58,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
clip->serial = 0;
- clip->region = NULL;
+ clip->has_region = FALSE;
clip->path = NULL;
}
@@ -71,9 +71,10 @@ _cairo_clip_fini (cairo_clip_t *clip)
clip->serial = 0;
- if (clip->region)
- pixman_region_destroy (clip->region);
- clip->region = NULL;
+ if (clip->has_region) {
+ pixman_region_uninit (&clip->region);
+ clip->has_region = FALSE;
+ }
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
@@ -89,11 +90,11 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
clip->serial = other->serial;
- if (other->region == NULL) {
- clip->region = other->region;
+ if (other->has_region) {
+ pixman_region_copy (&clip->region, &other->region);
+ clip->has_region = TRUE;
} else {
- clip->region = pixman_region_create ();
- pixman_region_copy (clip->region, other->region);
+ clip->has_region = FALSE;
}
clip->path = _cairo_clip_path_reference (other->path);
@@ -108,9 +109,10 @@ _cairo_clip_reset (cairo_clip_t *clip)
clip->serial = 0;
- if (clip->region)
- pixman_region_destroy (clip->region);
- clip->region = NULL;
+ if (clip->has_region) {
+ pixman_region_uninit (&clip->region);
+ clip->has_region = FALSE;
+ }
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
@@ -167,27 +169,19 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
return status;
}
- if (clip->region) {
- pixman_region16_t *intersection;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- pixman_region_status_t pixman_status;
+ if (clip->has_region) {
+ pixman_region16_t intersection;
- intersection = _cairo_region_create_from_rectangle (rectangle);
- if (intersection == NULL)
+ if (_cairo_region_init_from_rectangle (&intersection, rectangle))
return CAIRO_STATUS_NO_MEMORY;
- pixman_status = pixman_region_intersect (intersection,
- clip->region,
- intersection);
- if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
- _cairo_region_extents_rectangle (intersection, rectangle);
- else
- status = CAIRO_STATUS_NO_MEMORY;
-
- pixman_region_destroy (intersection);
+ if (PIXMAN_REGION_STATUS_SUCCESS !=
+ pixman_region_intersect (&intersection, &clip->region,
+ &intersection))
+ return CAIRO_STATUS_NO_MEMORY;
- if (status)
- return status;
+ _cairo_region_extents_rectangle (&intersection, rectangle);
+ return CAIRO_STATUS_SUCCESS;
}
if (clip->surface)
@@ -207,28 +201,18 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
/* Intersect clip path into region. */
}
- if (clip->region)
- pixman_region_intersect (region, clip->region, region);
+ if (clip->has_region)
+ pixman_region_intersect (region, &clip->region, region);
if (clip->surface) {
- pixman_region16_t *clip_rect;
- pixman_region_status_t pixman_status;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ pixman_region16_t clip_rect;
- clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
- if (clip_rect == NULL)
+ if (_cairo_region_init_from_rectangle (&clip_rect, &clip->surface_rect))
return CAIRO_STATUS_NO_MEMORY;
- pixman_status = pixman_region_intersect (region,
- clip_rect,
- region);
- if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
- status = CAIRO_STATUS_NO_MEMORY;
-
- pixman_region_destroy (clip_rect);
-
- if (status)
- return status;
+ if (PIXMAN_REGION_STATUS_SUCCESS !=
+ pixman_region_intersect (region, &clip_rect, region))
+ return CAIRO_STATUS_NO_MEMORY;
}
return CAIRO_STATUS_SUCCESS;
@@ -326,39 +310,36 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
free (clip_path);
}
-static cairo_status_t
+static cairo_int_status_t
_cairo_clip_intersect_region (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_surface_t *target)
{
- pixman_region16_t *region;
- cairo_status_t status;
+ pixman_region16_t region;
+ cairo_int_status_t status;
if (clip->mode != CAIRO_CLIP_MODE_REGION)
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_traps_extract_region (traps, ®ion);
+
if (status)
return status;
- if (region == NULL)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
status = CAIRO_STATUS_SUCCESS;
- if (clip->region == NULL) {
- clip->region = region;
+
+ if (!clip->has_region) {
+ pixman_region_copy (&clip->region, ®ion);
+ clip->has_region = TRUE;
} else {
- pixman_region16_t *intersection = pixman_region_create();
-
- if (pixman_region_intersect (intersection,
- clip->region, region)
- == PIXMAN_REGION_STATUS_SUCCESS) {
- pixman_region_destroy (clip->region);
- clip->region = intersection;
- } else {
- status = CAIRO_STATUS_NO_MEMORY;
- }
- pixman_region_destroy (region);
+ pixman_region16_t intersection;
+ pixman_region_init (&intersection, NULL);
+
+ if (PIXMAN_REGION_STATUS_SUCCESS !=
+ pixman_region_intersect (&intersection, &clip->region, ®ion))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ pixman_region_copy (&clip->region, &intersection);
}
clip->serial = _cairo_surface_allocate_clip_serial (target);
@@ -506,8 +487,8 @@ _cairo_clip_translate (cairo_clip_t *clip,
cairo_fixed_t tx,
cairo_fixed_t ty)
{
- if (clip->region) {
- pixman_region_translate (clip->region,
+ if (clip->has_region) {
+ pixman_region_translate (&clip->region,
_cairo_fixed_integer_part (tx),
_cairo_fixed_integer_part (ty));
}
@@ -557,9 +538,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->region) {
- clip->region = pixman_region_create ();
- pixman_region_copy (clip->region, other->region);
+ if (other->has_region) {
+ pixman_region_copy (&clip->region, &other->region);
+ clip->has_region = TRUE;
}
if (other->surface) {
@@ -610,16 +591,16 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
if (clip->path || clip->surface)
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
- n_boxes = clip->region ? pixman_region_num_rects (clip->region) : 1;
+ n_boxes = clip->has_region ? pixman_region_num_rects (&clip->region) : 1;
rectangles = malloc (sizeof (cairo_rectangle_t)*n_boxes);
if (rectangles == NULL)
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
- if (clip->region) {
+ if (clip->has_region) {
pixman_box16_t *boxes;
int i;
- boxes = pixman_region_rects (clip->region);
+ boxes = pixman_region_rects (&clip->region);
for (i = 0; i < n_boxes; ++i) {
if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
boxes[i].x2 - boxes[i].x1,
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 057f9fe..ea06b9e 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -36,30 +36,28 @@
#include <cairoint.h>
/**
- * _cairo_region_create_from_rectangle:
+ * _cairo_region_init_from_rectangle:
+ * @region: a #pixman_region16_t
* @rect: a #cairo_rectangle_int16_t
*
- * Creates a region with extents initialized from the given
- * rectangle.
+ * Initializes a region with extents from the given rectangle.
*
- * Return value: a newly created #pixman_region16_t or %NULL if
- * memory couldn't a allocated.
+ * Return value: #CAIRO_STATUS_SUCCESS on success, or
+ * #CAIRO_INT_STATUS_UNSUPPORTED if pixman failes to
+ * initialize the region.
**/
-pixman_region16_t *
-_cairo_region_create_from_rectangle (cairo_rectangle_int16_t *rect)
+cairo_int_status_t
+_cairo_region_init_from_rectangle (pixman_region16_t *region,
+ cairo_rectangle_int16_t *rect)
{
- /* We can't use pixman_region_create_simple(), because it doesn't
- * have an error return
- */
- pixman_region16_t *region = pixman_region_create ();
- if (pixman_region_union_rect (region, region,
- rect->x, rect->y,
- rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) {
- pixman_region_destroy (region);
- return NULL;
- }
+ pixman_region_init (region, NULL);
+
+ if (PIXMAN_REGION_STATUS_SUCCESS !=
+ pixman_region_union_rect (region, region, rect->x, rect->y,
+ rect->width, rect->height))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- return region;
+ return CAIRO_STATUS_SUCCESS;
}
/**
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 1a7d666..31f4a1a 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -511,147 +511,148 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
cairo_antialias_t antialias)
{
cairo_status_t status;
- pixman_region16_t *trap_region = NULL;
- pixman_region16_t *clear_region = NULL;
+ pixman_region16_t trap_region;
+ pixman_region16_t clear_region;
+ cairo_bool_t has_trap_region = FALSE;
+ cairo_bool_t has_clear_region = FALSE;
cairo_rectangle_int16_t extents;
cairo_composite_traps_info_t traps_info;
if (traps->num_traps == 0)
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_STATUS_SUCCESS;
status = _cairo_surface_get_extents (dst, &extents);
if (status)
- return status;
+ return status;
status = _cairo_traps_extract_region (traps, &trap_region);
- if (status)
- return status;
-
- if (_cairo_operator_bounded_by_mask (op))
- {
- cairo_rectangle_int16_t trap_extents;
- if (trap_region) {
- status = _cairo_clip_intersect_to_region (clip, trap_region);
- if (status)
- goto out;
-
- _cairo_region_extents_rectangle (trap_region, &trap_extents);
- } else {
- cairo_box_t trap_box;
- _cairo_traps_extents (traps, &trap_box);
- _cairo_box_round_to_rectangle (&trap_box, &trap_extents);
- }
- _cairo_rectangle_intersect (&extents, &trap_extents);
- status = _cairo_clip_intersect_to_rectangle (clip, &extents);
- if (status)
- goto out;
+ if (CAIRO_INT_STATUS_UNSUPPORTED == status) {
+ has_trap_region = FALSE;
+ } else if (status) {
+ return status;
+ } else {
+ has_trap_region = TRUE;
}
- else
- {
- cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
-
- 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.
- */
- clear_region = _cairo_region_create_from_rectangle (&extents);
- if (clear_region == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- status = _cairo_clip_intersect_to_region (clip, clear_region);
- if (status)
- return status;
-
- _cairo_region_extents_rectangle (clear_region, &extents);
-
- if (pixman_region_subtract (clear_region, clear_region, trap_region) != PIXMAN_REGION_STATUS_SUCCESS)
- return CAIRO_STATUS_NO_MEMORY;
-
- if (!pixman_region_not_empty (clear_region)) {
- pixman_region_destroy (clear_region);
- clear_region = NULL;
- }
- } else {
- status = _cairo_clip_intersect_to_rectangle (clip, &extents);
- if (status)
- return status;
- }
- }
-
- if (status)
- goto out;
- if (trap_region)
- {
- cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
-
- if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) &&
- !clip_surface)
- {
- const cairo_color_t *color;
-
- if (op == CAIRO_OPERATOR_CLEAR)
- color = CAIRO_COLOR_TRANSPARENT;
- else
- color = &((cairo_solid_pattern_t *)src)->color;
-
- /* Solid rectangles special case */
- status = _cairo_surface_fill_region (dst, op, color, trap_region);
- if (!status && clear_region)
- status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
- CAIRO_COLOR_TRANSPARENT,
- clear_region);
-
- goto out;
- }
-
- if ((_cairo_operator_bounded_by_mask (op) && op != CAIRO_OPERATOR_SOURCE) ||
- !clip_surface)
- {
- /* For a simple rectangle, we can just use composite(), for more
- * rectangles, we have to set a clip region. The cost of rasterizing
- * trapezoids is pretty high for most backends currently, so it's
- * worthwhile even if a region is needed.
- *
- * If we have a clip surface, we set it as the mask; this only works
- * for bounded operators other than SOURCE; for unbounded operators,
- * clip and mask cannot be interchanged. For SOURCE, the operator
- * as implemented by the backends is different in it's handling
- * of the mask then what we want.
- *
- * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has
- * more than rectangle and the destination doesn't support clip
- * regions. In that case, we fall through.
- */
- status = _composite_trap_region (clip, src, op, dst,
- trap_region, &extents);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- {
- if (!status && clear_region)
- status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
- CAIRO_COLOR_TRANSPARENT,
- clear_region);
- goto out;
- }
- }
+ if (_cairo_operator_bounded_by_mask (op)) {
+ cairo_rectangle_int16_t trap_extents;
+
+ if (has_trap_region) {
+ status = _cairo_clip_intersect_to_region (clip, &trap_region);
+
+ if (status)
+ return status;
+
+ _cairo_region_extents_rectangle (&trap_region, &trap_extents);
+ } else {
+ cairo_box_t trap_box;
+ _cairo_traps_extents (traps, &trap_box);
+ _cairo_box_round_to_rectangle (&trap_box, &trap_extents);
+ }
+
+ _cairo_rectangle_intersect (&extents, &trap_extents);
+ status = _cairo_clip_intersect_to_rectangle (clip, &extents);
+
+ if (status)
+ return status;
+ } else {
+ cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
+
+ if (has_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.
+ */
+ if (_cairo_region_init_from_rectangle (&clear_region, &extents))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ status = _cairo_clip_intersect_to_region (clip, &clear_region);
+
+ if (status)
+ return status;
+
+ _cairo_region_extents_rectangle (&clear_region, &extents);
+
+ if (PIXMAN_REGION_STATUS_SUCCESS !=
+ pixman_region_subtract (&clear_region, &clear_region, &trap_region))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ has_clear_region = pixman_region_not_empty (&clear_region);
+
+ if (has_clear_region) {
+ status = _cairo_clip_intersect_to_rectangle (clip, &extents);
+
+ if (status)
+ return status;
+ }
+ }
+
+ if (status)
+ return status;
+
+ if (has_trap_region) {
+ cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
+
+ if ((src->type == CAIRO_PATTERN_TYPE_SOLID ||
+ op == CAIRO_OPERATOR_CLEAR) && !clip_surface) {
+ const cairo_color_t *color;
+
+ if (op == CAIRO_OPERATOR_CLEAR) {
+ color = CAIRO_COLOR_TRANSPARENT;
+ } else {
+ color = &((cairo_solid_pattern_t *)src)->color;
+ }
+
+ /* Solid rectangles special case */
+ status = _cairo_surface_fill_region (dst, op, color,
+ has_trap_region ? &trap_region : NULL);
+
+ if (!status && has_clear_region)
+ status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear_region);
+
+ return status;
+ }
+
+ if ((_cairo_operator_bounded_by_mask (op) &&
+ op != CAIRO_OPERATOR_SOURCE) || !clip_surface) {
+ /* For a simple rectangle, we can just use composite(), for more
+ * rectangles, we have to set a clip region. The cost of rasterizing
+ * trapezoids is pretty high for most backends currently, so it's
+ * worthwhile even if a region is needed.
+ *
+ * If we have a clip surface, we set it as the mask; this only works
+ * for bounded operators other than SOURCE; for unbounded operators,
+ * clip and mask cannot be interchanged. For SOURCE, the operator
+ * as implemented by the backends is different in it's handling
+ * of the mask then what we want.
+ *
+ * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has
+ * more than rectangle and the destination doesn't support clip
+ * regions. In that case, we fall through.
+ */
+ status = _composite_trap_region (clip, src, op, dst,
+ has_trap_region ? &trap_region : NULL,
+ &extents);
+
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+ if (!status && has_clear_region)
+ status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear_region);
+ return status;
+ }
+ }
+ }
}
traps_info.traps = traps;
traps_info.antialias = antialias;
- status = _clip_and_composite (clip, op, src,
- _composite_traps_draw_func, &traps_info,
- dst, &extents);
-
- out:
- if (trap_region)
- pixman_region_destroy (trap_region);
- if (clear_region)
- pixman_region_destroy (clear_region);
-
- return status;
+ return _clip_and_composite (clip, op, src, _composite_traps_draw_func,
+ &traps_info, dst, &extents);
}
cairo_status_t
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index ad9c52d..fdb6b51 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1702,9 +1702,9 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
clip->path,
clip->serial);
- if (clip->region)
+ if (clip->has_region)
return _cairo_surface_set_clip_region (surface,
- clip->region,
+ &clip->region,
clip->serial);
}
@@ -1867,9 +1867,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
{
cairo_rectangle_int16_t dst_rectangle;
cairo_rectangle_int16_t drawn_rectangle;
- pixman_region16_t *drawn_region;
- pixman_region16_t *clear_region;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ pixman_region16_t drawn_region;
+ pixman_region16_t clear_region;
/* The area that was drawn is the area in the destination rectangle but not within
* the source or the mask.
@@ -1882,36 +1881,23 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
drawn_rectangle = dst_rectangle;
if (src_rectangle)
- _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle);
+ _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle);
if (mask_rectangle)
- _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle);
+ _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle);
/* Now compute the area that is in dst_rectangle but not in drawn_rectangle
*/
- drawn_region = _cairo_region_create_from_rectangle (&drawn_rectangle);
- clear_region = _cairo_region_create_from_rectangle (&dst_rectangle);
- if (!drawn_region || !clear_region) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto CLEANUP_REGIONS;
- }
-
- if (pixman_region_subtract (clear_region, clear_region, drawn_region) != PIXMAN_REGION_STATUS_SUCCESS) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto CLEANUP_REGIONS;
- }
+ if (_cairo_region_init_from_rectangle (&drawn_region, &drawn_rectangle) ||
+ _cairo_region_init_from_rectangle (&clear_region, &dst_rectangle))
+ return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
- CAIRO_COLOR_TRANSPARENT,
- clear_region);
+ if (pixman_region_subtract (&clear_region, &clear_region, &drawn_region) != PIXMAN_REGION_STATUS_SUCCESS)
+ return CAIRO_STATUS_NO_MEMORY;
- CLEANUP_REGIONS:
- if (drawn_region)
- pixman_region_destroy (drawn_region);
- if (clear_region)
- pixman_region_destroy (clear_region);
-
- return status;
+ return _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
+ CAIRO_COLOR_TRANSPARENT,
+ &clear_region);
}
/**
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 9b3931f..d5aca93 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -937,9 +937,9 @@ _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents)
*
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
**/
-cairo_status_t
-_cairo_traps_extract_region (cairo_traps_t *traps,
- pixman_region16_t **region)
+cairo_int_status_t
+_cairo_traps_extract_region (cairo_traps_t *traps,
+ pixman_region16_t *region)
{
int i;
@@ -950,11 +950,10 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
&& _cairo_fixed_is_integer(traps->traps[i].bottom)
&& _cairo_fixed_is_integer(traps->traps[i].left.p1.x)
&& _cairo_fixed_is_integer(traps->traps[i].right.p1.x))) {
- *region = NULL;
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
- *region = pixman_region_create ();
+ pixman_region_init (region, NULL);
for (i = 0; i < traps->num_traps; i++) {
int x = _cairo_fixed_integer_part(traps->traps[i].left.p1.x);
@@ -969,9 +968,9 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
if (width == 0 || height == 0)
continue;
- if (pixman_region_union_rect (*region, *region,
+ if (pixman_region_union_rect (region, region,
x, y, width, height) != PIXMAN_REGION_STATUS_SUCCESS) {
- pixman_region_destroy (*region);
+ pixman_region_uninit (region);
return CAIRO_STATUS_NO_MEMORY;
}
}
diff --git a/src/cairoint.h b/src/cairoint.h
index c487a5d..69193a0 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2296,9 +2296,9 @@ _cairo_traps_contain (cairo_traps_t *traps, double x, double y);
cairo_private void
_cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents);
-cairo_private cairo_status_t
-_cairo_traps_extract_region (cairo_traps_t *tr,
- pixman_region16_t **region);
+cairo_private cairo_int_status_t
+_cairo_traps_extract_region (cairo_traps_t *tr,
+ pixman_region16_t *region);
cairo_private void
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
@@ -2402,8 +2402,9 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate);
/* cairo-region.c */
-cairo_private pixman_region16_t *
-_cairo_region_create_from_rectangle (cairo_rectangle_int16_t *rect);
+cairo_private cairo_int_status_t
+_cairo_region_init_from_rectangle (pixman_region16_t *region,
+ cairo_rectangle_int16_t *rect);
cairo_private void
_cairo_region_extents_rectangle (pixman_region16_t *region,
--
1.4.4.2
More information about the cairo
mailing list