[gtk/matthiasc/for-master: 14/15] textlayout: Avoid allocations for line iteration




commit 6cf712591f5a9555a23f269883d4f688fa9a8c70
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 4 23:11:05 2021 -0400

    textlayout: Avoid allocations for line iteration
    
    No need to collect the lines firs, and allocate memory
    for that. We can just iterate over them right away.

 gtk/gtktextlayout.c        | 43 +++++++++++++++++++++++--------------------
 gtk/gtktextlayoutprivate.h |  8 ++++----
 2 files changed, 27 insertions(+), 24 deletions(-)
---
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index e59adb85e8..2f53d945fa 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -677,7 +677,7 @@ gtk_text_layout_cursors_changed (GtkTextLayout *layout,
  *
  * Returns: (element-type GtkTextLine) (transfer container):
  */
-GSList*
+GPtrArray *
 gtk_text_layout_get_lines (GtkTextLayout *layout,
                            /* [top_y, bottom_y) */
                            int top_y,
@@ -688,7 +688,7 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
   GtkTextLine *first_btree_line;
   GtkTextLine *last_btree_line;
   GtkTextLine *line;
-  GSList *retval;
+  GPtrArray *lines;
 
   g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
 
@@ -697,8 +697,6 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
 
   btree = _gtk_text_buffer_get_btree (layout->buffer);
 
-  retval = NULL;
-
   first_btree_line = _gtk_text_btree_find_line_by_y (btree, layout, top_y, first_line_y);
   if (first_btree_line == NULL)
     {
@@ -714,10 +712,12 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
 
   g_assert (last_btree_line != NULL);
 
+  lines = g_ptr_array_sized_new (32);
+
   line = first_btree_line;
   while (TRUE)
     {
-      retval = g_slist_prepend (retval, line);
+      g_ptr_array_add (lines, line);
 
       if (line == last_btree_line)
         break;
@@ -725,9 +725,7 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
       line = _gtk_text_line_next_excluding_last (line);
     }
 
-  retval = g_slist_reverse (retval);
-
-  return retval;
+  return lines;
 }
 
 static void
@@ -4104,10 +4102,11 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
   int selection_end_line;
   gboolean have_selection;
   const GdkRGBA *selection;
-  GSList *line_list;
-  GSList *tmp_list;
   GdkRGBA color;
   GtkSnapshot *cursor_snapshot;
+  GtkTextBTree *btree;
+  GtkTextLine *first_line;
+  GtkTextLine *last_line;
 
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (layout->default_style != NULL);
@@ -4116,10 +4115,18 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
 
   priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout);
 
-  line_list = gtk_text_layout_get_lines (layout, clip->y, clip->y + clip->height, &offset_y);
+  if (clip->height <= 0)
+    return;
 
-  if (line_list == NULL)
-    return; /* nothing on the screen */
+  btree = _gtk_text_buffer_get_btree (layout->buffer);
+
+  first_line = _gtk_text_btree_find_line_by_y (btree, layout, clip->y, &offset_y);
+  if (first_line == NULL)
+    return;
+
+  last_line = _gtk_text_btree_find_line_by_y (btree, layout, clip->y + clip->height - 1, NULL);
+  if (last_line == NULL)
+    last_line = _gtk_text_btree_get_end_iter_line (btree);
 
   context = gtk_widget_get_style_context (widget);
   gtk_style_context_get_color (context, &color);
@@ -4163,10 +4170,10 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
 
   gtk_text_layout_wrap_loop_start (layout);
 
-  tmp_list = line_list;
-  while (tmp_list != NULL)
+  for (GtkTextLine *line = first_line;
+       line != last_line;
+       line = _gtk_text_line_next_excluding_last (line))
     {
-      GtkTextLine *line = tmp_list->data;
       GtkTextLineDisplay *line_display;
       int selection_start_index = -1;
       int selection_end_index = -1;
@@ -4272,8 +4279,6 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
       offset_y += line_display->height;
 
       gtk_text_line_display_unref (line_display);
-
-      tmp_list = tmp_list->next;
     }
 
   gtk_text_layout_wrap_loop_end (layout);
@@ -4293,8 +4298,6 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
   /* 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);
 }
 
diff --git a/gtk/gtktextlayoutprivate.h b/gtk/gtktextlayoutprivate.h
index c1a8ed92a5..fc07fcbb6f 100644
--- a/gtk/gtktextlayoutprivate.h
+++ b/gtk/gtktextlayoutprivate.h
@@ -254,10 +254,10 @@ gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout     *layout);
 void    gtk_text_layout_get_size  (GtkTextLayout  *layout,
                                    int            *width,
                                    int            *height);
-GSList* gtk_text_layout_get_lines (GtkTextLayout  *layout,
-                                   int             top_y,
-                                   int             bottom_y,
-                                   int            *first_line_y);
+GPtrArray *gtk_text_layout_get_lines (GtkTextLayout  *layout,
+                                      int             top_y,
+                                      int             bottom_y,
+                                      int            *first_line_y);
 
 void gtk_text_layout_wrap_loop_start (GtkTextLayout *layout);
 void gtk_text_layout_wrap_loop_end   (GtkTextLayout *layout);


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