[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