summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-analysis-surface-private.h4
-rw-r--r--src/cairo-analysis-surface.c4
-rw-r--r--src/cairo-clip-private.h4
-rw-r--r--src/cairo-clip.c182
-rw-r--r--src/cairo-directfb-surface.c25
-rw-r--r--src/cairo-glitz-surface.c65
-rw-r--r--src/cairo-image-surface.c4
-rw-r--r--src/cairo-pattern.c16
-rw-r--r--src/cairo-region-private.h105
-rw-r--r--src/cairo-region.c173
-rw-r--r--src/cairo-surface-fallback.c29
-rw-r--r--src/cairo-surface.c63
-rw-r--r--src/cairo-traps.c50
-rw-r--r--src/cairo-win32-surface.c28
-rw-r--r--src/cairo-xcb-surface.c26
-rw-r--r--src/cairo-xlib-surface.c28
-rw-r--r--src/cairoint.h38
-rw-r--r--src/test-paginated-surface.c2
18 files changed, 598 insertions, 248 deletions
diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h
index bb114538..056972ac 100644
--- a/src/cairo-analysis-surface-private.h
+++ b/src/cairo-analysis-surface-private.h
@@ -42,10 +42,10 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
int width,
int height);
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
cairo_private cairo_bool_t
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index ff7e7d8a..3dbc73cb 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -234,14 +234,14 @@ FAIL:
return NULL;
}
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
}
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
{
/* XXX */
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index fa394232..61559ce5 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -72,7 +72,7 @@ struct _cairo_clip {
/*
* A clip region that can be placed in the surface
*/
- pixman_region16_t region;
+ cairo_region_t region;
cairo_bool_t has_region;
/*
* If the surface supports path clipping, we store the list of
@@ -109,7 +109,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
cairo_private cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
- pixman_region16_t *region);
+ cairo_region_t *region);
cairo_private cairo_status_t
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index e670456e..f0fcaa04 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
@@ -61,7 +62,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
clip->serial = 0;
- pixman_region_init (&clip->region);
+ _cairo_region_init (&clip->region);
clip->has_region = FALSE;
clip->path = NULL;
@@ -77,11 +78,13 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
clip->serial = other->serial;
- pixman_region_init (&clip->region);
+ _cairo_region_init (&clip->region);
if (other->has_region) {
- if (!pixman_region_copy (&clip->region, &other->region)) {
- pixman_region_fini (&clip->region);
+ if (_cairo_region_copy (&clip->region, &other->region) !=
+ CAIRO_STATUS_SUCCESS)
+ {
+ _cairo_region_fini (&clip->region);
cairo_surface_destroy (clip->surface);
return CAIRO_STATUS_NO_MEMORY;
}
@@ -105,11 +108,11 @@ _cairo_clip_reset (cairo_clip_t *clip)
clip->serial = 0;
if (clip->has_region) {
- /* pixman_region_fini just releases the resources used but
+ /* _cairo_region_fini just releases the resources used but
* doesn't bother with leaving the region in a valid state.
- * So pixman_region_init has to be called afterwards. */
- pixman_region_fini (&clip->region);
- pixman_region_init (&clip->region);
+ * So _cairo_region_init has to be called afterwards. */
+ _cairo_region_fini (&clip->region);
+ _cairo_region_init (&clip->region);
clip->has_region = FALSE;
}
@@ -169,20 +172,17 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
if (clip->has_region) {
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- pixman_region16_t intersection;
+ cairo_region_t intersection;
- pixman_region_init_rect (&intersection,
- rectangle->x, rectangle->y,
- rectangle->width, rectangle->height);
+ _cairo_region_init_rect (&intersection, rectangle);
- if (!pixman_region_intersect (&intersection, &clip->region,
- &intersection)) {
- status = CAIRO_STATUS_NO_MEMORY;
- } else {
- _cairo_region_extents_rectangle (&intersection, rectangle);
- }
+ status = _cairo_region_intersect (&intersection, &clip->region,
+ &intersection);
+
+ if (!status)
+ _cairo_region_get_extents (&intersection, rectangle);
- pixman_region_fini (&intersection);
+ _cairo_region_fini (&intersection);
if (status)
return status;
@@ -196,8 +196,10 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
- pixman_region16_t *region)
+ cairo_region_t *region)
{
+ cairo_status_t status;
+
if (!clip)
return CAIRO_STATUS_SUCCESS;
@@ -206,22 +208,19 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
}
if (clip->has_region) {
- if (!pixman_region_intersect (region, &clip->region, region))
- return CAIRO_STATUS_NO_MEMORY;
+ status = _cairo_region_intersect (region, &clip->region, region);
+ if (status)
+ return status;
}
if (clip->surface) {
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- pixman_region16_t clip_rect;
+ cairo_region_t clip_rect;
- pixman_region_init_rect (&clip_rect,
- clip->surface_rect.x, clip->surface_rect.y,
- clip->surface_rect.width, clip->surface_rect.height);
+ _cairo_region_init_rect (&clip_rect, &clip->surface_rect);
- if (!pixman_region_intersect (region, &clip_rect, region))
- status = CAIRO_STATUS_NO_MEMORY;
+ status = _cairo_region_intersect (region, &clip_rect, region);
- pixman_region_fini (&clip_rect);
+ _cairo_region_fini (&clip_rect);
if (status)
return status;
@@ -327,7 +326,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_surface_t *target)
{
- pixman_region16_t region;
+ cairo_region_t region;
cairo_int_status_t status;
if (clip->mode != CAIRO_CLIP_MODE_REGION)
@@ -341,25 +340,25 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
status = CAIRO_STATUS_SUCCESS;
if (!clip->has_region) {
- if (pixman_region_copy (&clip->region, &region))
+ status = _cairo_region_copy (&clip->region, &region);
+ if (status == CAIRO_STATUS_SUCCESS)
clip->has_region = TRUE;
- else
- status = CAIRO_STATUS_NO_MEMORY;
} else {
- pixman_region16_t intersection;
- pixman_region_init (&intersection);
+ cairo_region_t intersection;
+ _cairo_region_init (&intersection);
- if (!pixman_region_intersect (&intersection,
- &clip->region,
- &region) ||
- !pixman_region_copy (&clip->region, &intersection))
- status = CAIRO_STATUS_NO_MEMORY;
+ status = _cairo_region_intersect (&intersection,
+ &clip->region,
+ &region);
- pixman_region_fini (&intersection);
+ if (status == CAIRO_STATUS_SUCCESS)
+ status = _cairo_region_copy (&clip->region, &intersection);
+
+ _cairo_region_fini (&intersection);
}
clip->serial = _cairo_surface_allocate_clip_serial (target);
- pixman_region_fini (&region);
+ _cairo_region_fini (&region);
return status;
}
@@ -507,7 +506,7 @@ _cairo_clip_translate (cairo_clip_t *clip,
cairo_fixed_t ty)
{
if (clip->has_region) {
- pixman_region_translate (&clip->region,
+ _cairo_region_translate (&clip->region,
_cairo_fixed_integer_part (tx),
_cairo_fixed_integer_part (ty));
}
@@ -558,7 +557,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
* whatever the right handling is happen */
} else {
if (other->has_region) {
- if (!pixman_region_copy (&clip->region, &other->region))
+ if (_cairo_region_copy (&clip->region, &other->region) !=
+ CAIRO_STATUS_SUCCESS)
goto BAIL;
clip->has_region = TRUE;
}
@@ -584,7 +584,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
BAIL:
if (clip->has_region)
- pixman_region_fini (&clip->region);
+ _cairo_region_fini (&clip->region);
if (clip->surface)
cairo_surface_destroy (clip->surface);
@@ -597,19 +597,24 @@ static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
static cairo_bool_t
-_cairo_clip_rect_to_user (cairo_gstate_t *gstate,
- double x, double y, double width, double height,
- cairo_rectangle_t *rectangle)
+_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
+ cairo_rectangle_int_t *clip_rect,
+ cairo_rectangle_t *user_rect)
{
- double x2 = x + width;
- double y2 = y + height;
cairo_bool_t is_tight;
- _cairo_gstate_backend_to_user_rectangle (gstate, &x, &y, &x2, &y2, &is_tight);
- rectangle->x = x;
- rectangle->y = y;
- rectangle->width = x2 - x;
- rectangle->height = y2 - y;
+ double x1 = clip_rect->x;
+ double y1 = clip_rect->y;
+ double x2 = clip_rect->x + clip_rect->width;
+ double y2 = clip_rect->y + clip_rect->height;
+
+ _cairo_gstate_backend_to_user_rectangle (gstate, &x1, &y1, &x2, &y2, &is_tight);
+
+ user_rect->x = x1;
+ user_rect->y = y1;
+ user_rect->width = x2 - x1;
+ user_rect->height = y2 - y1;
+
return is_tight;
}
@@ -617,50 +622,51 @@ cairo_private cairo_rectangle_list_t*
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
{
cairo_rectangle_list_t *list;
- cairo_rectangle_t *rectangles;
+ cairo_rectangle_t *rectangles = NULL;
int n_boxes;
if (clip->path || clip->surface)
- return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
-
- n_boxes = clip->has_region ? pixman_region_n_rects (&clip->region) : 1;
- if (n_boxes > 0) {
- rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
- if (rectangles == NULL)
- return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
- } else {
- rectangles = NULL;
- }
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
if (clip->has_region) {
- pixman_box16_t *boxes;
+ cairo_box_int_t *boxes;
int i;
-
- boxes = pixman_region_rectangles (&clip->region, NULL);
+
+ if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+
+ rectangles = malloc (sizeof (cairo_rectangle_t) * n_boxes);
+ if (rectangles == NULL) {
+ _cairo_region_boxes_fini (&clip->region, boxes);
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+ }
+
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,
- boxes[i].y2 - boxes[i].y1,
- &rectangles[i])) {
- free (rectangles);
- return (cairo_rectangle_list_t*)
- &_cairo_rectangles_not_representable;
- }
+ cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
+ boxes[i].p2.x - boxes[i].p1.x,
+ boxes[i].p2.y - boxes[i].p1.y };
+
+ if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
+ _cairo_region_boxes_fini (&clip->region, boxes);
+ free (rectangles);
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
+ }
}
} else {
cairo_rectangle_int_t extents;
- if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
- &extents) != CAIRO_STATUS_SUCCESS) {
- free (rectangles);
+
+ n_boxes = 1;
+
+ rectangles = malloc(sizeof (cairo_rectangle_t));
+ if (rectangles == NULL)
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+
+ if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
+ !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
+ {
+ free (rectangles);
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
}
- if (! _cairo_clip_rect_to_user(gstate, extents.x, extents.y,
- extents.width, extents.height,
- rectangles)) {
- free (rectangles);
- return (cairo_rectangle_list_t*)
- &_cairo_rectangles_not_representable;
- }
}
list = malloc (sizeof (cairo_rectangle_list_t));
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index d6f827c4..78b3517e 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1095,8 +1095,8 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
static cairo_int_status_t
-_cairo_directfb_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+_cairo_directfb_surface_set_clip_region (void *abstract_surface,
+ cairo_region_t *region)
{
cairo_directfb_surface_t *surface = abstract_surface;
@@ -1105,16 +1105,19 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
__FUNCTION__, surface, region);
if (region) {
- pixman_box16_t *boxes = pixman_region_rects (region);
- int n_boxes = pixman_region_num_rects (region);
- int i;
-
+ cairo_box_int_t *boxes;
+ int n_boxes, i;
+
+ if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+ return CAIRO_STATUS_NO_MEMORY;
+
if (surface->n_clips != n_boxes) {
if( surface->clips )
free (surface->clips);
surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
if (!surface->clips) {
+ _cairo_region_boxes_fini (region, boxes);
surface->n_clips = 0;
return CAIRO_STATUS_NO_MEMORY;
}
@@ -1123,11 +1126,13 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
}
for (i = 0; i < n_boxes; i++) {
- surface->clips[i].x1 = boxes[i].x1;
- surface->clips[i].y1 = boxes[i].y1;
- surface->clips[i].x2 = boxes[i].x2;
- surface->clips[i].y2 = boxes[i].y2;
+ surface->clips[i].x1 = boxes[i].p1.x;
+ surface->clips[i].y1 = boxes[i].p1.y;
+ surface->clips[i].x2 = boxes[i].p2.x;
+ surface->clips[i].y2 = boxes[i].p2.y;
}
+
+ _cairo_region_boxes_fini (region, boxes);
}
else {
if (surface->clips) {
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 72754ad3..b0c33f57 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -34,7 +34,7 @@ typedef struct _cairo_glitz_surface {
glitz_surface_t *surface;
glitz_format_t *format;
cairo_bool_t has_clip;
- pixman_region16_t clip;
+ cairo_region_t clip;
} cairo_glitz_surface_t;
static const cairo_surface_backend_t *
@@ -47,7 +47,7 @@ _cairo_glitz_surface_finish (void *abstract_surface)
if (surface->has_clip) {
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
- pixman_region_fini (&surface->clip);
+ _cairo_region_fini (&surface->clip);
}
glitz_surface_destroy (surface->surface);
@@ -150,6 +150,36 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
return FALSE;
}
+static glitz_box_t *
+_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
+{
+ cairo_box_int_t *cboxes;
+ glitz_box_t *gboxes;
+ int n, i;
+
+ if (_cairo_region_get_boxes (&surface->clip, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
+ return NULL;
+
+ *nboxes = n;
+ if (n == 0)
+ return NULL;
+
+ gboxes = malloc (sizeof(glitz_box_t) * n);
+ if (gboxes == NULL)
+ goto done;
+
+ for (i = 0; i < n; i++) {
+ gboxes[i].x1 = cboxes[i].p1.x;
+ gboxes[i].y1 = cboxes[i].p1.y;
+ gboxes[i].x2 = cboxes[i].p2.x;
+ gboxes[i].y2 = cboxes[i].p2.y;
+ }
+
+done:
+ _cairo_region_boxes_fini (&sruface->clip, &cboxes);
+ return gboxes;
+}
+
static cairo_status_t
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
cairo_rectangle_int_t *interest,
@@ -264,10 +294,17 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
/* restore the clip, if any */
if (surface->has_clip) {
glitz_box_t *box;
- int n;
+ int n;
+
+ box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
+ if (box == NULL && n != 0) {
+ free (pixels);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
- box = (glitz_box_t *) pixman_region_rectangles (&surface->clip, &n);
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+
+ free (box);
}
/*
@@ -1393,37 +1430,45 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
static cairo_int_status_t
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+ cairo_region_t *region);
{
cairo_glitz_surface_t *surface = abstract_surface;
if (region)
+
{
glitz_box_t *box;
int n;
if (!surface->has_clip) {
- pixman_region_init (&surface->clip);
+ _cairo_region_init (&surface->clip);
surface->has_clip = TRUE;
}
- if (!pixman_region_copy (&surface->clip, region))
+ if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
{
- pixman_region_fini (&surface->clip);
+ _cairo_region_fini (&surface->clip);
surface->has_clip = FALSE;
return CAIRO_STATUS_NO_MEMORY;
}
- box = (glitz_box_t *) pixman_region_rectangles (&surface->clip, &n);
+ box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
+ if (box == NULL && n != 0) {
+ _cairo_region_fini (&surface->clip);
+ surface->has_clip = FALSE;
+ return CAIRO_STATUS_NO_MEMORY;
+ }
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+
+ free (box);
}
else
{
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
if (surface->has_clip) {
- pixman_region_fini (&surface->clip);
+ _cairo_region_fini (&surface->clip);
surface->has_clip = FALSE;
}
}
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index b833d09c..4546183a 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1032,11 +1032,11 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
cairo_int_status_t
_cairo_image_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+ cairo_region_t *region)
{
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
- if (!pixman_image_set_clip_region (surface->pixman_image, region))
+ if (!pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
return CAIRO_STATUS_NO_MEMORY;
surface->has_clip = region != NULL;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a4c4682f..7a81c3f9 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1771,10 +1771,10 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
cairo_color_t color;
_cairo_color_init_rgba (&color,
- src->stops->color.red / 65535.0,
- src->stops->color.green / 65535.0,
- src->stops->color.blue / 65535.0,
- src->stops->color.alpha / 65535.0);
+ src->stops->color.red,
+ src->stops->color.green,
+ src->stops->color.blue,
+ src->stops->color.alpha);
_cairo_pattern_init_solid (&solid, &color,
CAIRO_COLOR_IS_OPAQUE (&color) ?
@@ -2140,13 +2140,13 @@ cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
if (offset)
*offset = _cairo_fixed_to_double(gradient->stops[index].x);
if (red)
- *red = gradient->stops[index].color.red / (double) 0xffff;
+ *red = gradient->stops[index].color.red;
if (green)
- *green = gradient->stops[index].color.green / (double) 0xffff;
+ *green = gradient->stops[index].color.green;
if (blue)
- *blue = gradient->stops[index].color.blue / (double) 0xffff;
+ *blue = gradient->stops[index].color.blue;
if (alpha)
- *alpha = gradient->stops[index].color.alpha / (double) 0xffff;
+ *alpha = gradient->stops[index].color.alpha;
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
new file mode 100644
index 00000000..a3ee7596
--- /dev/null
+++ b/src/cairo-region-private.h
@@ -0,0 +1,105 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.com>
+ */
+
+#ifndef CAIRO_REGION_PRIVATE_H
+#define CAIRO_REGION_PRIVATE_H
+
+#include <pixman.h>
+
+/* cairo_region_t is defined in cairoint.h */
+
+struct _cairo_region {
+ pixman_region16_t rgn;
+};
+
+cairo_private void
+_cairo_region_init (cairo_region_t *region);
+
+cairo_private void
+_cairo_region_init_rect (cairo_region_t *region,
+ cairo_rectangle_int_t *rect);
+
+cairo_private cairo_int_status_t
+_cairo_region_init_boxes (cairo_region_t *region,
+ cairo_box_int_t *boxes,
+ int count);
+
+cairo_private void
+_cairo_region_fini (cairo_region_t *region);
+
+cairo_private cairo_int_status_t
+_cairo_region_copy (cairo_region_t *dst,
+ cairo_region_t *src);
+
+cairo_private int
+_cairo_region_num_boxes (cairo_region_t *region);
+
+cairo_private cairo_int_status_t
+_cairo_region_get_boxes (cairo_region_t *region,
+ int *num_boxes,
+ cairo_box_int_t **boxes);
+
+cairo_private void
+_cairo_region_boxes_fini (cairo_region_t *region,
+ cairo_box_int_t *boxes);
+
+cairo_private void
+_cairo_region_get_extents (cairo_region_t *region,
+ cairo_rectangle_int_t *extents);
+
+cairo_private cairo_int_status_t
+_cairo_region_subtract (cairo_region_t *dst,
+ cairo_region_t *a,
+ cairo_region_t *b);
+
+cairo_private cairo_int_status_t
+_cairo_region_intersect (cairo_region_t *dst,
+ cairo_region_t *a,
+ cairo_region_t *b);
+
+cairo_private cairo_int_status_t
+_cairo_region_union_rect (cairo_region_t *dst,
+ cairo_region_t *src,
+ cairo_rectangle_int_t *rect);
+
+cairo_private cairo_bool_t
+_cairo_region_not_empty (cairo_region_t *region);
+
+cairo_private void
+_cairo_region_translate (cairo_region_t *region,
+ int x, int y);
+
+#endif /* CAIRO_REGION_PRIVATE_H */
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 4538e1c3..287c1690 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
@@ -31,25 +32,177 @@
*
* Contributor(s):
* Owen Taylor <otaylor@redhat.com>
+ * Vladimir Vukicevic <vladimir@pobox.com>
*/
#include "cairoint.h"
+void
+_cairo_region_init (cairo_region_t *region)
+{
+ pixman_region_init (&region->rgn);
+}
+
+void
+_cairo_region_init_rect (cairo_region_t *region,
+ cairo_rectangle_int_t *rect)
+{
+ pixman_region_init_rect (&region->rgn,
+ rect->x, rect->y,
+ rect->width, rect->height);
+}
+
+#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_box16_t)))
+
+cairo_int_status_t
+_cairo_region_init_boxes (cairo_region_t *region,
+ cairo_box_int_t *boxes,
+ int count)
+{
+ pixman_box16_t stack_pboxes[STACK_BOXES_LEN];
+ pixman_box16_t *pboxes = stack_pboxes;
+ cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+ int i;
+
+ if (count > ARRAY_LENGTH(stack_pboxes)) {
+ pboxes = _cairo_malloc_ab (count, sizeof(pixman_box16_t));
+ if (pboxes == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < count; i++) {
+ pboxes[i].x1 = boxes[i].p1.x;
+ pboxes[i].y1 = boxes[i].p1.y;
+ pboxes[i].x2 = boxes[i].p2.x;
+ pboxes[i].y2 = boxes[i].p2.y;
+ }
+
+ if (!pixman_region_init_rects (region, pboxes, count))
+ status = CAIRO_STATUS_NO_MEMORY;
+
+ if (pboxes != stack_pboxes)
+ free (pboxes);
+
+ return status;
+}
+
+void
+_cairo_region_fini (cairo_region_t *region)
+{
+ pixman_region_fini (&region->rgn);
+}
+
+cairo_int_status_t
+_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
+{
+ if (!pixman_region_copy (&dst->rgn, &src->rgn))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+int
+_cairo_region_num_boxes (cairo_region_t *region)
+{
+ return pixman_region_n_rects(&region->rgn);
+}
+
+cairo_int_status_t
+_cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t **boxes)
+{
+ int nboxes = pixman_region_n_rects (&region->rgn);
+ pixman_box16_t *pboxes;
+ cairo_box_int_t *cboxes;
+ int i;
+
+ if (nboxes == 0) {
+ *num_boxes = 0;
+ *boxes = NULL;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ pboxes = pixman_region_rectangles (&region->rgn);
+ cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
+ if (cboxes == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ for (i = 0; i < nboxes; i++) {
+ cboxes[i].p1.x = pboxes[i].x1;
+ cboxes[i].p1.y = pboxes[i].y1;
+ cboxes[i].p2.x = pboxes[i].x2;
+ cboxes[i].p2.y = pboxes[i].y2;
+ }
+
+ *num_boxes = nboxes;
+ *boxes = cboxes;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_region_boxes_fini (cairo_region_t *region, cairo_box_int_t *boxes)
+{
+ free (boxes);
+}
+
/**
- * _cairo_region_extents_rectangle:
- * @region: a #pixman_region16_t
+ * _cairo_region_get_extents:
+ * @region: a #cairo_region_t
* @rect: rectangle into which to store the extents
*
- * Gets the bounding box of a region as a cairo_rectangle_int16_t
+ * Gets the bounding box of a region as a cairo_rectangle_int_t
**/
void
-_cairo_region_extents_rectangle (pixman_region16_t *region,
- cairo_rectangle_int_t *rect)
+_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
{
- pixman_box16_t *region_extents = pixman_region_extents (region);
+ pixman_box16_t *pextents = pixman_region_extents (&region->rgn);
+
+ extents->x = pextents->x1;
+ extents->y = pextents->y1;
+ extents->width = pextents->x2 - pextents->x1;
+ extents->height = pextents->y2 - pextents->y1;
+}
- rect->x = region_extents->x1;
- rect->y = region_extents->y1;
- rect->width = region_extents->x2 - region_extents->x1;
- rect->height = region_extents->y2 - region_extents->y1;
+cairo_int_status_t
+_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
+{
+ if (!pixman_region_subtract (&dst->rgn, &a->rgn, &b->rgn))
+ return 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)
+{
+ if (!pixman_region_intersect (&dst->rgn, &a->rgn, &b->rgn))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_region_union_rect (cairo_region_t *dst,
+ cairo_region_t *src,
+ cairo_rectangle_int_t *rect)
+{
+ if (!pixman_region_union_rect (&dst->rgn, &src->rgn,
+ rect->x, rect->y,
+ rect->width, rect->height))
+ return CAIRO_STATUS_NO_MEMORY;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_bool_t
+_cairo_region_not_empty (cairo_region_t *region)
+{
+ return (cairo_bool_t) pixman_region_not_empty (&region->rgn);
+}
+
+void
+_cairo_region_translate (cairo_region_t *region,
+ int x, int y)
+{
+ pixman_region_translate (&region->rgn, x, y);
}
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index c4c215ba..3929d8d0 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -410,13 +410,13 @@ _composite_trap_region (cairo_clip_t *clip,
cairo_pattern_t *src,
cairo_operator_t op,
cairo_surface_t *dst,
- pixman_region16_t *trap_region,
+ cairo_region_t *trap_region,
cairo_rectangle_int_t *extents)
{
cairo_status_t status;
cairo_pattern_union_t solid_pattern;
cairo_pattern_union_t mask;
- int num_rects = pixman_region_n_rects (trap_region);
+ int num_rects = _cairo_region_num_boxes (trap_region);
unsigned int clip_serial;
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
@@ -519,8 +519,8 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
cairo_antialias_t antialias)
{
cairo_status_t status;
- pixman_region16_t trap_region;
- pixman_region16_t clear_region;
+ 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_rectangle_int_t extents;
@@ -553,7 +553,7 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
if (status)
goto out;
- _cairo_region_extents_rectangle (&trap_region, &trap_extents);
+ _cairo_region_get_extents (&trap_region, &trap_extents);
} else {
cairo_box_t trap_box;
_cairo_traps_extents (traps, &trap_box);
@@ -573,9 +573,7 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
* _cairo_surface_fill_rectangles() or to drawing with a
* clip region, then we have an additional region to clear.
*/
- pixman_region_init_rect (&clear_region,
- extents.x, extents.y,
- extents.width, extents.height);
+ _cairo_region_init_rect (&clear_region, &extents);
has_clear_region = TRUE;
status = _cairo_clip_intersect_to_region (clip, &clear_region);
@@ -583,15 +581,14 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
if (status)
goto out;
- _cairo_region_extents_rectangle (&clear_region, &extents);
+ _cairo_region_get_extents (&clear_region, &extents);
- if (!pixman_region_subtract (&clear_region, &clear_region, &trap_region)) {
- status = CAIRO_STATUS_NO_MEMORY;
+ status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
+ if (status)
goto out;
- }
- if (!pixman_region_not_empty (&clear_region)) {
- pixman_region_fini (&clear_region);
+ if (!_cairo_region_not_empty (&clear_region)) {
+ _cairo_region_fini (&clear_region);
has_clear_region = FALSE;
}
} else {
@@ -665,9 +662,9 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
out:
if (has_trap_region)
- pixman_region_fini (&trap_region);
+ _cairo_region_fini (&trap_region);
if (has_clear_region)
- pixman_region_fini (&clear_region);
+ _cairo_region_fini (&clear_region);
return status;
}
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index a5c31090..05d9939f 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
@@ -1220,7 +1221,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
* @region: the region to modify, in backend coordinates
*
* Applies an operator to a set of rectangles specified as a
- * #pixman_region16_t using a solid color as the source.
+ * #cairo_region_t using a solid color as the source.
* See _cairo_surface_fill_rectangles() for full details.
*
* Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
@@ -1229,10 +1230,10 @@ cairo_status_t
_cairo_surface_fill_region (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_color_t *color,
- pixman_region16_t *region)
+ cairo_region_t *region)
{
- int num_rects;
- pixman_box16_t *boxes;
+ int num_boxes;
+ cairo_box_int_t *boxes;
cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
cairo_rectangle_int_t *rects;
cairo_status_t status;
@@ -1240,27 +1241,33 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
assert (! surface->is_snapshot);
- boxes = pixman_region_rectangles (region, &num_rects);
-
- if (!num_rects)
+ status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
+ if (status)
+ return status;
+
+ if (num_boxes == 0)
return CAIRO_STATUS_SUCCESS;
rects = stack_rects;
- if (num_rects > ARRAY_LENGTH (stack_rects)) {
- rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
- if (!rects)
+ if (num_boxes > ARRAY_LENGTH (stack_rects)) {
+ rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
+ if (!rects) {
+ _cairo_region_boxes_fini (region, boxes);
return CAIRO_STATUS_NO_MEMORY;
+ }
}
- for (i = 0; i < num_rects; i++) {
- rects[i].x = boxes[i].x1;
- rects[i].y = boxes[i].y1;
- rects[i].width = boxes[i].x2 - boxes[i].x1;
- rects[i].height = boxes[i].y2 - boxes[i].y1;
+ for (i = 0; i < num_boxes; i++) {
+ rects[i].x = boxes[i].p1.x;
+ rects[i].y = boxes[i].p1.y;
+ rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+ rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
}
status = _cairo_surface_fill_rectangles (surface, op,
- color, rects, num_rects);
+ color, rects, num_boxes);
+
+ _cairo_region_boxes_fini (region, boxes);
if (rects != stack_rects)
free (rects);
@@ -1630,7 +1637,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
/**
* _cairo_surface_set_clip_region:
* @surface: the #cairo_surface_t to reset the clip on
- * @region: the #pixman_region16_t to use for clipping
+ * @region: the #cairo_region_t to use for clipping
* @serial: the clip serial number associated with the region
*
* This function sets the clipping for the surface to
@@ -1639,7 +1646,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
*/
cairo_status_t
_cairo_surface_set_clip_region (cairo_surface_t *surface,
- pixman_region16_t *region,
+ cairo_region_t *region,
unsigned int serial)
{
cairo_status_t status;
@@ -1952,8 +1959,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
cairo_rectangle_int_t drawn_rectangle;
cairo_bool_t has_drawn_region = FALSE;
cairo_bool_t has_clear_region = FALSE;
- pixman_region16_t drawn_region;
- pixman_region16_t clear_region;
+ cairo_region_t drawn_region;
+ cairo_region_t clear_region;
cairo_status_t status;
/* The area that was drawn is the area in the destination rectangle but not within
@@ -1974,17 +1981,15 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
/* Now compute the area that is in dst_rectangle but not in drawn_rectangle
*/
- pixman_region_init_rect (&drawn_region,
- drawn_rectangle.x, drawn_rectangle.y,
- drawn_rectangle.width, drawn_rectangle.height);
- pixman_region_init_rect (&clear_region,
- dst_rectangle.x, dst_rectangle.y,
- dst_rectangle.width, dst_rectangle.height);
+ _cairo_region_init_rect (&drawn_region, &drawn_rectangle);
+ _cairo_region_init_rect (&clear_region, &dst_rectangle);
has_drawn_region = TRUE;
has_clear_region = TRUE;
- if (!pixman_region_subtract (&clear_region, &clear_region, &drawn_region)) {
+ if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
+ != CAIRO_STATUS_SUCCESS)
+ {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_REGIONS;
}
@@ -1995,9 +2000,9 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
CLEANUP_REGIONS:
if (has_drawn_region)
- pixman_region_fini (&drawn_region);
+ _cairo_region_fini (&drawn_region);
if (has_clear_region)
- pixman_region_fini (&clear_region);
+ _cairo_region_fini (&clear_region);
return status;
}
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 5ed1f7c5..0a1ccbeb 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -575,29 +575,30 @@ _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents)
*extents = traps->extents;
}
+#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(cairo_box_int_t)))
+
/**
* _cairo_traps_extract_region:
* @traps: a #cairo_traps_t
- * @region: on return, %NULL is stored here if the trapezoids aren't
- * exactly representable as a pixman region, otherwise a
- * a pointer to such a region, newly allocated.
- * (free with pixman region destroy)
+ * @region: a #cairo_region_t
*
* Determines if a set of trapezoids are exactly representable as a
- * pixman region, and if so creates such a region.
+ * cairo region. If so, the passed-in region is initialized to
+ * the area representing the given traps. It should be finalized
+ * with _cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED
+ * is returned.
*
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED
* or %CAIRO_STATUS_NO_MEMORY
**/
cairo_int_status_t
-_cairo_traps_extract_region (cairo_traps_t *traps,
- pixman_region16_t *region)
+_cairo_traps_extract_region (cairo_traps_t *traps,
+ cairo_region_t *region)
{
-#define NUM_STATIC_BOXES 16
- pixman_box16_t static_boxes[NUM_STATIC_BOXES];
- pixman_box16_t *boxes;
+ cairo_box_int_t stack_boxes[STACK_BOXES_LEN];
+ cairo_box_int_t *boxes = stack_boxes;
int i, box_count;
- pixman_bool_t status;
+ cairo_int_status_t status;
for (i = 0; i < traps->num_traps; i++)
if (!(traps->traps[i].left.p1.x == traps->traps[i].left.p2.x
@@ -609,11 +610,8 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
- if (traps->num_traps <= NUM_STATIC_BOXES) {
- boxes = static_boxes;
- } else {
- /*boxes = _cairo_malloc2 (traps->num_traps, sizeof(pixman_box16_t));*/
- boxes = malloc (traps->num_traps * sizeof(pixman_box16_t));
+ if (traps->num_traps > ARRAY_LENGTH(stack_boxes)) {
+ boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_t));
if (boxes == NULL)
return CAIRO_STATUS_NO_MEMORY;
@@ -633,23 +631,21 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
if (x1 == x2 || y1 == y2)
continue;
- boxes[box_count].x1 = (short) x1;
- boxes[box_count].y1 = (short) y1;
- boxes[box_count].x2 = (short) x2;
- boxes[box_count].y2 = (short) y2;
+ boxes[box_count].p1.x = x1;
+ boxes[box_count].p1.y = y1;
+ boxes[box_count].p2.x = x2;
+ boxes[box_count].p2.y = y2;
box_count++;
}
- status = pixman_region_init_rects (region, boxes, box_count);
+ status = _cairo_region_init_boxes (region, boxes, box_count);
- if (boxes != static_boxes)
+ if (boxes != stack_boxes)
free (boxes);
- if (!status) {
- pixman_region_fini (region);
- return CAIRO_INT_STATUS_UNSUPPORTED;
- }
+ if (status)
+ _cairo_region_fini (region);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index c698e103..f433b3de 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1374,8 +1374,8 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_win32_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+_cairo_win32_surface_set_clip_region (void *abstract_surface,
+ cairo_region_t *region)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -1404,9 +1404,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
} else {
- pixman_box16_t *boxes = pixman_region_rects (region);
- int num_boxes = pixman_region_num_rects (region);
- pixman_box16_t *extents = pixman_region_extents (region);
+ cairo_rectangle_int_t extents;
+ cairo_box_int_t *boxes;
+ int num_boxes;
RGNDATA *data;
size_t data_size;
RECT *rects;
@@ -1415,10 +1415,16 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
/* Create a GDI region for the cairo region */
+ _cairo_region_get_extents (region, &extents);
+ if (_cairo_region_get_boxes (region, &num_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+ return CAIRO_STATUS_NO_MEMORY;
+
data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
data = malloc (data_size);
- if (!data)
+ if (!data) {
+ _cairo_region_boxes_fini (region, boxes);
return CAIRO_STATUS_NO_MEMORY;
+ }
rects = (RECT *)data->Buffer;
data->rdh.dwSize = sizeof (RGNDATAHEADER);
@@ -1431,12 +1437,14 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
data->rdh.rcBound.bottom = extents->y2;
for (i = 0; i < num_boxes; i++) {
- rects[i].left = boxes[i].x1;
- rects[i].top = boxes[i].y1;
- rects[i].right = boxes[i].x2;
- rects[i].bottom = boxes[i].y2;
+ rects[i].left = boxes[i].p1.x;
+ rects[i].top = boxes[i].p1.y;
+ rects[i].right = boxes[i].p2.x;
+ rects[i].bottom = boxes[i].p2.y;
}
+ _cairo_region_boxes_fini (region, &boxes);
+
gdi_region = ExtCreateRegion (NULL, data_size, data);
free (data);
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 1c78a53a..684b43b1 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1532,8 +1532,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
}
static cairo_int_status_t
-_cairo_xcb_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+_cairo_xcb_surface_set_clip_region (void *abstract_surface,
+ cairo_region_t *region)
{
cairo_xcb_surface_t *surface = abstract_surface;
@@ -1554,28 +1554,32 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
xcb_render_change_picture (surface->dpy, surface->dst_picture,
XCB_RENDER_CP_CLIP_MASK, none);
} else {
- pixman_box16_t *boxes;
+ cairo_box_int_t *boxes;
xcb_rectangle_t *rects = NULL;
int n_boxes, i;
- n_boxes = pixman_region_num_rects (region);
+ if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+ return CAIRO_STATUS_NO_MEMORY;
+
if (n_boxes > 0) {
rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
- if (rects == NULL)
+ if (rects == NULL) {
+ _cairo_region_boxes_fini (region, boxes);
return CAIRO_STATUS_NO_MEMORY;
+ }
} else {
rects = NULL;
}
- boxes = pixman_region_rects (region);
-
for (i = 0; i < n_boxes; i++) {
- rects[i].x = boxes[i].x1;
- rects[i].y = boxes[i].y1;
- rects[i].width = boxes[i].x2 - boxes[i].x1;
- rects[i].height = boxes[i].y2 - boxes[i].y1;
+ rects[i].x = boxes[i].p1.x;
+ rects[i].y = boxes[i].p1.y;
+ rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+ rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
}
+ _cairo_region_boxes_fini (region, boxes);
+
surface->have_clip_rects = TRUE;
surface->clip_rects = rects;
surface->num_clip_rects = n_boxes;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index b1acf047..b685637e 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1813,8 +1813,8 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
}
static cairo_int_status_t
-_cairo_xlib_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+_cairo_xlib_surface_set_clip_region (void *abstract_surface,
+ cairo_region_t *region)
{
cairo_xlib_surface_t *surface = abstract_surface;
@@ -1830,28 +1830,32 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
surface->num_clip_rects = 0;
if (region != NULL) {
- pixman_box16_t *boxes;
+ cairo_box_int_t *boxes;
XRectangle *rects = NULL;
int n_boxes, i;
- n_boxes = pixman_region_n_rects (region);
+ if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+ return CAIRO_STATUS_NO_MEMORY;
+
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
rects = _cairo_malloc_ab (n_boxes, sizeof(XRectangle));
- if (rects == NULL)
+ if (rects == NULL) {
+ _cairo_region_boxes_fini (region, boxes);
return CAIRO_STATUS_NO_MEMORY;
- }else {
+ }
+ } else {
rects = surface->embedded_clip_rects;
}
- boxes = pixman_region_rectangles (region, NULL);
-
for (i = 0; i < n_boxes; i++) {
- rects[i].x = boxes[i].x1;
- rects[i].y = boxes[i].y1;
- rects[i].width = boxes[i].x2 - boxes[i].x1;
- rects[i].height = boxes[i].y2 - boxes[i].y1;
+ rects[i].x = boxes[i].p1.x;
+ rects[i].y = boxes[i].p1.y;
+ rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+ rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
}
+ _cairo_region_boxes_fini (region, boxes);
+
surface->have_clip_rects = TRUE;
surface->clip_rects = rects;
surface->num_clip_rects = n_boxes;
diff --git a/src/cairoint.h b/src/cairoint.h
index f06a9cc1..37b672b4 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -241,6 +241,8 @@ be32_to_cpu(uint32_t v)
#include "cairo-hash-private.h"
#include "cairo-cache-private.h"
+typedef struct _cairo_region cairo_region_t;
+
typedef struct _cairo_point {
cairo_fixed_t x;
cairo_fixed_t y;
@@ -282,12 +284,34 @@ typedef struct _cairo_rectangle_int32 {
uint32_t width, height;
} cairo_rectangle_int32_t;
+typedef struct _cairo_point_int16 {
+ int16_t x, y;
+} cairo_point_int16_t;
+
+typedef struct _cairo_point_int32 {
+ int16_t x, y;
+} cairo_point_int32_t;
+
+typedef struct _cairo_box_int16 {
+ cairo_point_int16_t p1;
+ cairo_point_int16_t p2;
+} cairo_box_int16_t;
+
+typedef struct _cairo_box_int32 {
+ cairo_point_int32_t p1;
+ cairo_point_int32_t p2;
+} cairo_box_int32_t;
+
#if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16
typedef cairo_rectangle_int16_t cairo_rectangle_int_t;
+typedef cairo_point_int16_t cairo_point_int_t;
+typedef cairo_box_int16_t cairo_box_int_t;
#define CAIRO_RECT_INT_MIN INT16_MIN
#define CAIRO_RECT_INT_MAX INT16_MAX
#elif CAIRO_FIXED_BITS == 32
typedef cairo_rectangle_int32_t cairo_rectangle_int_t;
+typedef cairo_point_int32_t cairo_point_int_t;
+typedef cairo_box_int32_t cairo_box_int_t;
#define CAIRO_RECT_INT_MIN INT32_MIN
#define CAIRO_RECT_INT_MAX INT32_MAX
#else
@@ -784,7 +808,7 @@ struct _cairo_surface_backend {
*/
cairo_warn cairo_int_status_t
(*set_clip_region) (void *surface,
- pixman_region16_t *region);
+ cairo_region_t *region);
/* Intersect the given path against the clip path currently set in
* the surface, using the given fill_rule and tolerance, and set
@@ -1769,7 +1793,7 @@ cairo_private cairo_status_t
_cairo_surface_fill_region (cairo_surface_t *surface,
cairo_operator_t op,
const cairo_color_t *color,
- pixman_region16_t *region);
+ cairo_region_t *region);
cairo_private cairo_status_t
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
@@ -1892,7 +1916,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_set_clip_region (cairo_surface_t *surface,
- pixman_region16_t *region,
+ cairo_region_t *region,
unsigned int serial);
cairo_private cairo_int_status_t
@@ -2050,7 +2074,7 @@ _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface);
*/
cairo_private cairo_int_status_t
_cairo_image_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region);
+ cairo_region_t *region);
cairo_private cairo_image_surface_t *
_cairo_image_surface_clone (cairo_image_surface_t *surface,
@@ -2227,7 +2251,7 @@ _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents);
cairo_private cairo_int_status_t
_cairo_traps_extract_region (cairo_traps_t *tr,
- pixman_region16_t *region);
+ cairo_region_t *region);
cairo_private void
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
@@ -2336,9 +2360,7 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate);
/* cairo-region.c */
-cairo_private void
-_cairo_region_extents_rectangle (pixman_region16_t *region,
- cairo_rectangle_int_t *rect);
+#include "cairo-region-private.h"
/* cairo_unicode.c */
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 99bd67c3..1e08c2d8 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -107,7 +107,7 @@ _test_paginated_surface_finish (void *abstract_surface)
static cairo_int_status_t
_test_paginated_surface_set_clip_region (void *abstract_surface,
- pixman_region16_t *region)
+ cairo_region_t *region)
{
test_paginated_surface_t *surface = abstract_surface;