1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2015 Benjamin Otte <otte@gnome.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gtkimagedefinitionprivate.h"
21
22 #include "deprecated/gtkiconfactory.h"
23
24 typedef struct _GtkImageDefinitionEmpty GtkImageDefinitionEmpty;
25 typedef struct _GtkImageDefinitionPixbuf GtkImageDefinitionPixbuf;
26 typedef struct _GtkImageDefinitionStock GtkImageDefinitionStock;
27 typedef struct _GtkImageDefinitionIconSet GtkImageDefinitionIconSet;
28 typedef struct _GtkImageDefinitionAnimation GtkImageDefinitionAnimation;
29 typedef struct _GtkImageDefinitionIconName GtkImageDefinitionIconName;
30 typedef struct _GtkImageDefinitionGIcon GtkImageDefinitionGIcon;
31 typedef struct _GtkImageDefinitionSurface GtkImageDefinitionSurface;
32
33 struct _GtkImageDefinitionEmpty {
34 GtkImageType type;
35 gint ref_count;
36 };
37
38 struct _GtkImageDefinitionPixbuf {
39 GtkImageType type;
40 gint ref_count;
41
42 GdkPixbuf *pixbuf;
43 int scale;
44 };
45
46 struct _GtkImageDefinitionStock {
47 GtkImageType type;
48 gint ref_count;
49
50 char *id;
51 };
52
53 struct _GtkImageDefinitionIconSet {
54 GtkImageType type;
55 gint ref_count;
56
57 GtkIconSet *icon_set;
58 };
59
60 struct _GtkImageDefinitionAnimation {
61 GtkImageType type;
62 gint ref_count;
63
64 GdkPixbufAnimation *animation;
65 int scale;
66 };
67
68 struct _GtkImageDefinitionIconName {
69 GtkImageType type;
70 gint ref_count;
71
72 char *icon_name;
73 };
74
75 struct _GtkImageDefinitionGIcon {
76 GtkImageType type;
77 gint ref_count;
78
79 GIcon *gicon;
80 };
81
82 struct _GtkImageDefinitionSurface {
83 GtkImageType type;
84 gint ref_count;
85
86 cairo_surface_t *surface;
87 };
88
89 union _GtkImageDefinition
90 {
91 GtkImageType type;
92 GtkImageDefinitionEmpty empty;
93 GtkImageDefinitionPixbuf pixbuf;
94 GtkImageDefinitionStock stock;
95 GtkImageDefinitionIconSet icon_set;
96 GtkImageDefinitionAnimation animation;
97 GtkImageDefinitionIconName icon_name;
98 GtkImageDefinitionGIcon gicon;
99 GtkImageDefinitionSurface surface;
100 };
101
102 GtkImageDefinition *
gtk_image_definition_new_empty(void)103 gtk_image_definition_new_empty (void)
104 {
105 static GtkImageDefinitionEmpty empty = { GTK_IMAGE_EMPTY, 1 };
106
107 return gtk_image_definition_ref ((GtkImageDefinition *) &empty);
108 }
109
110 static inline GtkImageDefinition *
gtk_image_definition_alloc(GtkImageType type)111 gtk_image_definition_alloc (GtkImageType type)
112 {
113 static gsize sizes[] = {
114 sizeof (GtkImageDefinitionEmpty),
115 sizeof (GtkImageDefinitionPixbuf),
116 sizeof (GtkImageDefinitionStock),
117 sizeof (GtkImageDefinitionIconSet),
118 sizeof (GtkImageDefinitionAnimation),
119 sizeof (GtkImageDefinitionIconName),
120 sizeof (GtkImageDefinitionGIcon),
121 sizeof (GtkImageDefinitionSurface)
122 };
123 GtkImageDefinition *def;
124
125 g_assert (type < G_N_ELEMENTS (sizes));
126
127 def = g_malloc0 (sizes[type]);
128 def->type = type;
129 def->empty.ref_count = 1;
130
131 return def;
132 }
133
134 GtkImageDefinition *
gtk_image_definition_new_pixbuf(GdkPixbuf * pixbuf,int scale)135 gtk_image_definition_new_pixbuf (GdkPixbuf *pixbuf,
136 int scale)
137 {
138 GtkImageDefinition *def;
139
140 if (pixbuf == NULL || scale <= 0)
141 return NULL;
142
143 def = gtk_image_definition_alloc (GTK_IMAGE_PIXBUF);
144 def->pixbuf.pixbuf = g_object_ref (pixbuf);
145 def->pixbuf.scale = scale;
146
147 return def;
148 }
149
150 GtkImageDefinition *
gtk_image_definition_new_stock(const char * stock_id)151 gtk_image_definition_new_stock (const char *stock_id)
152 {
153 GtkImageDefinition *def;
154
155 if (stock_id == NULL || stock_id[0] == '\0')
156 return NULL;
157
158 def = gtk_image_definition_alloc (GTK_IMAGE_STOCK);
159 def->stock.id = g_strdup (stock_id);
160
161 return def;
162 }
163
164 GtkImageDefinition *
gtk_image_definition_new_icon_set(GtkIconSet * icon_set)165 gtk_image_definition_new_icon_set (GtkIconSet *icon_set)
166 {
167 GtkImageDefinition *def;
168
169 if (icon_set == NULL)
170 return NULL;
171
172 def = gtk_image_definition_alloc (GTK_IMAGE_ICON_SET);
173 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
174 def->icon_set.icon_set = gtk_icon_set_ref (icon_set);
175 G_GNUC_END_IGNORE_DEPRECATIONS;
176
177 return def;
178 }
179
180 GtkImageDefinition *
gtk_image_definition_new_animation(GdkPixbufAnimation * animation,int scale)181 gtk_image_definition_new_animation (GdkPixbufAnimation *animation,
182 int scale)
183 {
184 GtkImageDefinition *def;
185
186 if (animation == NULL || scale <= 0)
187 return NULL;
188
189 def = gtk_image_definition_alloc (GTK_IMAGE_ANIMATION);
190 def->animation.animation = g_object_ref (animation);
191 def->animation.scale = scale;
192
193 return def;
194 }
195
196 GtkImageDefinition *
gtk_image_definition_new_icon_name(const char * icon_name)197 gtk_image_definition_new_icon_name (const char *icon_name)
198 {
199 GtkImageDefinition *def;
200
201 if (icon_name == NULL || icon_name[0] == '\0')
202 return NULL;
203
204 def = gtk_image_definition_alloc (GTK_IMAGE_ICON_NAME);
205 def->icon_name.icon_name = g_strdup (icon_name);
206
207 return def;
208 }
209
210 GtkImageDefinition *
gtk_image_definition_new_gicon(GIcon * gicon)211 gtk_image_definition_new_gicon (GIcon *gicon)
212 {
213 GtkImageDefinition *def;
214
215 if (gicon == NULL)
216 return NULL;
217
218 def = gtk_image_definition_alloc (GTK_IMAGE_GICON);
219 def->gicon.gicon = g_object_ref (gicon);
220
221 return def;
222 }
223
224 GtkImageDefinition *
gtk_image_definition_new_surface(cairo_surface_t * surface)225 gtk_image_definition_new_surface (cairo_surface_t *surface)
226 {
227 GtkImageDefinition *def;
228
229 if (surface == NULL)
230 return NULL;
231
232 def = gtk_image_definition_alloc (GTK_IMAGE_SURFACE);
233 def->surface.surface = cairo_surface_reference (surface);
234
235 return def;
236 }
237
238 GtkImageDefinition *
gtk_image_definition_ref(GtkImageDefinition * def)239 gtk_image_definition_ref (GtkImageDefinition *def)
240 {
241 def->empty.ref_count++;
242
243 return def;
244 }
245
246 void
gtk_image_definition_unref(GtkImageDefinition * def)247 gtk_image_definition_unref (GtkImageDefinition *def)
248 {
249 def->empty.ref_count--;
250
251 if (def->empty.ref_count > 0)
252 return;
253
254 switch (def->type)
255 {
256 default:
257 case GTK_IMAGE_EMPTY:
258 g_assert_not_reached ();
259 break;
260 case GTK_IMAGE_PIXBUF:
261 g_object_unref (def->pixbuf.pixbuf);
262 break;
263 case GTK_IMAGE_ANIMATION:
264 g_object_unref (def->animation.animation);
265 break;
266 case GTK_IMAGE_SURFACE:
267 cairo_surface_destroy (def->surface.surface);
268 break;
269 case GTK_IMAGE_STOCK:
270 g_free (def->stock.id);
271 break;
272 case GTK_IMAGE_ICON_SET:
273 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
274 gtk_icon_set_unref (def->icon_set.icon_set);
275 G_GNUC_END_IGNORE_DEPRECATIONS;
276 break;
277 case GTK_IMAGE_ICON_NAME:
278 g_free (def->icon_name.icon_name);
279 break;
280 case GTK_IMAGE_GICON:
281 g_object_unref (def->gicon.gicon);
282 break;
283 }
284
285 g_free (def);
286 }
287
288 GtkImageType
gtk_image_definition_get_storage_type(const GtkImageDefinition * def)289 gtk_image_definition_get_storage_type (const GtkImageDefinition *def)
290 {
291 return def->type;
292 }
293
294 gint
gtk_image_definition_get_scale(const GtkImageDefinition * def)295 gtk_image_definition_get_scale (const GtkImageDefinition *def)
296 {
297 switch (def->type)
298 {
299 default:
300 g_assert_not_reached ();
301 case GTK_IMAGE_EMPTY:
302 case GTK_IMAGE_SURFACE:
303 case GTK_IMAGE_STOCK:
304 case GTK_IMAGE_ICON_SET:
305 case GTK_IMAGE_ICON_NAME:
306 case GTK_IMAGE_GICON:
307 return 1;
308 case GTK_IMAGE_PIXBUF:
309 return def->pixbuf.scale;
310 case GTK_IMAGE_ANIMATION:
311 return def->animation.scale;
312 }
313 }
314
315 GdkPixbuf *
gtk_image_definition_get_pixbuf(const GtkImageDefinition * def)316 gtk_image_definition_get_pixbuf (const GtkImageDefinition *def)
317 {
318 if (def->type != GTK_IMAGE_PIXBUF)
319 return NULL;
320
321 return def->pixbuf.pixbuf;
322 }
323
324 const gchar *
gtk_image_definition_get_stock(const GtkImageDefinition * def)325 gtk_image_definition_get_stock (const GtkImageDefinition *def)
326 {
327 if (def->type != GTK_IMAGE_STOCK)
328 return NULL;
329
330 return def->stock.id;
331 }
332
333 GtkIconSet *
gtk_image_definition_get_icon_set(const GtkImageDefinition * def)334 gtk_image_definition_get_icon_set (const GtkImageDefinition *def)
335 {
336 if (def->type != GTK_IMAGE_ICON_SET)
337 return NULL;
338
339 return def->icon_set.icon_set;
340 }
341
342 GdkPixbufAnimation *
gtk_image_definition_get_animation(const GtkImageDefinition * def)343 gtk_image_definition_get_animation (const GtkImageDefinition *def)
344 {
345 if (def->type != GTK_IMAGE_ANIMATION)
346 return NULL;
347
348 return def->animation.animation;
349 }
350
351 const gchar *
gtk_image_definition_get_icon_name(const GtkImageDefinition * def)352 gtk_image_definition_get_icon_name (const GtkImageDefinition *def)
353 {
354 if (def->type != GTK_IMAGE_ICON_NAME)
355 return NULL;
356
357 return def->icon_name.icon_name;
358 }
359
360 GIcon *
gtk_image_definition_get_gicon(const GtkImageDefinition * def)361 gtk_image_definition_get_gicon (const GtkImageDefinition *def)
362 {
363 if (def->type != GTK_IMAGE_GICON)
364 return NULL;
365
366 return def->gicon.gicon;
367 }
368
369 cairo_surface_t *
gtk_image_definition_get_surface(const GtkImageDefinition * def)370 gtk_image_definition_get_surface (const GtkImageDefinition *def)
371 {
372 if (def->type != GTK_IMAGE_SURFACE)
373 return NULL;
374
375 return def->surface.surface;
376 }
377