[gtk/matthiasc/for-master: 10/15] textbtree: Return tags in a GPtrArray




commit d719a3d8770d2bca5b5e9fccef8dd66ef839c90b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 4 22:00:53 2021 -0400

    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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]