377 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			377 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * Copyright (C) 2015 Benjamin Otte <otte@gnome.org>
 | |
|  *
 | |
|  * 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 <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #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;
 | |
| }
 | 
