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

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat May 10 06:08:15 PDT 2008


 src/cairo-user-font.c |   32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

New commits:
commit 569cc3041195db9408c9c6531dc35b6f77434a25
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat May 10 14:58:11 2008 +0200

    [user-font] Normalize the space we compute extents in
    
    This way we wouldn't suffer from the limited precision of cairo_fixed_t.
    Bug reported by Peter Clifton on mailing list.

diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 9aaa34d..3745380 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -113,23 +113,45 @@ _cairo_user_scaled_glyph_init (void			 *abstract_font,
 	if (extents.width == 0.) {
 	    /* Compute extents.x/y/width/height from meta_surface, in font space */
 
+	    cairo_matrix_t matrix;
+	    double fixed_scale, x_scale, y_scale;
+
 	    cairo_box_t bbox;
 	    double x1, y1, x2, y2;
 	    cairo_surface_t *null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
 	    cairo_surface_t *analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
 	    cairo_surface_destroy (null_surface);
 
-	    _cairo_analysis_surface_set_ctm (analysis_surface, &scaled_font->base.scale_inverse);
+	    /* compute a normalized version of font scale matrix to compute
+	     * extents in.  This is to minimize error caused by the cairo_fixed_t
+	     * representation. */
+
+	    matrix = scaled_font->base.scale_inverse;
+	    status = _cairo_matrix_compute_scale_factors (&matrix, &x_scale, &y_scale, /* XXX */ 1);
+	    if (status)
+		return status;
+
+	    /* since glyphs are pretty much 1.0x1.0, we can reduce error by
+	     * scaling to a larger square.  say, 1024.x1024. */
+	    fixed_scale = 1024.;
+	    x_scale /= fixed_scale;
+	    y_scale /= fixed_scale;
+	    if (x_scale == 0) x_scale = 1. / fixed_scale;
+	    if (y_scale == 0) y_scale = 1. / fixed_scale;
+
+	    cairo_matrix_scale (&matrix, 1. / x_scale, 1. / y_scale);
+
+	    _cairo_analysis_surface_set_ctm (analysis_surface, &matrix);
 	    status = _cairo_meta_surface_replay (meta_surface, analysis_surface);
 	    _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
 	    cairo_surface_destroy (analysis_surface);
 
 	    _cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2);
 
-	    extents.x_bearing = x1;
-	    extents.y_bearing = y1;
-	    extents.width     = x2 - x1;
-	    extents.height    = y2 - y1;
+	    extents.x_bearing = x1 * x_scale;
+	    extents.y_bearing = y1 * y_scale;
+	    extents.width     = (x2 - x1) * x_scale;
+	    extents.height    = (y2 - y1) * y_scale;
 	}
 
 	_cairo_scaled_glyph_set_metrics (scaled_glyph,


More information about the cairo-commit mailing list