diff options
author | Andrea Canciani <ranma42@gmail.com> | 2010-06-29 09:58:54 +0200 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-06-30 12:31:25 +0200 |
commit | d2d6c96c24501d888422ea42d3c90d3c8f3647a0 (patch) | |
tree | edf850fa25b6b3b7b8602c1ac2b175d774c2c2c3 /src/cairo-user-font.c | |
parent | 6db247e13c6fa61879029b335c6fa649d810c11b (diff) | |
download | cairo-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.c | 60 |
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, |