[gtk+] css: Use a color matrix for recoloring -gtk-icontheme



commit 44a3f6bb41b35cfeb6089c6c6f3784f017e80fbd
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Nov 7 21:39:47 2017 -0500

    css: Use a color matrix for recoloring -gtk-icontheme
    
    This is the same approach we are already using in
    GtkIconHelper.

 gtk/gtkcssimageicontheme.c        |   54 +++++++++++++++++++++++++++---------
 gtk/gtkcssimageiconthemeprivate.h |    1 +
 2 files changed, 41 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkcssimageicontheme.c b/gtk/gtkcssimageicontheme.c
index b10f38d..399f7b4 100644
--- a/gtk/gtkcssimageicontheme.c
+++ b/gtk/gtkcssimageicontheme.c
@@ -49,6 +49,7 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
   GdkTexture *texture;
   double texture_width, texture_height;
   gint size;
+  gboolean symbolic;
 
   size = floor (MIN (width, height));
   if (size <= 0)
@@ -58,10 +59,10 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
       icon_theme->cached_texture != NULL)
     {
       texture = icon_theme->cached_texture;
+      symbolic = icon_theme->cached_symbolic;
     }
   else
     {
-      GError *error = NULL;
       GtkIconInfo *icon_info;
       GdkPixbuf *pixbuf;
 
@@ -70,24 +71,25 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
                                                         size,
                                                         icon_theme->scale,
                                                         GTK_ICON_LOOKUP_USE_BUILTIN);
-      if (icon_info == NULL)
+      if (icon_info)
         {
-          /* XXX: render missing icon image here? */
-          return;
+          symbolic = gtk_icon_info_is_symbolic (icon_info);
+          pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
+        }
+      else
+        {
+          pixbuf = NULL;
         }
 
-      pixbuf = gtk_icon_info_load_symbolic (icon_info,
-                                            &icon_theme->color,
-                                            &icon_theme->success,
-                                            &icon_theme->warning,
-                                            &icon_theme->error,
-                                            NULL,
-                                            &error);
       if (pixbuf == NULL)
         {
-          /* XXX: render missing icon image here? */
-          g_error_free (error);
-          return;
+          pixbuf = gtk_icon_theme_load_icon (icon_theme->icon_theme,
+                                             "image-missing",
+                                             size,
+                                             GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK,
+                                             NULL);
+          g_assert (pixbuf != NULL);
+          symbolic = FALSE;
         }
 
       texture = gdk_texture_new_for_pixbuf (pixbuf);
@@ -95,6 +97,7 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
       g_clear_object (&icon_theme->cached_texture);
       icon_theme->cached_size = size;
       icon_theme->cached_texture = texture;
+      icon_theme->cached_symbolic = symbolic;
 
       g_object_unref (pixbuf);
       g_object_unref (icon_info);
@@ -103,6 +106,27 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
   texture_width = (double) gdk_texture_get_width (texture) / icon_theme->scale;
   texture_height = (double) gdk_texture_get_height (texture) / icon_theme->scale;
 
+  if (symbolic)
+    {
+      graphene_matrix_t matrix;
+      graphene_vec4_t offset;
+      GdkRGBA fg = icon_theme->color;
+      GdkRGBA sc = icon_theme->success;
+      GdkRGBA wc = icon_theme->warning;
+      GdkRGBA ec = icon_theme->error;
+
+      graphene_matrix_init_from_float (&matrix,
+          (float[16]) {
+                       sc.red - fg.red, sc.green - fg.green, sc.blue - fg.blue, 0,
+                       wc.red - fg.red, wc.green - fg.green, wc.blue - fg.blue, 0,
+                       ec.red - fg.red, ec.green - fg.green, ec.blue - fg.blue, 0,
+                       0, 0, 0, fg.alpha
+                      });
+      graphene_vec4_init (&offset, fg.red, fg.green, fg.blue, 0);
+
+      gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset, "Recolor");
+    }
+
   gtk_snapshot_append_texture (snapshot,
                                texture,
                                &GRAPHENE_RECT_INIT(
@@ -112,6 +136,8 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
                                    texture_height
                                ),
                                "CssImageIconTheme<%s@%d>", icon_theme->name, icon_theme->scale);
+  if (symbolic)
+    gtk_snapshot_pop (snapshot);
 }
 
 
diff --git a/gtk/gtkcssimageiconthemeprivate.h b/gtk/gtkcssimageiconthemeprivate.h
index 1b61adb..f583b35 100644
--- a/gtk/gtkcssimageiconthemeprivate.h
+++ b/gtk/gtkcssimageiconthemeprivate.h
@@ -48,6 +48,7 @@ struct _GtkCssImageIconTheme
   char *name;
 
   int cached_size;
+  gboolean cached_symbolic;
   GdkTexture *cached_texture;
 };
 


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