[cairo-commit] src/cairo-clip.c src/cairo-directfb-surface.c src/cairo-paginated-surface.c src/cairo-region.c src/cairo-region-private.h src/cairo-sdl-surface.c src/cairo-surface.c src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-surface.c

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sun Feb 15 21:51:50 PST 2009


 src/cairo-clip.c              |   21 +++++++-----------
 src/cairo-directfb-surface.c  |   21 +++++++-----------
 src/cairo-paginated-surface.c |   19 +++++++---------
 src/cairo-region-private.h    |   10 ++------
 src/cairo-region.c            |   39 ++++++++--------------------------
 src/cairo-sdl-surface.c       |   21 +++++++-----------
 src/cairo-surface.c           |   44 ++++++++++++++------------------------
 src/cairo-win32-surface.c     |   48 ++++++++++++++++++++----------------------
 src/cairo-xcb-surface.c       |   26 +++++++++-------------
 src/cairo-xlib-surface.c      |   31 +++++++++++----------------
 10 files changed, 112 insertions(+), 168 deletions(-)

New commits:
commit f6daa664c1b2c894ba3baf2e7a72566bda1fd636
Author: Søren Sandmann <sandmann at daimi.au.dk>
Date:   Sun Feb 15 18:55:17 2009 -0500

    Delete _cairo_region_get_boxes() in favor of _cairo_region_get_box()
    
    The _cairo_region_get_boxes() interface was difficult to use and often
    caused unnecessary memory allocation. With _cairo_region_get_box() it
    is possible to access the boxes of a region without allocating a big
    temporary array.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index a64d524..9aac115 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -884,38 +884,35 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
     }
 
     if (clip->has_region) {
-	cairo_box_int_t *boxes;
         int i;
 
-	if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes))
-	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+	n_boxes = _cairo_region_num_boxes (&clip->region);
 
 	if (n_boxes) {
 	    rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
 	    if (unlikely (rectangles == NULL)) {
-		_cairo_region_boxes_fini (&clip->region, boxes);
 		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 		return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	    }
 
 	    for (i = 0; i < n_boxes; ++i) {
-               cairo_rectangle_int_t clip_rect;
+		cairo_box_int_t box;
+		cairo_rectangle_int_t clip_rect;
 
-               clip_rect.x = boxes[i].p1.x;
-               clip_rect.y = boxes[i].p1.y;
-               clip_rect.width  = boxes[i].p2.x - boxes[i].p1.x;
-               clip_rect.height = boxes[i].p2.y - boxes[i].p1.y;
+		_cairo_region_get_box (&clip->region, i, &box);
 
+		clip_rect.x = box.p1.x;
+		clip_rect.y = box.p1.y;
+		clip_rect.width  = box.p2.x - box.p1.x;
+		clip_rect.height = box.p2.y - box.p1.y;
+		
 		if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
 		    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
-		    _cairo_region_boxes_fini (&clip->region, boxes);
 		    free (rectangles);
 		    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 		}
 	    }
 	}
-
-	_cairo_region_boxes_fini (&clip->region, boxes);
     } else {
         cairo_rectangle_int_t extents;
 
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index ecce179..b902cca 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1299,17 +1299,13 @@ _cairo_directfb_surface_set_clip_region (void           *abstract_surface,
 		__FUNCTION__, surface, region);
 
     if (region) {
-	cairo_box_int_t *boxes;
 	int              n_boxes;
 	cairo_status_t   status;
 	int              i;
 
 	surface->has_clip = TRUE;
 
-	n_boxes = 0;
-	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
-	if (status)
-	    return status;
+	n_boxes = _cairo_region_num_boxes (region);
 
 	if (n_boxes == 0)
 	    return CAIRO_STATUS_SUCCESS;
@@ -1321,7 +1317,6 @@ _cairo_directfb_surface_set_clip_region (void           *abstract_surface,
 	    surface->clips = _cairo_malloc_ab (n_boxes, sizeof (DFBRegion));
 	    if (!surface->clips) {
 		surface->n_clips = 0;
-		_cairo_region_boxes_fini (region, boxes);
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    }
 
@@ -1329,13 +1324,15 @@ _cairo_directfb_surface_set_clip_region (void           *abstract_surface,
 	}
 
 	for (i = 0; i < n_boxes; i++) {
-	    surface->clips[i].x1 = boxes[i].p1.x;
-	    surface->clips[i].y1 = boxes[i].p1.y;
-	    surface->clips[i].x2 = boxes[i].p2.x - 1;
-	    surface->clips[i].y2 = boxes[i].p2.y - 1;
+	    cairo_box_int_t box;
+
+	    _cairo_region_get_box (region, i, &box);
+	    
+	    surface->clips[i].x1 = box.p1.x;
+	    surface->clips[i].y1 = box.p1.y;
+	    surface->clips[i].x2 = box.p2.x - 1;
+	    surface->clips[i].y2 = box.p2.y - 1;
 	}
-
-	_cairo_region_boxes_fini (region, boxes);
     } else {
 	surface->has_clip = FALSE;
 	if (surface->clips) {
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 5d4e08f..8c62644 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -381,7 +381,6 @@ _paint_page (cairo_paginated_surface_t *surface)
 
     if (has_finegrained_fallback) {
         cairo_region_t *region;
-        cairo_box_int_t *boxes;
         int num_boxes, i;
 
 	surface->backend->set_paginated_mode (surface->target,
@@ -398,19 +397,17 @@ _paint_page (cairo_paginated_surface_t *surface)
 
 	region = _cairo_analysis_surface_get_unsupported (analysis);
 
-	num_boxes = 0;
-	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
-	if (unlikely (status))
-	    goto FAIL;
-
+	num_boxes = _cairo_region_num_boxes (region);
 	for (i = 0; i < num_boxes; i++) {
-	    status = _paint_fallback_image (surface, &boxes[i]);
-	    if (unlikely (status)) {
-                _cairo_region_boxes_fini (region, boxes);
+	    cairo_box_int_t box;
+
+	    _cairo_region_get_box (region, i, &box);
+	    
+	    status = _paint_fallback_image (surface, &box);
+	    
+	    if (unlikely (status))
 		goto FAIL;
-            }
 	}
-        _cairo_region_boxes_fini (region, boxes);
     }
 
   FAIL:
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index 588762e..d969116 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -72,14 +72,10 @@ _cairo_region_copy (cairo_region_t *dst,
 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_region_get_box (cairo_region_t *region,
+		       int nth_box,
+		       cairo_box_int_t *box);
 
 cairo_private void
 _cairo_region_get_extents (cairo_region_t *region,
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 53a359b..a9efacc 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -105,38 +105,19 @@ _cairo_region_num_boxes (cairo_region_t *region)
     return pixman_region32_n_rects (&region->rgn);
 }
 
-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_get_box (cairo_region_t *region,
+		       int nth_box,
+		       cairo_box_int_t *box)
 {
-    int nboxes;
-    pixman_box32_t *pboxes;
-    cairo_box_int_t *cboxes;
-    int i;
-
-    pboxes = pixman_region32_rectangles (&region->rgn, &nboxes);
-    if (nboxes == 0) {
-	*num_boxes = 0;
-	return CAIRO_STATUS_SUCCESS;
-    }
+    pixman_box32_t *pbox;
 
-    if (nboxes > *num_boxes) {
-	cboxes = _cairo_malloc_ab (nboxes, sizeof (cairo_box_int_t));
-	if (unlikely (cboxes == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    } else
-	cboxes = *boxes;
-
-    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;
-    }
+    pbox = pixman_region32_rectangles (&region->rgn, NULL) + nth_box;
 
-    *num_boxes = nboxes;
-    *boxes = cboxes;
-
-    return CAIRO_STATUS_SUCCESS;
+    box->p1.x = pbox->x1;
+    box->p1.y = pbox->y1;
+    box->p2.x = pbox->x2;
+    box->p2.y = pbox->y2;
 }
 
 void
diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c
index 1f97fb4..9ab82a5 100644
--- a/src/cairo-sdl-surface.c
+++ b/src/cairo-sdl-surface.c
@@ -318,27 +318,24 @@ static cairo_status_t
 _cairo_sdl_surface_flush (void                  *abstract_surface)
 {
     cairo_sdl_surface_t *surface = abstract_surface;
-    cairo_box_int_t *boxes;
     int n_boxes, i;
-    cairo_status_t status;
 
-    n_boxes = 0;
-    status = _cairo_region_get_boxes (&surface->update, &n_boxes, &boxes);
-    if (unlikely (status))
-	return status;
+    n_boxes = _cairo_region_num_boxes (&surface->update);
     if (n_boxes == 0)
 	return CAIRO_STATUS_SUCCESS;
 
     for (i = 0; i < n_boxes; i++) {
+	cairo_box_int_t box;
+
+	_cairo_region_get_box (&surface->update, i, &box);
+	
 	SDL_UpdateRect (surface->sdl,
-			boxes[i].p1.x,
-			boxes[i].p1.y,
-			boxes[i].p2.x - boxes[i].p1.x,
-			boxes[i].p2.y - boxes[i].p1.y);
+			box.p1.x,
+			box.p1.y,
+			box.p2.x - box.p1.x,
+			box.p2.y - box.p1.y);
     }
 
-    _cairo_region_boxes_fini (&surface->update, boxes);
-
     _cairo_region_fini (&surface->update);
     _cairo_region_init (&surface->update);
 
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 7bb502b..6f522fc 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1579,7 +1579,6 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
 {
     int num_boxes;
     cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
-    cairo_box_int_t *boxes = (cairo_box_int_t *) stack_rects;
     cairo_rectangle_int_t *rects = stack_rects;
     cairo_status_t status;
     int i;
@@ -1593,38 +1592,29 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
     if (num_boxes == 0)
 	return CAIRO_STATUS_SUCCESS;
 
-    /* handle the common case of a single box without allocation */
-    if (num_boxes > 1) {
-	num_boxes = sizeof (stack_rects) / sizeof (cairo_box_int_t);
-	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
-	if (unlikely (status))
-	    return status;
-
-	if (num_boxes > ARRAY_LENGTH (stack_rects)) {
-	    rects = _cairo_malloc_ab (num_boxes,
-		                      sizeof (cairo_rectangle_int_t));
-	    if (rects == NULL) {
-		_cairo_region_boxes_fini (region, boxes);
-		return _cairo_surface_set_error (surface,
-			                         _cairo_error (CAIRO_STATUS_NO_MEMORY));
-	    }
+    if (num_boxes > ARRAY_LENGTH (stack_rects)) {
+	rects = _cairo_malloc_ab (num_boxes,
+				  sizeof (cairo_rectangle_int_t));
+	if (rects == NULL) {
+	    return _cairo_surface_set_error (surface,
+					     _cairo_error (CAIRO_STATUS_NO_MEMORY));
 	}
+    }
 
-	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 - rects[i].x;
-	    rects[i].height = boxes[i].p2.y - rects[i].y;
-	}
-    } else
-	_cairo_region_get_extents (region, &rects[0]);
+    for (i = 0; i < num_boxes; i++) {
+	cairo_box_int_t box;
+
+	_cairo_region_get_box (region, i, &box);
+	
+	rects[i].x = box.p1.x;
+	rects[i].y = box.p1.y;
+	rects[i].width  = box.p2.x - rects[i].x;
+	rects[i].height = box.p2.y - rects[i].y;
+    }
 
     status =  _cairo_surface_fill_rectangles (surface, op,
 					      color, rects, num_boxes);
 
-    if (boxes != (cairo_box_int_t *) stack_rects)
-	_cairo_region_boxes_fini (region, boxes);
-
     if (rects != stack_rects)
 	free (rects);
 
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 03a8f61..f0c7aa2 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1461,38 +1461,36 @@ _cairo_win32_surface_set_clip_region (void           *abstract_surface,
     /* Then combine any new region with it */
     if (region) {
 	cairo_rectangle_int_t extents;
-	cairo_box_int_t *boxes;
 	int num_boxes;
 	RGNDATA *data;
 	size_t data_size;
 	RECT *rects;
 	int i;
 	HRGN gdi_region;
+	cairo_box_int_t box0;
 
 	/* Create a GDI region for the cairo region */
 
 	_cairo_region_get_extents (region, &extents);
-	num_boxes = 0;
-	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
-	if (status)
-	    return status;
+	num_boxes = _cairo_region_num_boxes (region);
 
+	if (num_boxes == 1)
+	    _cairo_region_get_box (region, 0, &box0);
+	    
 	if (num_boxes == 1 &&
-	    boxes[0].p1.x == 0 &&
-	    boxes[0].p1.y == 0 &&
-	    boxes[0].p2.x == surface->extents.width &&
-	    boxes[0].p2.y == surface->extents.height)
+	    box0.p1.x == 0 &&
+	    box0.p1.y == 0 &&
+	    box0.p2.x == surface->extents.width &&
+	    box0.p2.y == surface->extents.height)
 	{
 	    gdi_region = NULL;
-
+	    
 	    SelectClipRgn (surface->dc, NULL);
 	    IntersectClipRect (surface->dc,
-			       boxes[0].p1.x,
-			       boxes[0].p1.y,
-			       boxes[0].p2.x,
-			       boxes[0].p2.y);
-
-	    _cairo_region_boxes_fini (region, boxes);
+			       box0.p1.x,
+			       box0.p1.y,
+			       box0.p2.x,
+			       box0.p2.y);
 	} else {
 	    /* XXX see notes in _cairo_win32_save_initial_clip --
 	     * this code will interact badly with a HDC which had an initial
@@ -1503,10 +1501,8 @@ _cairo_win32_surface_set_clip_region (void           *abstract_surface,
 
 	    data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
 	    data = malloc (data_size);
-	    if (!data) {
-		_cairo_region_boxes_fini (region, boxes);
+	    if (!data)
 		return _cairo_error(CAIRO_STATUS_NO_MEMORY);
-	    }
 	    rects = (RECT *)data->Buffer;
 
 	    data->rdh.dwSize = sizeof (RGNDATAHEADER);
@@ -1519,14 +1515,16 @@ _cairo_win32_surface_set_clip_region (void           *abstract_surface,
 	    data->rdh.rcBound.bottom = extents.y + extents.height;
 
 	    for (i = 0; i < num_boxes; i++) {
-		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_box_int_t box;
+
+		_cairo_region_get_box (region, i, &box);
+		
+		rects[i].left = box.p1.x;
+		rects[i].top = box.p1.y;
+		rects[i].right = box.p2.x;
+		rects[i].bottom = box.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 2ae7dcf..17a09e3 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1555,35 +1555,31 @@ _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 {
-	cairo_box_int_t *boxes;
 	cairo_status_t status;
 	xcb_rectangle_t *rects = NULL;
 	int n_boxes, i;
 
-	n_boxes = 0;
-	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
-        if (status)
-            return status;
+	n_boxes = _cairo_region_num_boxes (region);
 
 	if (n_boxes > 0) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
-	    if (rects == NULL) {
-                _cairo_region_boxes_fini (region, boxes);
+	    if (rects == NULL)
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-            }
 	} else {
 	    rects = NULL;
 	}
 
 	for (i = 0; i < n_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;
+	    cairo_box_int_t box;
+
+	    _cairo_region_get_box (region, i, &box);
+	    
+	    rects[i].x = box.p1.x;
+	    rects[i].y = box.p1.y;
+	    rects[i].width = box.p2.x - box.p1.x;
+	    rects[i].height = box.p2.y - box.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 c94004c..f86a133 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2289,7 +2289,6 @@ _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
     surface->num_clip_rects = 0;
 
     if (region != NULL) {
-	cairo_box_int_t *boxes;
 	cairo_status_t status;
 	XRectangle *rects = NULL;
 	int n_boxes, i;
@@ -2311,33 +2310,29 @@ _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
 	    return status;
 	}
 
-	n_boxes = sizeof (surface->embedded_clip_rects) / sizeof (cairo_box_int_t);
-	boxes = (cairo_box_int_t *) surface->embedded_clip_rects;
-	status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes);
-	if (unlikely (status)) {
-	    _cairo_region_fini (&bounded);
-	    return status;
-	}
+	n_boxes = _cairo_region_num_boxes (&bounded);
 
 	if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
 	    if (unlikely (rects == NULL)) {
-                _cairo_region_boxes_fini (&bounded, boxes);
 		_cairo_region_fini (&bounded);
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-            }
-	} else
+	    }
+	} else {
 	    rects = surface->embedded_clip_rects;
+	}
 
 	for (i = 0; i < n_boxes; i++) {
-	    rects[i].x = boxes[i].p1.x;
-	    rects[i].y = boxes[i].p1.y;
-	    rects[i].width  = boxes[i].p2.x - rects[i].x;
-	    rects[i].height = boxes[i].p2.y - rects[i].y;
-	}
+	    cairo_box_int_t box;
 
-	if (boxes != (cairo_box_int_t *) surface->embedded_clip_rects)
-	    _cairo_region_boxes_fini (&bounded, boxes);
+	    _cairo_region_get_box (&bounded, i, &box);
+
+	    rects[i].x = box.p1.x;
+	    rects[i].y = box.p1.y;
+	    rects[i].width  = box.p2.x - rects[i].x;
+	    rects[i].height = box.p2.y - rects[i].y;
+	}
+	
 	_cairo_region_fini (&bounded);
 
 	surface->have_clip_rects = TRUE;


More information about the cairo-commit mailing list