Index: ChangeLog =================================================================== RCS file: /mirrors/freedesktop/cairo/cairo/ChangeLog,v retrieving revision 1.941 diff -u -p -r1.941 ChangeLog --- ChangeLog 22 Aug 2005 22:19:03 -0000 1.941 +++ ChangeLog 22 Aug 2005 23:34:53 -0000 @@ -1,3 +1,14 @@ +2005-08-22 Carl Worth + + Fix for bug #4192: + + * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_map_destroy), + (_cairo_ft_unscaled_font_fini), (_cairo_ft_unscaled_font_destroy): + Pull FT_Done_Face out of _cairo_ft_unscaled_font_fini up into the + callers so that it can be next to font_map->num_open_faces--. Add + the two missing decrements to num_open_faces. Add two assert + statements to preserve this logic. + 2005-08-22 Owen Taylor Support artificial bold fonts with FC_EMBOLDEN; patch Index: src/cairo-ft-font.c =================================================================== RCS file: /mirrors/freedesktop/cairo/cairo/src/cairo-ft-font.c,v retrieving revision 1.105 diff -u -p -r1.105 cairo-ft-font.c --- src/cairo-ft-font.c 22 Aug 2005 22:19:03 -0000 1.105 +++ src/cairo-ft-font.c 22 Aug 2005 22:51:43 -0000 @@ -210,10 +210,18 @@ _cairo_ft_unscaled_font_map_destroy (voi break; _cairo_hash_table_remove (font_map->hash_table, &unscaled->base.hash_entry); + + if (unscaled->face) { + FT_Done_Face (unscaled->face); + unscaled->face = NULL; + font_map->num_open_faces--; + } _cairo_ft_unscaled_font_fini (unscaled); free (unscaled); } + assert (font_map->num_open_faces == 0); + FT_Done_FreeType (font_map->ft_library); _cairo_hash_table_destroy (font_map->hash_table); @@ -329,18 +337,25 @@ _cairo_unscaled_font_is_ft (cairo_unscal return unscaled_font->backend == &cairo_ft_unscaled_font_backend; } +/** + * _cairo_ft_unscaled_font_fini: + * + * Free all data associated with a cairo_ft_unscaled_font_t. + * + * WARNING: The unscaled->face field must be NULL before calling this + * function. This is because the cairo_ft_unscaled_font_map keeps a + * count of these faces (font_map->num_open_faces) so it maintains + * the unscaled->face field while it has its lock held. + **/ static void _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled) { + assert (unscaled->face == NULL); + if (unscaled->filename) { free (unscaled->filename); unscaled->filename = NULL; } - - if (unscaled->face) { - FT_Done_Face (unscaled->face); - unscaled->face = NULL; - } } static int @@ -460,9 +475,14 @@ _cairo_ft_unscaled_font_destroy (void *a _cairo_hash_table_remove (font_map->hash_table, &unscaled->base.hash_entry); - _cairo_ft_unscaled_font_map_unlock (); - + if (unscaled->face) { + FT_Done_Face (unscaled->face); + unscaled->face = NULL; + font_map->num_open_faces--; + } _cairo_ft_unscaled_font_fini (unscaled); + + _cairo_ft_unscaled_font_map_unlock (); } }