[pango/pango2: 70/135] line: Don't return GSList




commit b6de673fe2d718a4bef090d9bdf15b19c9807875
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jan 25 08:16:55 2022 -0500

    line: Don't return GSList
    
    Change pango_line_get_runs to return an array.
    
    So far, this changes just the API. All internals
    are still done on the list.

 pango/pango-line-iter.c    |  6 +++---
 pango/pango-line-private.h |  2 ++
 pango/pango-line.c         | 41 ++++++++++++++++++++++++++++++++++++++---
 pango/pango-line.h         |  5 ++++-
 pango/pango-lines.c        |  7 ++++---
 pango/pangocairo-font.c    | 10 +++++-----
 pango/pangofc-font.c       |  6 ++++--
 tests/testiter.c           |  6 +++---
 8 files changed, 63 insertions(+), 20 deletions(-)
---
diff --git a/pango/pango-line-iter.c b/pango/pango-line-iter.c
index e3eb9368..62d2dff7 100644
--- a/pango/pango-line-iter.c
+++ b/pango/pango-line-iter.c
@@ -338,7 +338,7 @@ pango_line_iter_new (PangoLines *lines)
 
   iter->line_no = 0;
   iter->line = pango_lines_get_line (iter->lines, 0, &iter->line_x, &iter->line_y);
-  iter->run_link = pango_line_get_runs (iter->line);
+  iter->run_link = iter->line->runs;
   if (iter->run_link)
     {
       iter->run = iter->run_link->data;
@@ -508,7 +508,7 @@ pango_line_iter_next_line (PangoLineIter *iter)
     return FALSE;
 
   iter->line_no++;
-  iter->run_link = pango_line_get_runs (iter->line);
+  iter->run_link = iter->line->runs;
   if (iter->run_link)
     iter->run = iter->run_link->data;
   else
@@ -707,7 +707,7 @@ pango_line_iter_get_run_extents (PangoLineIter  *iter,
     }
   else
     {
-      GSList *runs = pango_line_get_runs (iter->line);
+      GSList *runs = iter->line->runs;
       if (runs)
         {
           /* Virtual run at the end of a nonempty line */
diff --git a/pango/pango-line-private.h b/pango/pango-line-private.h
index 2ea21aa9..42d25137 100644
--- a/pango/pango-line-private.h
+++ b/pango/pango-line-private.h
@@ -31,6 +31,8 @@ struct _PangoLine
   int start_offset;
   int n_chars;
   GSList *runs;
+  PangoRun **run_array;
+  int n_runs;
 
   guint wrapped             : 1;
   guint ellipsized          : 1;
diff --git a/pango/pango-line.c b/pango/pango-line.c
index 4176c6c2..a2071a90 100644
--- a/pango/pango-line.c
+++ b/pango/pango-line.c
@@ -600,6 +600,7 @@ pango_line_copy (PangoLine *line)
   copy->has_extents = FALSE;
   copy->direction = line->direction;
   copy->runs = g_slist_copy_deep (line->runs, (GCopyFunc) pango_glyph_item_copy, NULL);
+  copy->n_runs = line->n_runs;
 
   return copy;
 }
@@ -610,11 +611,30 @@ pango_line_free (PangoLine *line)
   g_object_unref (line->context);
   line_data_unref (line->data);
   g_slist_free_full (line->runs, (GDestroyNotify)pango_glyph_item_free);
+  g_free (line->run_array);
   g_free (line);
 }
 
 /* {{{ Simple getters */
 
+/**
+ * pango_line_get_run_count:
+ * @line: a `PangoLine`
+ *
+ * Gets the number of runs in the line.
+ *
+ * Returns: the number of runs
+ */
+int
+pango_line_get_run_count (PangoLine *line)
+{
+  g_return_val_if_fail (line != NULL, 0);
+
+  pango_line_get_runs (line);
+
+  return line->n_runs;
+}
+
 /**
  * pango_line_get_runs:
  * @line: a `PangoLine`
@@ -624,14 +644,29 @@ pango_line_free (PangoLine *line)
  * Note that the returned list and its contents
  * are owned by Pango and must not be modified.
  *
- * Returns: (transfer none) (element-type PangoGlyphItem): a list of `PangoGlyphItem`
+ * The length of the returned array can be obtained
+ * with [method Pango Line.get_run_count].
+ *
+ * Returns: (transfer none): an array of `PangoRun`
  */
-GSList *
+PangoRun **
 pango_line_get_runs (PangoLine *line)
 {
   g_return_val_if_fail (line != NULL, NULL);
 
-  return line->runs;
+  if (!line->run_array)
+    {
+      GSList *l;
+      int i;
+
+      line->n_runs = g_slist_length (line->runs);
+
+      line->run_array = g_new (PangoRun *, line->n_runs);
+      for (l = line->runs, i = 0; l; l = l->next, i++)
+        line->run_array[i] = l->data;
+    }
+
+  return line->run_array;
 }
 
 /**
diff --git a/pango/pango-line.h b/pango/pango-line.h
index 665ced7e..b39fe81c 100644
--- a/pango/pango-line.h
+++ b/pango/pango-line.h
@@ -21,7 +21,10 @@ PangoLine *             pango_line_justify       (PangoLine       *line,
                                                   int                    width);
 
 PANGO_AVAILABLE_IN_ALL
-GSList *                pango_line_get_runs      (PangoLine       *line);
+int                     pango_line_get_run_count (PangoLine       *line);
+
+PANGO_AVAILABLE_IN_ALL
+PangoRun **             pango_line_get_runs      (PangoLine       *line);
 
 PANGO_AVAILABLE_IN_ALL
 const char *            pango_line_get_text      (PangoLine       *line,
diff --git a/pango/pango-lines.c b/pango/pango-lines.c
index ef74950c..1c055d94 100644
--- a/pango/pango-lines.c
+++ b/pango/pango-lines.c
@@ -3,6 +3,7 @@
 #include "pango-lines-private.h"
 #include "pango-line-private.h"
 #include "pango-item-private.h"
+#include "pango-run-private.h"
 #include "pango-line-iter-private.h"
 
 /**
@@ -621,9 +622,9 @@ pango_lines_get_x_ranges (PangoLines *lines,
     }
 
   accumulated_width = 0;
-  for (GSList *l = pango_line_get_runs (line); l; l = l->next)
+  for (int i = 0; i < pango_line_get_run_count (line); i++)
     {
-      PangoGlyphItem *run = l->data;
+      PangoGlyphItem *run = pango_run_get_glyph_item (pango_line_get_runs (line)[i]);
 
       if ((start_index < run->item->offset + run->item->length &&
            end_index > run->item->offset))
@@ -664,7 +665,7 @@ pango_lines_get_x_ranges (PangoLines *lines,
 
      range_count++;
 
-     if (l->next)
+     if (i + 1 < pango_line_get_run_count (line))
        accumulated_width += pango_glyph_string_get_width (run->glyphs);
    }
 
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index a9274a29..4c3dc787 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -191,19 +191,19 @@ max_glyph_width (PangoLayout *layout)
 {
   PangoLines *lines;
   int max_width = 0;
-  GSList *r;
 
   lines = pango_layout_get_lines (layout);
   for (int i = 0; i < pango_lines_get_line_count (lines); i++)
     {
       PangoLine *line = pango_lines_get_line (lines, i, NULL, NULL);
+      PangoRun **runs = pango_line_get_runs (line);
+      int n_runs = pango_line_get_run_count (line);
 
-      for (r = pango_line_get_runs (line); r; r = r->next)
+      for (int j = 0; j < n_runs; j++)
         {
-          PangoGlyphString *glyphs = ((PangoGlyphItem *)r->data)->glyphs;
-          int i;
+          PangoGlyphString *glyphs = pango_run_get_glyphs (runs[j]);
 
-          for (i = 0; i < glyphs->num_glyphs; i++)
+          for (int i = 0; i < glyphs->num_glyphs; i++)
             {
               if (glyphs->glyphs[i].geometry.width > max_width)
                 max_width = glyphs->glyphs[i].geometry.width;
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 573768c8..89088a85 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -425,10 +425,12 @@ max_glyph_width (PangoLayout *layout)
   for (int i = 0; i < pango_lines_get_line_count (lines); i++)
     {
       PangoLine *line = pango_lines_get_line (lines, i, NULL, NULL);
+      PangoRun **runs = pango_line_get_runs (line);
+      int n_runs = pango_line_get_run_count (line);
 
-      for (r = pango_line_get_runs (line); r; r = r->next)
+      for (int j = 0; j < n_runs; j++)
         {
-          PangoGlyphString *glyphs = ((PangoGlyphItem *)r->data)->glyphs;
+          PangoGlyphString *glyphs = pango_run_get_glyphs (runs[j]);
           int i;
 
           for (i = 0; i < glyphs->num_glyphs; i++)
diff --git a/tests/testiter.c b/tests/testiter.c
index a966342e..a55fc246 100644
--- a/tests/testiter.c
+++ b/tests/testiter.c
@@ -274,9 +274,9 @@ test_glyphitem_iter (void)
   text = pango_layout_get_text (layout);
 
   line = pango_lines_get_line (pango_layout_get_lines (layout), 0, NULL, NULL);
-  for (l = pango_line_get_runs (line); l; l = l->next)
-  {
-    PangoGlyphItem *run = l->data;
+  for (int i = 0; i < pango_line_get_run_count (line); i++)
+    {
+    PangoGlyphItem *run = (PangoGlyphItem *)pango_line_get_runs (line)[i];
     int direction;
 
     for (direction = 0; direction < 2; direction++)


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