[cairo-commit] src/cairo-scaled-font.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat Dec 23 14:00:58 PST 2006


 src/cairo-scaled-font.c |   58 +++++++++++++++++++++++++++++-------------------
 1 files changed, 36 insertions(+), 22 deletions(-)

New commits:
diff-tree 3212fc4f0fcc66ec3a93994f253c1477eb434572 (from 8368fa2fcfcf851b9a5b070d22905472f1f76234)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Dec 23 16:55:44 2006 -0500

    [cairo-scaled-font] Skip invisible glyphs (like space) in glyph_extents() (#9422)
    
    When computing extents for an array of glyphs, just taking min/max of x/y for
    the bounding box of each glyph doesn't work.  The reason being that an
    invisible glyph (like the space glyph) should not modify the resulting
    extents, but it will.  So now we skip invisible glyphs.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 316c603..e07ab53 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -705,24 +705,13 @@ cairo_scaled_font_glyph_extents (cairo_s
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     int i;
     double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0;
-    double x_pos = 0.0, y_pos = 0.0;
+    cairo_bool_t visible = FALSE;
+    cairo_scaled_glyph_t *scaled_glyph = NULL;
 
     if (scaled_font->status)
 	return;
 
-    if (!num_glyphs) {
-	extents->x_bearing = 0.0;
-	extents->y_bearing = 0.0;
-	extents->width = 0.0;
-	extents->height = 0.0;
-	extents->x_advance = 0.0;
-	extents->y_advance = 0.0;
-
-	return;
-    }
-
     for (i = 0; i < num_glyphs; i++) {
-	cairo_scaled_glyph_t	*scaled_glyph;
 	double			left, top, right, bottom;
 
 	status = _cairo_scaled_glyph_lookup (scaled_font,
@@ -734,12 +723,17 @@ cairo_scaled_font_glyph_extents (cairo_s
 	    return;
 	}
 
+	/* "Ink" extents should skip "invisible" glyphs */
+	if (scaled_glyph->metrics.width == 0 && scaled_glyph->metrics.height == 0)
+	    continue;
+
 	left = scaled_glyph->metrics.x_bearing + glyphs[i].x;
 	right = left + scaled_glyph->metrics.width;
 	top = scaled_glyph->metrics.y_bearing + glyphs[i].y;
 	bottom = top + scaled_glyph->metrics.height;
 
-	if (i == 0) {
+	if (!visible) {
+	    visible = TRUE;
 	    min_x = left;
 	    max_x = right;
 	    min_y = top;
@@ -750,16 +744,36 @@ cairo_scaled_font_glyph_extents (cairo_s
 	    if (top < min_y) min_y = top;
 	    if (bottom > max_y) max_y = bottom;
 	}
-	x_pos = glyphs[i].x + scaled_glyph->metrics.x_advance;
-	y_pos = glyphs[i].y + scaled_glyph->metrics.y_advance;
     }
 
-    extents->x_bearing = min_x - glyphs[0].x;
-    extents->y_bearing = min_y - glyphs[0].y;
-    extents->width = max_x - min_x;
-    extents->height = max_y - min_y;
-    extents->x_advance = x_pos - glyphs[0].x;
-    extents->y_advance = y_pos - glyphs[0].y;
+    if (visible) {
+	extents->x_bearing = min_x - glyphs[0].x;
+	extents->y_bearing = min_y - glyphs[0].y;
+	extents->width = max_x - min_x;
+	extents->height = max_y - min_y;
+    } else {
+	extents->x_bearing = 0.0;
+	extents->y_bearing = 0.0;
+	extents->width = 0.0;
+	extents->height = 0.0;
+    }
+
+    if (num_glyphs) {
+        double x0, y0, x1, y1;
+
+	x0 = glyphs[0].x;
+	y0 = glyphs[0].y;
+
+	/* scaled_glyphs contains the glyph for num_glyphs - 1 already. */
+	x1 = glyphs[num_glyphs - 1].x + scaled_glyph->metrics.x_advance;
+	y1 = glyphs[num_glyphs - 1].y + scaled_glyph->metrics.y_advance;
+
+	extents->x_advance = x1 - x0;
+	extents->y_advance = y1 - y0;
+    } else {
+	extents->x_advance = 0.0;
+	extents->y_advance = 0.0;
+    }
 }
 slim_hidden_def (cairo_scaled_font_glyph_extents);
 


More information about the cairo-commit mailing list