[gtk+/icon-shadow: 5/11] image: use gtk_render_icon()



commit 281f71e4c87907d5994d16f3ea9db9dafc41d31c
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Fri May 20 23:51:37 2011 -0400

    image: use gtk_render_icon()

 gtk/gtkimage.c |  141 ++++++++++++++++++++++++++------------------------------
 1 files changed, 65 insertions(+), 76 deletions(-)
---
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index c6ba294..28a0283 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -1426,8 +1426,9 @@ icon_theme_changed (GtkImage *image)
 }
 
 static void
-ensure_pixbuf_for_icon_name (GtkImage      *image,
-                             GtkStateFlags  state)
+ensure_pixbuf_for_icon_name (GtkImage        *image,
+                             GtkStyleContext *context,
+                             GtkStateFlags    real_state)
 {
   GtkImagePrivate *priv = image->priv;
   GdkScreen *screen;
@@ -1447,9 +1448,9 @@ ensure_pixbuf_for_icon_name (GtkImage      *image,
   if (priv->use_fallback)
     flags |= GTK_ICON_LOOKUP_GENERIC_FALLBACK;
   if (priv->data.name.pixbuf == NULL ||
-      (priv->was_symbolic && priv->last_rendered_state != state))
+      (priv->was_symbolic && priv->last_rendered_state != real_state))
     {
-      priv->last_rendered_state = state;
+      priv->last_rendered_state = real_state;
       if (priv->data.name.pixbuf)
         {
           g_object_unref (priv->data.name.pixbuf);
@@ -1508,15 +1509,18 @@ ensure_pixbuf_for_icon_name (GtkImage      *image,
                                          MIN (width, height), flags);
       if (info)
         {
-          GtkStyleContext *context;
           gboolean was_symbolic;
 
-          context = gtk_widget_get_style_context (GTK_WIDGET (image));
+          gtk_style_context_save (context);
+          gtk_style_context_set_state (context, real_state);
+
           priv->data.name.pixbuf =
             gtk_icon_info_load_symbolic_for_context (info,
                                                      context,
                                                      &was_symbolic,
                                                      NULL);
+          gtk_style_context_restore (context);
+
           priv->was_symbolic = was_symbolic;
           gtk_icon_info_free (info);
         }
@@ -1533,8 +1537,9 @@ ensure_pixbuf_for_icon_name (GtkImage      *image,
 }
 
 static void
-ensure_pixbuf_for_gicon (GtkImage      *image,
-                         GtkStateFlags  state)
+ensure_pixbuf_for_gicon (GtkImage        *image,
+                         GtkStyleContext *context,
+                         GtkStateFlags    real_state)
 {
   GtkImagePrivate *priv = image->priv;
   GdkScreen *screen;
@@ -1553,9 +1558,9 @@ ensure_pixbuf_for_gicon (GtkImage      *image,
   if (priv->use_fallback)
     flags |= GTK_ICON_LOOKUP_GENERIC_FALLBACK;
   if (priv->data.gicon.pixbuf == NULL ||
-      (priv->was_symbolic && priv->last_rendered_state != state))
+      (priv->was_symbolic && priv->last_rendered_state != real_state))
     {
-      priv->last_rendered_state = state;
+      priv->last_rendered_state = real_state;
       if (priv->data.gicon.pixbuf)
         {
           g_object_unref (priv->data.gicon.pixbuf);
@@ -1584,15 +1589,18 @@ ensure_pixbuf_for_gicon (GtkImage      *image,
 					     MIN (width, height), flags);
       if (info)
         {
-          GtkStyleContext *context;
           gboolean was_symbolic;
 
-          context = gtk_widget_get_style_context (GTK_WIDGET (image));
+          gtk_style_context_save (context);
+          gtk_style_context_set_state (context, real_state);
+
           priv->data.gicon.pixbuf =
             gtk_icon_info_load_symbolic_for_context (info,
                                                      context,
                                                      &was_symbolic,
                                                      NULL);
+          gtk_style_context_restore (context);
+
           priv->was_symbolic = was_symbolic;
           gtk_icon_info_free (info);
         }
@@ -1627,15 +1635,20 @@ gtk_image_draw (GtkWidget *widget,
       gint xpad, ypad;
       gfloat xalign, yalign;
       GdkPixbuf *pixbuf;
-      GtkStateFlags state;
-      gboolean needs_state_transform;
+      GtkStateFlags state, real_state;
       GtkStyleContext *context;
 
       misc = GTK_MISC (widget);
       context = gtk_widget_get_style_context (widget);
-      state = gtk_widget_get_state_flags (widget);
 
+      /* always render the icon with NORMAL state, gtk_render_icon()
+       * will apply the effects; except in case we're using a symbolic icon, which
+       * already transformes the state internally.
+       */
+      real_state = gtk_widget_get_state_flags (widget);
       gtk_style_context_save (context);
+
+      state = GTK_STATE_FLAG_NORMAL;
       gtk_style_context_set_state (context, state);
 
       /* For stock items and icon sets, we lazily calculate
@@ -1655,8 +1668,6 @@ gtk_image_draw (GtkWidget *widget,
       x = floor (xpad + ((gtk_widget_get_allocated_width (widget) - priv->required_width) * xalign));
       y = floor (ypad + ((gtk_widget_get_allocated_height (widget) - priv->required_height) * yalign));
 
-      needs_state_transform = state != 0;
-
       switch (priv->storage_type)
         {
 
@@ -1669,18 +1680,12 @@ gtk_image_draw (GtkWidget *widget,
           pixbuf = gtk_widget_render_icon_pixbuf (widget,
                                                   priv->data.stock.stock_id,
                                                   priv->icon_size);
-
-          /* already done */
-          needs_state_transform = FALSE;
           break;
 
         case GTK_IMAGE_ICON_SET:
           pixbuf =
             gtk_icon_set_render_icon_pixbuf (priv->data.icon_set.icon_set,
                                              context, priv->icon_size);
-
-          /* already done */
-          needs_state_transform = FALSE;
           break;
 
         case GTK_IMAGE_ANIMATION:
@@ -1706,17 +1711,7 @@ gtk_image_draw (GtkWidget *widget,
           break;
 
 	case GTK_IMAGE_ICON_NAME:
-	  if (state & GTK_STATE_FLAG_INSENSITIVE)
-	    {
-	      ensure_pixbuf_for_icon_name (image, 0);
-	    }
-	  else
-	    {
-	      ensure_pixbuf_for_icon_name (image, state);
-	      /* Already done by the loading function? */
-	      if (priv->was_symbolic)
-	        needs_state_transform = FALSE;
-	    }
+          ensure_pixbuf_for_icon_name (image, context, real_state);
 	  pixbuf = priv->data.name.pixbuf;
 	  if (pixbuf)
 	    {
@@ -1725,24 +1720,14 @@ gtk_image_draw (GtkWidget *widget,
 	  break;
 
 	case GTK_IMAGE_GICON:
-	  if (state & GTK_STATE_FLAG_INSENSITIVE)
-	    {
-	      ensure_pixbuf_for_gicon (image, 0);
-	    }
-	  else
-	    {
-	      ensure_pixbuf_for_gicon (image, state);
-	      /* Already done by the loading function? */
-	      if (priv->was_symbolic)
-	        needs_state_transform = FALSE;
-	    }
+          ensure_pixbuf_for_gicon (image, context, real_state);
 	  pixbuf = priv->data.gicon.pixbuf;
 	  if (pixbuf)
 	    {
 	      g_object_ref (pixbuf);
 	    }
 	  break;
-	  
+
         case GTK_IMAGE_EMPTY:
         default:
           g_assert_not_reached ();
@@ -1750,37 +1735,35 @@ gtk_image_draw (GtkWidget *widget,
           break;
         }
 
+      gtk_style_context_restore (context);
+
       if (pixbuf)
         {
-          if (needs_state_transform)
-            {
-              GtkIconSource *source;
-              GdkPixbuf *rendered;
-
-              source = gtk_icon_source_new ();
-              gtk_icon_source_set_pixbuf (source, pixbuf);
-              /* The size here is arbitrary; since size isn't
-               * wildcarded in the souce, it isn't supposed to be
-               * scaled by the engine function
-               */
-              gtk_icon_source_set_size (source,
-                                        GTK_ICON_SIZE_SMALL_TOOLBAR);
-              gtk_icon_source_set_size_wildcarded (source, FALSE);
-
-              rendered = gtk_render_icon_pixbuf (context, source, (GtkIconSize) -1);
-              gtk_icon_source_free (source);
-
-              g_object_unref (pixbuf);
-              pixbuf = rendered;
-            }
-
-          gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
-          cairo_paint (cr);
+          cairo_surface_t *surface;
+          cairo_t *surface_cr;
+
+          surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                gdk_pixbuf_get_width (pixbuf),
+                                                gdk_pixbuf_get_height (pixbuf));
+          surface_cr = cairo_create (surface);
+          gdk_cairo_set_source_pixbuf (surface_cr, pixbuf, 0, 0);
+          cairo_paint (surface_cr);
+          cairo_destroy (surface_cr);
 
+          gtk_style_context_save (context);
+          gtk_style_context_set_state (context, real_state);
+
+          gtk_render_icon (context, cr,
+                           x, y,
+                           priv->required_width, priv->required_height,
+                           surface,
+                           priv->was_symbolic);
+
+          gtk_style_context_restore (context);
+
+          cairo_surface_destroy (surface);
           g_object_unref (pixbuf);
         }
-
-      gtk_style_context_restore (context);
     }
 
   return FALSE;
@@ -1911,13 +1894,19 @@ gtk_image_calc_size (GtkImage *image)
   GtkImagePrivate *priv = image->priv;
   GdkPixbuf *pixbuf = NULL;
   GtkStyleContext *context;
-  GtkStateFlags state;
+  GtkStateFlags state, real_state;
 
   priv->need_calc_size = 0;
   context = gtk_widget_get_style_context (widget);
-  state = gtk_widget_get_state_flags (widget);
 
+  real_state = gtk_widget_get_state_flags (widget);
   gtk_style_context_save (context);
+
+  /* always render the icon with NORMAL state, gtk_render_icon()
+   * will apply the effects; except in case we're using a symbolic icon, which
+   * already transformes the state internally.
+   */
+  state = GTK_STATE_FLAG_NORMAL;
   gtk_style_context_set_state (context, state);
 
   /* We update stock/icon set on every size request, because
@@ -1938,12 +1927,12 @@ gtk_image_calc_size (GtkImage *image)
                                                 context, priv->icon_size);
       break;
     case GTK_IMAGE_ICON_NAME:
-      ensure_pixbuf_for_icon_name (image, 0);
+      ensure_pixbuf_for_icon_name (image, context, real_state);
       pixbuf = priv->data.name.pixbuf;
       if (pixbuf) g_object_ref (pixbuf);
       break;
     case GTK_IMAGE_GICON:
-      ensure_pixbuf_for_gicon (image, 0);
+      ensure_pixbuf_for_gicon (image, context, real_state);
       pixbuf = priv->data.gicon.pixbuf;
       if (pixbuf)
 	g_object_ref (pixbuf);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]