[maemo-commits] [maemo-commits] r18763 - in projects/haf/trunk/sapwood: . engine

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Fri Jun 19 14:46:23 EEST 2009
Author: herzi
Date: 2009-06-19 14:46:17 +0300 (Fri, 19 Jun 2009)
New Revision: 18763

Modified:
   projects/haf/trunk/sapwood/ChangeLog
   projects/haf/trunk/sapwood/engine/sapwood-style.c
Log:
2009-06-19  Sven Herzberg  <herzi at lanedo.com>

	NB#117873 - Dim insensitive icons with transparency instead of
	rasterizing.

	* engine/sapwood-style.c (set_transparency), (scale_or_ref),
	(render_icon): patch from Daniel Borgmann


Modified: projects/haf/trunk/sapwood/ChangeLog
===================================================================
--- projects/haf/trunk/sapwood/ChangeLog	2009-06-19 11:39:40 UTC (rev 18762)
+++ projects/haf/trunk/sapwood/ChangeLog	2009-06-19 11:46:17 UTC (rev 18763)
@@ -1,5 +1,13 @@
 2009-06-19  Sven Herzberg  <herzi at lanedo.com>
 
+	NB#117873 - Dim insensitive icons with transparency instead of
+	rasterizing.
+
+	* engine/sapwood-style.c (set_transparency), (scale_or_ref),
+	(render_icon): patch from Daniel Borgmann
+
+2009-06-19  Sven Herzberg  <herzi at lanedo.com>
+
 	NB#110565 - sapwood-server server prints debugging stuff to console
 
 	* server/sapwood-server.c (main): only display the message when we are

Modified: projects/haf/trunk/sapwood/engine/sapwood-style.c
===================================================================
--- projects/haf/trunk/sapwood/engine/sapwood-style.c	2009-06-19 11:39:40 UTC (rev 18762)
+++ projects/haf/trunk/sapwood/engine/sapwood-style.c	2009-06-19 11:46:17 UTC (rev 18763)
@@ -1464,6 +1464,60 @@
 }
 
 static GdkPixbuf *
+set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
+{
+        GdkPixbuf *target;
+        guchar *data, *current;
+        guint x, y, rowstride, height, width;
+
+        g_return_val_if_fail (pixbuf != NULL, NULL);
+        g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+        /* Returns a copy of pixbuf with it's non-completely-transparent pixels to
+           have an alpha level "alpha_percent" of their original value. */
+
+        target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+
+        if (alpha_percent == 1.0)
+                return target;
+        width = gdk_pixbuf_get_width (target);
+        height = gdk_pixbuf_get_height (target);
+        rowstride = gdk_pixbuf_get_rowstride (target);
+        data = gdk_pixbuf_get_pixels (target);
+
+        for (y = 0; y < height; y++)
+        {
+                for (x = 0; x < width; x++)
+                {
+                        /* The "4" is the number of chars per pixel, in this case, RGBA,
+                           the 3 means "skip to the alpha" */
+                        current = data + (y * rowstride) + (x * 4) + 3;
+                        *(current) = (guchar) (*(current) * alpha_percent);
+                }
+        }
+
+        return target;
+}
+
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+              int width,
+              int height)
+{
+        if (width == gdk_pixbuf_get_width (src) &&
+            height == gdk_pixbuf_get_height (src))
+        {
+                return g_object_ref (src);
+        }
+        else
+        {
+                return gdk_pixbuf_scale_simple (src,
+                                                 width, height,
+                                                 GDK_INTERP_BILINEAR);
+        }
+}
+
+static GdkPixbuf *
 render_icon (GtkStyle               *style,
 	     const GtkIconSource    *source,
 	     GtkTextDirection        direction,
@@ -1472,65 +1526,81 @@
 	     GtkWidget              *widget,
 	     const gchar            *detail)
 {
-  if (state == GTK_STATE_INSENSITIVE)
-    {
-      GdkPixbuf *pixbuf;
-      GdkPixbuf *stated;
-      guchar    *pixels;
-      int        y;
-      int        rowstride;
-      int        n_channels;
-      GdkColor   color;
+	int width = 1;
+	int height = 1;
+	GdkPixbuf *scaled;
+	GdkPixbuf *stated;
+	GdkPixbuf *base_pixbuf;
+	GdkScreen *screen;
+	GtkSettings *settings;
 
-      /* generate dimmed (insensitive) icon from normal state icon by adding
-       * a simple background color (white) raster on top
-       */
+	/* Oddly, style can be NULL in this function, because
+	 * GtkIconSet can be used without a style and if so
+	 * it uses this function.
+	 */
 
-      pixbuf = GTK_STYLE_CLASS (sapwood_style_parent_class)->render_icon (
-        style, source, direction, GTK_STATE_NORMAL, size, widget, detail);
-      if (!pixbuf)
-	return NULL;
+	base_pixbuf = gtk_icon_source_get_pixbuf (source);
 
-      stated = gdk_pixbuf_copy (pixbuf);
-      g_object_unref (pixbuf);
-      if (!stated)
-	return NULL;
+	g_return_val_if_fail (base_pixbuf != NULL, NULL);
 
-      color = style->bg[GTK_STATE_INSENSITIVE];
+	if (widget && gtk_widget_has_screen (widget))
+	{
+		screen = gtk_widget_get_screen (widget);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else if (style->colormap)
+	{
+		screen = gdk_colormap_get_screen (style->colormap);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else
+	{
+		settings = gtk_settings_get_default ();
+		GTK_NOTE (MULTIHEAD,
+			  g_warning ("Using the default screen for gtk_default_render_icon()"));
+	}
 
-      pixels     = gdk_pixbuf_get_pixels (stated);
-      rowstride  = gdk_pixbuf_get_rowstride (stated);
-      n_channels = gdk_pixbuf_get_n_channels (stated);
+	if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
+	{
+		g_warning (G_STRLOC ": invalid icon size '%d'", size);
+		return NULL;
+	}
 
-      for (y = 0; y < gdk_pixbuf_get_height (stated); y++, pixels += rowstride)
+	/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+	 * leave it alone.
+	 */
+	if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
+		scaled = scale_or_ref (base_pixbuf, width, height);
+	else
+		scaled = g_object_ref (base_pixbuf);
+
+	/* If the state was wildcarded, then generate a state. */
+	if (gtk_icon_source_get_state_wildcarded (source))
 	{
-	  guchar *p = pixels;
-	  int     x;
+		if (state == GTK_STATE_INSENSITIVE)
+		{
+			stated = set_transparency (scaled, 0.3);
+			gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);
 
-	  for (x = 0; x < gdk_pixbuf_get_width (stated); x++)
-	    {
-	      if ((x + y) % 2 == 0)
+			g_object_unref (scaled);
+		}
+		else if (state == GTK_STATE_PRELIGHT)
 		{
-		  p[0] = color.red >> 8;
-		  p[1] = color.blue >> 8;
-		  p[2] = color.green >> 8;
+			stated = gdk_pixbuf_copy (scaled);
 
-		  /* decrease alpha to avoid extreme contrast (such as in white
-		   * on black in audio player buttons)
-		   */
-		  if (n_channels == 4 && p[3] > 128)
-		    p[3] -= 127;
+			gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);
+
+			g_object_unref (scaled);
 		}
-
-	      p += n_channels;
-	    }
+		else
+		{
+			stated = scaled;
+		}
 	}
+	else
+		stated = scaled;
 
-      return stated;
-    }
-  else
-    return GTK_STYLE_CLASS (sapwood_style_parent_class)->render_icon (
-      style, source, direction, state, size, widget, detail);
+	return stated;
 }
 
 static void

More information about the maemo-commits mailing list