diff --git a/third_party/txt/src/minikin/FontCollection.cpp b/third_party/txt/src/minikin/FontCollection.cpp index 91d1ac295cdc1..69a0f873049ed 100644 --- a/third_party/txt/src/minikin/FontCollection.cpp +++ b/third_party/txt/src/minikin/FontCollection.cpp @@ -509,7 +509,9 @@ void FontCollection::itemize(const uint16_t* string, if (!shouldContinueRun) { const std::shared_ptr& family = getFamilyForChar( ch, isVariationSelector(nextCh) ? nextCh : 0, langListId, variant); - if (utf16Pos == 0 || family.get() != lastFamily) { + if (utf16Pos == 0 || family.get() != lastFamily || + (!(U_GET_GC_MASK(prevCh) & U_GC_L_MASK) && + (U_GET_GC_MASK(ch) & U_GC_L_MASK))) { size_t start = utf16Pos; // Workaround for combining marks and emoji modifiers until we implement // per-cluster font selection: if a combining mark or an emoji modifier @@ -528,8 +530,8 @@ void FontCollection::itemize(const uint16_t* string, } start -= prevChLength; } - result->push_back( - {family->getClosestMatch(style), static_cast(start), 0}); + result->push_back({family->getClosestMatch(style, ch, variant), + static_cast(start), 0}); run = &result->back(); lastFamily = family.get(); } diff --git a/third_party/txt/src/minikin/FontFamily.cpp b/third_party/txt/src/minikin/FontFamily.cpp index cf5a623c56132..a507ffeefa1d6 100644 --- a/third_party/txt/src/minikin/FontFamily.cpp +++ b/third_party/txt/src/minikin/FontFamily.cpp @@ -146,15 +146,28 @@ static FontFakery computeFakery(FontStyle wanted, FontStyle actual) { return FontFakery(isFakeBold, isFakeItalic); } -FakedFont FontFamily::getClosestMatch(FontStyle style) const { +FakedFont FontFamily::getClosestMatch( + FontStyle style, + uint32_t codepoint /* = 0 */, + uint32_t variationSelector /* = 0 */) const { const Font* bestFont = nullptr; - int bestMatch = 0; + int bestMatch = INT_MAX; for (size_t i = 0; i < mFonts.size(); i++) { const Font& font = mFonts[i]; int match = computeMatch(font.style, style); - if (i == 0 || match < bestMatch) { - bestFont = &font; - bestMatch = match; + bool result = false; + if (codepoint != 0) { + hb_font_t* hbFont = getHbFontLocked(font.typeface.get()); + uint32_t unusedGlyph = 0; + result = + hb_font_get_glyph(hbFont, codepoint, variationSelector, &unusedGlyph); + hb_font_destroy(hbFont); + } + if (codepoint == 0 || (codepoint != 0 && result)) { + if (match < bestMatch) { + bestFont = &font; + bestMatch = match; + } } } if (bestFont != nullptr) { diff --git a/third_party/txt/src/minikin/FontFamily.h b/third_party/txt/src/minikin/FontFamily.h index aac7a0d62bd12..1d9e6eefaa08c 100644 --- a/third_party/txt/src/minikin/FontFamily.h +++ b/third_party/txt/src/minikin/FontFamily.h @@ -140,7 +140,9 @@ class FontFamily { static bool analyzeStyle(const std::shared_ptr& typeface, int* weight, bool* italic); - FakedFont getClosestMatch(FontStyle style) const; + FakedFont getClosestMatch(FontStyle style, + uint32_t codepoint = 0, + uint32_t variationSelector = 0) const; uint32_t langId() const { return mLangId; } int variant() const { return mVariant; } diff --git a/third_party/txt/src/txt/font_collection.cc b/third_party/txt/src/txt/font_collection.cc index 7f949787ad1d5..e7bbe80d03473 100644 --- a/third_party/txt/src/txt/font_collection.cc +++ b/third_party/txt/src/txt/font_collection.cc @@ -244,6 +244,28 @@ void FontCollection::SortSkTypefaces( std::sort( sk_typefaces.begin(), sk_typefaces.end(), [](const sk_sp& a, const sk_sp& b) { + { + // A workaround to prevent emoji fonts being selected for normal text + // when normal and emojis are mixed at same font family. + + bool a_isEmojiFont = false; + bool b_isEmojiFont = false; + SkString postScriptName; + a->getPostScriptName(&postScriptName); + if (postScriptName.contains("Emoji")) { + a_isEmojiFont = true; + } + b->getPostScriptName(&postScriptName); + if (postScriptName.contains("Emoji")) { + b_isEmojiFont = true; + } + if (a_isEmojiFont && !b_isEmojiFont) { + return false; + } else if (!a_isEmojiFont && b_isEmojiFont) { + return true; + } + } + SkFontStyle a_style = a->fontStyle(); SkFontStyle b_style = b->fontStyle(); diff --git a/third_party/txt/src/txt/platform_linux.cc b/third_party/txt/src/txt/platform_linux.cc index b2e83a67d7967..98210dcabe26e 100644 --- a/third_party/txt/src/txt/platform_linux.cc +++ b/third_party/txt/src/txt/platform_linux.cc @@ -13,6 +13,9 @@ namespace txt { std::vector GetDefaultFontFamilies() { +#ifdef FLUTTER_USE_FONTCONFIG + return {"TizenDefaultFont"}; +#else return { "SamsungOneUI", "SamsungOneUIArabic", @@ -72,11 +75,12 @@ std::vector GetDefaultFontFamilies() { "BreezeSansFallback", "BreezeColorEmoji", }; +#endif } sk_sp GetDefaultFontManager() { #ifdef FLUTTER_USE_FONTCONFIG - return SkFontMgr_New_FontConfig(nullptr); + return SkFontMgr::RefDefault(); #else return SkFontMgr_New_Custom_Directory("/usr/share/fonts"); #endif