]> git.sur5r.net Git - glabels/blob - src/pixbuf-cache.c
Imported Upstream version 2.2.8
[glabels] / src / pixbuf-cache.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  pixbuf-cache.c:  GLabels pixbuf cache module
7  *
8  *  Copyright (C) 2003  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24 #include <config.h>
25
26 #include "pixbuf-cache.h"
27
28 #include "debug.h"
29
30 /*========================================================*/
31 /* Private types.                                         */
32 /*========================================================*/
33
34 typedef struct {
35         gchar     *key;
36         guint      references;
37         GdkPixbuf *pixbuf;
38 } CacheRecord;
39
40 /*========================================================*/
41 /* Private globals.                                       */
42 /*========================================================*/
43
44 /*========================================================*/
45 /* Private function prototypes.                           */
46 /*========================================================*/
47
48 static void  record_destroy   (gpointer val);
49
50 static void  add_name_to_list (gpointer key,
51                                gpointer val,
52                                gpointer user_data);
53
54 \f
55 /*---------------------------------------------------------------------------*/
56 /* PRIVATE.  Destroy cache record.                                           */
57 /*---------------------------------------------------------------------------*/
58 static void
59 record_destroy (gpointer val)
60 {
61         CacheRecord *record = (CacheRecord *)val;
62
63         g_return_if_fail (record);
64
65         g_free (record->key);
66         g_object_unref (record->pixbuf);
67         g_free (record);
68 }
69
70 /*****************************************************************************/
71 /* Create a new hash table to keep track of cached pixbufs.                  */
72 /*****************************************************************************/
73 GHashTable *
74 gl_pixbuf_cache_new (void)
75 {
76         GHashTable *pixbuf_cache;
77
78         gl_debug (DEBUG_PIXBUF_CACHE, "START");
79
80         pixbuf_cache = g_hash_table_new_full (g_str_hash,
81                                               g_str_equal,
82                                               NULL,
83                                               record_destroy);
84
85         gl_debug (DEBUG_PIXBUF_CACHE, "END pixbuf_cache=%p", pixbuf_cache);
86
87         return pixbuf_cache;
88 }
89
90 /*****************************************************************************/
91 /* Free up previously allocated hash table and its contents.                 */
92 /*****************************************************************************/
93 void
94 gl_pixbuf_cache_free (GHashTable *pixbuf_cache)
95 {
96         gl_debug (DEBUG_PIXBUF_CACHE, "START");
97
98         g_hash_table_destroy (pixbuf_cache);
99
100         gl_debug (DEBUG_PIXBUF_CACHE, "END");
101 }
102
103 /*****************************************************************************/
104 /* Add pixbuf to cache explicitly (not a reference).                         */
105 /*****************************************************************************/
106 void
107 gl_pixbuf_cache_add_pixbuf (GHashTable *pixbuf_cache,
108                             gchar      *name,
109                             GdkPixbuf  *pixbuf)
110 {
111         CacheRecord *test_record, *record;
112
113         gl_debug (DEBUG_PIXBUF_CACHE, "START");
114
115         test_record = g_hash_table_lookup (pixbuf_cache, name);
116         if (test_record != NULL) {
117                 /* pixbuf is already in the cache. */
118                 gl_debug (DEBUG_PIXBUF_CACHE, "END already in cache");
119                 return;
120         }
121
122         record = g_new0 (CacheRecord, 1);
123         record->key        = g_strdup (name);
124         record->references = 0; /* Nobody has referenced it yet. */
125         record->pixbuf     = g_object_ref (G_OBJECT (pixbuf));
126
127         g_hash_table_insert (pixbuf_cache, record->key, record);
128
129         gl_debug (DEBUG_PIXBUF_CACHE, "END");
130 }
131
132 /*****************************************************************************/
133 /* Get pixbuf.  If not in cache, read it and add to cache.                   */
134 /*****************************************************************************/
135 GdkPixbuf *
136 gl_pixbuf_cache_get_pixbuf (GHashTable *pixbuf_cache,
137                             gchar      *name)
138 {
139         CacheRecord *record;
140         GdkPixbuf   *pixbuf;
141
142         gl_debug (DEBUG_PIXBUF_CACHE, "START pixbuf_cache=%p", pixbuf_cache);
143
144         record = g_hash_table_lookup (pixbuf_cache, name);
145
146         if (record != NULL) {
147                 record->references++;
148                 gl_debug (DEBUG_PIXBUF_CACHE, "references=%d", record->references);
149                 gl_debug (DEBUG_PIXBUF_CACHE, "END cached");
150                 return record->pixbuf;
151         }
152
153
154         pixbuf = gdk_pixbuf_new_from_file (name, NULL);
155         if ( pixbuf != NULL) {
156                 record = g_new0 (CacheRecord, 1);
157                 record->key        = g_strdup (name);
158                 record->references = 1;
159                 record->pixbuf     = pixbuf;
160
161                 g_hash_table_insert (pixbuf_cache, record->key, record);
162         }
163
164         gl_debug (DEBUG_PIXBUF_CACHE, "END");
165
166         return pixbuf;
167 }
168
169 /*****************************************************************************/
170 /* Remove pixbuf, but only if no references left.                            */
171 /*****************************************************************************/
172 void
173 gl_pixbuf_cache_remove_pixbuf (GHashTable *pixbuf_cache,
174                                gchar      *name)
175 {
176         CacheRecord *record;
177
178         if (name == NULL) return;
179
180         gl_debug (DEBUG_PIXBUF_CACHE, "START");
181
182         record = g_hash_table_lookup (pixbuf_cache, name);
183         if (record == NULL) {
184                 gl_debug (DEBUG_PIXBUF_CACHE, "END not in cache");
185                 return;
186         }
187
188         record->references--;
189
190         if ( record->references == 0 ) {
191                 g_hash_table_remove (pixbuf_cache, name);
192         }
193
194         gl_debug (DEBUG_PIXBUF_CACHE, "END");
195 }
196
197 /*---------------------------------------------------------------------------*/
198 /* PRIVATE.  Add a name to a GList while iterating over cache.               */
199 /*---------------------------------------------------------------------------*/
200 static void
201 add_name_to_list (gpointer key,
202                   gpointer val,
203                   gpointer user_data)
204 {
205         gchar     *name       = (gchar *)key;
206         GList     **name_list = (GList **)user_data;
207
208         gl_debug (DEBUG_PIXBUF_CACHE, "START");
209
210         gl_debug (DEBUG_PIXBUF_CACHE, "adding name=%s", name);
211
212         *name_list = g_list_append (*name_list, g_strdup(name));
213
214         gl_debug (DEBUG_PIXBUF_CACHE, "END");
215 }
216
217 /*****************************************************************************/
218 /* Return a list of names for all pixbufs in the cache.                      */
219 /*****************************************************************************/
220 GList *
221 gl_pixbuf_cache_get_name_list (GHashTable *pixbuf_cache)
222 {
223         GList *name_list = NULL;
224
225         gl_debug (DEBUG_PIXBUF_CACHE, "START");
226
227         g_hash_table_foreach (pixbuf_cache, add_name_to_list, &name_list);
228
229         gl_debug (DEBUG_PIXBUF_CACHE, "END");
230
231         return name_list;
232 }
233
234 /*****************************************************************************/
235 /* Free up a list of pixbuf names.                                           */
236 /*****************************************************************************/
237 void
238 gl_pixbuf_cache_free_name_list (GList *name_list)
239 {
240         GList *p_name;
241
242         gl_debug (DEBUG_PIXBUF_CACHE, "START");
243
244         for (p_name = name_list; p_name != NULL; p_name = p_name->next) {
245                 g_free (p_name->data);
246                 p_name->data = NULL;
247         }
248
249         g_list_free (name_list);
250
251         gl_debug (DEBUG_PIXBUF_CACHE, "END");
252 }
253
254