summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-03-29 19:18:44 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-03-29 19:18:44 +0000
commitce13859046ac37ba94c6a5727c221b0b97e90a9e (patch)
tree263f6548706be5acbd6ba91a71252904cb21c757
parent5ccc0c7aa5de2667a5e0da8c35387eb662c3edff (diff)
parentb86ded710d391b78842c607962d9a2281596b862 (diff)
downloadpango-ce13859046ac37ba94c6a5727c221b0b97e90a9e.tar.gz
Merge branch 'misc-speedups' into 'master'
Misc speedups See merge request GNOME/pango!306
-rw-r--r--pango/break.c5
-rw-r--r--pango/pango-context.c15
-rw-r--r--pango/pango-emoji.c123
-rw-r--r--pango/pango-impl-utils.h3
-rw-r--r--pango/pangofc-shape.c27
5 files changed, 92 insertions, 81 deletions
diff --git a/pango/break.c b/pango/break.c
index fadf01d0..6b8e5c01 100644
--- a/pango/break.c
+++ b/pango/break.c
@@ -362,12 +362,15 @@ pango_default_break (const gchar *text,
case G_UNICODE_PARAGRAPH_SEPARATOR:
attrs[i].is_white = TRUE;
break;
- default:
+ case G_UNICODE_CONTROL:
if (wc == '\t' || wc == '\n' || wc == '\r' || wc == '\f')
attrs[i].is_white = TRUE;
else
attrs[i].is_white = FALSE;
break;
+ default:
+ attrs[i].is_white = FALSE;
+ break;
}
/* Just few spaces have variable width. So explicitly mark them.
diff --git a/pango/pango-context.c b/pango/pango-context.c
index ccaa1bac..90952add 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -910,6 +910,9 @@ width_iter_is_upright (gunichar ch)
int st = 0;
int ed = max;
+ if (ch < upright[0][0])
+ return FALSE;
+
while (st <= ed)
{
int mid = (st + ed) / 2;
@@ -926,7 +929,7 @@ width_iter_is_upright (gunichar ch)
}
static void
-width_iter_next(PangoWidthIter* iter)
+width_iter_next (PangoWidthIter *iter)
{
gboolean met_joiner = FALSE;
iter->start = iter->end;
@@ -958,9 +961,9 @@ width_iter_next(PangoWidthIter* iter)
}
/* for variation selector, tag and emoji modifier. */
- if (G_UNLIKELY(ch == 0xFE0EU || ch == 0xFE0FU
- || (ch >= 0xE0020 && ch <= 0xE007F)
- || (ch >= 0x1F3FB && ch <= 0x1F3FF)))
+ if (G_UNLIKELY (ch == 0xFE0EU || ch == 0xFE0FU ||
+ (ch >= 0xE0020 && ch <= 0xE007F) ||
+ (ch >= 0x1F3FB && ch <= 0x1F3FF)))
{
iter->end = g_utf8_next_char (iter->end);
continue;
@@ -968,6 +971,7 @@ width_iter_next(PangoWidthIter* iter)
if (width_iter_is_upright (ch) != iter->upright)
break;
+
iter->end = g_utf8_next_char (iter->end);
}
}
@@ -1000,7 +1004,6 @@ itemize_state_init (ItemizeState *state,
PangoAttrIterator *cached_iter,
const PangoFontDescription *desc)
{
-
state->context = context;
state->text = text;
state->end = text + start_index + length;
@@ -1576,7 +1579,7 @@ pango_itemize_with_base_dir (PangoContext *context,
g_return_val_if_fail (length >= 0, NULL);
g_return_val_if_fail (length == 0 || text != NULL, NULL);
- if (length == 0 || g_utf8_strlen (text + start_index, length) == 0)
+ if (length == 0 || g_utf8_get_char (text + start_index) == '\0')
return NULL;
itemize_state_init (&state, context, text, base_dir, start_index, length,
diff --git a/pango/pango-emoji.c b/pango/pango-emoji.c
index e316b370..8d5a46d6 100644
--- a/pango/pango-emoji.c
+++ b/pango/pango-emoji.c
@@ -52,40 +52,37 @@
#include "pango-emoji-private.h"
#include "pango-emoji-table.h"
-
-static int
-interval_compare (const void *key, const void *elt)
+static inline gboolean
+bsearch_interval (gunichar c,
+ const struct Interval table[],
+ guint n)
{
- gunichar c = GPOINTER_TO_UINT (key);
- struct Interval *interval = (struct Interval *)elt;
-
- if (c < interval->start)
- return -1;
- if (c > interval->end)
- return +1;
-
- return 0;
+ guint lower = 0;
+ guint upper = n - 1;
+
+ while (lower <= upper)
+ {
+ int mid = (lower + upper) / 2;
+
+ if (c < table[mid].start)
+ upper = mid - 1;
+ else if (c > table[mid].end)
+ lower = mid + 1;
+ else
+ return TRUE;
+ }
+
+ return FALSE;
}
#define DEFINE_pango_Is_(name) \
-static gboolean \
+static inline gboolean \
_pango_Is_##name (gunichar ch) \
{ \
- /* bsearch() is declared attribute(nonnull(1)) so we can't validly search \
- * for a NULL key */ \
- /* \
- if (G_UNLIKELY (ch == 0)) \
- return FALSE; \
- */ \
- \
- if (bsearch (GUINT_TO_POINTER (ch), \
- _pango_##name##_table, \
- G_N_ELEMENTS (_pango_##name##_table), \
- sizeof _pango_##name##_table[0], \
- interval_compare)) \
- return TRUE; \
- \
- return FALSE; \
+ return ch >= _pango_##name##_table[0].start && \
+ bsearch_interval (ch, \
+ _pango_##name##_table, \
+ G_N_ELEMENTS (_pango_##name##_table)); \
}
DEFINE_pango_Is_(Emoji)
@@ -106,36 +103,36 @@ _pango_Is_Emoji_Extended_Pictographic (gunichar ch)
return _pango_Is_Extended_Pictographic (ch);
}
-static gboolean
+static inline gboolean
_pango_Is_Emoji_Text_Default (gunichar ch)
{
return _pango_Is_Emoji (ch) && !_pango_Is_Emoji_Presentation (ch);
}
-static gboolean
+static inline gboolean
_pango_Is_Emoji_Emoji_Default (gunichar ch)
{
return _pango_Is_Emoji_Presentation (ch);
}
-static gboolean
+static inline gboolean
_pango_Is_Emoji_Keycap_Base (gunichar ch)
{
return (ch >= '0' && ch <= '9') || ch == '#' || ch == '*';
}
-static gboolean
+static inline gboolean
_pango_Is_Regional_Indicator (gunichar ch)
{
return (ch >= 0x1F1E6 && ch <= 0x1F1FF);
}
-const gunichar kCombiningEnclosingCircleBackslashCharacter = 0x20E0;
-const gunichar kCombiningEnclosingKeycapCharacter = 0x20E3;
-const gunichar kVariationSelector15Character = 0xFE0E;
-const gunichar kVariationSelector16Character = 0xFE0F;
-const gunichar kZeroWidthJoinerCharacter = 0x200D;
+#define kCombiningEnclosingCircleBackslashCharacter 0x20E0
+#define kCombiningEnclosingKeycapCharacter 0x20E3
+#define kVariationSelector15Character 0xFE0E
+#define kVariationSelector16Character 0xFE0F
+#define kZeroWidthJoinerCharacter 0x200D
enum PangoEmojiScannerCategory {
EMOJI = 0,
@@ -157,27 +154,38 @@ enum PangoEmojiScannerCategory {
kMaxEmojiScannerCategory = 16
};
-static unsigned char
+static inline unsigned char
_pango_EmojiSegmentationCategory (gunichar codepoint)
{
/* Specific ones first. */
- if (codepoint == kCombiningEnclosingKeycapCharacter)
- return COMBINING_ENCLOSING_KEYCAP;
- if (codepoint == kCombiningEnclosingCircleBackslashCharacter)
- return COMBINING_ENCLOSING_CIRCLE_BACKSLASH;
- if (codepoint == kZeroWidthJoinerCharacter)
- return ZWJ;
- if (codepoint == kVariationSelector15Character)
- return VS15;
- if (codepoint == kVariationSelector16Character)
- return VS16;
- if (codepoint == 0x1F3F4)
- return TAG_BASE;
- if ((codepoint >= 0xE0030 && codepoint <= 0xE0039) ||
- (codepoint >= 0xE0061 && codepoint <= 0xE007A))
- return TAG_SEQUENCE;
- if (codepoint == 0xE007F)
- return TAG_TERM;
+ switch (codepoint)
+ {
+ case 'a' ... 'z':
+ case 'A' ... 'Z':
+ case ' ':
+ return kMaxEmojiScannerCategory;
+ case '0' ... '9':
+ return KEYCAP_BASE;
+ case kCombiningEnclosingKeycapCharacter:
+ return COMBINING_ENCLOSING_KEYCAP;
+ case kCombiningEnclosingCircleBackslashCharacter:
+ return COMBINING_ENCLOSING_CIRCLE_BACKSLASH;
+ case kZeroWidthJoinerCharacter:
+ return ZWJ;
+ case kVariationSelector15Character:
+ return VS15;
+ case kVariationSelector16Character:
+ return VS16;
+ case 0x1F3F4:
+ return TAG_BASE;
+ case 0xE0030 ... 0xE0039:
+ case 0xE0061 ... 0xE007A:
+ return TAG_SEQUENCE;
+ case 0xE007F:
+ return TAG_TERM;
+ default: ;
+ }
+
if (_pango_Is_Emoji_Modifier_Base (codepoint))
return EMOJI_MODIFIER_BASE;
if (_pango_Is_Emoji_Modifier (codepoint))
@@ -186,13 +194,10 @@ _pango_EmojiSegmentationCategory (gunichar codepoint)
return REGIONAL_INDICATOR;
if (_pango_Is_Emoji_Keycap_Base (codepoint))
return KEYCAP_BASE;
-
if (_pango_Is_Emoji_Emoji_Default (codepoint))
return EMOJI_EMOJI_PRESENTATION;
- if (_pango_Is_Emoji_Text_Default (codepoint))
- return EMOJI_TEXT_PRESENTATION;
if (_pango_Is_Emoji (codepoint))
- return EMOJI;
+ return EMOJI_TEXT_PRESENTATION;
/* Ragel state machine will interpret unknown category as "any". */
return kMaxEmojiScannerCategory;
diff --git a/pango/pango-impl-utils.h b/pango/pango-impl-utils.h
index d2420321..bbeca994 100644
--- a/pango/pango-impl-utils.h
+++ b/pango/pango-impl-utils.h
@@ -163,6 +163,9 @@ pango_get_ignorable (gunichar ch)
for (i = 0; i < G_N_ELEMENTS (ignorables); i++)
{
+ if (ch < ignorables[i].ch)
+ return NULL;
+
if (ch == ignorables[i].ch)
return ignorables[i].nick;
}
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index 5c716b24..0a5ce7f9 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -151,18 +151,10 @@ pango_hb_font_get_nominal_glyph (hb_font_t *font,
{
PangoHbShapeContext *context = (PangoHbShapeContext *) font_data;
- if ((context->show_flags & PANGO_SHOW_IGNORABLES) != 0)
+ if (context->show_flags != 0)
{
- if (pango_get_ignorable (unicode))
- {
- *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
- return TRUE;
- }
- }
-
- if ((context->show_flags & PANGO_SHOW_SPACES) != 0)
- {
- if (g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR)
+ if ((context->show_flags & PANGO_SHOW_SPACES) != 0 &&
+ g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR)
{
/* Replace 0x20 by visible space, since we
* don't draw a hex box for 0x20
@@ -173,11 +165,16 @@ pango_hb_font_get_nominal_glyph (hb_font_t *font,
*glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
return TRUE;
}
- }
- if ((context->show_flags & PANGO_SHOW_LINE_BREAKS) != 0)
- {
- if (unicode == 0x2028)
+ if ((context->show_flags & PANGO_SHOW_IGNORABLES) != 0 &&
+ pango_get_ignorable (unicode))
+ {
+ *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
+ return TRUE;
+ }
+
+ if ((context->show_flags & PANGO_SHOW_LINE_BREAKS) != 0 &&
+ unicode == 0x2028)
{
/* Always mark LS as unknown. If it ends up
* at the line end, PangoLayout takes care of