summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2017-10-07 19:03:26 +0200
committerMatthias Clasen <mclasen@redhat.com>2017-10-27 16:29:14 -0400
commit0d14052d719274e586176280b3c98dd54fcf8764 (patch)
tree90c4b74b3c5e0624229eef4b97756a72f29b6cd2
parent1599288b4f5394a314bfadae5af56d9b60150562 (diff)
downloadpango-0d14052d719274e586176280b3c98dd54fcf8764.tar.gz
PangoLayoutIter: Allocate an array of Extents instead of a linked list
Since PangoLayout caches the amount of lines it contains in ->line_count, we can use this to pre-allocate an Extents array of the appropriate size. https://bugzilla.gnome.org/show_bug.cgi?id=788643
-rw-r--r--pango/pango-layout-private.h15
-rw-r--r--pango/pango-layout.c86
2 files changed, 42 insertions, 59 deletions
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h
index 9a23d9e7..4b5327ee 100644
--- a/pango/pango-layout-private.h
+++ b/pango/pango-layout-private.h
@@ -82,6 +82,17 @@ struct _PangoLayout
guint line_count; /* Number of lines in @lines. 0 if lines is %NULL */
};
+typedef struct _Extents Extents;
+struct _Extents
+{
+ /* Vertical position of the line's baseline in layout coords */
+ int baseline;
+
+ /* Line extents in layout coords */
+ PangoRectangle ink_rect;
+ PangoRectangle logical_rect;
+};
+
struct _PangoLayoutIter
{
PangoLayout *layout;
@@ -96,8 +107,8 @@ struct _PangoLayoutIter
int index;
/* list of Extents for each line in layout coordinates */
- GSList *line_extents;
- GSList *line_extents_link;
+ Extents *line_extents;
+ int line_index;
/* X position of the current run */
int run_x;
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 1e123efa..de2dc87d 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -79,20 +79,9 @@
#include "pango-layout-private.h"
-typedef struct _Extents Extents;
typedef struct _ItemProperties ItemProperties;
typedef struct _ParaBreakState ParaBreakState;
-struct _Extents
-{
- /* Vertical position of the line's baseline in layout coords */
- int baseline;
-
- /* Line extents in layout coords */
- PangoRectangle ink_rect;
- PangoRectangle logical_rect;
-};
-
struct _ItemProperties
{
PangoUnderline uline;
@@ -2534,12 +2523,13 @@ static void
pango_layout_get_extents_internal (PangoLayout *layout,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect,
- GSList **line_extents)
+ Extents **line_extents)
{
GSList *line_list;
int y_offset = 0;
int width;
gboolean need_width = FALSE;
+ int line_index = 0;
g_return_if_fail (layout != NULL);
@@ -2600,6 +2590,12 @@ pango_layout_get_extents_internal (PangoLayout *layout,
logical_rect->height = 0;
}
+
+ if (line_extents && layout->line_count > 0)
+ {
+ *line_extents = g_malloc (sizeof (Extents) * layout->line_count);
+ }
+
line_list = layout->lines;
while (line_list)
{
@@ -2620,13 +2616,12 @@ pango_layout_get_extents_internal (PangoLayout *layout,
ink_rect ? &line_ink_layout : NULL,
&line_logical_layout);
- if (line_extents)
+ if (line_extents && layout->line_count > 0)
{
- Extents *ext = g_slice_new (Extents);
+ Extents *ext = &(*line_extents)[line_index];
ext->baseline = baseline;
ext->ink_rect = line_ink_layout;
ext->logical_rect = line_logical_layout;
- *line_extents = g_slist_prepend (*line_extents, ext);
}
}
@@ -2695,6 +2690,7 @@ pango_layout_get_extents_internal (PangoLayout *layout,
y_offset += line_logical_layout.height + layout->spacing;
line_list = line_list->next;
+ line_index ++;
}
if (ink_rect)
@@ -2707,8 +2703,6 @@ pango_layout_get_extents_internal (PangoLayout *layout,
layout->logical_rect = *logical_rect;
layout->logical_rect_cached = TRUE;
}
- if (line_extents)
- *line_extents = g_slist_reverse (*line_extents);
}
/**
@@ -2911,12 +2905,6 @@ free_run (PangoLayoutRun *run, gpointer data)
g_slice_free (PangoLayoutRun, run);
}
-static void
-extents_free (Extents *ext, gpointer data G_GNUC_UNUSED)
-{
- g_slice_free (Extents, ext);
-}
-
static PangoItem *
uninsert_run (PangoLayoutLine *line)
{
@@ -5523,11 +5511,7 @@ static inline void
offset_y (PangoLayoutIter *iter,
int *y)
{
- Extents *line_ext;
-
- line_ext = (Extents*)iter->line_extents_link->data;
-
- *y += line_ext->baseline;
+ *y += iter->line_extents[iter->line_index].baseline;
}
/* Sets up the iter for the start of a new cluster. cluster_start_index
@@ -5585,9 +5569,7 @@ static void
update_run (PangoLayoutIter *iter,
int run_start_index)
{
- Extents *line_ext;
-
- line_ext = (Extents*)iter->line_extents_link->data;
+ const Extents *line_ext = &iter->line_extents[iter->line_index];
/* Note that in iter_new() the iter->run_width
* is garbage but we don't use it since we're on the first run of
@@ -5645,7 +5627,6 @@ PangoLayoutIter *
pango_layout_iter_copy (PangoLayoutIter *iter)
{
PangoLayoutIter *new;
- GSList *l;
if (iter == NULL)
return NULL;
@@ -5662,15 +5643,13 @@ pango_layout_iter_copy (PangoLayoutIter *iter)
new->index = iter->index;
new->line_extents = NULL;
- new->line_extents_link = NULL;
- for (l = iter->line_extents; l; l = l->next)
+ if (iter->line_extents != NULL)
{
- new->line_extents = g_slist_prepend (new->line_extents,
- g_slice_dup (Extents, l->data));
- if (l == iter->line_extents_link)
- new->line_extents_link = new->line_extents;
+ new->line_extents = g_memdup (iter->line_extents,
+ iter->layout->line_count * sizeof (Extents));
+
}
- new->line_extents = g_slist_reverse (new->line_extents);
+ new->line_index = iter->line_index;
new->run_x = iter->run_x;
new->run_width = iter->run_width;
@@ -5751,8 +5730,7 @@ _pango_layout_get_iter (PangoLayout *layout,
&logical_rect,
&iter->line_extents);
iter->layout_width = layout->width == -1 ? logical_rect.width : layout->width;
-
- iter->line_extents_link = iter->line_extents;
+ iter->line_index = 0;
update_run (iter, run_start_index);
}
@@ -5763,8 +5741,7 @@ _pango_layout_iter_destroy (PangoLayoutIter *iter)
if (iter == NULL)
return;
- g_slist_foreach (iter->line_extents, (GFunc)extents_free, NULL);
- g_slist_free (iter->line_extents);
+ g_free (iter->line_extents);
pango_layout_line_unref (iter->line);
g_object_unref (iter->layout);
}
@@ -5926,7 +5903,7 @@ pango_layout_iter_at_last_line (PangoLayoutIter *iter)
if (ITER_IS_INVALID (iter))
return FALSE;
- return iter->line_extents_link->next == NULL;
+ return iter->line_index == iter->layout->line_count - 1;
}
/**
@@ -6192,8 +6169,7 @@ pango_layout_iter_next_line (PangoLayoutIter *iter)
else
iter->run = NULL;
- iter->line_extents_link = iter->line_extents_link->next;
- g_assert (iter->line_extents_link != NULL);
+ iter->line_index ++;
update_run (iter, iter->line->start_index);
@@ -6376,12 +6352,12 @@ pango_layout_iter_get_line_extents (PangoLayoutIter *iter,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
- Extents *ext;
+ const Extents *ext;
if (ITER_IS_INVALID (iter))
return;
- ext = iter->line_extents_link->data;
+ ext = &iter->line_extents[iter->line_index];
if (ink_rect)
{
@@ -6417,13 +6393,13 @@ pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
int *y0,
int *y1)
{
- Extents *ext;
+ const Extents *ext;
int half_spacing;
if (ITER_IS_INVALID (iter))
return;
- ext = iter->line_extents_link->data;
+ ext = &iter->line_extents[iter->line_index];
half_spacing = iter->layout->spacing / 2;
@@ -6435,7 +6411,7 @@ pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
{
/* No spacing above the first line */
- if (iter->line_extents_link == iter->line_extents)
+ if (iter->line_index == 0)
*y0 = ext->logical_rect.y;
else
*y0 = ext->logical_rect.y - (iter->layout->spacing - half_spacing);
@@ -6444,7 +6420,7 @@ pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
if (y1)
{
/* No spacing below the last line */
- if (iter->line_extents_link->next == NULL)
+ if (iter->line_index == iter->layout->line_count - 1)
*y1 = ext->logical_rect.y + ext->logical_rect.height;
else
*y1 = ext->logical_rect.y + ext->logical_rect.height + half_spacing;
@@ -6463,14 +6439,10 @@ pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
int
pango_layout_iter_get_baseline (PangoLayoutIter *iter)
{
- Extents *ext;
-
if (ITER_IS_INVALID (iter))
return 0;
- ext = iter->line_extents_link->data;
-
- return ext->baseline;
+ return iter->line_extents[iter->line_index].baseline;
}
/**