[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 (®ion->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