2 * pango-fontcache.c: Cache of XFontStructs by XLFD
4 * Copyright (C) 2000 Red Hat Software
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 /* Number of fonts to retain after they are not otherwise referenced.
32 typedef struct _CacheEntry CacheEntry;
34 struct _PangoXFontCache
56 free_cache_entry (char *xlfd G_GNUC_UNUSED,
58 PangoXFontCache *cache)
61 XFreeFont (cache->display, entry->fs);
63 g_slice_free (CacheEntry, entry);
67 * pango_x_font_cache_free:
68 * @cache: a #PangoXFontCache
70 * Frees a #PangoXFontCache and all associated memory. All fonts loaded
71 * through this font cache will be freed along with the cache.
74 pango_x_font_cache_free (PangoXFontCache *cache)
76 g_return_if_fail (cache != NULL);
78 g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
80 g_hash_table_destroy (cache->forward);
81 g_hash_table_destroy (cache->back);
83 g_list_free (cache->mru);
85 g_slice_free (PangoXFontCache, cache);
89 * pango_x_font_cache_new:
90 * @display: an X display.
92 * Creates a font cache for the specified display.
94 * Return value: The newly allocated #PangoXFontCache, which should be
95 * freed with pango_x_font_cache_free().
98 pango_x_font_cache_new (Display *display)
100 PangoXFontCache *cache;
102 g_return_val_if_fail (display != NULL, NULL);
104 cache = g_slice_new (PangoXFontCache);
106 cache->display = display;
108 cache->forward = g_hash_table_new (g_str_hash, g_str_equal);
109 cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
112 cache->mru_tail = NULL;
113 cache->mru_count = 0;
119 cache_entry_unref (PangoXFontCache *cache, CacheEntry *entry)
121 if (g_atomic_int_dec_and_test (&entry->ref_count))
123 g_hash_table_remove (cache->forward, entry->xlfd);
124 g_hash_table_remove (cache->back, entry->fs);
126 free_cache_entry (NULL, entry, cache);
131 * pango_x_font_cache_load:
132 * @cache: a #PangoXFontCache
133 * @xlfd: the X Logical Font Description to load.
135 * Loads a #XFontStruct from a X Logical Font Description. The
136 * result may be newly loaded, or it may have been previously
139 * Return value: The font structure, or %NULL if the font could
140 * not be loaded. In order to free this structure, you must call
141 * pango_x_font_cache_unload().
144 pango_x_font_cache_load (PangoXFontCache *cache,
149 g_return_val_if_fail (cache != NULL, NULL);
150 g_return_val_if_fail (xlfd != NULL, NULL);
152 entry = g_hash_table_lookup (cache->forward, xlfd);
156 g_atomic_int_inc (&entry->ref_count);
160 XFontStruct *fs = XLoadQueryFont (cache->display, xlfd);
165 entry = g_slice_new (CacheEntry);
167 entry->xlfd = g_strdup (xlfd);
170 entry->ref_count = 1;
173 g_hash_table_insert (cache->forward, entry->xlfd, entry);
174 g_hash_table_insert (cache->back, entry->fs, entry);
179 if (cache->mru_count > 1 && entry->mru->prev)
181 /* Move to the head of the mru list */
183 if (entry->mru == cache->mru_tail)
185 cache->mru_tail = cache->mru_tail->prev;
186 cache->mru_tail->next = NULL;
190 entry->mru->prev->next = entry->mru->next;
191 entry->mru->next->prev = entry->mru->prev;
194 entry->mru->next = cache->mru;
195 entry->mru->prev = NULL;
196 cache->mru->prev = entry->mru;
197 cache->mru = entry->mru;
202 g_atomic_int_inc (&entry->ref_count);
204 /* Insert into the mru list */
206 if (cache->mru_count == CACHE_SIZE)
208 CacheEntry *old_entry = cache->mru_tail->data;
210 cache->mru_tail = cache->mru_tail->prev;
211 cache->mru_tail->next = NULL;
213 g_list_free_1 (old_entry->mru);
214 old_entry->mru = NULL;
215 cache_entry_unref (cache, old_entry);
220 cache->mru = g_list_prepend (cache->mru, entry);
221 if (!cache->mru_tail)
222 cache->mru_tail = cache->mru;
223 entry->mru = cache->mru;
230 * pango_x_font_cache_unload:
231 * @cache: a #PangoXFontCache
232 * @fs: the font structure to unload
234 * Frees a font structure previously loaded with pango_x_font_cache_load().
237 pango_x_font_cache_unload (PangoXFontCache *cache,
242 g_return_if_fail (cache != NULL);
243 g_return_if_fail (fs != NULL);
245 entry = g_hash_table_lookup (cache->back, fs);
246 g_return_if_fail (entry != NULL);
248 cache_entry_unref (cache, entry);