From 65e14eb8def5730f7581594ea539dffefab098a3 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Thu, 3 Jun 2021 21:49:13 +0800 Subject: [PATCH] Fix RichTextLabel auto-wrapping on CJK (cherry picked from commit 3a591aaeebcff234e6e694255919c5a311b28d02) --- scene/gui/label.cpp | 12 +++++++++--- scene/gui/rich_text_label.cpp | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index ae96cc5d85c..d0721eff841 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -413,11 +413,17 @@ void Label::regenerate_word_cache() { if (uppercase) current = String::char_uppercase(current); - // ranges taken from http://www.unicodemap.org/ + // ranges taken from https://en.wikipedia.org/wiki/Plane_(Unicode) // if your language is not well supported, consider helping improve // the unicode support in Godot. - bool separatable = (current >= 0x2E08 && current <= 0xFAFF) || (current >= 0xFE30 && current <= 0xFE4F); - //current>=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57); + bool separatable = (current >= 0x2E08 && current <= 0x9FFF) || // CJK scripts and symbols. + (current >= 0xAC00 && current <= 0xD7FF) || // Hangul Syllables and Hangul Jamo Extended-B. + (current >= 0xF900 && current <= 0xFAFF) || // CJK Compatibility Ideographs. + (current >= 0xFE30 && current <= 0xFE4F) || // CJK Compatibility Forms. + (current >= 0xFF65 && current <= 0xFF9F) || // Halfwidth forms of katakana + (current >= 0xFFA0 && current <= 0xFFDC) || // Halfwidth forms of compatibility jamo characters for Hangul + (current >= 0x20000 && current <= 0x2FA1F) || // CJK Unified Ideographs Extension B ~ F and CJK Compatibility Ideographs Supplement. + (current >= 0x30000 && current <= 0x3134F); // CJK Unified Ideographs Extension G. bool insert_newline = false; real_t char_width = 0; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4d7f16dbd68..300aa8f597a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -384,6 +384,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & l.char_count += text->text.length(); } + bool just_breaked_in_middle = false; rchar = 0; FontDrawer drawer(font, Color(1, 1, 1)); while (*c) { @@ -391,6 +392,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int end = 0; int w = 0; int fw = 0; + bool was_separatable = false; lh = 0; @@ -410,6 +412,25 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & break; //don't allow lines longer than assigned width } + // For info about the unicode range, see Label::regenerate_word_cache. + const CharType current = c[end]; + const bool separatable = (current >= 0x2E08 && current <= 0x9FFF) || // CJK scripts and symbols. + (current >= 0xAC00 && current <= 0xD7FF) || // Hangul Syllables and Hangul Jamo Extended-B. + (current >= 0xF900 && current <= 0xFAFF) || // CJK Compatibility Ideographs. + (current >= 0xFE30 && current <= 0xFE4F) || // CJK Compatibility Forms. + (current >= 0xFF65 && current <= 0xFF9F) || // Halfwidth forms of katakana + (current >= 0xFFA0 && current <= 0xFFDC) || // Halfwidth forms of compatibility jamo characters for Hangul + (current >= 0x20000 && current <= 0x2FA1F) || // CJK Unified Ideographs Extension B ~ F and CJK Compatibility Ideographs Supplement. + (current >= 0x30000 && current <= 0x3134F); // CJK Unified Ideographs Extension G. + const bool long_separatable = separatable && (wofs - backtrack + w + cw > p_width); + const bool separation_changed = end > 0 && was_separatable != separatable; + if (!just_breaked_in_middle && (long_separatable || separation_changed)) { + just_breaked_in_middle = true; + break; + } + was_separatable = separatable; + just_breaked_in_middle = false; + w += cw; fw += cw;