diff --git a/ChangeLog b/ChangeLog index 7f18ae37c..035cad0a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-02-03 Owen Taylor + + * src/cairo_ft_font.c (_cairo_ft_font_text_to_glyphs, + _cairo_ft_font_create_glyph): Fix missing cairo_ft_font_unlock_face(). + + * src/cairo_cache.c (_cairo_cache_random_entry): Fix problem + when no entry could be found. + 2005-02-03 Owen Taylor * src/cairo_font.c src/cairo.h doc/public/cairo-sections.txt: diff --git a/src/cairo-cache.c b/src/cairo-cache.c index 8cf432a24..d1ad5a4e2 100644 --- a/src/cairo-cache.c +++ b/src/cairo-cache.c @@ -503,7 +503,7 @@ _cairo_cache_random_entry (cairo_cache_t *cache, { cairo_cache_entry_base_t **slot = _random_entry (cache, predicate); - return *slot; + return slot ? *slot : NULL; } unsigned long diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index cd5440b13..5ede11160 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -353,7 +353,7 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) { ft_cache_t *ftcache; FT_Face face = NULL; - + if (unscaled->face) { unscaled->lock++; return unscaled->face; @@ -399,6 +399,8 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) static void _ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled) { + assert (unscaled->lock > 0); + unscaled->lock--; } @@ -730,8 +732,8 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, FT_Face face; cairo_glyph_cache_key_t key; cairo_image_glyph_cache_entry_t *val; - cairo_cache_t *cache; - cairo_status_t status; + cairo_cache_t *cache = NULL; + cairo_status_t status = CAIRO_STATUS_SUCCESS; _cairo_ft_font_get_glyph_cache_key (font, &key); @@ -739,28 +741,23 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, if (!CAIRO_OK (status)) return status; - if (ucs4 == NULL) - return CAIRO_STATUS_NO_MEMORY; - - *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); - if (*glyphs == NULL) - { - free (ucs4); - return CAIRO_STATUS_NO_MEMORY; - } - face = cairo_ft_font_lock_face ((cairo_font_t *)font); - if (!face) - { - free (ucs4); - return CAIRO_STATUS_NO_MEMORY; + if (!face) { + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL1; } _cairo_lock_global_image_glyph_cache (); cache = _cairo_get_global_image_glyph_cache (); if (cache == NULL) { - _cairo_unlock_global_image_glyph_cache (); - return CAIRO_STATUS_NO_MEMORY; + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL2; + } + + *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); + if (*glyphs == NULL) { + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL2; } for (i = 0; i < *nglyphs; i++) @@ -779,10 +776,19 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, x += val->extents.x_advance; y += val->extents.y_advance; } - _cairo_unlock_global_image_glyph_cache (); + + free (*glyphs); + FAIL2: + if (cache) + _cairo_unlock_global_image_glyph_cache (); + + cairo_ft_font_unlock_face ((cairo_font_t *)font); + + FAIL1: free (ucs4); - return CAIRO_STATUS_SUCCESS; + + return status; } @@ -1185,6 +1191,7 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) FT_BBox cbox; FT_Bitmap bitmap; FT_Glyph_Metrics *metrics; + cairo_status_t status = CAIRO_STATUS_SUCCESS; glyphslot = unscaled->face->glyph; metrics = &glyphslot->metrics; @@ -1195,8 +1202,10 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) _ft_unscaled_font_set_scale (unscaled, &val->key.scale); - if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) + if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) { + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; + } /* * Note: the font's coordinate system is upside down from ours, so the @@ -1246,13 +1255,16 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) bitmap.pitch = stride; bitmap.buffer = calloc (1, stride * height); - if (bitmap.buffer == NULL) + if (bitmap.buffer == NULL) { + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; + } FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { free (bitmap.buffer); + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; } @@ -1262,6 +1274,7 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) width, height, stride); if (val->image == NULL) { free (bitmap.buffer); + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; } @@ -1278,11 +1291,10 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) val->size.x = (short) (cbox.xMin >> 6); val->size.y = - (short) (cbox.yMax >> 6); - return CAIRO_STATUS_SUCCESS; - FAIL: _ft_unscaled_font_unlock_face (unscaled); - return CAIRO_STATUS_NO_MEMORY; + + return status; } const cairo_font_backend_t cairo_ft_font_backend = { diff --git a/src/cairo-hash.c b/src/cairo-hash.c index 8cf432a24..d1ad5a4e2 100644 --- a/src/cairo-hash.c +++ b/src/cairo-hash.c @@ -503,7 +503,7 @@ _cairo_cache_random_entry (cairo_cache_t *cache, { cairo_cache_entry_base_t **slot = _random_entry (cache, predicate); - return *slot; + return slot ? *slot : NULL; } unsigned long diff --git a/src/cairo_cache.c b/src/cairo_cache.c index 8cf432a24..d1ad5a4e2 100644 --- a/src/cairo_cache.c +++ b/src/cairo_cache.c @@ -503,7 +503,7 @@ _cairo_cache_random_entry (cairo_cache_t *cache, { cairo_cache_entry_base_t **slot = _random_entry (cache, predicate); - return *slot; + return slot ? *slot : NULL; } unsigned long diff --git a/src/cairo_ft_font.c b/src/cairo_ft_font.c index cd5440b13..5ede11160 100644 --- a/src/cairo_ft_font.c +++ b/src/cairo_ft_font.c @@ -353,7 +353,7 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) { ft_cache_t *ftcache; FT_Face face = NULL; - + if (unscaled->face) { unscaled->lock++; return unscaled->face; @@ -399,6 +399,8 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) static void _ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled) { + assert (unscaled->lock > 0); + unscaled->lock--; } @@ -730,8 +732,8 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, FT_Face face; cairo_glyph_cache_key_t key; cairo_image_glyph_cache_entry_t *val; - cairo_cache_t *cache; - cairo_status_t status; + cairo_cache_t *cache = NULL; + cairo_status_t status = CAIRO_STATUS_SUCCESS; _cairo_ft_font_get_glyph_cache_key (font, &key); @@ -739,28 +741,23 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, if (!CAIRO_OK (status)) return status; - if (ucs4 == NULL) - return CAIRO_STATUS_NO_MEMORY; - - *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); - if (*glyphs == NULL) - { - free (ucs4); - return CAIRO_STATUS_NO_MEMORY; - } - face = cairo_ft_font_lock_face ((cairo_font_t *)font); - if (!face) - { - free (ucs4); - return CAIRO_STATUS_NO_MEMORY; + if (!face) { + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL1; } _cairo_lock_global_image_glyph_cache (); cache = _cairo_get_global_image_glyph_cache (); if (cache == NULL) { - _cairo_unlock_global_image_glyph_cache (); - return CAIRO_STATUS_NO_MEMORY; + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL2; + } + + *glyphs = (cairo_glyph_t *) malloc ((*nglyphs) * (sizeof (cairo_glyph_t))); + if (*glyphs == NULL) { + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL2; } for (i = 0; i < *nglyphs; i++) @@ -779,10 +776,19 @@ _cairo_ft_font_text_to_glyphs (void *abstract_font, x += val->extents.x_advance; y += val->extents.y_advance; } - _cairo_unlock_global_image_glyph_cache (); + + free (*glyphs); + FAIL2: + if (cache) + _cairo_unlock_global_image_glyph_cache (); + + cairo_ft_font_unlock_face ((cairo_font_t *)font); + + FAIL1: free (ucs4); - return CAIRO_STATUS_SUCCESS; + + return status; } @@ -1185,6 +1191,7 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) FT_BBox cbox; FT_Bitmap bitmap; FT_Glyph_Metrics *metrics; + cairo_status_t status = CAIRO_STATUS_SUCCESS; glyphslot = unscaled->face->glyph; metrics = &glyphslot->metrics; @@ -1195,8 +1202,10 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) _ft_unscaled_font_set_scale (unscaled, &val->key.scale); - if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) + if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) { + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; + } /* * Note: the font's coordinate system is upside down from ours, so the @@ -1246,13 +1255,16 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) bitmap.pitch = stride; bitmap.buffer = calloc (1, stride * height); - if (bitmap.buffer == NULL) + if (bitmap.buffer == NULL) { + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; + } FT_Outline_Translate (outline, -cbox.xMin, -cbox.yMin); if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { free (bitmap.buffer); + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; } @@ -1262,6 +1274,7 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) width, height, stride); if (val->image == NULL) { free (bitmap.buffer); + status = CAIRO_STATUS_NO_MEMORY; goto FAIL; } @@ -1278,11 +1291,10 @@ _cairo_ft_font_create_glyph (cairo_image_glyph_cache_entry_t *val) val->size.x = (short) (cbox.xMin >> 6); val->size.y = - (short) (cbox.yMax >> 6); - return CAIRO_STATUS_SUCCESS; - FAIL: _ft_unscaled_font_unlock_face (unscaled); - return CAIRO_STATUS_NO_MEMORY; + + return status; } const cairo_font_backend_t cairo_ft_font_backend = {