snapshot: Make gtk_snapshot_append_node() take care of offset
authorBenjamin Otte <otte@redhat.com>
Tue, 20 Mar 2018 03:33:58 +0000 (04:33 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 26 Mar 2018 16:16:36 +0000 (18:16 +0200)
Push an offset node when append_node is called. That resets the offset.

gtk/gskpango.c
gtk/gtkcssshadowvalue.c
gtk/gtkoverlay.c
gtk/gtkrenderborder.c
gtk/gtksnapshot.c
gtk/gtksnapshotprivate.h
gtk/gtkstack.c

index e293759d2da98c5c3e3a344831303924c85c2110..1b84c71357f10ef3f075cc1f57d77c210c912402 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "gsk/gsk.h"
 #include "gskpango.h"
-#include "gtksnapshot.h"
+#include "gtksnapshotprivate.h"
 
 #include <math.h>
 
@@ -162,7 +162,7 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
       gsk_render_node_set_name (node, name);
     }
 
-  gtk_snapshot_append_node (crenderer->snapshot, node);
+  gtk_snapshot_append_node_internal (crenderer->snapshot, node);
   gsk_render_node_unref (node);
 }
 
index 9fee5abf15323d54da37f98db9236cea527c0eb1..f1198fff29466b3d40245d7e9cdaa3278a0a1175 100644 (file)
@@ -24,7 +24,7 @@
 #include "gtkcsscolorvalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
 #include "gtkcssrgbavalueprivate.h"
-#include "gtksnapshot.h"
+#include "gtksnapshotprivate.h"
 #include "gtkstylecontextprivate.h"
 #include "gtkpango.h"
 
@@ -1057,7 +1057,7 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue    *shadow,
                                      _gtk_css_number_value_get (shadow->radius, 0));
   if (gtk_snapshot_get_record_names (snapshot))
     gsk_render_node_set_name (node, "Outset Shadow");
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
@@ -1088,7 +1088,7 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue   *shadow,
                                     _gtk_css_number_value_get (shadow->radius, 0));
   if (gtk_snapshot_get_record_names (snapshot))
     gsk_render_node_set_name (node, "Inset Shadow");
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
index 2e8f4dc2f9fc98b3be398f24be41104cfbd65241..54230b687920bbf0704ca822b668662cc00eac6b 100644 (file)
@@ -655,7 +655,6 @@ gtk_overlay_snapshot (GtkWidget   *widget,
   GtkAllocation main_alloc;
   cairo_region_t *clip = NULL;
   int i;
-  graphene_matrix_t translate;
 
   main_widget = gtk_bin_get_child (GTK_BIN (widget));
   gtk_widget_get_allocation (widget, &main_alloc);
@@ -682,7 +681,6 @@ gtk_overlay_snapshot (GtkWidget   *widget,
               gtk_widget_snapshot (main_widget, child_snapshot);
               gtk_snapshot_offset (child_snapshot, -main_alloc.x, -main_alloc.y);
               main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
-              graphene_matrix_init_translate (&translate, &GRAPHENE_POINT3D_INIT (main_alloc.x,main_alloc.y, 0));
             }
 
           gtk_widget_get_allocation (child, &alloc);
index 132a30c21a78a165b7b53b6b7e5221cc07559cbf..540a66e2d8bd45a8948c911fa7803831a19fb7ff 100644 (file)
@@ -35,6 +35,7 @@
 #include "gtkcssstyleprivate.h"
 #include "gtkhslaprivate.h"
 #include "gtkroundedboxprivate.h"
+#include "gtksnapshotprivate.h"
 
 #include "gsk/gskroundedrectprivate.h"
 
@@ -440,7 +441,7 @@ snapshot_frame_fill (GtkSnapshot          *snapshot,
   node = gsk_border_node_new (&offset_outline, border_width, colors);
   if (gtk_snapshot_get_record_names (snapshot))
     gsk_render_node_set_name (node, "Border");
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
index cc8bd80b506ba89d0d5959ac64f35368c9468898..3299c4ccdcb27a96769c7441b312b8c9007055e0 100644 (file)
@@ -336,6 +336,98 @@ gtk_snapshot_push_transform (GtkSnapshot             *snapshot,
   graphene_matrix_multiply (transform, &offset, &state->data.transform.transform);
 }
 
+static GskRenderNode *
+gtk_snapshot_collect_offset (GtkSnapshot       *snapshot,
+                             GtkSnapshotState  *state,
+                             GskRenderNode    **nodes,
+                             guint              n_nodes,
+                             const char        *name)
+{
+  GskRenderNode *node, *offset_node;
+  GtkSnapshotState  *previous_state;
+
+  node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
+  if (node == NULL)
+    return NULL;
+
+  previous_state = gtk_snapshot_get_previous_state (snapshot);
+  if (previous_state->translate_x == 0.0 &&
+      previous_state->translate_y == 0.0)
+    return node;
+
+  offset_node = gsk_offset_node_new (node,
+                                     previous_state->translate_x,
+                                     previous_state->translate_y);
+  if (name)
+    gsk_render_node_set_name (offset_node, name);
+
+  gsk_render_node_unref (node);
+
+  return offset_node;
+}
+
+static void
+gtk_snapshot_push_offset (GtkSnapshot *snapshot,
+                          const char  *name,
+                          ...) G_GNUC_PRINTF(2, 3);
+static void
+gtk_snapshot_push_offset (GtkSnapshot *snapshot,
+                          const char  *name,
+                          ...)
+{
+  GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
+  char *str;
+  cairo_region_t *offset_clip;
+
+  if (name && snapshot->record_names)
+    {
+      va_list args;
+
+      va_start (args, name);
+      str = g_strdup_vprintf (name, args);
+      va_end (args);
+    }
+  else
+    str = NULL;
+
+  if (state->clip_region)
+    {
+      offset_clip = cairo_region_copy (state->clip_region);
+      if (state->translate_x != floor (state->translate_x))
+        {
+          cairo_region_translate (offset_clip, -1, 0);
+          cairo_region_union (offset_clip, state->clip_region);
+          if (state->translate_y != floor (state->translate_y))
+            {
+              cairo_region_t *tmp = cairo_region_copy (offset_clip);
+              cairo_region_translate (offset_clip, 0, -1);
+              cairo_region_union (offset_clip, tmp);
+              cairo_region_destroy (tmp);
+            }
+        }
+      else if (state->translate_y != floor (state->translate_y))
+        {
+          cairo_region_translate (offset_clip, 0, -1);
+          cairo_region_union (offset_clip, state->clip_region);
+        }
+      cairo_region_translate (offset_clip, 
+                              - floor (state->translate_x),
+                              - floor (state->translate_y));
+
+    }
+  else
+    {
+      offset_clip = NULL;
+    }
+  state = gtk_snapshot_push_state (snapshot,
+                                   str,
+                                   offset_clip,
+                                   0, 0,
+                                   gtk_snapshot_collect_offset);
+  if (offset_clip)
+    cairo_region_destroy (offset_clip);
+}
+
 static GskRenderNode *
 gtk_snapshot_collect_opacity (GtkSnapshot      *snapshot,
                               GtkSnapshotState *state,
@@ -1191,7 +1283,7 @@ gtk_snapshot_pop (GtkSnapshot *snapshot)
   node = gtk_snapshot_pop_internal (snapshot);
   if (node)
     {
-      gtk_snapshot_append_node (snapshot, node);
+      gtk_snapshot_append_node_internal (snapshot, node);
       gsk_render_node_unref (node);
     }
 }
@@ -1261,6 +1353,25 @@ gtk_snapshot_get_offset (GtkSnapshot *snapshot,
     *y = current_state->translate_y;
 }
 
+void
+gtk_snapshot_append_node_internal (GtkSnapshot   *snapshot,
+                                   GskRenderNode *node)
+{
+  GtkSnapshotState *current_state;
+
+  current_state = gtk_snapshot_get_current_state (snapshot);
+
+  if (current_state)
+    {
+      g_ptr_array_add (snapshot->nodes, gsk_render_node_ref (node));
+      current_state->n_nodes ++;
+    }
+  else
+    {
+      g_critical ("Tried appending a node to an already finished snapshot.");
+    }
+}
+
 /**
  * gtk_snapshot_append_node:
  * @snapshot: a #GtkSnapshot
@@ -1275,22 +1386,12 @@ void
 gtk_snapshot_append_node (GtkSnapshot   *snapshot,
                           GskRenderNode *node)
 {
-  GtkSnapshotState *current_state;
-
   g_return_if_fail (snapshot != NULL);
   g_return_if_fail (GSK_IS_RENDER_NODE (node));
 
-  current_state = gtk_snapshot_get_current_state (snapshot);
-
-  if (current_state)
-    {
-      g_ptr_array_add (snapshot->nodes, gsk_render_node_ref (node));
-      current_state->n_nodes ++;
-    }
-  else
-    {
-      g_critical ("Tried appending a node to an already finished snapshot.");
-    }
+  gtk_snapshot_push_offset (snapshot, "OffsetReset");
+  gtk_snapshot_append_node_internal (snapshot, node);
+  gtk_snapshot_pop (snapshot);
 }
 
 /**
@@ -1351,7 +1452,7 @@ gtk_snapshot_append_cairo (GtkSnapshot           *snapshot,
       g_free (str);
     }
 
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 
   cr = gsk_cairo_node_get_draw_context (node);
@@ -1404,7 +1505,7 @@ gtk_snapshot_append_texture (GtkSnapshot            *snapshot,
       g_free (str);
     }
 
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
@@ -1469,7 +1570,7 @@ gtk_snapshot_append_color (GtkSnapshot           *snapshot,
       g_free (str);
     }
 
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
@@ -1709,7 +1810,7 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot            *snapshot,
       g_free (str);
     }
 
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
 
@@ -1787,6 +1888,6 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot            *snapshot,
       g_free (str);
     }
 
-  gtk_snapshot_append_node (snapshot, node);
+  gtk_snapshot_append_node_internal (snapshot, node);
   gsk_render_node_unref (node);
 }
index 920da7917d49262654dc212eea4229df9e4fbf86..b1501f6307a12bce06550624d209a6af1951e17b 100644 (file)
@@ -97,6 +97,9 @@ struct _GtkSnapshotClass {
   GObjectClass           parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */
 };
 
+void            gtk_snapshot_append_node_internal       (GtkSnapshot            *snapshot,
+                                                         GskRenderNode          *node);
+
 G_END_DECLS
 
 #endif /* __GTK_SNAPSHOT_PRIVATE_H__ */
index a5c46ba2cfa2d17b215ef612cb50775bd39e94e0..0b05f42352a423b83df2b49b39ec0accfaa2805b 100644 (file)
@@ -1790,18 +1790,13 @@ gtk_stack_snapshot_crossfade (GtkWidget   *widget,
 
   if (priv->last_visible_node)
     {
-      graphene_matrix_t translate;
-
-      graphene_matrix_init_translate (&translate,
-                                      &GRAPHENE_POINT3D_INIT (
-                                        priv->last_visible_surface_allocation.x,
-                                        priv->last_visible_surface_allocation.y,
-                                        0)
-                                      );
-
-      gtk_snapshot_push_transform (snapshot, &translate, "CrossFadeStart");
+      gtk_snapshot_offset (snapshot,
+                           priv->last_visible_surface_allocation.x,
+                           priv->last_visible_surface_allocation.y);
       gtk_snapshot_append_node (snapshot, priv->last_visible_node);
-      gtk_snapshot_pop (snapshot);
+      gtk_snapshot_offset (snapshot,
+                           -priv->last_visible_surface_allocation.x,
+                           -priv->last_visible_surface_allocation.y);
     }
   gtk_snapshot_pop (snapshot);
 
@@ -1865,13 +1860,9 @@ gtk_stack_snapshot_under (GtkWidget   *widget,
 
   if (priv->last_visible_node)
     {
-      graphene_matrix_t matrix;
-
-      graphene_matrix_init_translate (&matrix, &GRAPHENE_POINT3D_INIT (pos_x, pos_y, 0));
-
-      gtk_snapshot_push_transform (snapshot, &matrix, "StackUnder");
+      gtk_snapshot_offset (snapshot, pos_x, pos_y);
       gtk_snapshot_append_node (snapshot, priv->last_visible_node);
-      gtk_snapshot_pop (snapshot);
+      gtk_snapshot_offset (snapshot, -pos_x, -pos_y);
     }
 }
 
@@ -1884,7 +1875,6 @@ gtk_stack_snapshot_slide (GtkWidget   *widget,
 
   if (priv->last_visible_node)
     {
-      graphene_matrix_t matrix;
       int x, y;
       int width, height;
 
@@ -1927,10 +1917,9 @@ gtk_stack_snapshot_slide (GtkWidget   *widget,
       else if (gtk_widget_get_valign (priv->last_visible_child->widget) == GTK_ALIGN_CENTER)
         y -= (priv->last_visible_widget_height - height) / 2;
 
-      graphene_matrix_init_translate (&matrix, &GRAPHENE_POINT3D_INIT (x, y, 0));
-      gtk_snapshot_push_transform (snapshot, &matrix, "StackSlide");
+      gtk_snapshot_offset (snapshot, x, y);
       gtk_snapshot_append_node (snapshot, priv->last_visible_node);
-      gtk_snapshot_pop (snapshot);
+      gtk_snapshot_offset (snapshot, -x, -y);
      }
 
   gtk_widget_snapshot_child (widget,