From e4ba8c550fbafac94c8759b83f493273ab9923e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 11 Nov 2025 12:05:46 +0200 Subject: [PATCH] [TextServer] Fix some emoji sequences and add missing ICU emoji property data. --- modules/text_server_adv/script_iterator.cpp | 13 ++++++++----- thirdparty/icu4c/godot_data.json | 2 ++ thirdparty/icu4c/icudt_godot.dat | Bin 4784480 -> 4797808 bytes 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/text_server_adv/script_iterator.cpp b/modules/text_server_adv/script_iterator.cpp index b03231b2395..41ef6f1349a 100644 --- a/modules/text_server_adv/script_iterator.cpp +++ b/modules/text_server_adv/script_iterator.cpp @@ -32,17 +32,21 @@ // This implementation is derived from ICU: icu4c/source/extra/scrptrun/scrptrun.cpp +inline constexpr UChar32 ZERO_WIDTH_JOINER = 0x200d; +inline constexpr UChar32 VARIATION_SELECTOR_15 = 0xfe0e; +inline constexpr UChar32 VARIATION_SELECTOR_16 = 0xfe0f; + inline bool ScriptIterator::same_script(int32_t p_script_one, int32_t p_script_two) { return p_script_one <= USCRIPT_INHERITED || p_script_two <= USCRIPT_INHERITED || p_script_one == p_script_two; } inline bool ScriptIterator::is_emoji(UChar32 p_c, UChar32 p_next) { - if (p_next == 0xFE0E) { // Variation Selector-15 + if (p_next == VARIATION_SELECTOR_15 && (u_hasBinaryProperty(p_c, UCHAR_EMOJI) || u_hasBinaryProperty(p_c, UCHAR_EXTENDED_PICTOGRAPHIC))) { return false; - } else if (p_next == 0xFE0F) { // Variation Selector-16 + } else if (p_next == VARIATION_SELECTOR_16 && (u_hasBinaryProperty(p_c, UCHAR_EMOJI) || u_hasBinaryProperty(p_c, UCHAR_EXTENDED_PICTOGRAPHIC))) { return true; } else { - return u_hasBinaryProperty(p_c, UCHAR_EMOJI) || u_hasBinaryProperty(p_c, UCHAR_EMOJI_PRESENTATION) || u_hasBinaryProperty(p_c, UCHAR_EMOJI_MODIFIER) || u_hasBinaryProperty(p_c, UCHAR_REGIONAL_INDICATOR) || u_hasBinaryProperty(p_c, UCHAR_EXTENDED_PICTOGRAPHIC); + return u_hasBinaryProperty(p_c, UCHAR_EMOJI_PRESENTATION) || u_hasBinaryProperty(p_c, UCHAR_EMOJI_MODIFIER) || u_hasBinaryProperty(p_c, UCHAR_REGIONAL_INDICATOR); } } @@ -119,8 +123,7 @@ ScriptIterator::ScriptIterator(const String &p_string, int p_start, int p_length } if (script_code == USCRIPT_SYMBOLS_EMOJI && script_code != sc) { - UCharCategory cat = (UCharCategory)u_charType(ch); - if ((cat >= U_SPACE_SEPARATOR && cat <= U_CONTROL_CHAR) || (cat >= U_DASH_PUNCTUATION && cat <= U_OTHER_PUNCTUATION) || (cat >= U_INITIAL_PUNCTUATION && cat <= U_FINAL_PUNCTUATION)) { + if (ch == VARIATION_SELECTOR_15 || n == VARIATION_SELECTOR_15 || !(is_emoji(ch, n) || ch == ZERO_WIDTH_JOINER || ch == VARIATION_SELECTOR_16 || u_hasBinaryProperty(ch, UCHAR_EXTENDED_PICTOGRAPHIC))) { break; } } else if (same_script(script_code, sc)) { diff --git a/thirdparty/icu4c/godot_data.json b/thirdparty/icu4c/godot_data.json index e36e2b078b5..645be125df7 100644 --- a/thirdparty/icu4c/godot_data.json +++ b/thirdparty/icu4c/godot_data.json @@ -7,5 +7,7 @@ misc: include normalization: include confusables: include + uemoji: include + uprops: include } } diff --git a/thirdparty/icu4c/icudt_godot.dat b/thirdparty/icu4c/icudt_godot.dat index c6b96c477b38368496659e0718fd5a7fc569e6eb..16fe24004b5eb2ea193eabdd93c1a7e3fc833a70 100644 GIT binary patch delta 13571 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