forked from AuroraMiddleware/gtk
do not call _gtk_text_btree_get_iter_at_line() and
2007-11-15 Yevgen Muntyan <muntyan@tamu.edu> * gtk/gtktextlayout.c: (gtk_text_layout_get_line_display), (get_style): do not call _gtk_text_btree_get_iter_at_line() and _gtk_text_btree_get_tags() for every segment, instead call them once and then collect the tags while iterating over the segments. (get_tags_array_at_iter), (tags_array_toggle_tag): new functions for tags array handling. svn path=/trunk/; revision=18994
This commit is contained in:
parent
aa8329533f
commit
a3eb6a98d7
@ -1,3 +1,12 @@
|
|||||||
|
2007-11-15 Yevgen Muntyan <muntyan@tamu.edu>
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c: (gtk_text_layout_get_line_display),
|
||||||
|
(get_style): do not call _gtk_text_btree_get_iter_at_line() and
|
||||||
|
_gtk_text_btree_get_tags() for every segment, instead call them
|
||||||
|
once and then collect the tags while iterating over the segments.
|
||||||
|
(get_tags_array_at_iter), (tags_array_toggle_tag): new functions
|
||||||
|
for tags array handling.
|
||||||
|
|
||||||
2007-11-14 Michael Natterer <mitch@imendio.com>
|
2007-11-14 Michael Natterer <mitch@imendio.com>
|
||||||
|
|
||||||
* gtk/gtkmenu.c (gtk_menu_popup): remove recently added
|
* gtk/gtkmenu.c (gtk_menu_popup): remove recently added
|
||||||
|
@ -1166,10 +1166,8 @@ gtk_text_layout_real_wrap (GtkTextLayout *layout,
|
|||||||
release_style () to free it. */
|
release_style () to free it. */
|
||||||
static GtkTextAttributes*
|
static GtkTextAttributes*
|
||||||
get_style (GtkTextLayout *layout,
|
get_style (GtkTextLayout *layout,
|
||||||
const GtkTextIter *iter)
|
GPtrArray *tags)
|
||||||
{
|
{
|
||||||
GtkTextTag** tags;
|
|
||||||
gint tag_count = 0;
|
|
||||||
GtkTextAttributes *style;
|
GtkTextAttributes *style;
|
||||||
|
|
||||||
/* If we have the one-style cache, then it means
|
/* If we have the one-style cache, then it means
|
||||||
@ -1184,11 +1182,8 @@ get_style (GtkTextLayout *layout,
|
|||||||
|
|
||||||
g_assert (layout->one_style_cache == NULL);
|
g_assert (layout->one_style_cache == NULL);
|
||||||
|
|
||||||
/* Get the tags at this spot */
|
|
||||||
tags = _gtk_text_btree_get_tags (iter, &tag_count);
|
|
||||||
|
|
||||||
/* No tags, use default style */
|
/* No tags, use default style */
|
||||||
if (tags == NULL || tag_count == 0)
|
if (tags == NULL || tags->len == 0)
|
||||||
{
|
{
|
||||||
/* One ref for the return value, one ref for the
|
/* One ref for the return value, one ref for the
|
||||||
layout->one_style_cache reference */
|
layout->one_style_cache reference */
|
||||||
@ -1196,24 +1191,17 @@ get_style (GtkTextLayout *layout,
|
|||||||
gtk_text_attributes_ref (layout->default_style);
|
gtk_text_attributes_ref (layout->default_style);
|
||||||
layout->one_style_cache = layout->default_style;
|
layout->one_style_cache = layout->default_style;
|
||||||
|
|
||||||
g_free (tags);
|
|
||||||
|
|
||||||
return layout->default_style;
|
return layout->default_style;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort tags in ascending order of priority */
|
|
||||||
_gtk_text_tag_array_sort (tags, tag_count);
|
|
||||||
|
|
||||||
style = gtk_text_attributes_new ();
|
style = gtk_text_attributes_new ();
|
||||||
|
|
||||||
gtk_text_attributes_copy_values (layout->default_style,
|
gtk_text_attributes_copy_values (layout->default_style,
|
||||||
style);
|
style);
|
||||||
|
|
||||||
_gtk_text_attributes_fill_from_tags (style,
|
_gtk_text_attributes_fill_from_tags (style,
|
||||||
tags,
|
(GtkTextTag**) tags->pdata,
|
||||||
tag_count);
|
tags->len);
|
||||||
|
|
||||||
g_free (tags);
|
|
||||||
|
|
||||||
g_assert (style->refcount == 1);
|
g_assert (style->refcount == 1);
|
||||||
|
|
||||||
@ -2071,6 +2059,60 @@ update_text_display_cursors (GtkTextLayout *layout,
|
|||||||
g_slist_free (cursor_segs);
|
g_slist_free (cursor_segs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Same as _gtk_text_btree_get_tags(), except it returns GPtrArray,
|
||||||
|
* to be used in gtk_text_layout_get_line_display(). */
|
||||||
|
static GPtrArray *
|
||||||
|
get_tags_array_at_iter (GtkTextIter *iter)
|
||||||
|
{
|
||||||
|
GtkTextTag **tags;
|
||||||
|
GPtrArray *array = NULL;
|
||||||
|
gint n_tags;
|
||||||
|
|
||||||
|
tags = _gtk_text_btree_get_tags (iter, &n_tags);
|
||||||
|
|
||||||
|
if (n_tags > 0)
|
||||||
|
{
|
||||||
|
/* Sort tags in ascending order of priority */
|
||||||
|
_gtk_text_tag_array_sort (tags, n_tags);
|
||||||
|
array = g_ptr_array_sized_new (n_tags);
|
||||||
|
g_ptr_array_set_size (array, n_tags);
|
||||||
|
memcpy (array->pdata, tags, n_tags * sizeof (GtkTextTag*));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (tags);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the tag to the array if it's not there already, and remove
|
||||||
|
* it otherwise. It keeps the array sorted by tags priority. */
|
||||||
|
static GPtrArray *
|
||||||
|
tags_array_toggle_tag (GPtrArray *array,
|
||||||
|
GtkTextTag *tag)
|
||||||
|
{
|
||||||
|
gint pos;
|
||||||
|
GtkTextTag **tags;
|
||||||
|
|
||||||
|
if (array == NULL)
|
||||||
|
array = g_ptr_array_new ();
|
||||||
|
|
||||||
|
tags = (GtkTextTag**) array->pdata;
|
||||||
|
|
||||||
|
for (pos = 0; pos < array->len && tags[pos]->priority < tag->priority; pos++) ;
|
||||||
|
|
||||||
|
if (pos < array->len && tags[pos] == tag)
|
||||||
|
g_ptr_array_remove_index (array, pos);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_ptr_array_set_size (array, array->len + 1);
|
||||||
|
if (pos < array->len - 1)
|
||||||
|
memmove (array->pdata + pos + 1, array->pdata + pos,
|
||||||
|
(array->len - pos - 1) * sizeof (GtkTextTag*));
|
||||||
|
array->pdata[pos] = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
GtkTextLineDisplay *
|
GtkTextLineDisplay *
|
||||||
gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
||||||
GtkTextLine *line,
|
GtkTextLine *line,
|
||||||
@ -2091,6 +2133,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
GSList *tmp_list1, *tmp_list2;
|
GSList *tmp_list1, *tmp_list2;
|
||||||
gboolean saw_widget = FALSE;
|
gboolean saw_widget = FALSE;
|
||||||
PangoDirection base_dir;
|
PangoDirection base_dir;
|
||||||
|
GPtrArray *tags;
|
||||||
|
gboolean initial_toggle_segments;
|
||||||
|
|
||||||
g_return_val_if_fail (line != NULL, NULL);
|
g_return_val_if_fail (line != NULL, NULL);
|
||||||
|
|
||||||
@ -2155,10 +2199,12 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
|
|
||||||
attrs = pango_attr_list_new ();
|
attrs = pango_attr_list_new ();
|
||||||
|
|
||||||
/* Iterate over segments, creating display chunks for them. */
|
/* Iterate over segments, creating display chunks for them, and updating the tags array. */
|
||||||
layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
|
layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
|
||||||
buffer_byte_offset = 0; /* position in the buffer line */
|
buffer_byte_offset = 0; /* position in the buffer line */
|
||||||
seg = _gtk_text_iter_get_any_segment (&iter);
|
seg = _gtk_text_iter_get_any_segment (&iter);
|
||||||
|
tags = get_tags_array_at_iter (&iter);
|
||||||
|
initial_toggle_segments = TRUE;
|
||||||
while (seg != NULL)
|
while (seg != NULL)
|
||||||
{
|
{
|
||||||
/* Displayable segments */
|
/* Displayable segments */
|
||||||
@ -2166,10 +2212,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
seg->type == >k_text_pixbuf_type ||
|
seg->type == >k_text_pixbuf_type ||
|
||||||
seg->type == >k_text_child_type)
|
seg->type == >k_text_child_type)
|
||||||
{
|
{
|
||||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
style = get_style (layout, tags);
|
||||||
&iter, line,
|
initial_toggle_segments = FALSE;
|
||||||
buffer_byte_offset);
|
|
||||||
style = get_style (layout, &iter);
|
|
||||||
|
|
||||||
/* We have to delay setting the paragraph values until we
|
/* We have to delay setting the paragraph values until we
|
||||||
* hit the first pixbuf or text segment because toggles at
|
* hit the first pixbuf or text segment because toggles at
|
||||||
@ -2298,6 +2342,10 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
/* Style may have changed, drop our
|
/* Style may have changed, drop our
|
||||||
current cached style */
|
current cached style */
|
||||||
invalidate_cached_style (layout);
|
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)
|
||||||
|
tags = tags_array_toggle_tag (tags, seg->body.toggle.info->tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Marks */
|
/* Marks */
|
||||||
@ -2318,7 +2366,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
text_allocated += layout->preedit_len;
|
text_allocated += layout->preedit_len;
|
||||||
text = g_realloc (text, text_allocated);
|
text = g_realloc (text, text_allocated);
|
||||||
|
|
||||||
style = get_style (layout, &iter);
|
style = get_style (layout, tags);
|
||||||
add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
|
add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
|
||||||
release_style (layout, style);
|
release_style (layout, style);
|
||||||
|
|
||||||
@ -2349,7 +2397,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
|
|
||||||
if (!para_values_set)
|
if (!para_values_set)
|
||||||
{
|
{
|
||||||
style = get_style (layout, &iter);
|
style = get_style (layout, tags);
|
||||||
set_para_values (layout, base_dir, style, display);
|
set_para_values (layout, base_dir, style, display);
|
||||||
release_style (layout, style);
|
release_style (layout, style);
|
||||||
}
|
}
|
||||||
@ -2426,6 +2474,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||||||
|
|
||||||
g_free (text);
|
g_free (text);
|
||||||
pango_attr_list_unref (attrs);
|
pango_attr_list_unref (attrs);
|
||||||
|
if (tags != NULL)
|
||||||
|
g_ptr_array_free (tags, TRUE);
|
||||||
|
|
||||||
layout->one_display_cache = display;
|
layout->one_display_cache = display;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user