summaryrefslogtreecommitdiff
path: root/src/cairo-user-font.c
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2010-06-29 09:58:54 +0200
committerAndrea Canciani <ranma42@gmail.com>2010-06-30 12:31:25 +0200
commitd2d6c96c24501d888422ea42d3c90d3c8f3647a0 (patch)
treeedf850fa25b6b3b7b8602c1ac2b175d774c2c2c3 /src/cairo-user-font.c
parent6db247e13c6fa61879029b335c6fa649d810c11b (diff)
downloadcairo-d2d6c96c24501d888422ea42d3c90d3c8f3647a0.tar.gz
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).
Diffstat (limited to 'src/cairo-user-font.c')
-rw-r--r--src/cairo-user-font.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index c00146f0c..34638addf 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,