[cairo-commit] 3 commits - boilerplate/cairo-boilerplate.c util/cairo-script util/cairo-trace
Chris Wilson
ickle at kemper.freedesktop.org
Sun Jun 28 02:50:29 PDT 2009
boilerplate/cairo-boilerplate.c | 2
util/cairo-script/cairo-script-operators.c | 413 +++++++++--------------------
util/cairo-trace/trace.c | 2
3 files changed, 134 insertions(+), 283 deletions(-)
New commits:
commit 963664727b4754f92a876c36557922821706f591
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 28 10:49:37 2009 +0100
[trace] Compile fix for --enable-script
Silly typo as pointed out by Hans Breuer <hans at breuer.org>.
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 5ef290f..92b4981 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -4133,7 +4133,7 @@ cairo_script_surface_create (const char *filename,
" surface dup /s%ld exch def\n",
width, height,
surface_id);
- _surface_set_size (ret, width, height);
+ _surface_object_set_size (ret, width, height);
_get_object (SURFACE, ret)->defined = true;
_push_operand (SURFACE, ret);
_write_unlock ();
commit 2ecafb025c8b15a86372b655e763d742a0f6ef85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 28 10:09:01 2009 +0100
[script] Reuse glyph advance cache over multiple invocations
Store the metric cache as user-data on the scaled-font so that we can
retrieve it on future calls to show-glyphs and friends.
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index 76ceb2d..407afae 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -2175,71 +2175,56 @@ _get (csi_t *ctx)
return _csi_push_ostack_copy (ctx, &obj);
}
-static csi_status_t
-_glyph_path (csi_t *ctx)
-{
- csi_object_t *obj;
- csi_array_t *array;
- csi_array_t *glyph_array;
- csi_string_t *glyph_string;
- csi_status_t status;
- cairo_t *cr;
- cairo_scaled_font_t *scaled_font;
- cairo_glyph_t stack_glyphs[256], *glyphs;
- double x,y;
- csi_integer_t nglyphs, i, j;
+struct glyph_advance_cache {
+ csi_t *ctx;
double glyph_advance[256][2];
- int have_glyph_advance[256];
-
- check (2);
+ unsigned long have_glyph_advance[256];
+};
- status = _csi_ostack_get_array (ctx, 0, &array);
- if (_csi_unlikely (status))
- return status;
- status = _csi_ostack_get_context (ctx, 1, &cr);
- if (_csi_unlikely (status))
- return status;
+static void
+glyph_advance_cache_destroy (void *closure)
+{
+ struct glyph_advance_cache *cache = closure;
+ _csi_free (cache->ctx, cache);
+}
- /* count glyphs */
- nglyphs = 0;
- for (i = 0; i < array->stack.len; i++) {
- obj = &array->stack.objects[i];
- switch ((int) csi_object_get_type (obj)) {
- case CSI_OBJECT_TYPE_ARRAY:
- nglyphs += obj->datum.array->stack.len;
- break;
- case CSI_OBJECT_TYPE_STRING:
- nglyphs += obj->datum.string->len;
- break;
- }
- }
- if (nglyphs == 0) {
- pop (1);
- return CSI_STATUS_SUCCESS;
+static int
+_glyph_string (csi_t *ctx,
+ csi_array_t *array,
+ cairo_scaled_font_t *scaled_font,
+ cairo_glyph_t *glyphs)
+{
+ double x,y;
+ csi_integer_t nglyphs, i, j;
+ struct glyph_advance_cache *cache;
+
+ cache = cairo_scaled_font_get_user_data (scaled_font,
+ (cairo_user_data_key_t *) &_glyph_string);
+ if (cache == NULL) {
+ cache = _csi_alloc (ctx, sizeof (*cache));
+ if (cache == NULL)
+ return -1;
+
+ cache->ctx = ctx;
+ memset (cache->have_glyph_advance, 0xff,
+ sizeof (cache->have_glyph_advance));
+
+ cairo_scaled_font_set_user_data (scaled_font,
+ (cairo_user_data_key_t *) &_glyph_string,
+ cache, glyph_advance_cache_destroy);
}
- if (nglyphs > ARRAY_LENGTH (stack_glyphs)) {
- if (_csi_unlikely ((unsigned) nglyphs >= INT_MAX / sizeof (cairo_glyph_t)))
- return _csi_error (CSI_STATUS_NO_MEMORY);
- glyphs = _csi_alloc (ctx, sizeof (cairo_glyph_t) * nglyphs);
- if (_csi_unlikely (glyphs == NULL))
- return _csi_error (CSI_STATUS_NO_MEMORY);
- } else
- glyphs = stack_glyphs;
-
- scaled_font = cairo_get_scaled_font (cr);
-
nglyphs = 0;
- memset (have_glyph_advance, 0, sizeof (have_glyph_advance));
x = y = 0;
for (i = 0; i < array->stack.len; i++) {
- obj = &array->stack.objects[i];
+ const csi_object_t *obj = &array->stack.objects[i];
+
switch ((int) csi_object_get_type (obj)) {
- case CSI_OBJECT_TYPE_ARRAY: /* glyphs */
- glyph_array = obj->datum.array;
+ case CSI_OBJECT_TYPE_ARRAY: {
+ const csi_array_t *glyph_array = obj->datum.array;
for (j = 0; j < glyph_array->stack.len; j++) {
unsigned long g;
- cairo_bool_t have_advance;
+ int gi;
obj = &glyph_array->stack.objects[j];
if (csi_object_get_type (obj) != CSI_OBJECT_TYPE_INTEGER)
@@ -2250,69 +2235,54 @@ _glyph_path (csi_t *ctx)
glyphs[nglyphs].x = x;
glyphs[nglyphs].y = y;
- if (g < ARRAY_LENGTH (have_glyph_advance)) {
- if (! have_glyph_advance[g]) {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- glyph_advance[g][0] = extents.x_advance;
- glyph_advance[g][1] = extents.y_advance;
- have_glyph_advance[g] = TRUE;
-
- }
-
- have_advance = glyph_advance[g][0] != 0.0;
- x += glyph_advance[g][0];
- y += glyph_advance[g][1];
- } else {
+ gi = g % ARRAY_LENGTH (cache->have_glyph_advance);
+ if (cache->have_glyph_advance[gi] != g) {
cairo_text_extents_t extents;
cairo_scaled_font_glyph_extents (scaled_font,
&glyphs[nglyphs], 1,
&extents);
- have_advance = extents.x_advance != 0.0;
- x += extents.x_advance;
- y += extents.y_advance;
+ cache->glyph_advance[gi][0] = extents.x_advance;
+ cache->glyph_advance[gi][1] = extents.y_advance;
+ cache->have_glyph_advance[gi] = g;
}
- nglyphs += have_advance;
+ x += cache->glyph_advance[gi][0];
+ y += cache->glyph_advance[gi][1];
+ nglyphs++;
}
break;
+ }
- case CSI_OBJECT_TYPE_STRING: /* glyphs */
- glyph_string = obj->datum.string;
+ case CSI_OBJECT_TYPE_STRING: {
+ const csi_string_t *glyph_string = obj->datum.string;
for (j = 0; j < glyph_string->len; j++) {
uint8_t g;
- cairo_bool_t have_advance;
g = glyph_string->string[j];
glyphs[nglyphs].index = g;
glyphs[nglyphs].x = x;
glyphs[nglyphs].y = y;
- if (! have_glyph_advance[g]) {
+ if (cache->have_glyph_advance[g] != g) {
cairo_text_extents_t extents;
cairo_scaled_font_glyph_extents (scaled_font,
&glyphs[nglyphs], 1,
&extents);
- glyph_advance[g][0] = extents.x_advance;
- glyph_advance[g][1] = extents.y_advance;
- have_glyph_advance[g] = TRUE;
+ cache->glyph_advance[g][0] = extents.x_advance;
+ cache->glyph_advance[g][1] = extents.y_advance;
+ cache->have_glyph_advance[g] = g;
}
- have_advance = glyph_advance[g][0] != 0.0;
- x += glyph_advance[g][0];
- y += glyph_advance[g][1];
-
- nglyphs += have_advance;
+ x += cache->glyph_advance[g][0];
+ y += cache->glyph_advance[g][1];
+ nglyphs++;
}
break;
+ }
case CSI_OBJECT_TYPE_INTEGER:
case CSI_OBJECT_TYPE_REAL: /* dx */
@@ -2324,10 +2294,68 @@ _glyph_path (csi_t *ctx)
}
}
+ return nglyphs;
+}
+
+static csi_status_t
+_glyph_path (csi_t *ctx)
+{
+ csi_object_t *obj;
+ csi_array_t *array;
+ csi_status_t status;
+ cairo_t *cr;
+ cairo_glyph_t stack_glyphs[256], *glyphs;
+ csi_integer_t nglyphs, i;
+
+ check (2);
+
+ status = _csi_ostack_get_array (ctx, 0, &array);
+ if (_csi_unlikely (status))
+ return status;
+ status = _csi_ostack_get_context (ctx, 1, &cr);
+ if (_csi_unlikely (status))
+ return status;
+
+ /* count glyphs */
+ nglyphs = 0;
+ for (i = 0; i < array->stack.len; i++) {
+ obj = &array->stack.objects[i];
+ switch ((int) csi_object_get_type (obj)) {
+ case CSI_OBJECT_TYPE_ARRAY:
+ nglyphs += obj->datum.array->stack.len;
+ break;
+ case CSI_OBJECT_TYPE_STRING:
+ nglyphs += obj->datum.string->len;
+ break;
+ }
+ }
+ if (nglyphs == 0) {
+ pop (1);
+ return CSI_STATUS_SUCCESS;
+ }
+
+ if (nglyphs > ARRAY_LENGTH (stack_glyphs)) {
+ if (_csi_unlikely ((unsigned) nglyphs >= INT_MAX / sizeof (cairo_glyph_t)))
+ return _csi_error (CSI_STATUS_NO_MEMORY);
+ glyphs = _csi_alloc (ctx, sizeof (cairo_glyph_t) * nglyphs);
+ if (_csi_unlikely (glyphs == NULL))
+ return _csi_error (CSI_STATUS_NO_MEMORY);
+ } else
+ glyphs = stack_glyphs;
+
+ nglyphs = _glyph_string (ctx, array, cairo_get_scaled_font (cr), glyphs);
+ if (_csi_unlikely (nglyphs < 0)) {
+ if (glyphs != stack_glyphs)
+ _csi_free (ctx, glyphs);
+
+ return _csi_error (CSI_STATUS_NO_MEMORY);
+ }
+
cairo_glyph_path (cr, glyphs, nglyphs);
if (glyphs != stack_glyphs)
_csi_free (ctx, glyphs);
+
pop (1);
return CSI_STATUS_SUCCESS;
}
@@ -4818,16 +4846,10 @@ _show_glyphs (csi_t *ctx)
{
csi_object_t *obj;
csi_array_t *array;
- csi_array_t *glyph_array;
- csi_string_t *glyph_string;
csi_status_t status;
cairo_t *cr;
- cairo_scaled_font_t *scaled_font;
cairo_glyph_t stack_glyphs[256], *glyphs;
- double x,y;
- csi_integer_t nglyphs, i, j;
- double glyph_advance[256][2];
- unsigned long have_glyph_advance[256];
+ csi_integer_t nglyphs, i;
check (2);
@@ -4865,97 +4887,18 @@ _show_glyphs (csi_t *ctx)
} else
glyphs = stack_glyphs;
- scaled_font = cairo_get_scaled_font (cr);
-
- nglyphs = 0;
- memset (have_glyph_advance, 0xff, sizeof (have_glyph_advance));
- x = y = 0;
- for (i = 0; i < array->stack.len; i++) {
- obj = &array->stack.objects[i];
- switch ((int) csi_object_get_type (obj)) {
- case CSI_OBJECT_TYPE_ARRAY: /* glyphs */
- glyph_array = obj->datum.array;
- for (j = 0; j < glyph_array->stack.len; j++) {
- unsigned long g;
- int gi;
- cairo_bool_t have_advance;
-
- obj = &glyph_array->stack.objects[j];
- if (csi_object_get_type (obj) != CSI_OBJECT_TYPE_INTEGER)
- break;
- g = obj->datum.integer;
-
- glyphs[nglyphs].index = g;
- glyphs[nglyphs].x = x;
- glyphs[nglyphs].y = y;
-
- gi = g % ARRAY_LENGTH (have_glyph_advance);
- if (have_glyph_advance[gi] != g) {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- glyph_advance[gi][0] = extents.x_advance;
- glyph_advance[gi][1] = extents.y_advance;
- have_glyph_advance[gi] = g;
- }
-
- have_advance = glyph_advance[gi][0] != 0.0;
- x += glyph_advance[gi][0];
- y += glyph_advance[gi][1];
-
- nglyphs += have_advance;
- }
- break;
-
- case CSI_OBJECT_TYPE_STRING: /* glyphs */
- glyph_string = obj->datum.string;
- for (j = 0; j < glyph_string->len; j++) {
- uint8_t g;
- cairo_bool_t have_advance;
-
- g = glyph_string->string[j];
- glyphs[nglyphs].index = g;
- glyphs[nglyphs].x = x;
- glyphs[nglyphs].y = y;
-
- if (have_glyph_advance[g] != g) {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- glyph_advance[g][0] = extents.x_advance;
- glyph_advance[g][1] = extents.y_advance;
- have_glyph_advance[g] = g;
- }
-
- have_advance = glyph_advance[g][0] != 0.0;
- x += glyph_advance[g][0];
- y += glyph_advance[g][1];
-
- nglyphs += have_advance;
- }
- break;
-
- case CSI_OBJECT_TYPE_INTEGER:
- case CSI_OBJECT_TYPE_REAL: /* dx */
- x = csi_number_get_value (obj);
- if (++i == array->stack.len)
- break;
- y = csi_number_get_value (&array->stack.objects[i]);
- break;
- }
+ nglyphs = _glyph_string (ctx, array, cairo_get_scaled_font (cr), glyphs);
+ if (_csi_unlikely (nglyphs < 0)) {
+ if (glyphs != stack_glyphs)
+ _csi_free (ctx, glyphs);
+ return _csi_error (CSI_STATUS_NO_MEMORY);
}
cairo_show_glyphs (cr, glyphs, nglyphs);
- cairo_move_to (cr, x, y);
if (glyphs != stack_glyphs)
_csi_free (ctx, glyphs);
+
pop (1);
return CSI_STATUS_SUCCESS;
}
@@ -4967,17 +4910,11 @@ _show_text_glyphs (csi_t *ctx)
csi_array_t *array;
csi_string_t *string;
csi_string_t *utf8_string;
- csi_string_t *glyph_string;
- csi_array_t *glyph_array;
csi_status_t status;
cairo_t *cr;
- cairo_scaled_font_t *scaled_font;
cairo_text_cluster_t stack_clusters[256], *clusters;
cairo_glyph_t stack_glyphs[256], *glyphs;
- double x,y;
- csi_integer_t nglyphs, nclusters, i, j;
- double glyph_advance[256][2];
- int have_glyph_advance[256];
+ csi_integer_t nglyphs, nclusters, i;
long direction;
check (5);
@@ -5064,102 +5001,15 @@ _show_text_glyphs (csi_t *ctx)
} else
glyphs = stack_glyphs;
- /* amalgamate glyph strings */
- scaled_font = cairo_get_scaled_font (cr);
+ nglyphs = _glyph_string (ctx, array, cairo_get_scaled_font (cr), glyphs);
+ if (_csi_unlikely (nglyphs < 0)) {
+ if (clusters != stack_clusters)
+ _csi_free (ctx, clusters);
- nglyphs = 0;
- memset (have_glyph_advance, 0, sizeof (have_glyph_advance));
- x = y = 0;
- for (i = 0; i < array->stack.len; i++) {
- obj = &array->stack.objects[i];
- switch ((int) csi_object_get_type (obj)) {
- case CSI_OBJECT_TYPE_ARRAY: /* glyphs */
- glyph_array = obj->datum.array;
- for (j = 0; j < glyph_array->stack.len; j++) {
- unsigned long g;
- cairo_bool_t have_advance;
-
- obj = &glyph_array->stack.objects[j];
- if (csi_object_get_type (obj) != CSI_OBJECT_TYPE_INTEGER)
- break;
- g = obj->datum.integer;
-
- glyphs[nglyphs].index = g;
- glyphs[nglyphs].x = x;
- glyphs[nglyphs].y = y;
-
- if (g < ARRAY_LENGTH (have_glyph_advance)) {
- if (! have_glyph_advance[g]) {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- glyph_advance[g][0] = extents.x_advance;
- glyph_advance[g][1] = extents.y_advance;
- have_glyph_advance[g] = TRUE;
-
- }
-
- have_advance = glyph_advance[g][0] != 0.0;
- x += glyph_advance[g][0];
- y += glyph_advance[g][1];
- } else {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- have_advance = extents.x_advance != 0.0;
- x += extents.x_advance;
- y += extents.y_advance;
- }
-
- nglyphs += have_advance;
- }
- break;
+ if (glyphs != stack_glyphs)
+ _csi_free (ctx, glyphs);
- case CSI_OBJECT_TYPE_STRING: /* glyphs */
- glyph_string = obj->datum.string;
- for (j = 0; j < glyph_string->len; j++) {
- uint8_t g;
- cairo_bool_t have_advance;
-
- g = glyph_string->string[j];
- glyphs[nglyphs].index = g;
- glyphs[nglyphs].x = x;
- glyphs[nglyphs].y = y;
-
- if (! have_glyph_advance[g]) {
- cairo_text_extents_t extents;
-
- cairo_scaled_font_glyph_extents (scaled_font,
- &glyphs[nglyphs], 1,
- &extents);
-
- glyph_advance[g][0] = extents.x_advance;
- glyph_advance[g][1] = extents.y_advance;
- have_glyph_advance[g] = TRUE;
- }
-
- have_advance = glyph_advance[g][0] != 0.0;
- x += glyph_advance[g][0];
- y += glyph_advance[g][1];
-
- nglyphs += have_advance;
- }
- break;
-
- case CSI_OBJECT_TYPE_INTEGER:
- case CSI_OBJECT_TYPE_REAL: /* dx */
- x = csi_number_get_value (obj);
- if (++i == array->stack.len)
- break;
- y = csi_number_get_value (&array->stack.objects[i]);
- break;
- }
+ return _csi_error (CSI_STATUS_NO_MEMORY);
}
cairo_show_text_glyphs (cr,
@@ -5167,7 +5017,6 @@ _show_text_glyphs (csi_t *ctx)
glyphs, nglyphs,
clusters, nclusters,
direction);
- cairo_move_to (cr, x, y);
if (clusters != stack_clusters)
_csi_free (ctx, clusters);
commit 663da31bbe7cf6021c8d59a4d4ddd2702cfe860f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 28 01:17:13 2009 +0100
[boilerplate] Propagate original error from create_from_png()
During cairo_boilerplate_get_image_surface_from_png() the original status
returned by cairo_image_surface_create_from_png() could have been masked
by inappropriate context construction when flattening or extracting.
Simply check after creating the surface from the png file, and return
immediately if in error.
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 1b0fa29..285b23a 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -225,6 +225,8 @@ cairo_boilerplate_get_image_surface_from_png (const char *filename,
cairo_surface_t *surface;
surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface))
+ return surface;
if (flatten) {
cairo_t *cr;
More information about the cairo-commit
mailing list