[cairo-commit] 2 commits - src/cairoint.h src/cairo-matrix.c src/cairo-scaled-font.c src/cairo-user-font.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Wed Jun 30 03:40:38 PDT 2010


 src/cairo-matrix.c      |    9 +++++++
 src/cairo-scaled-font.c |    5 +---
 src/cairo-user-font.c   |   58 ++++++++++++++++++++++++++++++------------------
 src/cairoint.h          |    3 ++
 4 files changed, 51 insertions(+), 24 deletions(-)

New commits:
commit d2d6c96c24501d888422ea42d3c90d3c8f3647a0
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Tue Jun 29 09:58:54 2010 +0200

    user-font: correct handling of size 0 text
    
    Text with size 0 has a singular scale matrix, thus requires special
    handling to avoid invalidating the context where it is used.
    
    Fixes pthread-show-text and text-zero-len (they failed with assertion
    when ran using the user font backend).

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index de1c6ed..6ae8e62 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -578,6 +578,15 @@ _cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
     return ISFINITE (det) && det != 0.;
 }
 
+cairo_bool_t
+_cairo_matrix_is_scale_0 (const cairo_matrix_t *matrix)
+{
+    return matrix->xx == 0. &&
+           matrix->xy == 0. &&
+           matrix->yx == 0. &&
+           matrix->yy == 0.;
+}
+
 double
 _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix)
 {
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 418f90a..8ad77f5 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -704,13 +704,12 @@ _cairo_scaled_font_init (cairo_scaled_font_t               *scaled_font,
 	 *
 	 * Also, the check for == 0. below may be too harsh...
 	 */
-        if (scaled_font->scale.xx == 0. && scaled_font->scale.xy == 0. &&
-	    scaled_font->scale.yx == 0. && scaled_font->scale.yy == 0.)
+        if (_cairo_matrix_is_scale_0 (&scaled_font->scale)) {
 	    cairo_matrix_init (&scaled_font->scale_inverse,
 			       0, 0, 0, 0,
 			       -scaled_font->scale.x0,
 			       -scaled_font->scale.y0);
-	else
+	} else
 	    return status;
     }
 
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index c00146f..34638ad 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -75,26 +75,34 @@ typedef struct _cairo_user_scaled_font {
 
 /* #cairo_user_scaled_font_t */
 
-static cairo_t *
-_cairo_user_scaled_font_create_recording_context (cairo_user_scaled_font_t *scaled_font)
+static cairo_surface_t *
+_cairo_user_scaled_font_create_recording_surface (const cairo_user_scaled_font_t *scaled_font)
 {
     cairo_content_t content;
-    cairo_surface_t *recording_surface;
-    cairo_matrix_t scale;
-    cairo_t *cr;
 
     content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
 						     CAIRO_CONTENT_COLOR_ALPHA :
 						     CAIRO_CONTENT_ALPHA;
 
-    recording_surface = cairo_recording_surface_create (content, NULL);
+    return cairo_recording_surface_create (content, NULL);
+}
+
+
+static cairo_t *
+_cairo_user_scaled_font_create_recording_context (const cairo_user_scaled_font_t *scaled_font,
+						  cairo_surface_t                *recording_surface)
+{
+    cairo_t *cr;
+
     cr = cairo_create (recording_surface);
-    cairo_surface_destroy (recording_surface);
 
-    scale = scaled_font->base.scale;
-    scale.x0 = scale.y0 = 0.;
+    if (!_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) {
+        cairo_matrix_t scale;
+	scale = scaled_font->base.scale;
+	scale.x0 = scale.y0 = 0.;
+	cairo_set_matrix (cr, &scale);
+    }
 
-    cairo_set_matrix (cr, &scale);
     cairo_set_font_size (cr, 1.0);
     cairo_set_font_options (cr, &scaled_font->base.options);
     cairo_set_source_rgb (cr, 1., 1., 1.);
@@ -117,25 +125,26 @@ _cairo_user_scaled_glyph_init (void			 *abstract_font,
 	cairo_text_extents_t extents = scaled_font->default_glyph_extents;
 	cairo_t *cr;
 
-	cr = _cairo_user_scaled_font_create_recording_context (scaled_font);
+	if (!face->scaled_font_methods.render_glyph)
+	    return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
 
-	if (face->scaled_font_methods.render_glyph) {
+	recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font);
+
+	/* special case for 0 rank matrix (as in _cairo_scaled_font_init): empty surface */
+        if (!_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) {
+	    cr = _cairo_user_scaled_font_create_recording_context (scaled_font, recording_surface);
 	    status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
 							     _cairo_scaled_glyph_index(scaled_glyph),
 							     cr, &extents);
-	} else
-	    status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
-
-	if (status == CAIRO_STATUS_SUCCESS)
-	    status = cairo_status (cr);
-
-	recording_surface = cairo_surface_reference (cairo_get_target (cr));
+	    cairo_destroy (cr);
 
-	cairo_destroy (cr);
+	    if (status == CAIRO_STATUS_SUCCESS)
+	        status = cairo_status (cr);
 
-	if (unlikely (status)) {
-	    cairo_surface_destroy (recording_surface);
-	    return status;
+	    if (unlikely (status)) {
+	        cairo_surface_destroy (recording_surface);
+	        return status;
+	    }
 	}
 
 	_cairo_scaled_glyph_set_recording_surface (scaled_glyph,
@@ -424,9 +433,12 @@ _cairo_user_font_face_scaled_font_create (void                        *abstract_
 	/* Give away fontmap lock such that user-font can use other fonts */
 	status = _cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font->base);
 	if (status == CAIRO_STATUS_SUCCESS) {
+	    cairo_surface_t *recording_surface;
 	    cairo_t *cr;
 
-	    cr = _cairo_user_scaled_font_create_recording_context (user_scaled_font);
+	    recording_surface = _cairo_user_scaled_font_create_recording_surface (user_scaled_font);
+	    cr = _cairo_user_scaled_font_create_recording_context (user_scaled_font, recording_surface);
+	    cairo_surface_destroy (recording_surface);
 
 	    status = font_face->scaled_font_methods.init (&user_scaled_font->base,
 							  cr,
diff --git a/src/cairoint.h b/src/cairoint.h
index 6ccc18f..1a938ed 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2052,6 +2052,9 @@ _cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix,
 cairo_private cairo_bool_t
 _cairo_matrix_is_invertible (const cairo_matrix_t *matrix) cairo_pure;
 
+cairo_private cairo_bool_t
+_cairo_matrix_is_scale_0 (const cairo_matrix_t *matrix) cairo_pure;
+
 cairo_private double
 _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix) cairo_pure;
 
commit 6db247e13c6fa61879029b335c6fa649d810c11b
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Tue Jun 29 09:28:04 2010 +0200

    user-font: ignore translation in scale matrix
    
    Currently the translation component of the scaled_font scale matrix
    is applied by gstate and only linear components should be applied in
    font backends.
    
    Fixes font-matrix-translation (when using user-font as font backend).

diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index b8b617b..c00146f 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -80,6 +80,7 @@ _cairo_user_scaled_font_create_recording_context (cairo_user_scaled_font_t *scal
 {
     cairo_content_t content;
     cairo_surface_t *recording_surface;
+    cairo_matrix_t scale;
     cairo_t *cr;
 
     content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
@@ -90,7 +91,10 @@ _cairo_user_scaled_font_create_recording_context (cairo_user_scaled_font_t *scal
     cr = cairo_create (recording_surface);
     cairo_surface_destroy (recording_surface);
 
-    cairo_set_matrix (cr, &scaled_font->base.scale);
+    scale = scaled_font->base.scale;
+    scale.x0 = scale.y0 = 0.;
+
+    cairo_set_matrix (cr, &scale);
     cairo_set_font_size (cr, 1.0);
     cairo_set_font_options (cr, &scaled_font->base.options);
     cairo_set_source_rgb (cr, 1., 1., 1.);


More information about the cairo-commit mailing list