From 5d20caf511b8b7f83b97637be5bc9e756bf3781a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 17 Jan 2023 21:47:50 -0500 Subject: Avoid some small allocations --- pango/itemize.c | 17 ++++++++++--- pango/pango-bidi-type.c | 58 ++++++++++++++++++++++++++++++++------------- pango/pango-emoji-private.h | 6 +++-- pango/pango-emoji.c | 16 +++++++++---- pango/pango-utils-private.h | 7 ++++++ 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/pango/itemize.c b/pango/itemize.c index 35f17d54..5500d56d 100644 --- a/pango/itemize.c +++ b/pango/itemize.c @@ -33,6 +33,7 @@ #include "pango-emoji-private.h" #include "pango-attributes-private.h" #include "pango-item-private.h" +#include "pango-utils-private.h" #include @@ -292,6 +293,7 @@ struct _ItemizeState PangoItem *item; guint8 *embedding_levels; + guint8 embedding_levels_[64]; int embedding_end_offset; const char *embedding_end; guint8 embedding; @@ -433,6 +435,10 @@ itemize_state_init (ItemizeState *state, PangoAttrIterator *cached_iter, const PangoFontDescription *desc) { + unsigned int n_chars; + + n_chars = g_utf8_strlen (text + start_index, length); + state->context = context; state->text = text; state->end = text + start_index + length; @@ -447,7 +453,11 @@ itemize_state_init (ItemizeState *state, /* First, apply the bidirectional algorithm to break * the text into directional runs. */ - state->embedding_levels = pango_log2vis_get_embedding_levels (text + start_index, length, &base_dir); + if (n_chars < 64) + state->embedding_levels = state->embedding_levels_; + else + state->embedding_levels = g_new (guint8, n_chars); + pango_log2vis_fill_embedding_levels (text + start_index, length, n_chars, state->embedding_levels, &base_dir); state->embedding_end_offset = 0; state->embedding_end = text + start_index; @@ -503,7 +513,7 @@ itemize_state_init (ItemizeState *state, &state->script_end, &state->script); width_iter_init (&state->width_iter, text + start_index, length); - _pango_emoji_iter_init (&state->emoji_iter, text + start_index, length); + _pango_emoji_iter_init (&state->emoji_iter, text + start_index, length, n_chars); if (!PANGO_GRAVITY_IS_VERTICAL (state->context->resolved_gravity)) state->width_iter.end = state->end; @@ -1017,7 +1027,8 @@ itemize_state_process_run (ItemizeState *state) static void itemize_state_finish (ItemizeState *state) { - g_free (state->embedding_levels); + if (state->embedding_levels != state->embedding_levels_) + g_free (state->embedding_levels); if (state->free_attr_iter) pango_attr_iterator_destroy (state->attr_iter); _pango_script_iter_fini (&state->script_iter); diff --git a/pango/pango-bidi-type.c b/pango/pango-bidi-type.c index f854a1b8..4277dc19 100644 --- a/pango/pango-bidi-type.c +++ b/pango/pango-bidi-type.c @@ -29,6 +29,7 @@ #include "pango-bidi-type.h" #include "pango-utils.h" +#include "pango-utils-private.h" /** * pango_bidi_type_for_unichar: @@ -109,15 +110,37 @@ pango_bidi_type_for_unichar (gunichar ch) */ guint8 * pango_log2vis_get_embedding_levels (const gchar *text, - int length, - PangoDirection *pbase_dir) + int length, + PangoDirection *pbase_dir) { - glong n_chars, i; - guint8 *embedding_levels_list; + unsigned int n_chars; + guint8 *embedding_levels; + + if (length < 0) + length = strlen (text); + + n_chars = g_utf8_strlen (text, length); + embedding_levels = g_new (guint8, n_chars); + + pango_log2vis_fill_embedding_levels (text, length, n_chars, embedding_levels, pbase_dir); + + return embedding_levels; +} + +void +pango_log2vis_fill_embedding_levels (const gchar *text, + int length, + unsigned int n_chars, + guint8 *embedding_levels_list, + PangoDirection *pbase_dir) +{ + glong i; const gchar *p; FriBidiParType fribidi_base_dir; FriBidiCharType *bidi_types; + FriBidiCharType bidi_types_[64]; FriBidiBracketType *bracket_types; + FriBidiBracketType bracket_types_[64]; FriBidiLevel max_level; FriBidiCharType ored_types = 0; FriBidiCharType anded_strongs = FRIBIDI_TYPE_RLE; @@ -145,14 +168,16 @@ pango_log2vis_get_embedding_levels (const gchar *text, break; } - if (length < 0) - length = strlen (text); - - n_chars = g_utf8_strlen (text, length); - - bidi_types = g_new (FriBidiCharType, n_chars); - bracket_types = g_new (FriBidiBracketType, n_chars); - embedding_levels_list = g_new (guint8, n_chars); + if (n_chars < 64) + { + bidi_types = bidi_types_; + bracket_types = bracket_types_; + } + else + { + bidi_types = g_new (FriBidiCharType, n_chars); + bracket_types = g_new (FriBidiBracketType, n_chars); + } for (i = 0, p = text; p < text + length; p = g_utf8_next_char(p), i++) { @@ -232,12 +257,13 @@ pango_log2vis_get_embedding_levels (const gchar *text, } resolved: - g_free (bidi_types); - g_free (bracket_types); + if (n_chars >= 64) + { + g_free (bidi_types); + g_free (bracket_types); + } *pbase_dir = (fribidi_base_dir == FRIBIDI_PAR_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; - - return embedding_levels_list; } /** diff --git a/pango/pango-emoji-private.h b/pango/pango-emoji-private.h index d5cbccf4..6f0d86f9 100644 --- a/pango/pango-emoji-private.h +++ b/pango/pango-emoji-private.h @@ -41,14 +41,16 @@ struct _PangoEmojiIter gboolean is_emoji; unsigned char *types; + unsigned char types_[64]; unsigned int n_chars; unsigned int cursor; }; PangoEmojiIter * _pango_emoji_iter_init (PangoEmojiIter *iter, - const char *text, - int length); + const char *text, + int length, + unsigned int n_chars); gboolean _pango_emoji_iter_next (PangoEmojiIter *iter); diff --git a/pango/pango-emoji.c b/pango/pango-emoji.c index e1f16dba..83ebfe6e 100644 --- a/pango/pango-emoji.c +++ b/pango/pango-emoji.c @@ -213,14 +213,19 @@ typedef unsigned char *emoji_text_iter_t; PangoEmojiIter * _pango_emoji_iter_init (PangoEmojiIter *iter, - const char *text, - int length) + const char *text, + int length, + unsigned int n_chars) { - unsigned int n_chars = g_utf8_strlen (text, length); - unsigned char *types = g_malloc (n_chars); + unsigned char *types; unsigned int i; const char *p; + if (n_chars < 64) + types = iter->types_; + else + types = g_malloc (n_chars); + p = text; for (i = 0; i < n_chars; i++) { @@ -247,7 +252,8 @@ _pango_emoji_iter_init (PangoEmojiIter *iter, void _pango_emoji_iter_fini (PangoEmojiIter *iter) { - g_free (iter->types); + if (iter->types != iter->types_) + g_free (iter->types); } gboolean diff --git a/pango/pango-utils-private.h b/pango/pango-utils-private.h index 4087dc14..78b06113 100644 --- a/pango/pango-utils-private.h +++ b/pango/pango-utils-private.h @@ -54,6 +54,13 @@ const char * pango_get_sysconf_subdirectory (void) G_GNUC_PURE; PANGO_DEPRECATED const char * pango_get_lib_subdirectory (void) G_GNUC_PURE; +void pango_log2vis_fill_embedding_levels (const char *text, + int length, + unsigned int n_chars, + guint8 *embedding_levels, + PangoDirection *pbase_dir); + + G_END_DECLS #endif /* __PANGO_UTILS_PRIATE_H__ */ -- cgit v1.2.1