summaryrefslogtreecommitdiff
path: root/pango/pango-emoji.c
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2019-01-23 10:56:37 +0100
committerBehdad Esfahbod <behdad@behdad.org>2019-01-23 10:56:37 +0100
commite7c292e918f318eccb6b756170640517331eee7a (patch)
treec9ae882fed6ed2798047ac6fabb7a68c23a81183 /pango/pango-emoji.c
parent546f4c242d6f4fe312de3b7c918a848e5172e18d (diff)
downloadpango-e7c292e918f318eccb6b756170640517331eee7a.tar.gz
handle VS15 emoji sequences
Diffstat (limited to 'pango/pango-emoji.c')
-rw-r--r--pango/pango-emoji.c75
1 files changed, 27 insertions, 48 deletions
diff --git a/pango/pango-emoji.c b/pango/pango-emoji.c
index 158daa5b..886fef53 100644
--- a/pango/pango-emoji.c
+++ b/pango/pango-emoji.c
@@ -192,11 +192,15 @@ _pango_EmojiSegmentationCategory (gunichar codepoint)
return kMaxEmojiScannerCategory;
}
-#define found_text_presentation_sequence
+#define found_text_presentation_sequence \
+ { \
+ if (0) g_print ("text %ld..%ld\n", ts - buffer, te - buffer); \
+ *end = te - buffer; \
+ return FALSE; \
+ }
#define found_emoji_presentation_sequence \
{ \
if (0) g_print ("emoji %ld..%ld\n", ts - buffer, te - buffer); \
- *last = ts - buffer; \
*end = te - buffer; \
return TRUE; \
}
@@ -221,7 +225,7 @@ _pango_emoji_iter_init (PangoEmojiIter *iter,
p = g_utf8_next_char (p);
}
- iter->text_start = iter->start = iter->end = iter->token_start = iter->token_end = text;
+ iter->text_start = iter->start = iter->end = text;
if (length >= 0)
iter->text_end = text + length;
else
@@ -246,56 +250,31 @@ _pango_emoji_iter_fini (PangoEmojiIter *iter)
gboolean
_pango_emoji_iter_next (PangoEmojiIter *iter)
{
+ unsigned int old_cursor, cursor;
+ gboolean is_emoji;
+
if (iter->end >= iter->text_end)
return FALSE;
iter->start = iter->end;
- /* The scan_emoji_presentation scanner function returns false when it reaches
- * the end of the buffer and has not discovered any emoji runs in between. For
- * Emoji runs, it returns true, and token_start_ and token_end_ are set to the
- * start and end of the emoji sequence. This means, it may skip over text runs
- * in between, see below. */
- if (iter->start >= iter->token_end)
- {
- /* We need to scan furhter. */
- unsigned int token_start, token_end;
- if (!scan_emoji_presentation (iter->types, iter->n_chars, iter->cursor,
- &token_start, &token_end))
- {
- /* The scanner returned false, which means it has reached the end of the
- * buffer without discovering any emoji segments in between. */
- iter->end = iter->text_end;
- iter->is_emoji = FALSE;
-
- return TRUE;
- };
- /* Ugly... */
- g_assert (iter->cursor <= token_start && token_start < token_end && token_end <= iter->n_chars);
- iter->token_start = g_utf8_offset_to_pointer (iter->token_end, token_start - iter->cursor);
- iter->token_end = g_utf8_offset_to_pointer (iter->token_end, token_end - iter->cursor);
- iter->cursor = token_end;
- }
-
- if (iter->start < iter->token_start)
- {
- /* The scanner function has progressed to the next emoji segment, but we
- * need to return the text segment over which it had skipped. */
- iter->end = iter->token_start;
- iter->is_emoji = FALSE;
- return TRUE;
- }
-
- if (iter->start >= iter->token_start && iter->start < iter->token_end)
- {
- /* Now our cursor has reached the emoji segment, and we can return it. */
- iter->end = iter->token_end;
- iter->is_emoji = TRUE;
- return TRUE;
- }
-
- g_assert_not_reached ();
- return FALSE;
+ old_cursor = cursor = iter->cursor;
+ is_emoji = scan_emoji_presentation (iter->types, iter->n_chars, cursor, &cursor);
+ do
+ {
+ iter->cursor = cursor;
+ iter->is_emoji = is_emoji;
+
+ if (cursor == iter->n_chars)
+ break;
+
+ is_emoji = scan_emoji_presentation (iter->types, iter->n_chars, cursor, &cursor);
+ }
+ while (iter->is_emoji == is_emoji);
+
+ iter->end = g_utf8_offset_to_pointer (iter->start, iter->cursor - old_cursor);
+
+ return TRUE;
}