From 3bd4eef72636dd86c380c643157276953ce99a4f Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 22 Oct 2024 17:52:35 -0700 Subject: [PATCH] gtk/textlayout: remove one_style_cache When porting textlayout to GTK 4 a line display cache was introduced. That cache creates a situation where you may not create GtkTextLineDisplay in order from GtkTextLineSegment. Because of that, we must start the creation of each line display from fresh line state or we could re-apply the GtkTextAppearance of another row. However, once you do that, one_style_cache will never have a match and therefore is pure overhead. This removes one_style_cache altogether. Fixes: #7108 --- gtk/gtktextlayout.c | 101 ++----------------------------------- gtk/gtktextlayoutprivate.h | 8 --- 2 files changed, 4 insertions(+), 105 deletions(-) diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 26bca13ffe..f34cc1fd7c 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -291,16 +291,6 @@ gtk_text_layout_new (void) return g_object_new (GTK_TYPE_TEXT_LAYOUT, NULL); } -static void -free_style_cache (GtkTextLayout *text_layout) -{ - if (text_layout->one_style_cache) - { - gtk_text_attributes_unref (text_layout->one_style_cache); - text_layout->one_style_cache = NULL; - } -} - /* * gtk_text_layout_set_buffer: * @buffer: (nullable): @@ -315,8 +305,6 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout, if (layout->buffer == buffer) return; - free_style_cache (layout); - if (layout->buffer) { _gtk_text_btree_remove_view (_gtk_text_buffer_get_btree (layout->buffer), @@ -515,7 +503,6 @@ gtk_text_layout_set_screen_width (GtkTextLayout *layout, int width) { g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); g_return_if_fail (width >= 0); - g_return_if_fail (layout->wrap_loop_count == 0); if (layout->screen_width == width) return; @@ -673,43 +660,6 @@ gtk_text_layout_cursors_changed (GtkTextLayout *layout, gtk_text_layout_emit_changed (layout, y, old_height, new_height); } -static void -invalidate_cached_style (GtkTextLayout *layout) -{ - free_style_cache (layout); -} - -/* These should be called around a loop which wraps a CONTIGUOUS bunch - * of display lines. If the lines aren’t contiguous you can’t call - * these. - */ -void -gtk_text_layout_wrap_loop_start (GtkTextLayout *layout) -{ - g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); - g_return_if_fail (layout->one_style_cache == NULL); - - layout->wrap_loop_count += 1; -} - -void -gtk_text_layout_wrap_loop_end (GtkTextLayout *layout) -{ - g_return_if_fail (layout->wrap_loop_count > 0); - - layout->wrap_loop_count -= 1; - - if (layout->wrap_loop_count == 0) - { - /* We cache a some stuff if we're iterating over some lines wrapping - * them. This cleans it up. - */ - /* Nuke our cached style */ - invalidate_cached_style (layout); - g_assert (layout->one_style_cache == NULL); - } -} - static void gtk_text_layout_invalidate_all (GtkTextLayout *layout) { @@ -790,7 +740,6 @@ gtk_text_layout_invalidate (GtkTextLayout *layout, GtkTextLine *last_line; g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); - g_return_if_fail (layout->wrap_loop_count == 0); /* Because we may be invalidating a mark, it's entirely possible * that gtk_text_iter_equal (start, end) in which case we @@ -1089,51 +1038,24 @@ gtk_text_layout_wrap (GtkTextLayout *layout, /* If you get the style with get_style () you need to call release_style () to free it. */ -static GtkTextAttributes* +static GtkTextAttributes * get_style (GtkTextLayout *layout, - GPtrArray *tags) + GPtrArray *tags) { GtkTextAttributes *style; - /* If we have the one-style cache, then it means - that we haven't seen a toggle since we filled in the - one-style cache. - */ - if (layout->one_style_cache != NULL) - { - gtk_text_attributes_ref (layout->one_style_cache); - return layout->one_style_cache; - } - - g_assert (layout->one_style_cache == NULL); - /* No tags, use default style */ if (tags == NULL || tags->len == 0) - { - /* One ref for the return value, one ref for the - layout->one_style_cache reference */ - gtk_text_attributes_ref (layout->default_style); - gtk_text_attributes_ref (layout->default_style); - layout->one_style_cache = layout->default_style; - - return layout->default_style; - } + return gtk_text_attributes_ref (layout->default_style); style = gtk_text_attributes_new (); - gtk_text_attributes_copy_values (layout->default_style, - style); + gtk_text_attributes_copy_values (layout->default_style, style); _gtk_text_attributes_fill_from_tags (style, tags); g_assert (style->refcount == 1); - /* Leave this style as the last one seen */ - g_assert (layout->one_style_cache == NULL); - gtk_text_attributes_ref (style); /* ref held by layout->one_style_cache */ - layout->one_style_cache = style; - - /* Returning yet another refcount */ return style; } @@ -1176,8 +1098,6 @@ totally_invisible_line (GtkTextLayout *layout, if (seg->byte_count <= 0 && seg->type == >k_text_toggle_on_type) { - invalidate_cached_style (layout); - /* Bail out if an elision-unsetting tag begins */ if (seg->body.toggle.info->tag->priv->invisible_set && !seg->body.toggle.info->tag->priv->values->invisible) @@ -1185,8 +1105,6 @@ totally_invisible_line (GtkTextLayout *layout, } else if (seg->type == >k_text_toggle_off_type) { - invalidate_cached_style (layout); - /* Bail out if an elision-setting tag ends */ if (seg->body.toggle.info->tag->priv->invisible_set && seg->body.toggle.info->tag->priv->values->invisible) @@ -2487,9 +2405,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout, else if (seg->type == >k_text_toggle_on_type || seg->type == >k_text_toggle_off_type) { - /* Style may have changed, drop our - current cached style */ - invalidate_cached_style (layout); /* Add the tag only after we have seen some non-toggle non-mark segment, * otherwise the tag is already accounted for by _gtk_text_btree_get_tags(). */ if (!initial_toggle_segments) @@ -2621,10 +2536,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout, } } - /* Free this if we aren't in a loop */ - if (layout->wrap_loop_count == 0) - invalidate_cached_style (layout); - g_free (text); pango_attr_list_unref (attrs); if (tags != NULL) @@ -4188,8 +4099,6 @@ gtk_text_layout_snapshot (GtkTextLayout *layout, draw_selection_text = FALSE; } - gtk_text_layout_wrap_loop_start (layout); - for (GtkTextLine *line = first_line; line != NULL; line = _gtk_text_line_next_excluding_last (line)) @@ -4318,8 +4227,6 @@ gtk_text_layout_snapshot (GtkTextLayout *layout, break; } - gtk_text_layout_wrap_loop_end (layout); - if (cursor_snapshot) { GskRenderNode *cursors; diff --git a/gtk/gtktextlayoutprivate.h b/gtk/gtktextlayoutprivate.h index e48f5ca487..0c27cfb1e6 100644 --- a/gtk/gtktextlayoutprivate.h +++ b/gtk/gtktextlayoutprivate.h @@ -124,14 +124,6 @@ struct _GtkTextLayout PangoContext *ltr_context; PangoContext *rtl_context; - /* A cache of one style; this is used to ensure - * we don't constantly regenerate the style - * over long runs with the same style. */ - GtkTextAttributes *one_style_cache; - - /* Whether we are allowed to wrap right now */ - int wrap_loop_count; - /* Whether to show the insertion cursor */ guint cursor_visible : 1;