[gtk+] snapshot: Add infrastructure to snapshot CSS images



commit 6d9725f7fdc97bbb5c04a22fb3f664bda686f048
Author: Benjamin Otte <otte redhat com>
Date:   Wed Nov 16 20:51:53 2016 +0100

    snapshot: Add infrastructure to snapshot CSS images
    
    Use this infrastructure to render builtin images. Which means from now
    on, GtkCheckbutton, GtkSpinner and a few others use snapshots.

 gtk/gtkbuiltinicon.c            |   21 +++++++++++++++
 gtk/gtkcssimage.c               |   34 +++++++++++++++++++++++++
 gtk/gtkcssimagebuiltin.c        |   28 +++++++++++++++++++++
 gtk/gtkcssimagebuiltinprivate.h |    5 +++
 gtk/gtkcssimageprivate.h        |    9 ++++++
 gtk/gtkiconhelper.c             |    2 +-
 gtk/gtkrendericon.c             |   52 ++++++++++++++++++++++++++++++++++++--
 gtk/gtkrendericonprivate.h      |    7 ++++-
 gtk/gtksnapshot.c               |    6 ++--
 9 files changed, 156 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkbuiltinicon.c b/gtk/gtkbuiltinicon.c
index ab294af..547fc35 100644
--- a/gtk/gtkbuiltinicon.c
+++ b/gtk/gtkbuiltinicon.c
@@ -145,6 +145,26 @@ gtk_builtin_icon_draw (GtkCssGadget *gadget,
   return FALSE;
 }
 
+static gboolean
+gtk_builtin_icon_snapshot (GtkCssGadget *gadget,
+                           GtkSnapshot  *snapshot,
+                           int           x,
+                           int           y,
+                           int           width,
+                           int           height)
+{
+  GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
+
+  gtk_snapshot_translate_2d (snapshot, x, y);
+  gtk_css_style_snapshot_icon (gtk_css_gadget_get_style (gadget),
+                               snapshot,
+                               width, height,
+                               priv->image_type);
+  gtk_snapshot_translate_2d (snapshot, -x, -y);
+
+  return FALSE;
+}
+
 static void
 gtk_builtin_icon_style_changed (GtkCssGadget      *gadget,
                                 GtkCssStyleChange *change)
@@ -165,6 +185,7 @@ gtk_builtin_icon_class_init (GtkBuiltinIconClass *klass)
   gadget_class->get_preferred_size = gtk_builtin_icon_get_preferred_size;
   gadget_class->allocate = gtk_builtin_icon_allocate;
   gadget_class->draw = gtk_builtin_icon_draw;
+  gadget_class->snapshot = gtk_builtin_icon_snapshot;
   gadget_class->style_changed = gtk_builtin_icon_style_changed;
 }
 
diff --git a/gtk/gtkcssimage.c b/gtk/gtkcssimage.c
index 0f6c4e8..81ab757 100644
--- a/gtk/gtkcssimage.c
+++ b/gtk/gtkcssimage.c
@@ -96,6 +96,21 @@ gtk_css_image_real_transition (GtkCssImage *start,
 }
 
 static void
+gtk_css_image_real_snapshot (GtkCssImage *image,
+                             GtkSnapshot *snapshot,
+                             double       width,
+                             double       height)
+{
+  cairo_t *cr;
+
+  cr = gtk_snapshot_append_cairo_node (snapshot,
+                                       &(graphene_rect_t)GRAPHENE_RECT_INIT (0, 0, width, height),
+                                       "Fallback<%s>", G_OBJECT_TYPE_NAME (image));
+  _gtk_css_image_draw (image, cr, width, height);
+  cairo_destroy (cr);
+}
+
+static void
 _gtk_css_image_class_init (GtkCssImageClass *klass)
 {
   klass->get_width = gtk_css_image_real_get_width;
@@ -104,6 +119,7 @@ _gtk_css_image_class_init (GtkCssImageClass *klass)
   klass->compute = gtk_css_image_real_compute;
   klass->equal = gtk_css_image_real_equal;
   klass->transition = gtk_css_image_real_transition;
+  klass->snapshot = gtk_css_image_real_snapshot;
 }
 
 static void
@@ -241,6 +257,24 @@ _gtk_css_image_draw (GtkCssImage        *image,
 }
 
 void
+gtk_css_image_snapshot (GtkCssImage *image,
+                        GtkSnapshot *snapshot,
+                        double       width,
+                        double       height)
+{
+  GtkCssImageClass *klass;
+
+  g_return_if_fail (GTK_IS_CSS_IMAGE (image));
+  g_return_if_fail (snapshot != NULL);
+  g_return_if_fail (width > 0);
+  g_return_if_fail (height > 0);
+
+  klass = GTK_CSS_IMAGE_GET_CLASS (image);
+
+  klass->snapshot (image, snapshot, width, height);
+}
+
+void
 _gtk_css_image_print (GtkCssImage *image,
                       GString     *string)
 {
diff --git a/gtk/gtkcssimagebuiltin.c b/gtk/gtkcssimagebuiltin.c
index 3c045d9..841ae91 100644
--- a/gtk/gtkcssimagebuiltin.c
+++ b/gtk/gtkcssimagebuiltin.c
@@ -643,3 +643,31 @@ gtk_css_image_builtin_draw (GtkCssImage            *image,
   }
 }
 
+void
+gtk_css_image_builtin_snapshot (GtkCssImage            *image,
+                                GtkSnapshot            *snapshot,
+                                double                  width,
+                                double                  height,
+                                GtkCssImageBuiltinType  image_type)
+{
+  cairo_t *cr;
+
+  g_return_if_fail (GTK_IS_CSS_IMAGE (image));
+  g_return_if_fail (snapshot != NULL);
+  g_return_if_fail (width > 0);
+  g_return_if_fail (height > 0);
+
+  if (!GTK_IS_CSS_IMAGE_BUILTIN (image))
+    {
+      gtk_css_image_snapshot (image, snapshot, width, height);
+      return;
+    }
+
+  cr = gtk_snapshot_append_cairo_node (snapshot,
+                                       &(graphene_rect_t)GRAPHENE_RECT_INIT (0, 0, width, height),
+                                       "BuiltinImage<%d>", (int) image_type);
+  gtk_css_image_builtin_draw (image, cr, width, height, image_type);
+  cairo_destroy (cr);
+}
+
+
diff --git a/gtk/gtkcssimagebuiltinprivate.h b/gtk/gtkcssimagebuiltinprivate.h
index 1ceeeff..66c94d2 100644
--- a/gtk/gtkcssimagebuiltinprivate.h
+++ b/gtk/gtkcssimagebuiltinprivate.h
@@ -57,6 +57,11 @@ void           gtk_css_image_builtin_draw                  (GtkCssImage
                                                             double                       width,
                                                             double                       height,
                                                             GtkCssImageBuiltinType       image_type);
+void           gtk_css_image_builtin_snapshot              (GtkCssImage                 *image,
+                                                            GtkSnapshot                 *snapshot,
+                                                            double                       width,
+                                                            double                       height,
+                                                            GtkCssImageBuiltinType       image_type);
 
 G_END_DECLS
 
diff --git a/gtk/gtkcssimageprivate.h b/gtk/gtkcssimageprivate.h
index 912d0d7..492734c 100644
--- a/gtk/gtkcssimageprivate.h
+++ b/gtk/gtkcssimageprivate.h
@@ -25,6 +25,7 @@
 
 #include "gtk/gtkcssparserprivate.h"
 #include "gtk/gtkcsstypesprivate.h"
+#include "gtk/gtksnapshotprivate.h"
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,10 @@ struct _GtkCssImageClass
                                                     cairo_t                    *cr,
                                                     double                      width,
                                                     double                      height);
+  void         (* snapshot)                        (GtkCssImage                *image,
+                                                    GtkSnapshot                *snapshot,
+                                                    double                      width,
+                                                    double                      height);
   /* parse CSS, return TRUE on success */
   gboolean     (* parse)                           (GtkCssImage                *image,
                                                     GtkCssParser               *parser);
@@ -107,6 +112,10 @@ void           _gtk_css_image_draw                 (GtkCssImage                *
                                                     cairo_t                    *cr,
                                                     double                      width,
                                                     double                      height);
+void           gtk_css_image_snapshot              (GtkCssImage                *image,
+                                                    GtkSnapshot                *snapshot,
+                                                    double                      width,
+                                                    double                      height);
 void           _gtk_css_image_print                (GtkCssImage                *image,
                                                     GString                    *string);
 
diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c
index bd9a6f6..98b0362 100644
--- a/gtk/gtkiconhelper.c
+++ b/gtk/gtkiconhelper.c
@@ -870,7 +870,7 @@ gtk_icon_helper_snapshot (GtkIconHelper *self,
  
   style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
 
-  gtk_css_style_snapshot_icon (style, snapshot, texture);
+  gtk_css_style_snapshot_icon_texture (style, snapshot, texture);
 }
 
 gboolean
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index cd43ec9..8ed65e0 100644
--- a/gtk/gtkrendericon.c
+++ b/gtk/gtkrendericon.c
@@ -82,6 +82,52 @@ gtk_css_style_render_icon (GtkCssStyle            *style,
   cairo_set_matrix (cr, &saved_matrix);
 }
 
+void
+gtk_css_style_snapshot_icon (GtkCssStyle            *style,
+                             GtkSnapshot            *snapshot,
+                             double                  width,
+                             double                  height,
+                             GtkCssImageBuiltinType  builtin_type)
+{
+  const GtkCssValue *shadows, *transform;
+  cairo_matrix_t transform_matrix;
+  graphene_matrix_t matrix, other, saved_matrix;
+  GtkCssImage *image;
+
+  g_return_if_fail (GTK_IS_CSS_STYLE (style));
+  g_return_if_fail (snapshot != NULL);
+
+  image = _gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE));
+  if (image == NULL)
+    return;
+
+  shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
+  transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
+
+  if (!_gtk_css_transform_value_get_matrix (transform, &transform_matrix))
+    return;
+
+  graphene_matrix_init_from_matrix (&saved_matrix, gtk_snapshot_get_transform (snapshot));
+
+  /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
+  graphene_matrix_init_translate (&matrix, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(width / 2.0, height / 
2.0, 0));
+  graphene_matrix_init_from_2d (&other, transform_matrix.xx, transform_matrix.yx,
+                                        transform_matrix.xy, transform_matrix.yy,
+                                        transform_matrix.x0, transform_matrix.y0);
+  graphene_matrix_multiply (&other, &matrix, &matrix);
+  graphene_matrix_init_translate (&other, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(- width / 2.0, - height 
/ 2.0, 0));
+  graphene_matrix_multiply (&matrix, &other, &matrix);
+  gtk_snapshot_transform (snapshot, &matrix);
+
+  if (!_gtk_css_shadows_value_is_none (shadows))
+    {
+      g_warning ("Painting shadows not implemented for textures yet.");
+    }
+  gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
+
+  gtk_snapshot_set_transform (snapshot, &saved_matrix);
+}
+
 static gboolean
 get_surface_extents (cairo_surface_t *surface,
                      GdkRectangle    *out_extents)
@@ -224,9 +270,9 @@ gtk_css_style_render_icon_get_extents (GtkCssStyle  *style,
 }
 
 void
-gtk_css_style_snapshot_icon (GtkCssStyle *style,
-                             GtkSnapshot *snapshot,
-                             GskTexture  *texture)
+gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
+                                     GtkSnapshot *snapshot,
+                                     GskTexture  *texture)
 {
   const GtkCssValue *shadows, *transform;
   cairo_matrix_t transform_matrix;
diff --git a/gtk/gtkrendericonprivate.h b/gtk/gtkrendericonprivate.h
index 83a3b04..8b12d13 100644
--- a/gtk/gtkrendericonprivate.h
+++ b/gtk/gtkrendericonprivate.h
@@ -37,13 +37,18 @@ void    gtk_css_style_render_icon               (GtkCssStyle            *style,
                                                  double                  width,
                                                  double                  height,
                                                  GtkCssImageBuiltinType  builtin_type);
+void    gtk_css_style_snapshot_icon             (GtkCssStyle            *style,
+                                                 GtkSnapshot            *snapshot,
+                                                 double                  width,
+                                                 double                  height,
+                                                 GtkCssImageBuiltinType  builtin_type);
 
 void    gtk_css_style_render_icon_surface       (GtkCssStyle            *style,
                                                  cairo_t                *cr,
                                                  cairo_surface_t        *surface,
                                                  double                  x,
                                                  double                  y);
-void    gtk_css_style_snapshot_icon             (GtkCssStyle            *style,
+void    gtk_css_style_snapshot_icon_texture     (GtkCssStyle            *style,
                                                  GtkSnapshot            *snapshot,
                                                  GskTexture             *texture);
 
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 7a7fd66..3f2fd4b 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -402,9 +402,9 @@ gtk_snapshot_render_icon (GtkSnapshot     *snapshot,
 
   texture = gsk_texture_new_for_pixbuf (pixbuf);
   gtk_snapshot_translate_2d (snapshot, x, y);
-  gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
-                               snapshot,
-                               texture);
+  gtk_css_style_snapshot_icon_texture (gtk_style_context_lookup_style (context),
+                                       snapshot,
+                                       texture);
   gtk_snapshot_translate_2d (snapshot, -x, -y);
   gsk_texture_unref (texture);
 }


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