summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
Diffstat (limited to 'pango')
-rw-r--r--pango/itemize.c17
-rw-r--r--pango/pango-bidi-type.c58
-rw-r--r--pango/pango-emoji-private.h6
-rw-r--r--pango/pango-emoji.c16
-rw-r--r--pango/pango-utils-private.h7
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 <hb-ot.h>
@@ -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__ */