From e0c32e06ad760841757337c6344fb515486618b2 Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Fri, 1 Oct 2021 13:20:55 +0900 Subject: [PATCH] Fix ZWJ, ZWNJ issues Current font load logic classifies ZWJ, ZWNJ as COMMON script. This interrupts them from being combined into one emoji in the EMOJI + ZWJ + EMOJI case. This patch treats ZWJ, ZWNJ as EMOJI script in this case, so that they can be loaded with the same color emoji font. Please refer the example below. The expected result is to be combined into one emoji character due to ZWJ. But the actual result is 3 characters rendered. // example TextLabel label = TextLabel::New("👩‍🔬"); Change-Id: Ic8e921ffcb63c27638afe781527b5c6b90aa92b1 Signed-off-by: Bowon Ryu --- .../src/dali-toolkit/utc-Dali-TextLabel.cpp | 7 ++++++ .../internal/text/multi-language-support-impl.cpp | 25 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp index 5495c9d..c9453e1 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp @@ -836,6 +836,13 @@ int UtcDaliToolkitTextLabelEmojisP(void) application.SendNotification(); application.Render(); + // EMOJI + ZWJ + EMOJI case for coverage. + const std::string emojiWithZWJ = "👩‍🔬"; + label.SetProperty( TextLabel::Property::TEXT, emojiWithZWJ ); + + application.SendNotification(); + application.Render(); + END_TEST; } diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index a0e6ae5..82470f8 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -228,7 +228,8 @@ void MultilanguageSupport::SetScripts(const Vector& text, // Check if whether is right to left markup and Keeps true if the previous value was true. currentScriptRun.isRightToLeft = currentScriptRun.isRightToLeft || TextAbstraction::IsRightToLeftMark(character); - if(TextAbstraction::EMOJI == currentScriptRun.script) + // ZWJ, ZWNJ between emojis should be treated as EMOJI. + if(TextAbstraction::EMOJI == currentScriptRun.script && !(TextAbstraction::IsZeroWidthJoiner(character) || TextAbstraction::IsZeroWidthNonJoiner(character))) { // Emojis doesn't mix well with characters common to all scripts. Insert the emoji run. scripts.Insert(scripts.Begin() + scriptIndex, currentScriptRun); @@ -444,7 +445,8 @@ void MultilanguageSupport::ValidateFonts(const Vector& Vector::ConstIterator scriptRunEndIt = scripts.End(); bool isNewParagraphCharacter = false; - bool isPreviousEmojiScript = false; + bool isPreviousEmojiScript = false; + FontId previousEmojiFontId = 0u; CharacterIndex lastCharacter = startIndex + numberOfCharacters; for(Length index = startIndex; index < lastCharacter; ++index) @@ -535,6 +537,16 @@ void MultilanguageSupport::ValidateFonts(const Vector& currentFontRun.isBoldRequired = false; } + // ZWJ, ZWNJ between emojis should use the previous emoji font. + if(isEmojiScript && (TextAbstraction::IsZeroWidthJoiner(character) || TextAbstraction::IsZeroWidthNonJoiner(character))) + { + if(0u != previousEmojiFontId) + { + fontId = previousEmojiFontId; + isValidFont = true; + } + } + // If the given font is not valid, it means either: // - there is no cached font for the current script yet or, // - the user has set a different font than the default one for the current script or, @@ -647,6 +659,15 @@ void MultilanguageSupport::ValidateFonts(const Vector& } // !isValidFont (2) } // !isValidFont (1) + // Store the font id when the first character is an emoji. + if(isEmojiScript && !isPreviousEmojiScript) + { + if(0u != fontId) + { + previousEmojiFontId = fontId; + } + } + #ifdef DEBUG_ENABLED { Dali::TextAbstraction::FontDescription description; -- 2.7.4