diff options
-rw-r--r-- | src/cairo-analysis-surface-private.h | 4 | ||||
-rw-r--r-- | src/cairo-analysis-surface.c | 4 | ||||
-rw-r--r-- | src/cairo-clip-private.h | 4 | ||||
-rw-r--r-- | src/cairo-clip.c | 182 | ||||
-rw-r--r-- | src/cairo-directfb-surface.c | 25 | ||||
-rw-r--r-- | src/cairo-glitz-surface.c | 65 | ||||
-rw-r--r-- | src/cairo-image-surface.c | 4 | ||||
-rw-r--r-- | src/cairo-pattern.c | 16 | ||||
-rw-r--r-- | src/cairo-region-private.h | 105 | ||||
-rw-r--r-- | src/cairo-region.c | 173 | ||||
-rw-r--r-- | src/cairo-surface-fallback.c | 29 | ||||
-rw-r--r-- | src/cairo-surface.c | 63 | ||||
-rw-r--r-- | src/cairo-traps.c | 50 | ||||
-rw-r--r-- | src/cairo-win32-surface.c | 28 | ||||
-rw-r--r-- | src/cairo-xcb-surface.c | 26 | ||||
-rw-r--r-- | src/cairo-xlib-surface.c | 28 | ||||
-rw-r--r-- | src/cairoint.h | 38 | ||||
-rw-r--r-- | src/test-paginated-surface.c | 2 |
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, ®ion)) + status = _cairo_region_copy (&clip->region, ®ion); + 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, - ®ion) || - !pixman_region_copy (&clip->region, &intersection)) - status = CAIRO_STATUS_NO_MEMORY; + status = _cairo_region_intersect (&intersection, + &clip->region, + ®ion); - 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 (®ion); + _cairo_region_fini (®ion); 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, ®ion->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 (®ion->rgn); +} + +void +_cairo_region_init_rect (cairo_region_t *region, + cairo_rectangle_int_t *rect) +{ + pixman_region_init_rect (®ion->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 (®ion->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(®ion->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 (®ion->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 (®ion->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 (®ion->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 (®ion->rgn); +} + +void +_cairo_region_translate (cairo_region_t *region, + int x, int y) +{ + pixman_region_translate (®ion->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; |