textbtree: Return tags in a GPtrArray

One of the callers prefers that, it lets us avoid
copying the array in one place, and generally makes
for better code.
This commit is contained in:
Matthias Clasen 2021-04-04 22:00:53 -04:00
parent b0df8910ba
commit d719a3d877
7 changed files with 51 additions and 115 deletions

View File

@ -250,22 +250,19 @@ gtk_text_attributes_unref (GtkTextAttributes *values)
void
_gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
GtkTextTag** tags,
guint n_tags)
GPtrArray *tags)
{
guint n = 0;
guint left_margin_accumulative = 0;
guint right_margin_accumulative = 0;
while (n < n_tags)
for (guint n = 0; n < tags->len; n++)
{
GtkTextTag *tag = tags[n];
GtkTextTag *tag = g_ptr_array_index (tags, n);
GtkTextAttributes *vals = tag->priv->values;
g_assert (tag->priv->table != NULL);
if (n > 0)
g_assert (tags[n]->priv->priority > tags[n-1]->priv->priority);
g_assert (((GtkTextTag*)g_ptr_array_index (tags, n))->priv->priority > ((GtkTextTag *)g_ptr_array_index (tags, n - 1))->priv->priority);
if (tag->priv->bg_color_set)
{
@ -438,8 +435,6 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
if (tag->priv->insert_hyphens_set)
dest->no_hyphens = vals->no_hyphens;
++n;
}
dest->left_margin += left_margin_accumulative;

View File

@ -80,15 +80,8 @@
*/
typedef struct TagInfo {
int numTags; /* Number of tags for which there
* is currently information in
* tags and counts. */
int arraySize; /* Number of entries allocated for
* tags and counts. */
GtkTextTag **tags; /* Array of tags seen so far.
* Malloc-ed. */
int *counts; /* Toggle count (so far) for each
* entry in tags. Malloc-ed. */
GPtrArray *tags;
GArray *counts;
} TagInfo;
@ -2200,9 +2193,8 @@ _gtk_text_btree_get_line_at_char (GtkTextBTree *tree,
/* It returns an array sorted by tags priority, ready to pass to
* _gtk_text_attributes_fill_from_tags() */
GtkTextTag**
_gtk_text_btree_get_tags (const GtkTextIter *iter,
int *num_tags)
GPtrArray *
_gtk_text_btree_get_tags (const GtkTextIter *iter)
{
GtkTextBTreeNode *node;
GtkTextLine *siblingline;
@ -2217,10 +2209,8 @@ _gtk_text_btree_get_tags (const GtkTextIter *iter,
line = _gtk_text_iter_get_text_line (iter);
byte_index = gtk_text_iter_get_line_index (iter);
tagInfo.numTags = 0;
tagInfo.arraySize = NUM_TAG_INFOS;
tagInfo.tags = g_new (GtkTextTag*, NUM_TAG_INFOS);
tagInfo.counts = g_new (int, NUM_TAG_INFOS);
tagInfo.tags = g_ptr_array_sized_new (NUM_TAG_INFOS);
tagInfo.counts = g_array_new (FALSE, FALSE, sizeof (int));
/*
* Record tag toggles within the line of indexPtr but preceding
@ -2291,26 +2281,26 @@ _gtk_text_btree_get_tags (const GtkTextIter *iter,
* of interest, but not at the desired character itself).
*/
for (src = 0, dst = 0; src < tagInfo.numTags; src++)
for (src = 0, dst = 0; src < tagInfo.tags->len; src++)
{
if (tagInfo.counts[src] & 1)
if (g_array_index (tagInfo.counts, int, src) & 1)
{
g_assert (GTK_IS_TEXT_TAG (tagInfo.tags[src]));
tagInfo.tags[dst] = tagInfo.tags[src];
g_assert (GTK_IS_TEXT_TAG (g_ptr_array_index (tagInfo.tags, src)));
g_ptr_array_index (tagInfo.tags, dst) = g_ptr_array_index (tagInfo.tags, src);
dst++;
}
}
*num_tags = dst;
g_free (tagInfo.counts);
g_ptr_array_set_size (tagInfo.tags, dst);
g_array_unref (tagInfo.counts);
if (dst == 0)
{
g_free (tagInfo.tags);
g_ptr_array_unref (tagInfo.tags);
return NULL;
}
/* Sort tags in ascending order of priority */
_gtk_text_tag_array_sort (tagInfo.tags, dst);
_gtk_text_tag_array_sort (tagInfo.tags);
return tagInfo.tags;
}
@ -6453,15 +6443,12 @@ _gtk_change_node_toggle_count (GtkTextBTreeNode *node,
static void
inc_count (GtkTextTag *tag, int inc, TagInfo *tagInfoPtr)
{
GtkTextTag **tag_p;
int count;
for (tag_p = tagInfoPtr->tags, count = tagInfoPtr->numTags;
count > 0; tag_p++, count--)
for (int i = 0; i < tagInfoPtr->tags->len; i++)
{
if (*tag_p == tag)
GtkTextTag *t = g_ptr_array_index (tagInfoPtr->tags, i);
if (t == tag)
{
tagInfoPtr->counts[tagInfoPtr->numTags-count] += inc;
g_array_index (tagInfoPtr->counts, int, i) += inc;
return;
}
}
@ -6472,17 +6459,8 @@ inc_count (GtkTextTag *tag, int inc, TagInfo *tagInfoPtr)
* arrays first.
*/
if (tagInfoPtr->numTags == tagInfoPtr->arraySize)
{
int newSize = 2 * tagInfoPtr->arraySize;
tagInfoPtr->tags = g_realloc (tagInfoPtr->tags, newSize * sizeof (GtkTextTag *));
tagInfoPtr->counts = g_realloc (tagInfoPtr->counts, newSize * sizeof (int));
tagInfoPtr->arraySize = newSize;
}
tagInfoPtr->tags[tagInfoPtr->numTags] = tag;
tagInfoPtr->counts[tagInfoPtr->numTags] = inc;
tagInfoPtr->numTags++;
g_ptr_array_add (tagInfoPtr->tags, tag);
g_array_append_val (tagInfoPtr->counts, inc);
}
static void

View File

@ -128,8 +128,7 @@ GtkTextLine * _gtk_text_btree_get_line_at_char (GtkTextBTree *tree,
int char_index,
int *line_start_index,
int *real_char_index);
GtkTextTag** _gtk_text_btree_get_tags (const GtkTextIter *iter,
int *num_tags);
GPtrArray * _gtk_text_btree_get_tags (const GtkTextIter *iter);
char *_gtk_text_btree_get_text (const GtkTextIter *start,
const GtkTextIter *end,
gboolean include_hidden,

View File

@ -1386,36 +1386,30 @@ gtk_text_iter_has_tag (const GtkTextIter *iter,
GSList*
gtk_text_iter_get_tags (const GtkTextIter *iter)
{
GtkTextTag** tags;
int tag_count = 0;
int i;
GPtrArray *tags;
GSList *retval;
g_return_val_if_fail (iter != NULL, NULL);
/* Get the tags at this spot */
tags = _gtk_text_btree_get_tags (iter, &tag_count);
tags = _gtk_text_btree_get_tags (iter);
/* No tags, use default style */
if (tags == NULL || tag_count == 0)
if (tags == NULL || tags->len == 0)
{
g_free (tags);
if (tags)
g_ptr_array_unref (tags);
return NULL;
}
retval = NULL;
i = 0;
while (i < tag_count)
{
retval = g_slist_prepend (retval, tags[i]);
++i;
}
g_free (tags);
for (int i = tags->len - 1; i >= 0; i--)
retval = g_slist_prepend (retval, g_ptr_array_index (tags, i));
/* Return tags in ascending order of priority */
return g_slist_reverse (retval);
g_ptr_array_unref (tags);
return retval;
}
/**
@ -1506,25 +1500,22 @@ gboolean
gtk_text_iter_get_attributes (const GtkTextIter *iter,
GtkTextAttributes *values)
{
GtkTextTag** tags;
int tag_count = 0;
GPtrArray *tags;
/* Get the tags at this spot */
tags = _gtk_text_btree_get_tags (iter, &tag_count);
tags = _gtk_text_btree_get_tags (iter);
/* No tags, use default style */
if (tags == NULL || tag_count == 0)
if (tags == NULL || tags->len == 0)
{
g_free (tags);
if (tags)
g_ptr_array_unref (tags);
return FALSE;
}
_gtk_text_attributes_fill_from_tags (values,
tags,
tag_count);
_gtk_text_attributes_fill_from_tags (values, tags);
g_free (tags);
g_ptr_array_unref (tags);
return TRUE;
}

View File

@ -1167,9 +1167,7 @@ get_style (GtkTextLayout *layout,
gtk_text_attributes_copy_values (layout->default_style,
style);
_gtk_text_attributes_fill_from_tags (style,
(GtkTextTag**) tags->pdata,
tags->len);
_gtk_text_attributes_fill_from_tags (style, tags);
g_assert (style->refcount == 1);
@ -2263,28 +2261,6 @@ gtk_text_layout_update_display_cursors (GtkTextLayout *layout,
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;
int n_tags;
tags = _gtk_text_btree_get_tags (iter, &n_tags);
if (n_tags > 0)
{
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 *
@ -2386,7 +2362,7 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
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 */
seg = _gtk_text_iter_get_any_segment (&iter);
tags = get_tags_array_at_iter (&iter);
tags = _gtk_text_btree_get_tags (&iter);
initial_toggle_segments = TRUE;
while (seg != NULL)
{

View File

@ -2410,8 +2410,7 @@ tag_sort_func (gconstpointer first, gconstpointer second)
}
void
_gtk_text_tag_array_sort (GtkTextTag **tag_array_p,
guint len)
_gtk_text_tag_array_sort (GPtrArray *tags)
{
qsort (tag_array_p, len, sizeof (GtkTextTag *), tag_sort_func);
g_ptr_array_sort (tags, tag_sort_func);
}

View File

@ -97,10 +97,8 @@ struct _GtkTextTagPrivate
* ascending order of priority
*/
void _gtk_text_attributes_fill_from_tags (GtkTextAttributes *values,
GtkTextTag **tags,
guint n_tags);
void _gtk_text_tag_array_sort (GtkTextTag **tag_array_p,
guint len);
GPtrArray *tags);
void _gtk_text_tag_array_sort (GPtrArray *tags);
gboolean _gtk_text_tag_affects_size (GtkTextTag *tag);
gboolean _gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag);