diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 14:58:41 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 15:02:26 +0000 |
commit | 44a093eb95c950b0e8f2d7d1cdb9719cb8a550f7 (patch) | |
tree | 12eec52b6554d16f2194c598dde91fc388c94186 | |
parent | 80cc532271d7e94ad02732841fbcdc811cce8754 (diff) |
scaled-font: Always hold the mutex even for single glyph probes
The freeze/thaw routines have a side-effect of managing the global glyph
cache in addition to taking the mutex on the font. If we don't call
them, we may end up indefinitely keeping the global glyph cache frozen
(effectively leaking glyphs to the maximum of all open fonts) and
triggering asserts.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/cairo-scaled-font.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index dc6a6fd7..9b0fc923 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -2131,36 +2131,37 @@ _cairo_scaled_font_single_glyph_device_extents (cairo_scaled_font_t *scaled_fon const cairo_glyph_t *glyph, cairo_rectangle_int_t *extents) { - cairo_round_glyph_positions_t round_xy; cairo_scaled_glyph_t *scaled_glyph; cairo_status_t status; - cairo_box_t box; - cairo_fixed_t v; + _cairo_scaled_font_freeze_cache (scaled_font); status = _cairo_scaled_glyph_lookup (scaled_font, glyph->index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (unlikely (status)) - return status; + if (likely (status == CAIRO_STATUS_SUCCESS)) { + cairo_bool_t round_xy = _cairo_font_options_get_round_glyph_positions (&scaled_font->options) == CAIRO_ROUND_GLYPH_POS_ON; + cairo_box_t box; + cairo_fixed_t v; - round_xy = _cairo_font_options_get_round_glyph_positions (&scaled_font->options); - if (round_xy == CAIRO_ROUND_GLYPH_POS_ON) - v = _cairo_fixed_from_int (_cairo_lround (glyph->x)); - else - v = _cairo_fixed_from_double (glyph->x); - box.p1.x = v + scaled_glyph->bbox.p1.x; - box.p2.x = v + scaled_glyph->bbox.p2.x; + if (round_xy) + v = _cairo_fixed_from_int (_cairo_lround (glyph->x)); + else + v = _cairo_fixed_from_double (glyph->x); + box.p1.x = v + scaled_glyph->bbox.p1.x; + box.p2.x = v + scaled_glyph->bbox.p2.x; - if (round_xy == CAIRO_ROUND_GLYPH_POS_ON) - v = _cairo_fixed_from_int (_cairo_lround (glyph->y)); - else - v = _cairo_fixed_from_double (glyph->y); - box.p1.y = v + scaled_glyph->bbox.p1.y; - box.p2.y = v + scaled_glyph->bbox.p2.y; + if (round_xy) + v = _cairo_fixed_from_int (_cairo_lround (glyph->y)); + else + v = _cairo_fixed_from_double (glyph->y); + box.p1.y = v + scaled_glyph->bbox.p1.y; + box.p2.y = v + scaled_glyph->bbox.p2.y; - _cairo_box_round_to_rectangle (&box, extents); - return CAIRO_STATUS_SUCCESS; + _cairo_box_round_to_rectangle (&box, extents); + } + _cairo_scaled_font_thaw_cache (scaled_font); + return status; } /* |