3 * Copyright (C) 2003-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
25 #include "svg-cache.h"
30 /*========================================================*/
32 /*========================================================*/
37 RsvgHandle *svg_handle;
42 /*========================================================*/
43 /* Private globals. */
44 /*========================================================*/
47 /*========================================================*/
48 /* Private function prototypes. */
49 /*========================================================*/
51 static void record_destroy (gpointer val);
53 static void add_name_to_list (gpointer key,
58 /*---------------------------------------------------------------------------*/
59 /* PRIVATE. Destroy cache record. */
60 /*---------------------------------------------------------------------------*/
62 record_destroy (gpointer val)
64 CacheRecord *record = (CacheRecord *)val;
66 g_return_if_fail (record);
69 g_object_unref (record->svg_handle);
70 g_free (record->contents);
75 /*****************************************************************************/
76 /* Create a new hash table to keep track of cached svgs. */
77 /*****************************************************************************/
79 gl_svg_cache_new (void)
81 GHashTable *svg_cache;
83 gl_debug (DEBUG_SVG_CACHE, "START");
85 svg_cache = g_hash_table_new_full (g_str_hash,
90 gl_debug (DEBUG_SVG_CACHE, "END svg_cache=%p", svg_cache);
96 /*****************************************************************************/
97 /* Free up previously allocated hash table and its contents. */
98 /*****************************************************************************/
100 gl_svg_cache_free (GHashTable *svg_cache)
102 gl_debug (DEBUG_SVG_CACHE, "START");
104 g_hash_table_destroy (svg_cache);
106 gl_debug (DEBUG_SVG_CACHE, "END");
110 /*****************************************************************************/
111 /* Add svg to cache explicitly. */
112 /*****************************************************************************/
114 gl_svg_cache_add_svg (GHashTable *svg_cache,
116 const gchar *contents)
118 CacheRecord *test_record, *record;
120 gl_debug (DEBUG_SVG_CACHE, "START");
122 test_record = g_hash_table_lookup (svg_cache, name);
123 if (test_record != NULL) {
124 /* svg is already in the cache. */
125 gl_debug (DEBUG_SVG_CACHE, "END already in cache");
129 record = g_new0 (CacheRecord, 1);
130 record->key = g_strdup (name);
131 record->references = 0; /* No references yet. */
132 record->svg_handle = rsvg_handle_new_from_data ((guchar *)contents, strlen(contents), NULL);
133 record->contents = g_strdup (contents);
135 g_hash_table_insert (svg_cache, record->key, record);
137 gl_debug (DEBUG_SVG_CACHE, "END");
141 /*****************************************************************************/
142 /* Get svg handle adding a reference. If not in cache, read it and add. */
143 /*****************************************************************************/
145 gl_svg_cache_get_handle (GHashTable *svg_cache,
149 RsvgHandle *svg_handle = NULL;
154 gl_debug (DEBUG_SVG_CACHE, "START svg_cache=%p", svg_cache);
156 record = g_hash_table_lookup (svg_cache, name);
160 record->references++;
161 gl_debug (DEBUG_SVG_CACHE, "references=%d", record->references);
162 gl_debug (DEBUG_SVG_CACHE, "END cached");
163 return record->svg_handle;
167 file = g_file_new_for_path (name);
168 if ( g_file_load_contents (file, NULL, &buffer, &length, NULL, NULL) )
170 svg_handle = rsvg_handle_new_from_data ((guchar *)buffer, length, NULL);
171 if ( svg_handle != NULL) {
172 record = g_new0 (CacheRecord, 1);
173 record->key = g_strdup (name);
174 record->references = 1;
175 record->svg_handle = svg_handle;
176 record->contents = buffer;
178 g_hash_table_insert (svg_cache, record->key, record);
181 g_object_unref (file);
183 gl_debug (DEBUG_SVG_CACHE, "END");
189 /*****************************************************************************/
190 /* Get contents. Do not add reference. */
191 /*****************************************************************************/
193 gl_svg_cache_get_contents (GHashTable *svg_cache,
198 gl_debug (DEBUG_SVG_CACHE, "START svg_cache=%p", svg_cache);
200 record = g_hash_table_lookup (svg_cache, name);
204 gl_debug (DEBUG_SVG_CACHE, "references=%d", record->references);
205 gl_debug (DEBUG_SVG_CACHE, "END cached");
206 return g_strdup (record->contents);
209 gl_debug (DEBUG_SVG_CACHE, "END");
215 /*****************************************************************************/
216 /* Remove svg, but only if no references left. */
217 /*****************************************************************************/
219 gl_svg_cache_remove_svg (GHashTable *svg_cache,
224 if (name == NULL) return;
226 gl_debug (DEBUG_SVG_CACHE, "START");
228 record = g_hash_table_lookup (svg_cache, name);
229 if (record == NULL) {
230 gl_debug (DEBUG_SVG_CACHE, "END not in cache");
234 record->references--;
236 if ( record->references == 0 ) {
237 g_hash_table_remove (svg_cache, name);
240 gl_debug (DEBUG_SVG_CACHE, "END");
244 /*---------------------------------------------------------------------------*/
245 /* PRIVATE. Add a name to a GList while iterating over cache. */
246 /*---------------------------------------------------------------------------*/
248 add_name_to_list (gpointer key,
252 gchar *name = (gchar *)key;
253 GList **name_list = (GList **)user_data;
255 gl_debug (DEBUG_SVG_CACHE, "START");
257 gl_debug (DEBUG_SVG_CACHE, "adding name=%s", name);
259 *name_list = g_list_append (*name_list, g_strdup(name));
261 gl_debug (DEBUG_SVG_CACHE, "END");
265 /*****************************************************************************/
266 /* Return a list of names for all svgs in the cache. */
267 /*****************************************************************************/
269 gl_svg_cache_get_name_list (GHashTable *svg_cache)
271 GList *name_list = NULL;
273 gl_debug (DEBUG_SVG_CACHE, "START");
275 g_hash_table_foreach (svg_cache, add_name_to_list, &name_list);
277 gl_debug (DEBUG_SVG_CACHE, "END");
283 /*****************************************************************************/
284 /* Free up a list of svg names. */
285 /*****************************************************************************/
287 gl_svg_cache_free_name_list (GList *name_list)
291 gl_debug (DEBUG_SVG_CACHE, "START");
293 for (p_name = name_list; p_name != NULL; p_name = p_name->next) {
294 g_free (p_name->data);
298 g_list_free (name_list);
300 gl_debug (DEBUG_SVG_CACHE, "END");
307 * Local Variables: -- emacs
309 * c-basic-offset: 8 -- emacs
310 * tab-width: 8 -- emacs
311 * indent-tabs-mode: nil -- emacs