[gtk: 15/31] Replace last users of gtk_icon_paintable_download_texture ()



commit 6317fd35294da0cb58c464612e1bcdf33a1192c6
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Feb 6 17:10:13 2020 +0100

    Replace last users of gtk_icon_paintable_download_texture ()
    
    These now render the paintable to a cairo surface and convert that
    to a texture. This is sort of a hack, but its only used in two
    special cases internally and in two hacky test apps.

 gtk/gtkmountoperation.c   | 35 +++++++++++++++++++++--
 gtk/gtkwindow.c           | 42 +++++++++++++++++++++++-----
 tests/testclipboard2.c    | 44 ++++++++++++++++++++++++++++-
 tests/testdnd2.c          | 71 +++++++++++++++++++++++++++++++++++++++--------
 testsuite/gtk/icontheme.c | 60 +--------------------------------------
 5 files changed, 172 insertions(+), 80 deletions(-)
---
diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c
index 07fc81c5c3..6efba15c59 100644
--- a/gtk/gtkmountoperation.c
+++ b/gtk/gtkmountoperation.c
@@ -55,7 +55,8 @@
 #include "gtkgestureclick.h"
 #include "gtkmodelbuttonprivate.h"
 #include "gtkpopover.h"
-
+#include "gtksnapshot.h"
+#include "gdktextureprivate.h"
 #include <glib/gprintf.h>
 
 /**
@@ -1137,6 +1138,36 @@ diff_sorted_arrays (GArray         *array1,
     }
 }
 
+static GdkTexture *
+render_paintable_to_texture (GdkPaintable *paintable)
+{
+  GtkSnapshot *snapshot;
+  GskRenderNode *node;
+  int width, height;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  GdkTexture *texture;
+
+  width = gdk_paintable_get_intrinsic_width (paintable);
+  height = gdk_paintable_get_intrinsic_height (paintable);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+
+  snapshot = gtk_snapshot_new ();
+  gdk_paintable_snapshot (paintable, snapshot, width, height);
+  node = gtk_snapshot_free_to_node (snapshot);
+
+  cr = cairo_create (surface);
+  gsk_render_node_draw (node, cr);
+  cairo_destroy (cr);
+
+  gsk_render_node_unref (node);
+
+  texture = gdk_texture_new_for_surface (surface);
+  cairo_surface_destroy (surface);
+
+  return texture;
+}
 
 static void
 add_pid_to_process_list_store (GtkMountOperation              *mount_operation,
@@ -1180,7 +1211,7 @@ add_pid_to_process_list_store (GtkMountOperation              *mount_operation,
                                          24, 1,
                                          gtk_widget_get_direction (GTK_WIDGET 
(mount_operation->priv->dialog)),
                                          0);
-      texture = gtk_icon_paintable_download_texture (icon);
+      texture = render_paintable_to_texture (GDK_PAINTABLE (icon));
       g_object_unref (icon);
     }
 
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 882b0048fa..c945468e7e 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -3999,6 +3999,37 @@ icon_size_compare (GdkTexture *a,
   return area_a - area_b;
 }
 
+static GdkTexture *
+render_paintable_to_texture (GdkPaintable *paintable)
+{
+  GtkSnapshot *snapshot;
+  GskRenderNode *node;
+  int width, height;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  GdkTexture *texture;
+
+  width = gdk_paintable_get_intrinsic_width (paintable);
+  height = gdk_paintable_get_intrinsic_height (paintable);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+
+  snapshot = gtk_snapshot_new ();
+  gdk_paintable_snapshot (paintable, snapshot, width, height);
+  node = gtk_snapshot_free_to_node (snapshot);
+
+  cr = cairo_create (surface);
+  gsk_render_node_draw (node, cr);
+  cairo_destroy (cr);
+
+  gsk_render_node_unref (node);
+
+  texture = gdk_texture_new_for_surface (surface);
+  cairo_surface_destroy (surface);
+
+  return texture;
+}
+
 static GList *
 icon_list_from_theme (GtkWindow   *window,
                      const gchar *name)
@@ -4009,6 +4040,7 @@ icon_list_from_theme (GtkWindow   *window,
   GtkCssValue *value;
   GtkIconTheme *icon_theme;
   GtkIconPaintable *info;
+  GdkTexture *texture;
   gint *sizes;
   gint i;
 
@@ -4036,14 +4068,10 @@ icon_list_from_theme (GtkWindow   *window,
                                            sizes[i], priv->scale,
                                            gtk_widget_get_direction (GTK_WIDGET (window)),
                                            0);
-      if (info)
-        {
-          GdkTexture *texture = gtk_icon_paintable_download_texture (info);
-          if (texture)
-            list = g_list_insert_sorted (list, texture, (GCompareFunc) icon_size_compare);
 
-          g_object_unref (info);
-        }
+      texture = render_paintable_to_texture (GDK_PAINTABLE (info));
+      list = g_list_insert_sorted (list, texture, (GCompareFunc) icon_size_compare);
+      g_object_unref (info);
     }
 
   g_free (sizes);
diff --git a/tests/testclipboard2.c b/tests/testclipboard2.c
index 35b58e5167..edb5ae51b3 100644
--- a/tests/testclipboard2.c
+++ b/tests/testclipboard2.c
@@ -17,6 +17,48 @@
 
 #include <gtk/gtk.h>
 
+static GdkTexture *
+render_paintable_to_texture (GdkPaintable *paintable)
+{
+  GtkSnapshot *snapshot;
+  GskRenderNode *node;
+  int width, height;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  GdkTexture *texture;
+  GBytes *bytes;
+
+  width = gdk_paintable_get_intrinsic_width (paintable);
+  height = gdk_paintable_get_intrinsic_height (paintable);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+
+  snapshot = gtk_snapshot_new ();
+  gdk_paintable_snapshot (paintable, snapshot, width, height);
+  node = gtk_snapshot_free_to_node (snapshot);
+
+  cr = cairo_create (surface);
+  gsk_render_node_draw (node, cr);
+  cairo_destroy (cr);
+
+  gsk_render_node_unref (node);
+
+  bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface),
+                                      cairo_image_surface_get_height (surface)
+                                      * cairo_image_surface_get_stride (surface),
+                                      (GDestroyNotify) cairo_surface_destroy,
+                                      cairo_surface_reference (surface));
+  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
+                                    cairo_image_surface_get_height (surface),
+                                    GDK_MEMORY_DEFAULT,
+                                    bytes,
+                                    cairo_image_surface_get_stride (surface));
+  g_bytes_unref (bytes);
+  cairo_surface_destroy (surface);
+
+  return texture;
+}
+
 static void
 clipboard_changed_cb (GdkClipboard *clipboard,
                       GtkWidget    *stack)
@@ -292,7 +334,7 @@ get_button_list (GdkClipboard *clipboard,
                                      48, 1,
                                      gtk_widget_get_direction (box),
                                      0);
-  texture = gtk_icon_paintable_download_texture (icon);
+  texture = render_paintable_to_texture (GDK_PAINTABLE (icon));
   g_value_take_object (&value, gdk_pixbuf_get_from_texture (texture));
   g_object_unref (texture);
   g_object_unref (icon);
diff --git a/tests/testdnd2.c b/tests/testdnd2.c
index f419c975bf..e98ac71499 100644
--- a/tests/testdnd2.c
+++ b/tests/testdnd2.c
@@ -6,6 +6,53 @@
 #include <io.h>
 #endif
 
+static GdkTexture *
+render_paintable_to_texture (GdkPaintable *paintable)
+{
+  GtkSnapshot *snapshot;
+  GskRenderNode *node;
+  int width, height;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  GdkTexture *texture;
+  GBytes *bytes;
+
+  width = gdk_paintable_get_intrinsic_width (paintable);
+  if (width == 0)
+    width = 32;
+
+  height = gdk_paintable_get_intrinsic_height (paintable);
+  if (height == 0)
+    height = 32;
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+
+  snapshot = gtk_snapshot_new ();
+  gdk_paintable_snapshot (paintable, snapshot, width, height);
+  node = gtk_snapshot_free_to_node (snapshot);
+
+  cr = cairo_create (surface);
+  gsk_render_node_draw (node, cr);
+  cairo_destroy (cr);
+
+  gsk_render_node_unref (node);
+
+  bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface),
+                                      cairo_image_surface_get_height (surface)
+                                      * cairo_image_surface_get_stride (surface),
+                                      (GDestroyNotify) cairo_surface_destroy,
+                                      cairo_surface_reference (surface));
+  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
+                                    cairo_image_surface_get_height (surface),
+                                    GDK_MEMORY_DEFAULT,
+                                    bytes,
+                                    cairo_image_surface_get_stride (surface));
+  g_bytes_unref (bytes);
+  cairo_surface_destroy (surface);
+
+  return texture;
+}
+
 static GdkTexture *
 get_image_texture (GtkImage *image,
                    int      *out_size)
@@ -13,7 +60,7 @@ get_image_texture (GtkImage *image,
   GtkIconTheme *icon_theme;
   const char *icon_name;
   int width = 48;
-  GdkPaintable *paintable;
+  GdkPaintable *paintable = NULL;
   GdkTexture *texture = NULL;
   GtkIconPaintable *icon;
 
@@ -21,29 +68,28 @@ get_image_texture (GtkImage *image,
     {
     case GTK_IMAGE_PAINTABLE:
       paintable = gtk_image_get_paintable (image);
-      if (GDK_IS_TEXTURE (paintable))
-        {
-          *out_size = gdk_paintable_get_intrinsic_width (paintable);
-          texture = g_object_ref (GDK_TEXTURE (paintable));
-        }
+      break;
     case GTK_IMAGE_ICON_NAME:
       icon_name = gtk_image_get_icon_name (image);
       icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
-      *out_size = width;
       icon = gtk_icon_theme_lookup_icon (icon_theme,
                                          icon_name,
                                          NULL,
                                          width, 1,
                                          gtk_widget_get_direction (GTK_WIDGET (image)),
                                          0);
-      if (icon)
-        texture = gtk_icon_paintable_download_texture (icon);
-      g_object_unref (icon);
+      paintable = GDK_PAINTABLE (icon);
+      break;
     default:
       g_warning ("Image storage type %d not handled",
                  gtk_image_get_storage_type (image));
     }
 
+  if (paintable)
+    texture = render_paintable_to_texture (paintable);
+
+  g_object_unref (paintable);
+
   return texture;
 }
 
@@ -238,11 +284,14 @@ update_source_icon (GtkDragSource *source,
   int hot_x, hot_y;
   int size = 48;
 
+  if (widget == NULL)
+    return;
+
   icon = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_for_display (gtk_widget_get_display (widget)),
                                      icon_name,
                                      NULL,
                                      size, 1,
-                                     gtk_widget_get_direction (widget),
+                                     gtk_widget_get_direction (widget) ,
                                      0);
   switch (hotspot)
     {
diff --git a/testsuite/gtk/icontheme.c b/testsuite/gtk/icontheme.c
index 4cbce215bc..5c3b6cd008 100644
--- a/testsuite/gtk/icontheme.c
+++ b/testsuite/gtk/icontheme.c
@@ -93,14 +93,7 @@ assert_icon_lookup_size (const char         *icon_name,
       g_assert (gtk_icon_paintable_get_filename (info) == NULL);
     }
 
-  if (pixbuf_size > 0)
-    {
-      GdkTexture *texture;
-
-      texture = gtk_icon_paintable_download_texture (info);
-      g_assert_cmpint (gdk_texture_get_width (texture), ==, pixbuf_size);
-      g_object_unref (texture);
-    }
+  g_assert_cmpint (gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (info)), ==, size);
 
   g_object_unref (info);
 }
@@ -711,56 +704,6 @@ test_inherit (void)
                       "/icons2/scalable/one-two-symbolic-rtl.svg");
 }
 
-static void
-test_nonsquare_symbolic (void)
-{
-  gint width, height;
-  GtkIconTheme *icon_theme;
-  GtkIconPaintable *info;
-  GFile *file;
-  GIcon *icon;
-  GError *error = NULL;
-  GdkTexture *texture;
-  gchar *path = g_build_filename (g_test_get_dir (G_TEST_DIST),
-                                 "icons",
-                                 "scalable",
-                                 "nonsquare-symbolic.svg",
-                                 NULL);
-
-  /* load the original image for reference */
-  GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path, &error);
-  g_assert_no_error (error);
-  g_assert_nonnull (pixbuf);
-
-  width = gdk_pixbuf_get_width (pixbuf);
-  height = gdk_pixbuf_get_height (pixbuf);
-  g_assert_cmpint (width, !=, height);
-
-  /* now load it through GtkIconTheme */
-  icon_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
-  file = g_file_new_for_path (path);
-  icon = g_file_icon_new (file);
-  info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon,
-                                         height, 1, GTK_TEXT_DIR_NONE, 0);
-  g_assert_nonnull (info);
-
-  g_object_unref (pixbuf);
-  texture = gtk_icon_paintable_download_texture (info);
-
-  /* we are loaded successfully */
-  g_assert_nonnull (texture);
-
-  /* the original dimensions have been preserved */
-  g_assert_cmpint (gdk_texture_get_width (texture), ==, width);
-  g_assert_cmpint (gdk_texture_get_height (texture), ==, height);
-
-  g_free (path);
-  g_object_unref (texture);
-  g_object_unref (file);
-  g_object_unref (icon);
-  g_object_unref (info);
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -777,7 +720,6 @@ main (int argc, char *argv[])
   g_test_add_func ("/icontheme/size", test_size);
   g_test_add_func ("/icontheme/list", test_list);
   g_test_add_func ("/icontheme/inherit", test_inherit);
-  g_test_add_func ("/icontheme/nonsquare-symbolic", test_nonsquare_symbolic);
 
   return g_test_run();
 }


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