summaryrefslogtreecommitdiff
path: root/pango/pangox-fontmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/pangox-fontmap.c')
-rw-r--r--pango/pangox-fontmap.c67
1 files changed, 58 insertions, 9 deletions
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));
+}