From ec2958682949220f15a32066eff412d857c735c5 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 25 Jan 2022 08:16:55 -0500 Subject: 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 04b01a43..93314b4f 100644 --- a/pango/pango-line.c +++ b/pango/pango-line.c @@ -609,6 +609,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; } @@ -619,11 +620,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` @@ -633,14 +653,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 2d5fea44..95a12ce9 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)) @@ -668,7 +669,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 d2454328..738b741f 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -190,19 +190,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 8a774cbb..a7995998 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -427,10 +427,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++) -- cgit v1.2.1