[cairo-commit] 6 commits - src/cairo.c src/cairo-directfb-surface.c src/cairo-glitz-surface.c src/cairo-image-surface.c src/cairoint.h src/cairo-paginated-surface.c src/cairo-region.c src/cairo-sdl-surface.c src/cairo-surface.c src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-surface.c src/cairo-xlib-surface-private.h util/cairo-script

Chris Wilson ickle at kemper.freedesktop.org
Fri Nov 21 01:43:59 PST 2008


 src/cairo-directfb-surface.c               |    6 +++-
 src/cairo-glitz-surface.c                  |    1 
 src/cairo-image-surface.c                  |   11 ++++----
 src/cairo-paginated-surface.c              |    3 ++
 src/cairo-region.c                         |   11 ++++----
 src/cairo-sdl-surface.c                    |    1 
 src/cairo-surface.c                        |   37 ++++++++++-------------------
 src/cairo-win32-surface.c                  |    3 +-
 src/cairo-xcb-surface.c                    |    1 
 src/cairo-xlib-surface-private.h           |    2 -
 src/cairo-xlib-surface.c                   |   13 ++++++----
 src/cairo.c                                |   18 ++++++++++----
 src/cairoint.h                             |   10 ++++---
 util/cairo-script/cairo-script-operators.c |    5 +--
 14 files changed, 69 insertions(+), 53 deletions(-)

New commits:
commit f15b1f26becf28457e9ccf8903257a0dec25d547
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 23:19:19 2008 +0000

    [region] Use the caller supplied array for extracting boxes.
    
    Allow the user to pass in a pre-allocated array and use it if the number
    of boxes permits. This eliminates the frequent allocations during clipping
    by toolkits.

diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 5a970b9..8cbd3bc 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1305,12 +1305,14 @@ _cairo_directfb_surface_set_clip_region (void           *abstract_surface,
 
 	surface->has_clip = TRUE;
 
+	n_boxes = 0;
 	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
-	if (n_boxes == 0)
-	    return CAIRO_STATUS_SUCCESS;
 	if (status)
 	    return status;
 
+	if (n_boxes == 0)
+	    return CAIRO_STATUS_SUCCESS;
+
 	if (surface->n_clips != n_boxes) {
 	    if (surface->clips)
 		free (surface->clips);
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 5bdfa70..203c063 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -153,6 +153,7 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes,
     cairo_status_t status;
     int n, i;
 
+    n = 0;
     status = _cairo_region_get_boxes (region, &n, &cboxes);
     if (status)
 	return status;
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 94a599e..bb542ff 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -397,9 +397,12 @@ _paint_page (cairo_paginated_surface_t *surface)
 	    goto FAIL;
 
 	region = _cairo_analysis_surface_get_unsupported (analysis);
+
+	num_boxes = 0;
 	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
 	if (status)
 	    goto FAIL;
+
 	for (i = 0; i < num_boxes; i++) {
 	    status = _paint_fallback_image (surface, &boxes[i]);
 	    if (status) {
diff --git a/src/cairo-region.c b/src/cairo-region.c
index a89c4d0..146ae60 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -114,16 +114,17 @@ _cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t
     int i;
 
     pboxes = pixman_region32_rectangles (&region->rgn, &nboxes);
-
     if (nboxes == 0) {
 	*num_boxes = 0;
-	*boxes = NULL;
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
-    if (cboxes == NULL)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    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;
diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c
index b9d604e..18f13ea 100644
--- a/src/cairo-sdl-surface.c
+++ b/src/cairo-sdl-surface.c
@@ -322,6 +322,7 @@ _cairo_sdl_surface_flush (void                  *abstract_surface)
     int n_boxes, i;
     cairo_status_t status;
 
+    n_boxes = 0;
     status = _cairo_region_get_boxes (&surface->update, &n_boxes, &boxes);
     if (status)
 	return status;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index e3a31d7..eaff47a 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1535,6 +1535,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t	   *surface,
  *
  * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
  **/
+COMPILE_TIME_ASSERT (sizeof (cairo_box_int_t) <= sizeof (cairo_rectangle_int_t));
 cairo_status_t
 _cairo_surface_fill_region (cairo_surface_t	   *surface,
 			    cairo_operator_t	    op,
@@ -1542,8 +1543,8 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
 			    cairo_region_t         *region)
 {
     int num_boxes;
-    cairo_box_int_t *boxes = NULL;
     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;
@@ -1554,12 +1555,12 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
     assert (! surface->is_snapshot);
 
     num_boxes = _cairo_region_num_boxes (region);
-
     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 (status)
 	    return status;
@@ -1567,18 +1568,18 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
 	if (num_boxes > ARRAY_LENGTH (stack_rects)) {
 	    rects = _cairo_malloc_ab (num_boxes,
 		                      sizeof (cairo_rectangle_int_t));
-	    if (!rects) {
+	    if (rects == NULL) {
 		_cairo_region_boxes_fini (region, boxes);
 		return _cairo_surface_set_error (surface,
-			                         CAIRO_STATUS_NO_MEMORY);
+			                         _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 - boxes[i].p1.x;
-	    rects[i].height = boxes[i].p2.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]);
@@ -1586,7 +1587,7 @@ _cairo_surface_fill_region (cairo_surface_t	   *surface,
     status =  _cairo_surface_fill_rectangles (surface, op,
 					      color, rects, num_boxes);
 
-    if (boxes != NULL)
+    if (boxes != (cairo_box_int_t *) stack_rects)
 	_cairo_region_boxes_fini (region, boxes);
 
     if (rects != stack_rects)
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 70af72b..863f9d5 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1469,11 +1469,12 @@ _cairo_win32_surface_set_clip_region (void           *abstract_surface,
 	/* 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;
 
-	if (num_boxes == 1 && 
+	if (num_boxes == 1 &&
 	    boxes[0].p1.x == 0 &&
 	    boxes[0].p1.y == 0 &&
 	    boxes[0].p2.x == surface->extents.width &&
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 63618bb..999f7d5 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1560,6 +1560,7 @@ _cairo_xcb_surface_set_clip_region (void           *abstract_surface,
 	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;
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index 87be9e6..fe37e5f 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -86,7 +86,7 @@ struct _cairo_xlib_surface {
     unsigned int clip_dirty;
     cairo_bool_t have_clip_rects;
     cairo_bool_t gc_has_clip_rects;
-    XRectangle embedded_clip_rects[4];
+    XRectangle embedded_clip_rects[8];
     XRectangle *clip_rects;
     int num_clip_rects;
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 368f4e4..2ae727f 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2261,6 +2261,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     return status;
 }
 
+COMPILE_TIME_ASSERT (sizeof (XRectangle) <= sizeof (cairo_box_int_t));
 static cairo_int_status_t
 _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
 				     cairo_region_t *region)
@@ -2304,6 +2305,8 @@ _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 (status) {
 	    _cairo_region_fini (&bound);
@@ -2319,18 +2322,18 @@ _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
 		_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 - boxes[i].p1.x;
-	    rects[i].height = boxes[i].p2.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_region_boxes_fini (&bounded, boxes);
+	if (boxes != (cairo_box_int_t *) surface->embedded_clip_rects)
+	    _cairo_region_boxes_fini (&bounded, boxes);
 	_cairo_region_fini (&bounded);
 	_cairo_region_fini (&bound);
 
commit 9d2c55c661885c06eed44e810004c2ebe07038d3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 21:53:34 2008 +0000

    [traps] Embed sufficient traps to accommodate a stroke rectangle
    
    Small numbers of traps are frequently generated from either a path of a
    single line, or that of a rectangle. Therefore should embed sufficient
    storage with cairo_traps_t to accommodate the stroke of a single rectangle
    (e.g. a pango unknown glyph hexbox) to avoid frequent allocations.

diff --git a/src/cairoint.h b/src/cairoint.h
index c790444..d219061 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -942,7 +942,8 @@ typedef struct _cairo_traps {
     int num_traps;
     int traps_size;
     cairo_trapezoid_t *traps;
-    cairo_trapezoid_t  traps_embedded[1];
+    /* embed enough storage for a stroked rectangle */
+    cairo_trapezoid_t  traps_embedded[4];
 
     cairo_bool_t has_limits;
     cairo_box_t limits;
commit a11442154d958d5c9694eb944a715a6c689fda85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 18:00:40 2008 +0000

    [cairo] Allocate glyphs on the stack for show_text().
    
    First try to use a stack buffer for the glyphs and clusters if the user
    calls cairo_show_text() - for example, as pango does to draw the unknown hex
    box.

diff --git a/src/cairo.c b/src/cairo.c
index ac128dd..f53d0b0 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -3086,12 +3086,14 @@ cairo_show_text (cairo_t *cr, const char *utf8)
 {
     cairo_text_extents_t extents;
     cairo_status_t status;
-    cairo_glyph_t *glyphs = NULL, *last_glyph;
-    cairo_text_cluster_t *clusters = NULL;
+    cairo_glyph_t *glyphs, *last_glyph;
+    cairo_text_cluster_t *clusters;
     int utf8_len, num_glyphs, num_clusters;
     cairo_text_cluster_flags_t cluster_flags;
     double x, y;
     cairo_bool_t has_show_text_glyphs;
+    cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
+    cairo_text_cluster_t stack_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
 
     if (cr->status)
 	return;
@@ -3106,6 +3108,12 @@ cairo_show_text (cairo_t *cr, const char *utf8)
     has_show_text_glyphs =
 	cairo_surface_has_show_text_glyphs (cairo_get_target (cr));
 
+    glyphs = stack_glyphs;
+    num_glyphs = ARRAY_LENGTH (stack_glyphs);
+
+    clusters = stack_clusters;
+    num_clusters = ARRAY_LENGTH (stack_clusters);
+
     status = _cairo_gstate_text_to_glyphs (cr->gstate,
 					   x, y,
 					   utf8, utf8_len,
@@ -3138,8 +3146,10 @@ cairo_show_text (cairo_t *cr, const char *utf8)
     cairo_move_to (cr, x, y);
 
  BAIL:
-    cairo_glyph_free (glyphs);
-    cairo_text_cluster_free (clusters);
+    if (glyphs != stack_glyphs)
+	cairo_glyph_free (glyphs);
+    if (clusters != stack_clusters)
+	cairo_text_cluster_free (clusters);
 
     if (status)
 	_cairo_set_error (cr, status);
commit 9556266ffcb1c34187730af90bb847950d6db66e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 09:40:25 2008 +0000

    [surface] Make the error surfaces have a NULL backend.
    
    By using a NULL backend for the error surfaces, instead of a pointer to
    the image surface backend end, we save a few lookup/redirections during
    dynamic linking.

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 77e8352..e3a31d7 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -44,25 +44,15 @@
 
 #define DEFINE_NIL_SURFACE(status, name)			\
 const cairo_surface_t name = {					\
-    &_cairo_image_surface_backend,	/* backend */		\
-    CAIRO_SURFACE_TYPE_IMAGE,					\
-    CAIRO_CONTENT_COLOR,					\
+    NULL,				/* backend */		\
+    CAIRO_SURFACE_TYPE_IMAGE,		/* type */		\
+    CAIRO_CONTENT_COLOR,		/* content */		\
     CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */		\
     status,				/* status */		\
     FALSE,				/* finished */		\
-    { 0,	/* size */					\
-      0,	/* num_elements */				\
-      0,	/* element_size */				\
-      NULL,	/* elements */					\
-    },					/* user_data */		\
-    { 1.0, 0.0,							\
-      0.0, 1.0,							\
-      0.0, 0.0							\
-    },					/* device_transform */	\
-    { 1.0, 0.0,							\
-      0.0, 1.0,							\
-      0.0, 0.0							\
-    },					/* device_transform_inverse */	\
+    { 0, 0, 0, NULL, },			/* user_data */		\
+    { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },   /* device_transform */	\
+    { 1.0, 0.0,	0.0, 1.0, 0.0, 0.0 },	/* device_transform_inverse */	\
     0.0,				/* x_resolution */	\
     0.0,				/* y_resolution */	\
     0.0,				/* x_fallback_resolution */	\
commit cfd2c73826f5bf20624fbdf5b16fd08fbe18a914
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 09:36:02 2008 +0000

    [image] Trim image surface size by a few bytes
    
    Convert an infrequently accessed series of cairo_bool_t and short enums
    to a common bitfield.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 0efdb7a..234a6f9 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -731,7 +731,7 @@ _cairo_image_surface_finish (void *abstract_surface)
 void
 _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface)
 {
-    surface->owns_data = 1;
+    surface->owns_data = TRUE;
 }
 
 static cairo_status_t
@@ -1064,10 +1064,11 @@ _cairo_image_surface_fill_rectangles (void		      *abstract_surface,
 
     /* XXX: pixman_fill_rectangles() should be implemented */
     if (! pixman_image_fill_rectangles (_pixman_operator (op),
-				       surface->pixman_image,
-				       &pixman_color,
-				       num_rects,
-				       pixman_rects)) {
+					surface->pixman_image,
+					&pixman_color,
+					num_rects,
+					pixman_rects))
+    {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
diff --git a/src/cairoint.h b/src/cairoint.h
index 3aad4d7..c790444 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -835,9 +835,6 @@ struct _cairo_image_surface {
     pixman_format_code_t pixman_format;
     cairo_format_t format;
     unsigned char *data;
-    cairo_bool_t owns_data;
-    cairo_bool_t has_clip;
-    cairo_image_transparency_t transparency;
 
     int width;
     int height;
@@ -845,6 +842,10 @@ struct _cairo_image_surface {
     int depth;
 
     pixman_image_t *pixman_image;
+
+    unsigned owns_data : 1;
+    unsigned has_clip : 1;
+    unsigned transparency : 2;
 };
 
 extern const cairo_private cairo_surface_backend_t _cairo_image_surface_backend;
commit 1f48b36933b5ff082edf3e221563c15c3bf16b75
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 20 12:41:18 2008 +0000

    [script] Build fix for ! HAS_FT_FONT
    
    Correct the macro definition used when compiling without FreeType.

diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index 03bd521..a70b55d 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -32,7 +32,7 @@
  *	Chris Wilson <chris at chris-wilson.co.uk>
  */
 
-/* TODO real matrix and path types */
+/* TODO real path type */
 
 #include "cairo-script-private.h"
 
@@ -1823,8 +1823,7 @@ _ft_type42_create (csi_t *ctx,
     return _csi_error (CSI_STATUS_INVALID_SCRIPT);
 }
 #else
-#define _ft_type1_create(font, face_out) CSI_INT_STATUS_UNSUPPORTED
-#define _ft_type42_create(font, face_out) CSI_INT_STATUS_UNSUPPORTED
+#define _ft_type42_create(ctx, font, face_out) CSI_INT_STATUS_UNSUPPORTED
 #endif
 
 static csi_status_t


More information about the cairo-commit mailing list