diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-06-05 19:36:33 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-06-05 19:36:33 +0000 |
commit | 7b428440247958a9c52fe29c4aeeecfd6f43f39b (patch) | |
tree | 586a5c61355a622caab97e583e703e2390dbbf8f /pango | |
parent | 40638f2de292719e3615e5ae77ff5f97d57300bc (diff) | |
download | pango-7b428440247958a9c52fe29c4aeeecfd6f43f39b.tar.gz |
Fix problem with unloading fonts.
Mon Jun 5 15:35:03 2000 Owen Taylor <otaylor@redhat.com>
* pango/pangox-fontcache.c (pango_x_font_cache_unload): Fix
problem with unloading fonts.
* pango/pangox-fontmap.c pango/pangox-private.h pangox/pangox.c:
Add a simple PangoXFont; get rid of the eternal caching of
all fonts.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-fontmap.h | 1 | ||||
-rw-r--r-- | pango/pangox-fontcache.c | 2 | ||||
-rw-r--r-- | pango/pangox-fontmap.c | 67 | ||||
-rw-r--r-- | pango/pangox-private.h | 11 | ||||
-rw-r--r-- | pango/pangox.c | 31 |
5 files changed, 100 insertions, 12 deletions
diff --git a/pango/pango-fontmap.h b/pango/pango-fontmap.h index 7fbe3785..a0ad1510 100644 --- a/pango/pango-fontmap.h +++ b/pango/pango-fontmap.h @@ -48,7 +48,6 @@ struct _PangoFontMapClass { GObjectClass parent_class; - void (*destroy) (PangoFontMap *fontmap); PangoFont *(*load_font) (PangoFontMap *fontmap, const PangoFontDescription *desc); void (*list_fonts) (PangoFontMap *fontmap, diff --git a/pango/pangox-fontcache.c b/pango/pangox-fontcache.c index 50264a2c..14b17a70 100644 --- a/pango/pangox-fontcache.c +++ b/pango/pangox-fontcache.c @@ -238,7 +238,7 @@ pango_x_font_cache_unload (PangoXFontCache *cache, g_return_if_fail (cache != NULL); g_return_if_fail (fs != NULL); - entry = g_hash_table_lookup (cache->forward, fs); + entry = g_hash_table_lookup (cache->back, fs); g_return_if_fail (entry != NULL); cache_entry_unref (cache, entry); diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index ac552e04..6309387a 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -40,6 +40,9 @@ typedef struct _PangoXFontMap PangoXFontMap; typedef struct _PangoXFontMapClass PangoXFontMapClass; typedef struct _PangoXSizeInfo PangoXSizeInfo; +/* Number of freed fonts */ +#define MAX_FREED_FONTS 16 + /* This is the largest field length we will accept. If a fontname has a field larger than this we will skip it. */ #define XLFD_MAX_FIELD_LEN 64 @@ -72,6 +75,7 @@ struct _PangoXFontMap Display *display; PangoXFontCache *font_cache; + GQueue *freed_fonts; GHashTable *families; GHashTable *size_infos; @@ -245,7 +249,8 @@ pango_x_font_map_for_display (Display *display) xfontmap->display = display; xfontmap->font_cache = pango_x_font_cache_new (display); - + xfontmap->freed_fonts = g_queue_new (); + /* Get a maximum of MAX_FONTS fontnames from the X server. Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since the latter may result in fonts being returned which don't actually exist. @@ -283,6 +288,9 @@ pango_x_font_map_finalize (GObject *object) PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (object); pango_x_font_cache_free (xfontmap->font_cache); + g_list_foreach (xfontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); + g_queue_free (xfontmap->freed_fonts); + /* FIXME: Lots more here */ fontmaps = g_list_remove (fontmaps, object); @@ -472,7 +480,11 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, if (xfont->size == description->size) { result = (PangoFont *)xfont; + g_object_ref (G_OBJECT (result)); + if (xfont->in_cache) + pango_x_fontmap_cache_remove (fontmap, xfont); + break; } tmp_list = tmp_list->next; @@ -480,15 +492,14 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, if (!result) { - result = (PangoFont *)pango_x_font_new (xfontmap->display, best_match->xlfd, description->size); - ((PangoXFont *)result)->entry = best_match; - best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, result); - } + PangoXFont *xfont = pango_x_font_new (xfontmap->display, best_match->xlfd, description->size); + + xfont->fontmap = fontmap; + xfont->entry = best_match; + best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont); - /* HORRIBLE performance hack until some better caching scheme is arrived at - */ - if (result) - g_object_ref (G_OBJECT (result)); + result = (PangoFont *)xfont; + } } } @@ -1400,3 +1411,41 @@ pango_x_font_map_get_font_cache (PangoFontMap *font_map) return PANGO_X_FONT_MAP (font_map)->font_cache; } + +void +pango_x_fontmap_cache_add (PangoFontMap *fontmap, + PangoXFont *xfont) +{ + PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (fontmap); + + if (xfontmap->freed_fonts->length == MAX_FREED_FONTS) + { + PangoXFont *old_font = g_queue_pop_tail (xfontmap->freed_fonts); + g_object_unref (G_OBJECT (old_font)); + } + + g_object_ref (G_OBJECT (xfont)); + g_queue_push_head (xfontmap->freed_fonts, xfont); + xfont->in_cache = TRUE; +} + +void +pango_x_fontmap_cache_remove (PangoFontMap *fontmap, + PangoXFont *xfont) +{ + PangoXFontMap *xfontmap = PANGO_X_FONT_MAP (fontmap); + + GList *link = g_list_find (xfontmap->freed_fonts->head, xfont); + if (link == xfontmap->freed_fonts->tail) + { + xfontmap->freed_fonts->tail = xfontmap->freed_fonts->tail->prev; + if (xfontmap->freed_fonts->tail) + xfontmap->freed_fonts->tail->next = NULL; + } + + xfontmap->freed_fonts->head = g_list_delete_link (xfontmap->freed_fonts->head, link); + xfontmap->freed_fonts->length--; + xfont->in_cache = FALSE; + + g_object_unref (G_OBJECT (xfont)); +} diff --git a/pango/pangox-private.h b/pango/pangox-private.h index e627bd44..5d90c186 100644 --- a/pango/pangox-private.h +++ b/pango/pangox-private.h @@ -50,6 +50,12 @@ struct _PangoXFont int max_subfonts; GSList *metrics_by_lang; + + PangoFontMap *fontmap; + /* If TRUE, font is in cache of recently unused fonts and not otherwise + * in use. + */ + gboolean in_cache; PangoXFontEntry *entry; /* Used to remove cached fonts */ }; @@ -68,4 +74,9 @@ PangoCoverage *pango_x_font_entry_get_coverage (PangoXFontEntry *entry, void pango_x_font_entry_remove (PangoXFontEntry *entry, PangoFont *font); +void pango_x_fontmap_cache_add (PangoFontMap *fontmap, + PangoXFont *xfont); +void pango_x_fontmap_cache_remove (PangoFontMap *fontmap, + PangoXFont *xfont); + #endif /* __PANGOX_PRIVATE_H__ */ diff --git a/pango/pangox.c b/pango/pangox.c index f28a0381..9110ace1 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -69,8 +69,11 @@ struct _PangoXFontClass PangoFontClass parent_class; }; +static PangoFontClass *parent_class; /* Parent class structure for PangoXFont */ + static void pango_x_font_class_init (PangoXFontClass *class); static void pango_x_font_init (PangoXFont *xfont); +static void pango_x_font_shutdown (GObject *object); static void pango_x_font_finalize (GObject *object); static PangoFontDescription *pango_x_font_describe (PangoFont *font); @@ -249,8 +252,12 @@ pango_x_font_class_init (PangoXFontClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); PangoFontClass *font_class = PANGO_FONT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_x_font_finalize; + object_class->shutdown = pango_x_font_shutdown; + font_class->describe = pango_x_font_describe; font_class->get_coverage = pango_x_font_get_coverage; font_class->find_shaper = pango_x_font_find_shaper; @@ -901,6 +908,22 @@ pango_x_font_subfont_xlfd (PangoFont *font, } static void +pango_x_font_shutdown (GObject *object) +{ + PangoXFont *xfont = PANGO_X_FONT (object); + + /* If the font is not already in the freed-fonts cache, add it, + * if it is already there, do nothing and the font will be + * freed. + */ + if (!xfont->in_cache) + pango_x_fontmap_cache_add (xfont->fontmap, xfont); + + G_OBJECT_CLASS (parent_class)->shutdown (object); +} + + +static void subfonts_foreach (gpointer key, gpointer value, gpointer data) { g_free (key); @@ -911,6 +934,9 @@ static void pango_x_font_finalize (GObject *object) { PangoXFont *xfont = (PangoXFont *)object; + PangoFontMap *fontmap = pango_x_font_map_for_display (xfont->display); + PangoXFontCache *cache = pango_x_font_map_get_font_cache (fontmap); + int i; for (i=0; i<xfont->n_subfonts; i++) @@ -918,8 +944,9 @@ pango_x_font_finalize (GObject *object) PangoXSubfontInfo *info = xfont->subfonts[i]; g_free (info->xlfd); + if (info->font_struct) - XFreeFont (xfont->display, info->font_struct); + pango_x_font_cache_unload (cache, info->font_struct); g_free (info); } @@ -936,6 +963,8 @@ pango_x_font_finalize (GObject *object) pango_x_font_entry_remove (xfont->entry, (PangoFont *)xfont); g_strfreev (xfont->fonts); + + G_OBJECT_CLASS (parent_class)->finalize (object); } static PangoFontDescription * |