From b162701621063eaf59b24e899e9d3f0103cd2f93 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru Michis Date: Mon, 24 Aug 2020 21:02:10 +0300 Subject: [PATCH] Backed out changeset 0cad1ef724ee (bug 1371386) for causing failures in emoji-fallback-3.html CLOSED TREE --- gfx/thebes/SharedFontList.cpp | 18 +- gfx/thebes/gfxAndroidPlatform.cpp | 4 +- gfx/thebes/gfxAndroidPlatform.h | 3 +- gfx/thebes/gfxFont.cpp | 34 --- gfx/thebes/gfxFont.h | 2 - gfx/thebes/gfxFontEntry.cpp | 30 +-- gfx/thebes/gfxFontEntry.h | 30 +-- gfx/thebes/gfxFontUtils.cpp | 10 - gfx/thebes/gfxFontUtils.h | 11 - gfx/thebes/gfxPlatform.h | 8 +- gfx/thebes/gfxPlatformFontList.cpp | 97 +++------ gfx/thebes/gfxPlatformFontList.h | 29 ++- gfx/thebes/gfxPlatformGtk.cpp | 6 +- gfx/thebes/gfxPlatformGtk.h | 3 +- gfx/thebes/gfxPlatformMac.cpp | 6 +- gfx/thebes/gfxPlatformMac.h | 3 +- gfx/thebes/gfxTextRun.cpp | 198 +++++------------- gfx/thebes/gfxTextRun.h | 17 +- gfx/thebes/gfxWindowsPlatform.cpp | 4 +- gfx/thebes/gfxWindowsPlatform.h | 3 +- intl/unicharutil/util/nsUnicodeProperties.h | 13 ++ .../font-matching/emoji-fallback-2-ref.html | 2 +- .../font-matching/emoji-fallback-2.html | 4 - .../font-matching/emoji-fallback-3-ref.html | 2 +- .../font-matching/emoji-fallback-3.html | 4 - .../reftests/text/1320665-cmap-format-13.html | 2 +- layout/reftests/text/reftest.list | 2 +- layout/reftests/xul/text-crop-ref.xhtml | 4 +- layout/reftests/xul/text-crop.xhtml | 4 +- 29 files changed, 142 insertions(+), 411 deletions(-) diff --git a/gfx/thebes/SharedFontList.cpp b/gfx/thebes/SharedFontList.cpp index 4a270b7b393d..5055af22d5a6 100644 --- a/gfx/thebes/SharedFontList.cpp +++ b/gfx/thebes/SharedFontList.cpp @@ -33,8 +33,7 @@ static double WSSDistance(const Face* aFace, const gfxFontStyle& aStyle) { // weight/style/stretch priority: stretch >> style >> weight // so we multiply the stretch and style values to make them dominate // the result - return stretchDist * kStretchFactor + styleDist * kStyleFactor + - weightDist * kWeightFactor; + return stretchDist * 1.0e8 + styleDist * 1.0e4 + weightDist; } void* Pointer::ToPtr(FontList* aFontList) const { @@ -399,21 +398,6 @@ void Family::SearchAllFontsForChar(FontList* aList, if (!charmap && !fe->HasCharacter(aMatchData->mCh)) { continue; } - if (aMatchData->mPresentation != eFontPresentation::Any) { - gfxFont* font = fe->FindOrMakeFont(&aMatchData->mStyle); - if (!font) { - continue; - } - bool hasColorGlyph = - font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh); - if (hasColorGlyph != - (aMatchData->mPresentation == eFontPresentation::Emoji)) { - distance += kPresentationMismatch; - if (distance >= aMatchData->mMatchDistance) { - continue; - } - } - } aMatchData->mBestMatch = fe; aMatchData->mMatchDistance = distance; aMatchData->mMatchedSharedFamily = this; diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index ac05c480a917..0eaf6ebd7c07 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -156,14 +156,14 @@ static bool IsJapaneseLocale() { } void gfxAndroidPlatform::GetCommonFallbackFonts( - uint32_t aCh, Script aRunScript, eFontPresentation aPresentation, + uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) { static const char kDroidSansJapanese[] = "Droid Sans Japanese"; static const char kMotoyaLMaru[] = "MotoyaLMaru"; static const char kNotoSansCJKJP[] = "Noto Sans CJK JP"; static const char kNotoColorEmoji[] = "Noto Color Emoji"; - if (aPresentation == eFontPresentation::Emoji) { + if (ShouldPreferEmojiFont(aCh, aNextCh)) { aFontList.AppendElement(kNotoColorEmoji); } diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index 19073bdf1311..73a823bbea3f 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -38,8 +38,7 @@ class gfxAndroidPlatform final : public gfxPlatform { void ReadSystemFontList( nsTArray* aFontList) override; - void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, + void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) override; bool FontHintingEnabled() override; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index fb6538368206..dbb9e337f301 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -2409,40 +2409,6 @@ bool gfxFont::RenderColorGlyph(DrawTarget* aDrawTarget, gfxContext* aContext, return true; } -bool gfxFont::HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh) { - // Bitmap fonts are assumed to provide "color" glyphs for all supported chars. - gfxFontEntry* fe = GetFontEntry(); - if (fe->HasColorBitmapTable()) { - return true; - } - // Use harfbuzz shaper to look up the default glyph ID for the character. - if (!mHarfBuzzShaper) { - mHarfBuzzShaper = MakeUnique(this); - } - auto* shaper = static_cast(mHarfBuzzShaper.get()); - if (!shaper->Initialize()) { - return false; - } - uint32_t gid = 0; - if (gfxFontUtils::IsVarSelector(aNextCh)) { - gid = shaper->GetVariationGlyph(aCh, aNextCh); - } - if (!gid) { - gid = shaper->GetNominalGlyph(aCh); - } - if (!gid) { - return false; - } - // Check if there is a COLR/CPAL or SVG glyph for this ID. - if (fe->TryGetColorGlyphs() && fe->HasColorLayersForGlyph(gid)) { - return true; - } - if (fe->TryGetSVGData(this) && fe->HasSVGGlyph(gid)) { - return true; - } - return false; -} - static void UnionRange(gfxFloat aX, gfxFloat* aDestMin, gfxFloat* aDestMax) { *aDestMin = std::min(*aDestMin, aX); *aDestMax = std::max(*aDestMax, aX); diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 15903da1fdd8..b06b1e921da3 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1864,8 +1864,6 @@ class gfxFont { // glyphs. This does not add a reference to the returned font. gfxFont* GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel); - bool HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh); - protected: virtual const Metrics& GetHorizontalMetrics() = 0; diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index 5b9376f6161d..6b33706dbf6d 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -1556,8 +1556,7 @@ static inline double WeightStyleStretchDistance( // weight/style/stretch priority: stretch >> style >> weight // so we multiply the stretch and style values to make them dominate // the result - return stretchDist * kStretchFactor + styleDist * kStyleFactor + - weightDist * kWeightFactor; + return stretchDist * 1.0e8 + styleDist * 1.0e4 + weightDist; } void gfxFontFamily::FindAllFontsForStyle( @@ -1795,18 +1794,6 @@ void gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) { fe = e; distance = WeightStyleStretchDistance(fe, aMatchData->mStyle); - if (aMatchData->mPresentation != eFontPresentation::Any) { - RefPtr font = fe->FindOrMakeFont(&aMatchData->mStyle); - if (!font) { - continue; - } - bool hasColorGlyph = - font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh); - if (hasColorGlyph != - (aMatchData->mPresentation == eFontPresentation::Emoji)) { - distance += kPresentationMismatch; - } - } break; } } @@ -1815,8 +1802,7 @@ void gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) { // If style/weight/stretch was not Normal, see if we can // fall back to a next-best face (e.g. Arial Black -> Bold, // or Arial Narrow -> Regular). - GlobalFontMatch data(aMatchData->mCh, aMatchData->mNextCh, - aMatchData->mStyle, aMatchData->mPresentation); + GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle); SearchAllFontsForChar(&data); if (!data.mBestMatch) { return; @@ -1850,18 +1836,6 @@ void gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData) { gfxFontEntry* fe = mAvailableFonts[i]; if (fe && fe->HasCharacter(aMatchData->mCh)) { float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle); - if (aMatchData->mPresentation != eFontPresentation::Any) { - RefPtr font = fe->FindOrMakeFont(&aMatchData->mStyle); - if (!font) { - continue; - } - bool hasColorGlyph = - font->HasColorGlyphFor(aMatchData->mCh, aMatchData->mNextCh); - if (hasColorGlyph != - (aMatchData->mPresentation == eFontPresentation::Emoji)) { - distance += kPresentationMismatch; - } - } if (distance < aMatchData->mMatchDistance || (distance == aMatchData->mMatchDistance && Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) { diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 78546720b5fd..7bfa37301ee4 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -12,7 +12,6 @@ #include "gfxFontFeatures.h" #include "gfxFontUtils.h" #include "gfxFontVariations.h" -#include "gfxPlatform.h" #include "nsTArray.h" #include "nsTHashtable.h" #include "mozilla/HashFunctions.h" @@ -255,15 +254,6 @@ class gfxFontEntry { const mozilla::gfx::DeviceColor& aDefaultColor, nsTArray& layerGlyphs, nsTArray& layerColors); - bool HasColorLayersForGlyph(uint32_t aGlyphId) { - MOZ_ASSERT(mCOLR); - return gfxFontUtils::HasColorLayersForGlyph(mCOLR, aGlyphId); - } - - bool HasColorBitmapTable() { - return HasFontTable(TRUETYPE_TAG('C', 'B', 'D', 'T')) || - HasFontTable(TRUETYPE_TAG('s', 'b', 'i', 'x')); - } // Access to raw font table data (needed for Harfbuzz): // returns a pointer to data owned by the fontEntry or the OS, @@ -762,23 +752,17 @@ inline bool gfxFontEntry::SupportsBold() { // used when iterating over all fonts looking for a match for a given character struct GlobalFontMatch { - GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh, - const gfxFontStyle& aStyle, eFontPresentation aPresentation) - : mStyle(aStyle), - mCh(aCharacter), - mNextCh(aNextCh), - mPresentation(aPresentation) {} + GlobalFontMatch(const uint32_t aCharacter, const gfxFontStyle& aStyle) + : mStyle(aStyle), mCh(aCharacter) {} RefPtr mBestMatch; // current best match RefPtr mMatchedFamily; // the family it belongs to mozilla::fontlist::Family* mMatchedSharedFamily = nullptr; - const gfxFontStyle& mStyle; // style to match - const uint32_t mCh; // codepoint to be matched - const uint32_t mNextCh; // following codepoint (or zero) - eFontPresentation mPresentation; - uint32_t mCount = 0; // number of fonts matched - uint32_t mCmapsTested = 0; // number of cmaps tested - double mMatchDistance = INFINITY; // metric indicating closest match + const gfxFontStyle& mStyle; // style to match + const uint32_t mCh; // codepoint to be matched + uint32_t mCount = 0; // number of fonts matched + uint32_t mCmapsTested = 0; // number of cmaps tested + float mMatchDistance = INFINITY; // metric indicating closest match }; // Installation status (base system / langpack / user-installed) may determine diff --git a/gfx/thebes/gfxFontUtils.cpp b/gfx/thebes/gfxFontUtils.cpp index f5d1d4011aca..495051eb0611 100644 --- a/gfx/thebes/gfxFontUtils.cpp +++ b/gfx/thebes/gfxFontUtils.cpp @@ -1722,16 +1722,6 @@ bool gfxFontUtils::GetColorGlyphLayers( return true; } -bool gfxFontUtils::HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId) { - unsigned int blobLength; - const COLRHeader* colr = - reinterpret_cast(hb_blob_get_data(aCOLR, &blobLength)); - MOZ_ASSERT(colr, "Cannot get COLR raw data"); - MOZ_ASSERT(blobLength, "Found COLR data, but length is 0"); - - return LookForBaseGlyphRecord(colr, aGlyphId); -} - void gfxFontUtils::GetVariationData( gfxFontEntry* aFontEntry, nsTArray* aAxes, nsTArray* aInstances) { diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index 83d32ffa83da..b4933dcc56f2 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -1159,7 +1159,6 @@ class gfxFontUtils { const mozilla::gfx::DeviceColor& aDefaultColor, nsTArray& aGlyphs, nsTArray& aColors); - static bool HasColorLayersForGlyph(hb_blob_t* aCOLR, uint32_t aGlyphId); // Helper used to implement gfxFontEntry::GetVariation{Axes,Instances} for // platforms where the native font APIs don't provide the info we want @@ -1205,16 +1204,6 @@ class gfxFontUtils { static const mozilla::Encoding* gMSFontNameCharsets[]; }; -// Factors used to weight the distances between the available and target font -// properties during font-matching. These ensure that we respect the CSS-fonts -// requirement that font-stretch >> font-style >> font-weight; and in addition, -// a mismatch between the desired and actual glyph presentation (emoji vs text) -// will take precedence over any of the style attributes. -constexpr double kPresentationMismatch = 1.0e12; -constexpr double kStretchFactor = 1.0e8; -constexpr double kStyleFactor = 1.0e4; -constexpr double kWeightFactor = 1.0e0; - // style distance ==> [0,500] static inline double StyleDistance(const mozilla::SlantStyleRange& aRange, mozilla::FontSlantStyle aTargetStyle) { diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 79a86a40361c..c5cacf6a9899 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -96,10 +96,6 @@ enum eGfxLog { eGfxLog_textperf = 5 }; -// Used during font matching to express a preference, if any, for whether -// to use a font that will present a color or monochrome glyph. -enum class eFontPresentation : uint8_t { Any = 0, Text = 1, Emoji = 2 }; - // when searching through pref langs, max number of pref langs const uint32_t kMaxLenPrefLangList = 32; @@ -479,8 +475,8 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener { // returns a list of commonly used fonts for a given character // these are *possible* matches, no cmap-checking is done at this level - virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, Script /*aRunScript*/, - eFontPresentation /*aPresentation*/, + virtual void GetCommonFallbackFonts(uint32_t /*aCh*/, uint32_t /*aNextCh*/, + Script /*aRunScript*/, nsTArray& /*aFontList*/) { // platform-specific override, by default do nothing } diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 431c9aa941f1..575c6a8674dd 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -863,19 +863,20 @@ void gfxPlatformFontList::GetFontFamilyList( } } -gfxFont* gfxPlatformFontList::SystemFindFontForChar( +gfxFontEntry* gfxPlatformFontList::SystemFindFontForChar( uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation, const gfxFontStyle* aStyle, - FontVisibility* aVisibility, FontMatchingStats* aFontMatchingStats) { + const gfxFontStyle* aStyle, FontVisibility* aVisibility, + FontMatchingStats* aFontMatchingStats) { MOZ_ASSERT(!mCodepointsWithNoFonts.test(aCh), "don't call for codepoints already known to be unsupported"); + gfxFontEntry* fontEntry = nullptr; + // Try to short-circuit font fallback for U+FFFD, used to represent // encoding errors: just use cached family from last time U+FFFD was seen. // This helps speed up pages with lots of encoding errors, binary-as-text, // etc. if (aCh == 0xFFFD) { - gfxFontEntry* fontEntry = nullptr; if (mReplacementCharFallbackFamily.mIsShared && mReplacementCharFallbackFamily.mShared) { fontlist::Face* face = @@ -896,7 +897,7 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar( // this should never fail, as we must have found U+FFFD in order to set // mReplacementCharFallbackFamily at all, but better play it safe if (fontEntry && fontEntry->HasCharacter(aCh)) { - return fontEntry->FindOrMakeFont(aStyle); + return fontEntry; } } @@ -905,35 +906,15 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar( // search commonly available fonts bool common = true; FontFamily fallbackFamily; - gfxFont* candidate = CommonFontFallback( - aCh, aNextCh, aRunScript, aPresentation, aStyle, fallbackFamily); - gfxFont* font = nullptr; - if (candidate) { - if (aPresentation == eFontPresentation::Any) { - font = candidate; - } else { - bool hasColorGlyph = candidate->HasColorGlyphFor(aCh, aNextCh); - if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) { - font = candidate; - } - } - } + fontEntry = + CommonFontFallback(aCh, aNextCh, aRunScript, aStyle, fallbackFamily); - // If we didn't find a common font, or it was not the preferred type (color - // or monochrome), do system-wide fallback (except for specials). + // if didn't find a font, do system-wide fallback (except for specials) uint32_t cmapCount = 0; - if (!font) { + if (!fontEntry) { common = false; - font = GlobalFontFallback(aCh, aNextCh, aRunScript, aPresentation, aStyle, - cmapCount, fallbackFamily, aFontMatchingStats); - // If the font we found doesn't match the requested type, and we also found - // a candidate above, prefer that one. - if (font && aPresentation != eFontPresentation::Any && candidate) { - bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh); - if (hasColorGlyph != (aPresentation == eFontPresentation::Emoji)) { - font = candidate; - } - } + fontEntry = GlobalFontFallback(aCh, aRunScript, aStyle, cmapCount, + fallbackFamily, aFontMatchingStats); } TimeDuration elapsed = TimeStamp::Now() - start; @@ -946,12 +927,12 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar( "script: %d match: [%s]" " time: %dus cmaps: %d\n", (common ? "common" : "global"), aCh, static_cast(script), - (font ? font->GetFontEntry()->Name().get() : ""), + (fontEntry ? fontEntry->Name().get() : ""), int32_t(elapsed.ToMicroseconds()), cmapCount)); } // no match? add to set of non-matching codepoints - if (!font) { + if (!fontEntry) { mCodepointsWithNoFonts.set(aCh); } else { *aVisibility = fallbackFamily.mIsShared @@ -976,19 +957,18 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar( Telemetry::Accumulate(Telemetry::SYSTEM_FONT_FALLBACK_SCRIPT, int(aRunScript) + 1); - return font; + return fontEntry; } #define NUM_FALLBACK_FONTS 8 -gfxFont* gfxPlatformFontList::CommonFontFallback( +gfxFontEntry* gfxPlatformFontList::CommonFontFallback( uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation, const gfxFontStyle* aMatchStyle, - FontFamily& aMatchedFamily) { + const gfxFontStyle* aMatchStyle, FontFamily& aMatchedFamily) { AutoTArray defaultFallbacks; - gfxPlatform::GetPlatform()->GetCommonFallbackFonts( - aCh, aRunScript, aPresentation, defaultFallbacks); - GlobalFontMatch data(aCh, aNextCh, *aMatchStyle, aPresentation); + gfxPlatform::GetPlatform()->GetCommonFallbackFonts(aCh, aNextCh, aRunScript, + defaultFallbacks); + GlobalFontMatch data(aCh, *aMatchStyle); if (SharedFontList()) { for (const auto name : defaultFallbacks) { fontlist::Family* family = FindSharedFamily(nsDependentCString(name)); @@ -998,7 +978,7 @@ gfxFont* gfxPlatformFontList::CommonFontFallback( family->SearchAllFontsForChar(SharedFontList(), &data); if (data.mBestMatch) { aMatchedFamily = FontFamily(family); - return data.mBestMatch->FindOrMakeFont(aMatchStyle); + return data.mBestMatch; } } } else { @@ -1011,16 +991,15 @@ gfxFont* gfxPlatformFontList::CommonFontFallback( fallback->FindFontForChar(&data); if (data.mBestMatch) { aMatchedFamily = FontFamily(fallback); - return data.mBestMatch->FindOrMakeFont(aMatchStyle); + return data.mBestMatch; } } } return nullptr; } -gfxFont* gfxPlatformFontList::GlobalFontFallback( - uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation, const gfxFontStyle* aMatchStyle, +gfxFontEntry* gfxPlatformFontList::GlobalFontFallback( + const uint32_t aCh, Script aRunScript, const gfxFontStyle* aMatchStyle, uint32_t& aCmapCount, FontFamily& aMatchedFamily, FontMatchingStats* aFontMatchingStats) { bool useCmaps = IsFontFamilyWhitelistActive() || @@ -1033,30 +1012,12 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback( if (fe) { if (aMatchedFamily.mIsShared) { if (IsVisibleToCSS(*aMatchedFamily.mShared)) { - gfxFont* font = fe->FindOrMakeFont(aMatchStyle); - if (font) { - if (aPresentation == eFontPresentation::Any) { - return font; - } - bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh); - if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) { - return font; - } - } + return fe; } rejectedFallbackVisibility = aMatchedFamily.mShared->Visibility(); } else { if (IsVisibleToCSS(*aMatchedFamily.mUnshared)) { - gfxFont* font = fe->FindOrMakeFont(aMatchStyle); - if (font) { - if (aPresentation == eFontPresentation::Any) { - return font; - } - bool hasColorGlyph = font->HasColorGlyphFor(aCh, aNextCh); - if (hasColorGlyph == (aPresentation == eFontPresentation::Emoji)) { - return font; - } - } + return fe; } rejectedFallbackVisibility = aMatchedFamily.mUnshared->Visibility(); } @@ -1064,7 +1025,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback( } // otherwise, try to find it among local fonts - GlobalFontMatch data(aCh, aNextCh, *aMatchStyle, aPresentation); + GlobalFontMatch data(aCh, *aMatchStyle); if (SharedFontList()) { fontlist::Family* families = SharedFontList()->Families(); if (families) { @@ -1081,7 +1042,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback( } if (data.mBestMatch) { aMatchedFamily = FontFamily(data.mMatchedSharedFamily); - return data.mBestMatch->FindOrMakeFont(aMatchStyle); + return data.mBestMatch; } } } else { @@ -1103,7 +1064,7 @@ gfxFont* gfxPlatformFontList::GlobalFontFallback( aCmapCount = data.mCmapsTested; if (data.mBestMatch) { aMatchedFamily = FontFamily(data.mMatchedFamily); - return data.mBestMatch->FindOrMakeFont(aMatchStyle); + return data.mBestMatch; } } diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 91f6325fab97..9dbcb634eba0 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -209,12 +209,11 @@ class gfxPlatformFontList : public gfxFontInfoLoader { void GetFontFamilyList(nsTArray>& aFamilyArray); - gfxFont* SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh, - Script aRunScript, - eFontPresentation aPresentation, - const gfxFontStyle* aStyle, - FontVisibility* aVisibility, - FontMatchingStats* aFontMatchingStats); + gfxFontEntry* SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh, + Script aRunScript, + const gfxFontStyle* aStyle, + FontVisibility* aVisibility, + FontMatchingStats* aFontMatchingStats); // Flags to control optional behaviors in FindAndAddFamilies. The sense // of the bit flags have been chosen such that the default parameter of @@ -623,17 +622,17 @@ class gfxPlatformFontList : public gfxFontInfoLoader { } // returns default font for a given character, null otherwise - gfxFont* CommonFontFallback(uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation, - const gfxFontStyle* aMatchStyle, - FontFamily& aMatchedFamily); + gfxFontEntry* CommonFontFallback(uint32_t aCh, uint32_t aNextCh, + Script aRunScript, + const gfxFontStyle* aMatchStyle, + FontFamily& aMatchedFamily); // Search fonts system-wide for a given character, null if not found. - gfxFont* GlobalFontFallback(uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation, - const gfxFontStyle* aMatchStyle, - uint32_t& aCmapCount, FontFamily& aMatchedFamily, - FontMatchingStats* aFontMatchingStats); + gfxFontEntry* GlobalFontFallback(const uint32_t aCh, Script aRunScript, + const gfxFontStyle* aMatchStyle, + uint32_t& aCmapCount, + FontFamily& aMatchedFamily, + FontMatchingStats* aFontMatchingStats); // Platform-specific implementation of global font fallback, if any; // this may return nullptr in which case the default cmap-based fallback diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 52b3da627499..c4eea496f7af 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -206,10 +206,10 @@ static const char kFontWenQuanYiMicroHei[] = "WenQuanYi Micro Hei"; static const char kFontNanumGothic[] = "NanumGothic"; static const char kFontSymbola[] = "Symbola"; -void gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, +void gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, + Script aRunScript, nsTArray& aFontList) { - if (aPresentation == eFontPresentation::Emoji) { + if (ShouldPreferEmojiFont(aCh, aNextCh)) { aFontList.AppendElement(kFontTwemojiMozilla); } diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h index ae46695b4116..c2036d1b00a0 100644 --- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -42,8 +42,7 @@ class gfxPlatformGtk final : public gfxPlatform { nsresult UpdateFontList() override; - void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, + void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) override; gfxPlatformFontList* CreatePlatformFontList() override; diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 0f1d77a94234..687690bb558f 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -171,10 +171,10 @@ static const char kFontSTIXGeneral[] = "STIXGeneral"; static const char kFontTamilMN[] = "Tamil MN"; static const char kFontZapfDingbats[] = "Zapf Dingbats"; -void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, +void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, + Script aRunScript, nsTArray& aFontList) { - if (aPresentation == eFontPresentation::Emoji) { + if (ShouldPreferEmojiFont(aCh, aNextCh)) { aFontList.AppendElement(kFontAppleColorEmoji); } diff --git a/gfx/thebes/gfxPlatformMac.h b/gfx/thebes/gfxPlatformMac.h index f11608c03c35..3ea53b7b51b0 100644 --- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -39,8 +39,7 @@ class gfxPlatformMac : public gfxPlatform { bool IsFontFormatSupported(uint32_t aFormatFlags) override; - void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, + void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) override; // lookup the system font for a particular system font type and set diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 9ffa7be05b96..9966c71a1f6a 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -2909,10 +2909,9 @@ gfxTextRun* gfxFontGroup::GetEllipsisTextRun( return mCachedEllipsisTextRun.get(); } -gfxFont* gfxFontGroup::FindFallbackFaceForChar( - gfxFontFamily* aFamily, uint32_t aCh, uint32_t aNextCh, - eFontPresentation aPresentation) { - GlobalFontMatch data(aCh, aNextCh, mStyle, aPresentation); +gfxFont* gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, + uint32_t aCh) { + GlobalFontMatch data(aCh, mStyle); aFamily->SearchAllFontsForChar(&data); gfxFontEntry* fe = data.mBestMatch; if (!fe) { @@ -2921,12 +2920,11 @@ gfxFont* gfxFontGroup::FindFallbackFaceForChar( return fe->FindOrMakeFont(&mStyle); } -gfxFont* gfxFontGroup::FindFallbackFaceForChar( - fontlist::Family* aFamily, uint32_t aCh, uint32_t aNextCh, - eFontPresentation aPresentation) { +gfxFont* gfxFontGroup::FindFallbackFaceForChar(fontlist::Family* aFamily, + uint32_t aCh) { fontlist::FontList* list = gfxPlatformFontList::PlatformFontList()->SharedFontList(); - GlobalFontMatch data(aCh, aNextCh, mStyle, aPresentation); + GlobalFontMatch data(aCh, mStyle); aFamily->SearchAllFontsForChar(list, &data); gfxFontEntry* fe = data.mBestMatch; if (!fe) { @@ -2935,15 +2933,12 @@ gfxFont* gfxFontGroup::FindFallbackFaceForChar( return fe->FindOrMakeFont(&mStyle); } -gfxFont* gfxFontGroup::FindFallbackFaceForChar( - const FamilyFace& aFamily, uint32_t aCh, uint32_t aNextCh, - eFontPresentation aPresentation) { +gfxFont* gfxFontGroup::FindFallbackFaceForChar(const FamilyFace& aFamily, + uint32_t aCh) { if (aFamily.IsSharedFamily()) { - return FindFallbackFaceForChar(aFamily.SharedFamily(), aCh, aNextCh, - aPresentation); + return FindFallbackFaceForChar(aFamily.SharedFamily(), aCh); } - return FindFallbackFaceForChar(aFamily.OwnedFamily(), aCh, aNextCh, - aPresentation); + return FindFallbackFaceForChar(aFamily.OwnedFamily(), aCh); } gfxFloat gfxFontGroup::GetUnderlineOffset() { @@ -3035,41 +3030,12 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, bool isJoinControl = gfxFontUtils::IsJoinControl(aCh); bool wasJoinCauser = gfxFontUtils::IsJoinCauser(aPrevCh); bool isVarSelector = gfxFontUtils::IsVarSelector(aCh); - bool nextIsVarSelector = gfxFontUtils::IsVarSelector(aNextCh); // Whether we've seen a font that is currently loading a resource that may // provide this character (so we should not start a new load). bool loading = false; - // Do we need to explicitly look for a font that does or does not provide a - // color glyph for the given character? - // For characters with no `EMOJI` property, we'll use whatever the family - // list calls for; but if it's a potential emoji codepoint, we need to check - // if there's a variation selector specifically asking for Text-style or - // Emoji-style rendering and look for a suitable font. - eFontPresentation presentation = eFontPresentation::Any; - EmojiPresentation emojiPresentation = GetEmojiPresentation(aCh); - if (emojiPresentation != TextOnly) { - // If the prefer-emoji selector is present, or if it's a default-emoji char - // and the prefer-text selector is NOT present, or if there's a skin-tone - // modifier, we specifically look for a font with a color glyph. - // If the prefer-text selector is present, we specifically look for a font - // that will provide a monochrome glyph. - // Otherwise, we'll accept either color or monochrome font-family entries, - // so that a color font can be explicitly applied via font-family even to - // characters that are not inherently emoji-style. - if (aNextCh == kVariationSelector16 || - (emojiPresentation == EmojiPresentation::EmojiDefault && - aNextCh != kVariationSelector15) || - (aNextCh >= kEmojiSkinToneFirst && aNextCh <= kEmojiSkinToneLast)) { - presentation = eFontPresentation::Emoji; - } else if (aNextCh == kVariationSelector15) { - presentation = eFontPresentation::Text; - } - } - - if (!isJoinControl && !wasJoinCauser && !isVarSelector && - !nextIsVarSelector && presentation == eFontPresentation::Any) { + if (!isJoinControl && !wasJoinCauser && !isVarSelector) { gfxFont* firstFont = GetFontAt(0, aCh, &loading); if (firstFont) { if (firstFont->HasCharacter(aCh)) { @@ -3079,13 +3045,13 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, gfxFont* font = nullptr; if (mFonts[0].CheckForFallbackFaces()) { - font = FindFallbackFaceForChar(mFonts[0], aCh, aNextCh, presentation); + font = FindFallbackFaceForChar(mFonts[0], aCh); } else if (!firstFont->GetFontEntry()->IsUserFont()) { // For platform fonts (but not userfonts), we may need to do // fallback within the family to handle cases where some faces // such as Italic or Black have reduced character sets compared // to the family's Regular face. - font = FindFallbackFaceForChar(mFonts[0], aCh, aNextCh, presentation); + font = FindFallbackFaceForChar(mFonts[0], aCh); } if (font) { *aMatchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()}; @@ -3127,36 +3093,6 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, return aPrevMatchedFont; } - // Used to remember the first "candidate" font that would provide a fallback - // text-style rendering if no color glyph can be found. - gfxFont* candidateFont = nullptr; - FontMatchType candidateMatchType; - - // Handle a candidate font that could support the character, returning true - // if we should go ahead and return |f|, false to continue searching. - auto CheckCandidate = [&](gfxFont* f, FontMatchType t) -> bool { - // If no preference, then just accept the font. - if (presentation == eFontPresentation::Any) { - RefPtr autoRefDeref(candidateFont); - *aMatchType = t; - return true; - } - // Does the candidate font provide a color glyph for the current character? - bool hasColorGlyph = f->HasColorGlyphFor(aCh, aNextCh); - // If the provided glyph matches the preference, accept the font. - if (hasColorGlyph == (presentation == eFontPresentation::Emoji)) { - RefPtr autoRefDeref(candidateFont); - *aMatchType = t; - return true; - } - // Otherwise, remember the first potential fallback, but keep searching. - if (!candidateFont) { - candidateFont = f; - candidateMatchType = t; - } - return false; - }; - // 1. check remaining fonts in the font group for (uint32_t i = nextIndex; i < fontListLength; i++) { FamilyFace& ff = mFonts[i]; @@ -3171,10 +3107,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, if (font) { // if available, use already-made gfxFont and check for character if (font->HasCharacter(aCh)) { - if (CheckCandidate(font, - {FontMatchType::Kind::kFontGroup, ff.Generic()})) { - return font; - } + *aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()}; + return font; } } else { // don't have a gfxFont yet, test charmap before instantiating @@ -3205,10 +3139,9 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, if (pfe && pfe->HasCharacter(aCh)) { font = GetFontAt(i, aCh, &loading); if (font) { - if (CheckCandidate(font, {FontMatchType::Kind::kFontGroup, - mFonts[i].Generic()})) { - return font; - } + *aMatchType = {FontMatchType::Kind::kFontGroup, + mFonts[i].Generic()}; + return font; } } } else if (fe && fe->HasCharacter(aCh)) { @@ -3216,10 +3149,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, // build the font via GetFontAt font = GetFontAt(i, aCh, &loading); if (font) { - if (CheckCandidate(font, {FontMatchType::Kind::kFontGroup, - mFonts[i].Generic()})) { - return font; - } + *aMatchType = {FontMatchType::Kind::kFontGroup, mFonts[i].Generic()}; + return font; } } } @@ -3240,12 +3171,10 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, "should only do fallback once per font family"); } #endif - font = FindFallbackFaceForChar(ff, aCh, aNextCh, presentation); + font = FindFallbackFaceForChar(ff, aCh); if (font) { - if (CheckCandidate(font, - {FontMatchType::Kind::kFontGroup, ff.Generic()})) { - return font; - } + *aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()}; + return font; } } else { // For platform fonts, but not user fonts, consider intra-family @@ -3253,12 +3182,10 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, // also above). gfxFontEntry* fe = ff.FontEntry(); if (fe && !fe->mIsUserFontContainer && !fe->IsUserFont()) { - font = FindFallbackFaceForChar(ff, aCh, aNextCh, presentation); + font = FindFallbackFaceForChar(ff, aCh); if (font) { - if (CheckCandidate(font, - {FontMatchType::Kind::kFontGroup, ff.Generic()})) { - return font; - } + *aMatchType = {FontMatchType::Kind::kFontGroup, ff.Generic()}; + return font; } } } @@ -3267,9 +3194,8 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, if (fontListLength == 0) { gfxFont* defaultFont = GetDefaultFont(); if (defaultFont->HasCharacter(aCh)) { - if (CheckCandidate(defaultFont, FontMatchType::Kind::kFontGroup)) { - return defaultFont; - } + *aMatchType = FontMatchType::Kind::kFontGroup; + return defaultFont; } } @@ -3282,56 +3208,34 @@ gfxFont* gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, // fallback has already noted a failure. if (gfxPlatformFontList::PlatformFontList()->SkipFontFallbackForChar(aCh) || GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) { - if (candidateFont) { - *aMatchType = candidateMatchType; - } - return candidateFont; + return nullptr; } // 2. search pref fonts - gfxFont* font = WhichPrefFontSupportsChar(aCh, aNextCh, presentation); + gfxFont* font = WhichPrefFontSupportsChar(aCh, aNextCh); if (font) { - if (CheckCandidate(font, FontMatchType::Kind::kPrefsFallback)) { - return font; - } - } - - // For fallback searches, we don't want to use a color-emoji font unless - // emoji-style presentation is specifically required, so we map Any to - // Text here. - if (presentation == eFontPresentation::Any) { - presentation = eFontPresentation::Text; + *aMatchType = FontMatchType::Kind::kPrefsFallback; + return font; } // 3. use fallback fonts // -- before searching for something else check the font used for the // previous character if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) { - if (CheckCandidate(aPrevMatchedFont, - FontMatchType::Kind::kSystemFallback)) { - return aPrevMatchedFont; - } + *aMatchType = FontMatchType::Kind::kSystemFallback; + return aPrevMatchedFont; } // for known "space" characters, don't do a full system-fallback search; // we'll synthesize appropriate-width spaces instead of missing-glyph boxes if (GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR && GetFirstValidFont()->SynthesizeSpaceWidth(aCh) >= 0.0) { - RefPtr autoRefDeref(candidateFont); return nullptr; } // -- otherwise look for other stuff - font = WhichSystemFontSupportsChar(aCh, aNextCh, aRunScript, presentation); - if (font) { - if (CheckCandidate(font, FontMatchType::Kind::kSystemFallback)) { - return font; - } - } - if (candidateFont) { - *aMatchType = candidateMatchType; - } - return candidateFont; + *aMatchType = FontMatchType::Kind::kSystemFallback; + return WhichSystemFontSupportsChar(aCh, aNextCh, aRunScript); } template @@ -3403,8 +3307,7 @@ void gfxFontGroup::ComputeRanges(nsTArray& aRanges, const T* aString, (!IsClusterExtender(ch) && ch != NARROW_NO_BREAK_SPACE && !gfxFontUtils::IsJoinControl(ch) && !gfxFontUtils::IsJoinCauser(prevCh) && - !gfxFontUtils::IsVarSelector(ch) && - GetEmojiPresentation(ch) == TextOnly))) { + !gfxFontUtils::IsVarSelector(ch)))) { matchType = {FontMatchType::Kind::kFontGroup, mFonts[0].Generic()}; } else { font = @@ -3590,12 +3493,12 @@ bool gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont) { return false; } -gfxFont* gfxFontGroup::WhichPrefFontSupportsChar( - uint32_t aCh, uint32_t aNextCh, eFontPresentation aPresentation) { +gfxFont* gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh, + uint32_t aNextCh) { eFontPrefLang charLang; gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList(); - if (aPresentation == eFontPresentation::Emoji) { + if (ShouldPreferEmojiFont(aCh, aNextCh)) { charLang = eFontPrefLang_Emoji; } else { // get the pref font list if it hasn't been set up already @@ -3671,10 +3574,8 @@ gfxFont* gfxFontGroup::WhichPrefFontSupportsChar( // alternative face in the same family. if (!prefFont) { prefFont = family.mIsShared - ? FindFallbackFaceForChar(family.mShared, aCh, aNextCh, - aPresentation) - : FindFallbackFaceForChar(family.mUnshared, aCh, aNextCh, - aPresentation); + ? FindFallbackFaceForChar(family.mShared, aCh) + : FindFallbackFaceForChar(family.mUnshared, aCh); } if (prefFont) { mLastPrefFamily = family; @@ -3692,15 +3593,14 @@ gfxFont* gfxFontGroup::WhichPrefFontSupportsChar( return nullptr; } -gfxFont* gfxFontGroup::WhichSystemFontSupportsChar( - uint32_t aCh, uint32_t aNextCh, Script aRunScript, - eFontPresentation aPresentation) { +gfxFont* gfxFontGroup::WhichSystemFontSupportsChar(uint32_t aCh, + uint32_t aNextCh, + Script aRunScript) { FontVisibility visibility; - gfxFont* font = + gfxFontEntry* fe = gfxPlatformFontList::PlatformFontList()->SystemFindFontForChar( - aCh, aNextCh, aRunScript, aPresentation, &mStyle, &visibility, - mFontMatchingStats); - if (font) { + aCh, aNextCh, aRunScript, &mStyle, &visibility, mFontMatchingStats); + if (fe) { if (mFontMatchingStats) { switch (visibility) { case FontVisibility::Unknown: @@ -3728,7 +3628,7 @@ gfxFont* gfxFontGroup::WhichSystemFontSupportsChar( break; } } - return font; + return fe->FindOrMakeFont(&mStyle); } return nullptr; diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h index c8c702a01c0c..1b9e36e79547 100644 --- a/gfx/thebes/gfxTextRun.h +++ b/gfx/thebes/gfxTextRun.h @@ -1113,12 +1113,10 @@ class gfxFontGroup final : public gfxTextRunFactory { // search through pref fonts for a character, return nullptr if no matching // pref font - gfxFont* WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh, - eFontPresentation aPresentation); + gfxFont* WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh); gfxFont* WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh, - Script aRunScript, - eFontPresentation aPresentation); + Script aRunScript); template void ComputeRanges(nsTArray& aRanges, const T* aString, @@ -1470,17 +1468,12 @@ class gfxFontGroup final : public gfxTextRunFactory { // Helper for font-matching: // search all faces in a family for a fallback in cases where it's unclear // whether the family might have a font for a given character - gfxFont* FindFallbackFaceForChar(const FamilyFace& aFamily, uint32_t aCh, - uint32_t aNextCh, - eFontPresentation aPresentation); + gfxFont* FindFallbackFaceForChar(const FamilyFace& aFamily, uint32_t aCh); gfxFont* FindFallbackFaceForChar(mozilla::fontlist::Family* aFamily, - uint32_t aCh, uint32_t aNextCh, - eFontPresentation aPresentation); + uint32_t aCh); - gfxFont* FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh, - uint32_t aNextCh, - eFontPresentation aPresentation); + gfxFont* FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh); // helper methods for looking up fonts diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 018ae2d23089..389d77d2f070 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -663,9 +663,9 @@ static const char kFontUtsaah[] = "Utsaah"; static const char kFontYuGothic[] = "Yu Gothic"; void gfxWindowsPlatform::GetCommonFallbackFonts( - uint32_t aCh, Script aRunScript, eFontPresentation aPresentation, + uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) { - if (aPresentation == eFontPresentation::Emoji) { + if (ShouldPreferEmojiFont(aCh, aNextCh)) { aFontList.AppendElement(kFontSegoeUIEmoji); aFontList.AppendElement(kFontTwemojiMozilla); } diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 09e55a86b775..d6be686cc76f 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -148,8 +148,7 @@ class gfxWindowsPlatform final : public gfxPlatform { */ void VerifyD2DDevice(bool aAttemptForce); - void GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, - eFontPresentation aPresentation, + void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray& aFontList) override; bool CanUseHardwareVideoDecoding() override; diff --git a/intl/unicharutil/util/nsUnicodeProperties.h b/intl/unicharutil/util/nsUnicodeProperties.h index 11566cbffc97..a021c1ce568e 100644 --- a/intl/unicharutil/util/nsUnicodeProperties.h +++ b/intl/unicharutil/util/nsUnicodeProperties.h @@ -182,6 +182,19 @@ inline EmojiPresentation GetEmojiPresentation(uint32_t aCh) { return TextDefault; } +inline bool ShouldPreferEmojiFont(uint32_t aCh, uint32_t aNextCh) { + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if (emoji != EmojiPresentation::TextOnly) { + if (aNextCh == kVariationSelector16 || + (aNextCh != kVariationSelector15 && + emoji == EmojiPresentation::EmojiDefault) || + (aNextCh >= kEmojiSkinToneFirst && aNextCh <= kEmojiSkinToneLast)) { + return true; + } + } + return false; +} + // returns the simplified Gen Category as defined in nsUGenCategory inline nsUGenCategory GetGenCategory(uint32_t aCh) { return sDetailedToGeneralCategory[GetGeneralCategory(aCh)]; diff --git a/layout/reftests/font-matching/emoji-fallback-2-ref.html b/layout/reftests/font-matching/emoji-fallback-2-ref.html index 2260bc54facf..2922dd28cc4c 100644 --- a/layout/reftests/font-matching/emoji-fallback-2-ref.html +++ b/layout/reftests/font-matching/emoji-fallback-2-ref.html @@ -12,7 +12,7 @@ -
⌚︎⌛︎🌀︎🌁︎
+
⌚⌛🌀🌁
diff --git a/layout/reftests/font-matching/emoji-fallback-2.html b/layout/reftests/font-matching/emoji-fallback-2.html index e3543d2fe526..d136ff7d67af 100644 --- a/layout/reftests/font-matching/emoji-fallback-2.html +++ b/layout/reftests/font-matching/emoji-fallback-2.html @@ -5,10 +5,6 @@ emoji fallback to text font diff --git a/layout/reftests/font-matching/emoji-fallback-3-ref.html b/layout/reftests/font-matching/emoji-fallback-3-ref.html index c885500c1306..f14c9099fb14 100644 --- a/layout/reftests/font-matching/emoji-fallback-3-ref.html +++ b/layout/reftests/font-matching/emoji-fallback-3-ref.html @@ -5,7 +5,7 @@ emoji fallback to color font diff --git a/layout/reftests/font-matching/emoji-fallback-3.html b/layout/reftests/font-matching/emoji-fallback-3.html index 78b2d8b86c65..57046b555641 100644 --- a/layout/reftests/font-matching/emoji-fallback-3.html +++ b/layout/reftests/font-matching/emoji-fallback-3.html @@ -5,10 +5,6 @@ emoji fallback to color font diff --git a/layout/reftests/text/1320665-cmap-format-13.html b/layout/reftests/text/1320665-cmap-format-13.html index d8992a236cb5..7ffc472b5330 100644 --- a/layout/reftests/text/1320665-cmap-format-13.html +++ b/layout/reftests/text/1320665-cmap-format-13.html @@ -19,4 +19,4 @@ span { -P (fail) Aሴ顶ꯍS𐐀🌳︎S +P (fail) Aሴ顶ꯍS𐐀🌳S diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 8a4844123bef..958251b0baad 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -187,7 +187,7 @@ random-if(!winWidget) == arial-bold-lam-alef-1.html arial-bold-lam-alef-1-ref.ht fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9 == 1331339-script-extensions-shaping-1.html 1331339-script-extensions-shaping-1-ref.html skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics -fuzzy-if(Android,0-128,0-233) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html +fuzzy-if(Android,0-128,0-233) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html # Win10: regional indicators not supported by system emoji font fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android == 1507661-spurious-hyphenation-after-explicit.html 1507661-spurious-hyphenation-after-explicit-ref.html fuzzy-if(!webrender,12-66,288-1681) fails-if(gtkWidget&&!webrender) == 1522857-1.html 1522857-1-ref.html # antialiasing fuzz in non-webrender cases diff --git a/layout/reftests/xul/text-crop-ref.xhtml b/layout/reftests/xul/text-crop-ref.xhtml index 2ff7341a9fbe..20ac65f53c5d 100644 --- a/layout/reftests/xul/text-crop-ref.xhtml +++ b/layout/reftests/xul/text-crop-ref.xhtml @@ -21,9 +21,7 @@