From d719a3d8770d2bca5b5e9fccef8dd66ef839c90b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 4 Apr 2021 22:00:53 -0400 Subject: [PATCH] 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. --- gtk/gtktextattributes.c | 13 +++------ gtk/gtktextbtree.c | 62 +++++++++++++---------------------------- gtk/gtktextbtree.h | 3 +- gtk/gtktextiter.c | 49 +++++++++++++------------------- gtk/gtktextlayout.c | 28 ++----------------- gtk/gtktexttag.c | 5 ++-- gtk/gtktexttagprivate.h | 6 ++-- 7 files changed, 51 insertions(+), 115 deletions(-) diff --git a/gtk/gtktextattributes.c b/gtk/gtktextattributes.c index 0f0abe8e38..1028865247 100644 --- a/gtk/gtktextattributes.c +++ b/gtk/gtktextattributes.c @@ -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; diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c index 80c67d6deb..bd0c817d98 100644 --- a/gtk/gtktextbtree.c +++ b/gtk/gtktextbtree.c @@ -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 diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h index 40d864e074..66e61c686f 100644 --- a/gtk/gtktextbtree.h +++ b/gtk/gtktextbtree.h @@ -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, diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index 9868110568..dad790f3ff 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -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); - /* Return tags in ascending order of priority */ - return g_slist_reverse (retval); + for (int i = tags->len - 1; i >= 0; i--) + retval = g_slist_prepend (retval, g_ptr_array_index (tags, i)); + + 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; } diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 7a3759ec45..353cebb7ce 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -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) { diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c index 0eec046a5d..2bbb827300 100644 --- a/gtk/gtktexttag.c +++ b/gtk/gtktexttag.c @@ -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); } diff --git a/gtk/gtktexttagprivate.h b/gtk/gtktexttagprivate.h index 13a8338f7f..b0bd079532 100644 --- a/gtk/gtktexttagprivate.h +++ b/gtk/gtktexttagprivate.h @@ -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);