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 <bowon.ryu@samsung.com>
application.SendNotification();
application.Render();
application.SendNotification();
application.Render();
+ // EMOJI + ZWJ + EMOJI case for coverage.
+ const std::string emojiWithZWJ = "👩‍🔬";
+ label.SetProperty( TextLabel::Property::TEXT, emojiWithZWJ );
+
+ application.SendNotification();
+ application.Render();
+
// Check if whether is right to left markup and Keeps true if the previous value was true.
currentScriptRun.isRightToLeft = currentScriptRun.isRightToLeft || TextAbstraction::IsRightToLeftMark(character);
// 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);
{
// Emojis doesn't mix well with characters common to all scripts. Insert the emoji run.
scripts.Insert(scripts.Begin() + scriptIndex, currentScriptRun);
Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
bool isNewParagraphCharacter = false;
Vector<ScriptRun>::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)
CharacterIndex lastCharacter = startIndex + numberOfCharacters;
for(Length index = startIndex; index < lastCharacter; ++index)
currentFontRun.isBoldRequired = false;
}
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,
// 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,
} // !isValidFont (2)
} // !isValidFont (1)
} // !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;
#ifdef DEBUG_ENABLED
{
Dali::TextAbstraction::FontDescription description;