[gtk/wip/chergert/group-gsk-pango] gskpango: group similar drawings together



commit 908b708d33f542eb53f6209d346d8e76a7bb70e7
Author: Christian Hergert <chergert redhat com>
Date:   Sat Jul 27 16:38:28 2019 -0700

    gskpango: group similar drawings together
    
    This groups various operations together into a common parent render node.
    The longer term goal is to simplify drawing items of similar types
    together.

 gtk/gskpango.c      | 108 ++++++++++++++++++++++++++++++++++++++++++++--------
 gtk/gskpango.h      |   8 +++-
 gtk/gtktextlayout.c |  71 +++++++++++++++++++++++-----------
 3 files changed, 149 insertions(+), 38 deletions(-)
---
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index ae7bbb3672..e07ad4b82b 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -43,6 +43,32 @@ gsk_pango_renderer_set_state (GskPangoRenderer      *crenderer,
   crenderer->state = state;
 }
 
+static GtkSnapshot *
+get_snapshot (GskPangoRenderer *crenderer,
+              gboolean          foreground)
+{
+  switch (crenderer->state)
+    {
+    case GSK_PANGO_RENDERER_CURSOR:
+      return crenderer->cursors_snapshot;
+
+    case GSK_PANGO_RENDERER_NORMAL:
+      if (foreground)
+        return crenderer->fg_snapshot;
+      else
+        return crenderer->bg_snapshot;
+
+    case GSK_PANGO_RENDERER_SELECTED:
+      if (foreground)
+        return crenderer->selection_fg_snapshot;
+      else
+        return crenderer->selection_bg_snapshot;
+
+    default:
+      g_return_val_if_reached (NULL);
+    }
+}
+
 static void
 get_color (GskPangoRenderer *crenderer,
            PangoRenderPart   part,
@@ -97,7 +123,7 @@ gsk_pango_renderer_draw_glyph_item (PangoRenderer  *renderer,
 
   get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
 
-  gtk_snapshot_append_text (crenderer->snapshot,
+  gtk_snapshot_append_text (get_snapshot (crenderer, TRUE),
                             glyph_item->item->analysis.font,
                             glyph_item->glyphs,
                             &color,
@@ -117,7 +143,7 @@ gsk_pango_renderer_draw_rectangle (PangoRenderer     *renderer,
   GdkRGBA rgba;
 
   get_color (crenderer, part, &rgba);
-  gtk_snapshot_append_color (crenderer->snapshot,
+  gtk_snapshot_append_color (get_snapshot (crenderer, FALSE),
                              &rgba,
                              &GRAPHENE_RECT_INIT ((double)x / PANGO_SCALE,
                                                   (double)y / PANGO_SCALE,
@@ -139,7 +165,8 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer   *renderer,
   cairo_t *cr;
   gdouble x, y;
 
-  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
+  cr = gtk_snapshot_append_cairo (get_snapshot (crenderer, TRUE),
+                                  &crenderer->bounds);
 
   set_color (crenderer, part, cr);
 
@@ -168,12 +195,14 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
                                          int            width,
                                          int            height)
 {
+  GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+  GtkSnapshot *snapshot;
   GdkRGBA rgba;
   double xx, yy, ww, hh;
   double hs;
   double e, o;
 
-  GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+  snapshot = get_snapshot (crenderer, TRUE);
 
   xx = (double)x / PANGO_SCALE;
   yy = (double)y / PANGO_SCALE;
@@ -185,18 +214,18 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
 
 #if 0
   gdk_rgba_parse (&rgba, "yellow");
-  gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+  gtk_snapshot_append_color (snapshot, &rgba,
                              &GRAPHENE_RECT_INIT (xx, yy, ww, hh));
 #endif
 
 
   get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba);
-  gtk_snapshot_save (crenderer->snapshot);
-  gtk_snapshot_translate (crenderer->snapshot,
+  gtk_snapshot_save (snapshot);
+  gtk_snapshot_translate (snapshot,
                           &GRAPHENE_POINT_INIT (xx, yy));
 
-  gtk_snapshot_rotate (crenderer->snapshot, 45);
-  gtk_snapshot_translate (crenderer->snapshot,
+  gtk_snapshot_rotate (snapshot, 45);
+  gtk_snapshot_translate (snapshot,
                           &GRAPHENE_POINT_INIT (e / 2 + hs * HEIGHT_RATIO,
                                                 - hs * HEIGHT_RATIO));
 
@@ -206,7 +235,7 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
       if (o + hs * (1 + HEIGHT_RATIO) >= ww)
         break;
 
-      gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+      gtk_snapshot_append_color (snapshot, &rgba,
                                  &GRAPHENE_RECT_INIT (xx, yy, hh, hh * HEIGHT_RATIO));
 
       xx += hh * (1 - HEIGHT_RATIO);
@@ -216,13 +245,13 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
       if (o + hs * (1 + HEIGHT_RATIO) >= ww)
         break;
 
-      gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+      gtk_snapshot_append_color (snapshot, &rgba,
                                  &GRAPHENE_RECT_INIT (xx, yy, hh * HEIGHT_RATIO, hh));
 
       o += hs * (1 - HEIGHT_RATIO);
     }
 
-  gtk_snapshot_restore (crenderer->snapshot);
+  gtk_snapshot_restore (snapshot);
 }
 
 static void
@@ -232,6 +261,7 @@ gsk_pango_renderer_draw_shape (PangoRenderer  *renderer,
                                int             y)
 {
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+  GtkSnapshot *snapshot;
   cairo_t *cr;
   PangoLayout *layout;
   PangoCairoShapeRendererFunc shape_renderer;
@@ -239,7 +269,8 @@ gsk_pango_renderer_draw_shape (PangoRenderer  *renderer,
   double base_x = (double)x / PANGO_SCALE;
   double base_y = (double)y / PANGO_SCALE;
 
-  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
+  snapshot = get_snapshot (crenderer, TRUE);
+  cr = gtk_snapshot_append_cairo (snapshot, &crenderer->bounds);
 
   layout = pango_renderer_get_layout (renderer);
   if (!layout)
@@ -419,6 +450,12 @@ gsk_pango_renderer_acquire (void)
       renderer = g_object_new (GSK_TYPE_PANGO_RENDERER, NULL);
     }
 
+  renderer->fg_snapshot = gtk_snapshot_new ();
+  renderer->bg_snapshot = gtk_snapshot_new ();
+  renderer->selection_fg_snapshot = gtk_snapshot_new ();
+  renderer->selection_bg_snapshot = gtk_snapshot_new ();
+  renderer->cursors_snapshot = gtk_snapshot_new ();
+
   return renderer;
 }
 
@@ -428,7 +465,6 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
   if (G_LIKELY (renderer->is_cached_renderer))
     {
       renderer->widget = NULL;
-      renderer->snapshot = NULL;
 
       if (renderer->error_color)
         {
@@ -436,12 +472,54 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
           renderer->error_color = NULL;
         }
 
+      g_clear_object (&renderer->fg_snapshot);
+      g_clear_object (&renderer->bg_snapshot);
+      g_clear_object (&renderer->selection_fg_snapshot);
+      g_clear_object (&renderer->selection_bg_snapshot);
+      g_clear_object (&renderer->cursors_snapshot);
+
       G_UNLOCK (cached_renderer);
     }
   else
     g_object_unref (renderer);
 }
 
+static void
+append_to_snapshot (GtkSnapshot  *snapshot,
+                    GtkSnapshot **source)
+{
+  g_assert (GTK_IS_SNAPSHOT (snapshot));
+  g_assert (source != NULL);
+
+  if (*source != NULL)
+    {
+      GskRenderNode *node;
+
+      node = gtk_snapshot_free_to_node (*source);
+      *source = NULL;
+
+      if (node != NULL)
+        {
+          gtk_snapshot_append_node (snapshot, node);
+          gsk_render_node_unref (node);
+        }
+    }
+}
+
+void
+gsk_pango_renderer_apply (GskPangoRenderer *crenderer,
+                          GtkSnapshot      *snapshot)
+{
+  g_return_if_fail (GSK_IS_PANGO_RENDERER (crenderer));
+  g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
+
+  append_to_snapshot (snapshot, &crenderer->bg_snapshot);
+  append_to_snapshot (snapshot, &crenderer->fg_snapshot);
+  append_to_snapshot (snapshot, &crenderer->selection_bg_snapshot);
+  append_to_snapshot (snapshot, &crenderer->selection_fg_snapshot);
+  append_to_snapshot (snapshot, &crenderer->cursors_snapshot);
+}
+
 /**
  * gtk_snapshot_append_layout:
  * @snapshot: a #GtkSnapshot
@@ -465,7 +543,6 @@ gtk_snapshot_append_layout (GtkSnapshot   *snapshot,
 
   crenderer = gsk_pango_renderer_acquire ();
 
-  crenderer->snapshot = snapshot;
   crenderer->fg_color = *color;
 
   pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
@@ -473,5 +550,6 @@ gtk_snapshot_append_layout (GtkSnapshot   *snapshot,
 
   pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
 
+  gsk_pango_renderer_apply (crenderer, snapshot);
   gsk_pango_renderer_release (crenderer);
 }
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 33ebff422a..1e01645486 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -52,7 +52,11 @@ struct _GskPangoRenderer
   PangoRenderer          parent_instance;
 
   GtkWidget             *widget;
-  GtkSnapshot           *snapshot;
+  GtkSnapshot           *fg_snapshot;
+  GtkSnapshot           *bg_snapshot;
+  GtkSnapshot           *selection_fg_snapshot;
+  GtkSnapshot           *selection_bg_snapshot;
+  GtkSnapshot           *cursors_snapshot;
   GdkRGBA                fg_color;
   graphene_rect_t        bounds;
 
@@ -75,6 +79,8 @@ void              gsk_pango_renderer_set_state (GskPangoRenderer      *crenderer
                                                 GskPangoRendererState  state);
 GskPangoRenderer *gsk_pango_renderer_acquire   (void);
 void              gsk_pango_renderer_release   (GskPangoRenderer      *crenderer);
+void              gsk_pango_renderer_apply     (GskPangoRenderer      *crenderer,
+                                                GtkSnapshot           *snapshot);
 
 G_END_DECLS
 
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 2ee27ed762..0a578ea3de 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -3847,6 +3847,33 @@ gtk_text_layout_after_buffer_delete_range (GtkTextBuffer *textbuffer,
   gtk_text_layout_update_cursor_line (layout);
 }
 
+static void
+push_translate (GskPangoRenderer       *crenderer,
+                const graphene_point_t *point)
+{
+  gtk_snapshot_save (crenderer->fg_snapshot);
+  gtk_snapshot_save (crenderer->bg_snapshot);
+  gtk_snapshot_save (crenderer->selection_fg_snapshot);
+  gtk_snapshot_save (crenderer->selection_bg_snapshot);
+  gtk_snapshot_save (crenderer->cursors_snapshot);
+
+  gtk_snapshot_translate (crenderer->fg_snapshot, point);
+  gtk_snapshot_translate (crenderer->bg_snapshot, point);
+  gtk_snapshot_translate (crenderer->selection_fg_snapshot, point);
+  gtk_snapshot_translate (crenderer->selection_bg_snapshot, point);
+  gtk_snapshot_translate (crenderer->cursors_snapshot, point);
+}
+
+static void
+pop_translate (GskPangoRenderer *crenderer)
+{
+  gtk_snapshot_restore (crenderer->fg_snapshot);
+  gtk_snapshot_restore (crenderer->bg_snapshot);
+  gtk_snapshot_restore (crenderer->selection_fg_snapshot);
+  gtk_snapshot_restore (crenderer->selection_bg_snapshot);
+  gtk_snapshot_restore (crenderer->cursors_snapshot);
+}
+
 static void
 render_para (GskPangoRenderer   *crenderer,
              int                 offset_y,
@@ -3880,8 +3907,7 @@ render_para (GskPangoRenderer   *crenderer,
       gtk_style_context_restore (context);
     }
 
-  gtk_snapshot_save (crenderer->snapshot);
-  gtk_snapshot_translate (crenderer->snapshot, &point);
+  push_translate (crenderer, &point);
 
   do
     {
@@ -3923,7 +3949,7 @@ render_para (GskPangoRenderer   *crenderer,
       if (selection_start_index < byte_offset &&
           selection_end_index > line->length + byte_offset) /* All selected */
         {
-          gtk_snapshot_append_color (crenderer->snapshot,
+          gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
                                      selection,
                                      &GRAPHENE_RECT_INIT (line_display->left_margin,
                                                           selection_y,
@@ -3938,7 +3964,7 @@ render_para (GskPangoRenderer   *crenderer,
       else
         {
           if (line_display->pg_bg_rgba_set)
-            gtk_snapshot_append_color (crenderer->snapshot,
+            gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
                                        &line_display->pg_bg_rgba,
                                        &GRAPHENE_RECT_INIT (line_display->left_margin,
                                                             selection_y,
@@ -3975,13 +4001,13 @@ render_para (GskPangoRenderer   *crenderer,
                   bounds.size.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]);
                   bounds.size.height = selection_height;
 
-                  gtk_snapshot_append_color (crenderer->snapshot, selection, &bounds);
-                  gtk_snapshot_push_clip (crenderer->snapshot, &bounds);
+                  gtk_snapshot_append_color (crenderer->selection_bg_snapshot, selection, &bounds);
+                  gtk_snapshot_push_clip (crenderer->selection_fg_snapshot, &bounds);
                   pango_renderer_draw_layout_line (PANGO_RENDERER (crenderer),
                                                    line,
                                                    line_rect.x,
                                                    baseline);
-                  gtk_snapshot_pop (crenderer->snapshot);
+                  gtk_snapshot_pop (crenderer->selection_fg_snapshot);
                 }
 
               g_free (ranges);
@@ -3990,7 +4016,7 @@ render_para (GskPangoRenderer   *crenderer,
               if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
                   ((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
                    (line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + 
line->length)))
-                gtk_snapshot_append_color (crenderer->snapshot,
+                gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
                                            selection,
                                            &GRAPHENE_RECT_INIT (line_display->left_margin,
                                                                 selection_y,
@@ -4006,7 +4032,7 @@ render_para (GskPangoRenderer   *crenderer,
                                       + screen_width
                                       - PANGO_PIXELS (line_rect.x)
                                       - PANGO_PIXELS (line_rect.width);
-                  gtk_snapshot_append_color (crenderer->snapshot,
+                  gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
                                              selection,
                                              &GRAPHENE_RECT_INIT (PANGO_PIXELS (line_rect.x) + PANGO_PIXELS 
(line_rect.width),
                                                                   selection_y,
@@ -4032,21 +4058,21 @@ render_para (GskPangoRenderer   *crenderer,
                * (normally white on black) */
               _gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
 
-              gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
-              gtk_snapshot_append_color (crenderer->snapshot, &cursor_color, &bounds);
+              gtk_snapshot_push_opacity (crenderer->cursors_snapshot, cursor_alpha);
+              gtk_snapshot_append_color (crenderer->cursors_snapshot, &cursor_color, &bounds);
 
               /* draw text under the cursor if any */
               if (!line_display->cursor_at_line_end)
                 {
                   gsk_pango_renderer_set_state (crenderer, GSK_PANGO_RENDERER_CURSOR);
-                  gtk_snapshot_push_clip (crenderer->snapshot, &bounds);
+                  gtk_snapshot_push_clip (crenderer->cursors_snapshot, &bounds);
                   pango_renderer_draw_layout_line (PANGO_RENDERER (crenderer),
                                                    line,
                                                    line_rect.x,
                                                    baseline);
-                  gtk_snapshot_pop (crenderer->snapshot);
+                  gtk_snapshot_pop (crenderer->cursors_snapshot);
                 }
-              gtk_snapshot_pop (crenderer->snapshot);
+              gtk_snapshot_pop (crenderer->cursors_snapshot);
             }
         }
 
@@ -4054,7 +4080,7 @@ render_para (GskPangoRenderer   *crenderer,
     }
   while (pango_layout_iter_next_line (iter));
 
-  gtk_snapshot_restore (crenderer->snapshot);
+  pop_translate (crenderer);
 
   gdk_rgba_free (selection);
   pango_layout_iter_free (iter);
@@ -4070,12 +4096,12 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
   GtkTextLayoutPrivate *priv;
   GskPangoRenderer *crenderer;
   GtkStyleContext *context;
-  gint offset_y;
   GtkTextIter selection_start, selection_end;
   gboolean have_selection;
   GSList *line_list;
   GSList *tmp_list;
   GdkRGBA color;
+  gint offset_y;
 
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (layout->default_style != NULL);
@@ -4095,7 +4121,6 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
   crenderer = gsk_pango_renderer_acquire ();
 
   crenderer->widget = widget;
-  crenderer->snapshot = snapshot;
   crenderer->fg_color = color;
 
   graphene_rect_init (&crenderer->bounds, 0, 0, clip->width, clip->height);
@@ -4157,7 +4182,7 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
             {
               int i;
 
-              gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
+              gtk_snapshot_push_opacity (crenderer->cursors_snapshot, cursor_alpha);
               for (i = 0; i < line_display->cursors->len; i++)
                 {
                   int index;
@@ -4166,12 +4191,12 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
                   index = g_array_index(line_display->cursors, int, i);
                   dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL : 
PANGO_DIRECTION_LTR;
 
-                  gtk_snapshot_render_insertion_cursor (crenderer->snapshot, context,
+                  gtk_snapshot_render_insertion_cursor (crenderer->cursors_snapshot, context,
                                                         line_display->x_offset, offset_y + 
line_display->top_margin,
                                                         line_display->layout, index, dir);
                 }
 
-              gtk_snapshot_pop (crenderer->snapshot);
+              gtk_snapshot_pop (crenderer->cursors_snapshot);
             }
         } /* line_display->height > 0 */
 
@@ -4184,11 +4209,13 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
 
   gtk_text_layout_wrap_loop_end (layout);
 
+  g_slist_free (line_list);
+
+  gsk_pango_renderer_apply (crenderer, snapshot);
+
   /* Only update eviction source once per snapshot */
   gtk_text_line_display_cache_delay_eviction (priv->cache);
 
-  g_slist_free (line_list);
-
   gsk_pango_renderer_release (crenderer);
 }
 


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