/* GTK - The GIMP Toolkit * Copyright (C) 2015 Benjamin Otte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "config.h" #include "gtkimagedefinitionprivate.h" #include "deprecated/gtkiconfactory.h" typedef struct _GtkImageDefinitionEmpty GtkImageDefinitionEmpty; typedef struct _GtkImageDefinitionPixbuf GtkImageDefinitionPixbuf; typedef struct _GtkImageDefinitionStock GtkImageDefinitionStock; typedef struct _GtkImageDefinitionIconSet GtkImageDefinitionIconSet; typedef struct _GtkImageDefinitionAnimation GtkImageDefinitionAnimation; typedef struct _GtkImageDefinitionIconName GtkImageDefinitionIconName; typedef struct _GtkImageDefinitionGIcon GtkImageDefinitionGIcon; typedef struct _GtkImageDefinitionSurface GtkImageDefinitionSurface; struct _GtkImageDefinitionEmpty { GtkImageType type; gint ref_count; }; struct _GtkImageDefinitionPixbuf { GtkImageType type; gint ref_count; GdkPixbuf *pixbuf; int scale; }; struct _GtkImageDefinitionStock { GtkImageType type; gint ref_count; char *id; }; struct _GtkImageDefinitionIconSet { GtkImageType type; gint ref_count; GtkIconSet *icon_set; }; struct _GtkImageDefinitionAnimation { GtkImageType type; gint ref_count; GdkPixbufAnimation *animation; int scale; }; struct _GtkImageDefinitionIconName { GtkImageType type; gint ref_count; char *icon_name; }; struct _GtkImageDefinitionGIcon { GtkImageType type; gint ref_count; GIcon *gicon; }; struct _GtkImageDefinitionSurface { GtkImageType type; gint ref_count; cairo_surface_t *surface; }; union _GtkImageDefinition { GtkImageType type; GtkImageDefinitionEmpty empty; GtkImageDefinitionPixbuf pixbuf; GtkImageDefinitionStock stock; GtkImageDefinitionIconSet icon_set; GtkImageDefinitionAnimation animation; GtkImageDefinitionIconName icon_name; GtkImageDefinitionGIcon gicon; GtkImageDefinitionSurface surface; }; GtkImageDefinition * gtk_image_definition_new_empty (void) { static GtkImageDefinitionEmpty empty = { GTK_IMAGE_EMPTY, 1 }; return gtk_image_definition_ref ((GtkImageDefinition *) &empty); } static inline GtkImageDefinition * gtk_image_definition_alloc (GtkImageType type) { static gsize sizes[] = { sizeof (GtkImageDefinitionEmpty), sizeof (GtkImageDefinitionPixbuf), sizeof (GtkImageDefinitionStock), sizeof (GtkImageDefinitionIconSet), sizeof (GtkImageDefinitionAnimation), sizeof (GtkImageDefinitionIconName), sizeof (GtkImageDefinitionGIcon), sizeof (GtkImageDefinitionSurface) }; GtkImageDefinition *def; g_assert (type < G_N_ELEMENTS (sizes)); def = g_malloc0 (sizes[type]); def->type = type; def->empty.ref_count = 1; return def; } GtkImageDefinition * gtk_image_definition_new_pixbuf (GdkPixbuf *pixbuf, int scale) { GtkImageDefinition *def; if (pixbuf == NULL || scale <= 0) return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_PIXBUF); def->pixbuf.pixbuf = g_object_ref (pixbuf); def->pixbuf.scale = scale; return def; } GtkImageDefinition * gtk_image_definition_new_stock (const char *stock_id) { GtkImageDefinition *def; if (stock_id == NULL || stock_id[0] == '\0') return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_STOCK); def->stock.id = g_strdup (stock_id); return def; } GtkImageDefinition * gtk_image_definition_new_icon_set (GtkIconSet *icon_set) { GtkImageDefinition *def; if (icon_set == NULL) return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_ICON_SET); G_GNUC_BEGIN_IGNORE_DEPRECATIONS; def->icon_set.icon_set = gtk_icon_set_ref (icon_set); G_GNUC_END_IGNORE_DEPRECATIONS; return def; } GtkImageDefinition * gtk_image_definition_new_animation (GdkPixbufAnimation *animation, int scale) { GtkImageDefinition *def; if (animation == NULL || scale <= 0) return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_ANIMATION); def->animation.animation = g_object_ref (animation); def->animation.scale = scale; return def; } GtkImageDefinition * gtk_image_definition_new_icon_name (const char *icon_name) { GtkImageDefinition *def; if (icon_name == NULL || icon_name[0] == '\0') return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_ICON_NAME); def->icon_name.icon_name = g_strdup (icon_name); return def; } GtkImageDefinition * gtk_image_definition_new_gicon (GIcon *gicon) { GtkImageDefinition *def; if (gicon == NULL) return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_GICON); def->gicon.gicon = g_object_ref (gicon); return def; } GtkImageDefinition * gtk_image_definition_new_surface (cairo_surface_t *surface) { GtkImageDefinition *def; if (surface == NULL) return NULL; def = gtk_image_definition_alloc (GTK_IMAGE_SURFACE); def->surface.surface = cairo_surface_reference (surface); return def; } GtkImageDefinition * gtk_image_definition_ref (GtkImageDefinition *def) { def->empty.ref_count++; return def; } void gtk_image_definition_unref (GtkImageDefinition *def) { def->empty.ref_count--; if (def->empty.ref_count > 0) return; switch (def->type) { default: case GTK_IMAGE_EMPTY: g_assert_not_reached (); break; case GTK_IMAGE_PIXBUF: g_object_unref (def->pixbuf.pixbuf); break; case GTK_IMAGE_ANIMATION: g_object_unref (def->animation.animation); break; case GTK_IMAGE_SURFACE: cairo_surface_destroy (def->surface.surface); break; case GTK_IMAGE_STOCK: g_free (def->stock.id); break; case GTK_IMAGE_ICON_SET: G_GNUC_BEGIN_IGNORE_DEPRECATIONS; gtk_icon_set_unref (def->icon_set.icon_set); G_GNUC_END_IGNORE_DEPRECATIONS; break; case GTK_IMAGE_ICON_NAME: g_free (def->icon_name.icon_name); break; case GTK_IMAGE_GICON: g_object_unref (def->gicon.gicon); break; } g_free (def); } GtkImageType gtk_image_definition_get_storage_type (const GtkImageDefinition *def) { return def->type; } gint gtk_image_definition_get_scale (const GtkImageDefinition *def) { switch (def->type) { default: g_assert_not_reached (); case GTK_IMAGE_EMPTY: case GTK_IMAGE_SURFACE: case GTK_IMAGE_STOCK: case GTK_IMAGE_ICON_SET: case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: return 1; case GTK_IMAGE_PIXBUF: return def->pixbuf.scale; case GTK_IMAGE_ANIMATION: return def->animation.scale; } } GdkPixbuf * gtk_image_definition_get_pixbuf (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_PIXBUF) return NULL; return def->pixbuf.pixbuf; } const gchar * gtk_image_definition_get_stock (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_STOCK) return NULL; return def->stock.id; } GtkIconSet * gtk_image_definition_get_icon_set (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_ICON_SET) return NULL; return def->icon_set.icon_set; } GdkPixbufAnimation * gtk_image_definition_get_animation (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_ANIMATION) return NULL; return def->animation.animation; } const gchar * gtk_image_definition_get_icon_name (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_ICON_NAME) return NULL; return def->icon_name.icon_name; } GIcon * gtk_image_definition_get_gicon (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_GICON) return NULL; return def->gicon.gicon; } cairo_surface_t * gtk_image_definition_get_surface (const GtkImageDefinition *def) { if (def->type != GTK_IMAGE_SURFACE) return NULL; return def->surface.surface; }