summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-04-04 23:11:05 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-04-04 23:42:58 -0400
commit6cf712591f5a9555a23f269883d4f688fa9a8c70 (patch)
tree24dafc8ec48c46423d95057fd49a12cd431d56b2
parentb32cd5d32871b76e7eba808b0d9dcd2377f0de11 (diff)
downloadgtk+-6cf712591f5a9555a23f269883d4f688fa9a8c70.tar.gz
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.
-rw-r--r--gtk/gtktextlayout.c43
-rw-r--r--gtk/gtktextlayoutprivate.h8
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);