Index: src/cairo-scaled-font.c =================================================================== RCS file: /mirrors/freedesktop/cairo/cairo/src/cairo-scaled-font.c,v retrieving revision 1.4 diff -u -p -r1.4 cairo-scaled-font.c --- src/cairo-scaled-font.c 12 Sep 2005 18:15:52 -0000 1.4 +++ src/cairo-scaled-font.c 12 Sep 2005 23:52:22 -0000 @@ -461,6 +461,8 @@ UNWIND: cairo_scaled_font_t * cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font) { + cairo_scaled_font_map_t *font_map; + if (scaled_font == NULL) return NULL; @@ -471,30 +473,31 @@ cairo_scaled_font_reference (cairo_scale * we are using ref_count == 0 as a legitimate case for the * holdovers array. See below. */ - /* If the original reference count is 0, then this font must have - * been found in font_map->holdovers, (which means this caching is - * actually working). So now we remove it from the holdovers - * array. */ - if (scaled_font->ref_count == 0) { - cairo_scaled_font_map_t *font_map; - int i; - - font_map = _cairo_scaled_font_map_lock (); - { + font_map = _cairo_scaled_font_map_lock (); + { + /* If the original reference count is 0, then this font must have + * been found in font_map->holdovers, (which means this caching is + * actually working). So now we remove it from the holdovers + * array. */ + if (scaled_font->ref_count == 0) { + int i; + for (i = 0; i < font_map->num_holdovers; i++) if (font_map->holdovers[i] == scaled_font) break; + assert (i < font_map->num_holdovers); - + font_map->num_holdovers--; memmove (&font_map->holdovers[i], &font_map->holdovers[i+1], (font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*)); } - _cairo_scaled_font_map_unlock (); + + scaled_font->ref_count++; } + _cairo_scaled_font_map_unlock (); - scaled_font->ref_count++; return scaled_font; } @@ -518,38 +521,39 @@ cairo_scaled_font_destroy (cairo_scaled_ if (scaled_font->ref_count == (unsigned int)-1) return; - assert (scaled_font->ref_count > 0); - - if (--(scaled_font->ref_count) > 0) - return; - font_map = _cairo_scaled_font_map_lock (); - assert (font_map != NULL); { - /* Rather than immediately destroying this object, we put it into - * the font_map->holdovers array in case it will get used again - * soon. To make room for it, we do actually destroy the - * least-recently-used holdover. - */ - if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS) { - cairo_scaled_font_t *lru; + assert (font_map != NULL); - lru = font_map->holdovers[0]; - assert (lru->ref_count == 0); - - _cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry); + assert (scaled_font->ref_count > 0); - _cairo_scaled_font_fini (lru); - free (lru); - - font_map->num_holdovers--; - memmove (&font_map->holdovers[0], - &font_map->holdovers[1], - font_map->num_holdovers * sizeof (cairo_scaled_font_t*)); + if (--(scaled_font->ref_count) == 0) + { + /* Rather than immediately destroying this object, we put it into + * the font_map->holdovers array in case it will get used again + * soon. To make room for it, we do actually destroy the + * least-recently-used holdover. + */ + if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS) { + cairo_scaled_font_t *lru; + + lru = font_map->holdovers[0]; + assert (lru->ref_count == 0); + + _cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry); + + _cairo_scaled_font_fini (lru); + free (lru); + + font_map->num_holdovers--; + memmove (&font_map->holdovers[0], + &font_map->holdovers[1], + font_map->num_holdovers * sizeof (cairo_scaled_font_t*)); + } + + font_map->holdovers[font_map->num_holdovers] = scaled_font; + font_map->num_holdovers++; } - - font_map->holdovers[font_map->num_holdovers] = scaled_font; - font_map->num_holdovers++; } _cairo_scaled_font_map_unlock (); } @@ -691,6 +695,7 @@ _cairo_scaled_font_text_to_glyphs (cairo &scaled_glyph); if (status) { free (*glyphs); + *glyphs = NULL; goto FAIL; } @@ -1100,7 +1105,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled cairo_scaled_glyph_info_t info, cairo_scaled_glyph_t **scaled_glyph_ret) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_cache_entry_t key; cairo_scaled_glyph_t *scaled_glyph; cairo_scaled_glyph_info_t need_info; @@ -1108,6 +1113,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled if (scaled_font->status) return scaled_font->status; + _cairo_scaled_font_map_lock (); + key.hash = index; /* * Check cache for glyph @@ -1122,8 +1129,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t)); if (scaled_glyph == NULL) { status = CAIRO_STATUS_NO_MEMORY; - _cairo_scaled_font_set_error (scaled_font, status); - return status; + goto CLEANUP; } _cairo_scaled_glyph_set_index(scaled_glyph, index); @@ -1136,18 +1142,13 @@ _cairo_scaled_glyph_lookup (cairo_scaled /* ask backend to initialize metrics and shape fields */ status = (*scaled_font->backend-> scaled_glyph_init) (scaled_font, scaled_glyph, info); - if (status) { - _cairo_scaled_glyph_destroy (scaled_glyph); - _cairo_scaled_font_set_error (scaled_font, status); - return status; - } + if (status) + goto CLEANUP; + status = _cairo_cache_insert (scaled_font->glyphs, &scaled_glyph->cache_entry); - if (status) { - _cairo_scaled_glyph_destroy (scaled_glyph); - _cairo_scaled_font_set_error (scaled_font, status); - return status; - } + if (status) + goto CLEANUP; } /* * Check and see if the glyph, as provided, @@ -1166,8 +1167,20 @@ _cairo_scaled_glyph_lookup (cairo_scaled status = (*scaled_font->backend-> scaled_glyph_init) (scaled_font, scaled_glyph, need_info); if (status) - return status; + goto CLEANUP; } - *scaled_glyph_ret = scaled_glyph; - return CAIRO_STATUS_SUCCESS; + + CLEANUP: + if (status) { + _cairo_scaled_font_set_error (scaled_font, status); + if (scaled_glyph) + _cairo_scaled_glyph_destroy (scaled_glyph); + *scaled_glyph_ret = NULL; + } else { + *scaled_glyph_ret = scaled_glyph; + } + + _cairo_scaled_font_map_lock (); + + return status; }