mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 05:01:09 +00:00
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
This commit is contained in:
parent
f6faff1b13
commit
3bd4eef726
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user