From b8b20f1afe981bc4b13453eb77f4769dce124a29 Mon Sep 17 00:00:00 2001 From: Andrew Osmond Date: Wed, 14 Dec 2022 17:50:54 +0000 Subject: [PATCH] Bug 1798591. r=jfkthame Differential Revision: https://phabricator.services.mozilla.com/D163295 --- gfx/thebes/gfxDWriteFontList.cpp | 2 +- gfx/thebes/gfxFontEntry.h | 35 ++- gfx/thebes/gfxPlatformFontList.cpp | 60 +++--- gfx/thebes/gfxPlatformFontList.h | 6 + gfx/thebes/gfxTextRun.cpp | 12 +- gfx/thebes/gfxUserFontSet.cpp | 205 ++++++++---------- gfx/thebes/gfxUserFontSet.h | 129 ++++++----- layout/style/FontFaceImpl.cpp | 145 ++++++------- layout/style/FontFaceImpl.h | 32 +-- layout/style/FontFaceSetDocumentImpl.cpp | 13 +- layout/style/FontFaceSetImpl.cpp | 259 +++++++++-------------- layout/style/FontFaceSetImpl.h | 27 +-- layout/style/FontFaceSetWorkerImpl.cpp | 6 + layout/style/FontFaceSetWorkerImpl.h | 3 + 14 files changed, 413 insertions(+), 521 deletions(-) diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 410ede63c896..a7417cc28aee 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -2212,7 +2212,7 @@ gfxFontEntry* gfxDWriteFontList::PlatformGlobalFontFallback( FindFamily(aPresContext, mFallbackRenderer->FallbackFamilyName()); if (!family.IsNull()) { gfxFontEntry* fontEntry = nullptr; - if (family.mIsShared) { + if (family.mShared) { auto face = family.mShared->FindFaceForStyle(SharedFontList(), *aMatchStyle); if (face) { diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 7c63243f9394..d1a99005171f 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -1106,33 +1106,28 @@ class gfxFontFamily { }; }; -// Wrapper for either a mozilla::fontlist::Family in the shared font list or an -// unshared gfxFontFamily that belongs just to the current process. This does -// not own a reference, it just wraps a raw pointer and records the type. +// Wrapper for either a raw pointer to a mozilla::fontlist::Family in the shared +// font list or a strong pointer to an unshared gfxFontFamily that belongs just +// to the current process. struct FontFamily { - FontFamily() : mUnshared(nullptr), mIsShared(false) {} - + FontFamily() = default; FontFamily(const FontFamily& aOther) = default; - explicit FontFamily(gfxFontFamily* aFamily) - : mUnshared(aFamily), mIsShared(false) {} + explicit FontFamily(RefPtr&& aFamily) + : mUnshared(std::move(aFamily)) {} - explicit FontFamily(mozilla::fontlist::Family* aFamily) - : mShared(aFamily), mIsShared(true) {} + explicit FontFamily(gfxFontFamily* aFamily) : mUnshared(aFamily) {} + + explicit FontFamily(mozilla::fontlist::Family* aFamily) : mShared(aFamily) {} bool operator==(const FontFamily& aOther) const { - return mIsShared == aOther.mIsShared && - (mIsShared ? mShared == aOther.mShared - : mUnshared == aOther.mUnshared); + return mShared == aOther.mShared && mUnshared == aOther.mUnshared; } - bool IsNull() const { return mIsShared ? !mShared : !mUnshared; } + bool IsNull() const { return !mShared && !mUnshared; } - union { - gfxFontFamily* mUnshared; - mozilla::fontlist::Family* mShared; - }; - bool mIsShared; + RefPtr mUnshared; + mozilla::fontlist::Family* mShared = nullptr; }; // Struct used in the gfxFontGroup font list to keep track of a font family @@ -1146,6 +1141,10 @@ struct FamilyAndGeneric final { mozilla::StyleGenericFontFamily aGeneric = mozilla::StyleGenericFontFamily(0)) : mFamily(aFamily), mGeneric(aGeneric) {} + explicit FamilyAndGeneric(RefPtr&& aFamily, + mozilla::StyleGenericFontFamily aGeneric = + mozilla::StyleGenericFontFamily(0)) + : mFamily(std::move(aFamily)), mGeneric(aGeneric) {} explicit FamilyAndGeneric(mozilla::fontlist::Family* aFamily, mozilla::StyleGenericFontFamily aGeneric = mozilla::StyleGenericFontFamily(0)) diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 3e12e4ab6b35..532735c824f6 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -510,17 +510,8 @@ bool gfxPlatformFontList::InitFontList() { // There's no need to broadcast this reflow request to child processes, as // ContentParent::NotifyUpdatedFonts deals with it by re-entering into this // function on child processes. - if (NS_IsMainThread()) { - gfxPlatform::ForceGlobalReflow(gfxPlatform::NeedsReframe::Yes, - gfxPlatform::BroadcastToChildren::No); - } else { - NS_DispatchToMainThread( - NS_NewRunnableFunction("font-info-updated notification callback", [] { - gfxPlatform::ForceGlobalReflow( - gfxPlatform::NeedsReframe::Yes, - gfxPlatform::BroadcastToChildren::No); - })); - } + ForceGlobalReflowLocked(gfxPlatform::NeedsReframe::Yes, + gfxPlatform::BroadcastToChildren::No); mAliasTable.Clear(); mLocalNameTable.Clear(); @@ -610,7 +601,7 @@ bool gfxPlatformFontList::InitFontList() { gfxFontStyle defStyle; FontFamily fam = GetDefaultFontLocked(nullptr, &defStyle); gfxFontEntry* fe; - if (fam.mIsShared) { + if (fam.mShared) { auto face = fam.mShared->FindFaceForStyle(SharedFontList(), defStyle); fe = face ? GetOrCreateFontEntryLocked(face, fam.mShared) : nullptr; } else { @@ -651,7 +642,7 @@ void gfxPlatformFontList::FontListChanged() { // safe to use: ensure they all get flushed. RebuildLocalFonts(/*aForgetLocalFaces*/ true); } - gfxPlatform::ForceGlobalReflow(gfxPlatform::NeedsReframe::Yes); + ForceGlobalReflowLocked(gfxPlatform::NeedsReframe::Yes); } void gfxPlatformFontList::GenerateFontListKey(const nsACString& aKeyName, @@ -886,7 +877,7 @@ void gfxPlatformFontList::UpdateFontList(bool aFullRebuild) { if (mStartedLoadingCmapsFrom != 0xffffffffu) { InitializeCodepointsWithNoFonts(); mStartedLoadingCmapsFrom = 0xffffffffu; - gfxPlatform::ForceGlobalReflow(gfxPlatform::NeedsReframe::No); + ForceGlobalReflowLocked(gfxPlatform::NeedsReframe::No); } } } @@ -967,14 +958,14 @@ already_AddRefed gfxPlatformFontList::SystemFindFontForChar( if (aCh == 0xFFFD) { gfxFontEntry* fontEntry = nullptr; auto& fallbackFamily = mReplacementCharFallbackFamily[level]; - if (fallbackFamily.mIsShared && fallbackFamily.mShared) { + if (fallbackFamily.mShared) { fontlist::Face* face = fallbackFamily.mShared->FindFaceForStyle(SharedFontList(), *aStyle); if (face) { fontEntry = GetOrCreateFontEntryLocked(face, fallbackFamily.mShared); *aVisibility = fallbackFamily.mShared->Visibility(); } - } else if (!fallbackFamily.mIsShared && fallbackFamily.mUnshared) { + } else if (fallbackFamily.mUnshared) { fontEntry = fallbackFamily.mUnshared->FindFontForStyle(*aStyle); *aVisibility = fallbackFamily.mUnshared->Visibility(); } @@ -1041,7 +1032,7 @@ already_AddRefed gfxPlatformFontList::SystemFindFontForChar( if (!font) { mCodepointsWithNoFonts[level].set(aCh); } else { - *aVisibility = fallbackFamily.mIsShared + *aVisibility = fallbackFamily.mShared ? fallbackFamily.mShared->Visibility() : fallbackFamily.mUnshared->Visibility(); if (aCh == 0xFFFD) { @@ -1160,7 +1151,7 @@ already_AddRefed gfxPlatformFontList::GlobalFontFallback( gfxFontEntry* fe = PlatformGlobalFontFallback(aPresContext, aCh, aRunScript, aMatchStyle, aMatchedFamily); if (fe) { - if (aMatchedFamily.mIsShared) { + if (aMatchedFamily.mShared) { if (IsVisibleToCSS(*aMatchedFamily.mShared, level)) { RefPtr font = fe->FindOrMakeFont(aMatchStyle); if (font) { @@ -1640,7 +1631,7 @@ fontlist::Family* gfxPlatformFontList::FindSharedFamily( if (!FindAndAddFamiliesLocked(aPresContext, StyleGenericFontFamily::None, aFamily, &families, aFlags, aStyle, aLanguage, aDevToCss) || - !families[0].mFamily.mIsShared) { + !families[0].mFamily.mShared) { return nullptr; } fontlist::Family* family = families[0].mFamily.mShared; @@ -1750,7 +1741,7 @@ gfxFontEntry* gfxPlatformFontList::FindFontForFamily( if (family.IsNull()) { return nullptr; } - if (family.mIsShared) { + if (family.mShared) { auto face = family.mShared->FindFaceForStyle(SharedFontList(), *aStyle); if (!face) { return nullptr; @@ -1818,12 +1809,11 @@ bool gfxPlatformFontList::GetStandardFamilyName(const nsCString& aFontName, bool gfxPlatformFontList::GetLocalizedFamilyName(const FontFamily& aFamily, nsACString& aFamilyName) { - if (aFamily.mIsShared) { - if (aFamily.mShared) { - aFamilyName = SharedFontList()->LocalizedFamilyName(aFamily.mShared); - return true; - } - } else if (aFamily.mUnshared) { + if (aFamily.mShared) { + aFamilyName = SharedFontList()->LocalizedFamilyName(aFamily.mShared); + return true; + } + if (aFamily.mUnshared) { aFamily.mUnshared->LocalizedName(aFamilyName); return true; } @@ -2599,7 +2589,7 @@ void gfxPlatformFontList::CleanupLoader() { FindFamiliesFlags::eNoAddToNamesMissedWhenSearching)); }); if (forceReflow) { - gfxPlatform::ForceGlobalReflow(gfxPlatform::NeedsReframe::No); + ForceGlobalReflowLocked(gfxPlatform::NeedsReframe::No); } mOtherNamesMissed = nullptr; @@ -2620,6 +2610,22 @@ void gfxPlatformFontList::CleanupLoader() { gfxFontInfoLoader::CleanupLoader(); } +void gfxPlatformFontList::ForceGlobalReflowLocked( + gfxPlatform::NeedsReframe aNeedsReframe, + gfxPlatform::BroadcastToChildren aBroadcastToChildren) { + if (!NS_IsMainThread()) { + NS_DispatchToMainThread(NS_NewRunnableFunction( + "gfxPlatformFontList::ForceGlobalReflowLocked", + [aNeedsReframe, aBroadcastToChildren] { + gfxPlatform::ForceGlobalReflow(aNeedsReframe, aBroadcastToChildren); + })); + return; + } + + AutoUnlock unlock(mLock); + gfxPlatform::ForceGlobalReflow(aNeedsReframe, aBroadcastToChildren); +} + void gfxPlatformFontList::GetPrefsAndStartLoader() { // If we're already in shutdown, there's no point in starting this, and it // could trigger an assertion if we try to use the Thread Manager too late. diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index ff38d314d760..7b2f1fa8a670 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -165,6 +165,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader { typedef mozilla::intl::Script Script; using AutoLock = mozilla::RecursiveMutexAutoLock; + using AutoUnlock = mozilla::RecursiveMutexAutoUnlock; // Class used to hold cached copies of the font-name prefs, so that they can // be accessed from non-main-thread callers who are not allowed to touch the @@ -865,6 +866,11 @@ class gfxPlatformFontList : public gfxFontInfoLoader { bool LoadFontInfo() override; void CleanupLoader() override; + void ForceGlobalReflowLocked( + gfxPlatform::NeedsReframe aNeedsReframe, + gfxPlatform::BroadcastToChildren aBroadcastToChildren = + gfxPlatform::BroadcastToChildren::Yes) MOZ_REQUIRES(mLock); + // read the loader initialization prefs, and start it void GetPrefsAndStartLoader(); diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 46e466417dd3..833c2eb04f60 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -1971,7 +1971,7 @@ void gfxFontGroup::BuildFontList() { // build the fontlist from the specified families for (const auto& f : fonts) { - if (f.mFamily.mIsShared) { + if (f.mFamily.mShared) { AddFamilyToFontList(f.mFamily.mShared, f.mGeneric); } else { AddFamilyToFontList(f.mFamily.mUnshared, f.mGeneric); @@ -1988,9 +1988,9 @@ void gfxFontGroup::AddPlatformFont(const nsACString& aName, bool aQuotedName, if (mUserFontSet) { // Add userfonts to the fontlist whether already loaded // or not. Loading is initiated during font matching. - gfxFontFamily* family = mUserFontSet->LookupFamily(aName); + RefPtr family = mUserFontSet->LookupFamily(aName); if (family) { - aFamilyList.AppendElement(family); + aFamilyList.AppendElement(std::move(family)); return; } } @@ -2166,7 +2166,7 @@ already_AddRefed gfxFontGroup::GetDefaultFont() { "invalid default font returned by GetDefaultFont"); gfxFontEntry* fe = nullptr; - if (family.mIsShared) { + if (family.mShared) { fontlist::Family* fam = family.mShared; if (!fam->IsInitialized()) { // If this fails, FindFaceForStyle will just safely return nullptr @@ -3753,7 +3753,7 @@ already_AddRefed gfxFontGroup::WhichPrefFontSupportsChar( } gfxFontEntry* fe = nullptr; - if (family.mIsShared) { + if (family.mShared) { fontlist::Family* fam = family.mShared; if (!fam->IsInitialized()) { Unused << pfl->InitializeFamily(fam); @@ -3786,7 +3786,7 @@ already_AddRefed gfxFontGroup::WhichPrefFontSupportsChar( // If the char was not available, see if we can fall back to an // alternative face in the same family. if (!prefFont) { - prefFont = family.mIsShared + prefFont = family.mShared ? FindFallbackFaceForChar(family.mShared, aCh, aNextCh, aPresentation) : FindFallbackFaceForChar(family.mUnshared, aCh, aNextCh, diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index f9f12aeb1d6e..df11aace87f1 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -37,64 +37,53 @@ mozilla::LogModule* gfxUserFontSet::GetUserFontsLog() { static Atomic sFontSetGeneration(0); -gfxUserFontEntry::gfxUserFontEntry( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) +gfxUserFontEntry::gfxUserFontEntry(nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) : gfxFontEntry("userfont"_ns), mUserFontLoadState(STATUS_NOT_LOADED), mFontDataLoadingState(NOT_LOADING), mSeenLocalSource(false), mUnsupportedFormat(false), - mFontDisplay(aFontDisplay), + mFontDisplay(aAttr.mFontDisplay), mLoader(nullptr) { mIsUserFontContainer = true; - mSrcList = aFontFaceSrcList.Clone(); + mSrcList = std::move(aFontFaceSrcList); mCurrentSrcIndex = 0; - mWeightRange = aWeight; - mStretchRange = aStretch; - mStyleRange = aStyle; - mFeatureSettings.AppendElements(aFeatureSettings); - mVariationSettings.AppendElements(aVariationSettings); - mLanguageOverride = aLanguageOverride; - SetUnicodeRangeMap(aUnicodeRanges); - mRangeFlags = aRangeFlags; - mAscentOverride = aAscentOverride; - mDescentOverride = aDescentOverride; - mLineGapOverride = aLineGapOverride; - mSizeAdjust = aSizeAdjust; + mWeightRange = aAttr.mWeight; + mStretchRange = aAttr.mStretch; + mStyleRange = aAttr.mStyle; + mFeatureSettings = std::move(aAttr.mFeatureSettings); + mVariationSettings = std::move(aAttr.mVariationSettings); + mLanguageOverride = aAttr.mLanguageOverride; + SetUnicodeRangeMap(std::move(aAttr.mUnicodeRanges)); + mRangeFlags = aAttr.mRangeFlags; + mAscentOverride = aAttr.mAscentOverride; + mDescentOverride = aAttr.mDescentOverride; + mLineGapOverride = aAttr.mLineGapOverride; + mSizeAdjust = aAttr.mSizeAdjust; + mFamilyName = aAttr.mFamilyName; } -void gfxUserFontEntry::UpdateAttributes( - WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) { +void gfxUserFontEntry::UpdateAttributes(gfxUserFontAttributes&& aAttr) { + MOZ_ASSERT(NS_IsMainThread()); + // Remove the entry from the user font cache, if present there, as the cache // key may no longer be correct with the new attributes. gfxUserFontSet::UserFontCache::ForgetFont(this); - mFontDisplay = aFontDisplay; - mWeightRange = aWeight; - mStretchRange = aStretch; - mStyleRange = aStyle; - mFeatureSettings = aFeatureSettings.Clone(); - mVariationSettings = aVariationSettings.Clone(); - mLanguageOverride = aLanguageOverride; - SetUnicodeRangeMap(aUnicodeRanges); - mRangeFlags = aRangeFlags; - mAscentOverride = aAscentOverride; - mDescentOverride = aDescentOverride; - mLineGapOverride = aLineGapOverride; - mSizeAdjust = aSizeAdjust; + mFontDisplay = aAttr.mFontDisplay; + mWeightRange = aAttr.mWeight; + mStretchRange = aAttr.mStretch; + mStyleRange = aAttr.mStyle; + mFeatureSettings = std::move(aAttr.mFeatureSettings); + mVariationSettings = std::move(aAttr.mVariationSettings); + mLanguageOverride = aAttr.mLanguageOverride; + SetUnicodeRangeMap(std::move(aAttr.mUnicodeRanges)); + mRangeFlags = aAttr.mRangeFlags; + mAscentOverride = aAttr.mAscentOverride; + mDescentOverride = aAttr.mDescentOverride; + mLineGapOverride = aAttr.mLineGapOverride; + mSizeAdjust = aAttr.mSizeAdjust; } gfxUserFontEntry::~gfxUserFontEntry() { @@ -104,26 +93,22 @@ gfxUserFontEntry::~gfxUserFontEntry() { MOZ_ASSERT(!gfxFontUtils::IsInServoTraversal()); } -bool gfxUserFontEntry::Matches( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) { - return Weight() == aWeight && Stretch() == aStretch && - SlantStyle() == aStyle && mFeatureSettings == aFeatureSettings && - mVariationSettings == aVariationSettings && - mLanguageOverride == aLanguageOverride && - mSrcList == aFontFaceSrcList && mFontDisplay == aFontDisplay && - mRangeFlags == aRangeFlags && mAscentOverride == aAscentOverride && - mDescentOverride == aDescentOverride && - mLineGapOverride == aLineGapOverride && mSizeAdjust == aSizeAdjust && - ((!aUnicodeRanges && !mCharacterMap) || - (aUnicodeRanges && mCharacterMap && - GetCharacterMap()->Equals(aUnicodeRanges))); +bool gfxUserFontEntry::Matches(const nsTArray& aFontFaceSrcList, + const gfxUserFontAttributes& aAttr) { + return mWeightRange == aAttr.mWeight && mStretchRange == aAttr.mStretch && + mStyleRange == aAttr.mStyle && + mFeatureSettings == aAttr.mFeatureSettings && + mVariationSettings == aAttr.mVariationSettings && + mLanguageOverride == aAttr.mLanguageOverride && + mSrcList == aFontFaceSrcList && mFontDisplay == aAttr.mFontDisplay && + mRangeFlags == aAttr.mRangeFlags && + mAscentOverride == aAttr.mAscentOverride && + mDescentOverride == aAttr.mDescentOverride && + mLineGapOverride == aAttr.mLineGapOverride && + mSizeAdjust == aAttr.mSizeAdjust && + ((!aAttr.mUnicodeRanges && !mCharacterMap) || + (aAttr.mUnicodeRanges && mCharacterMap && + GetCharacterMap()->Equals(aAttr.mUnicodeRanges))); } gfxFont* gfxUserFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle) { @@ -975,15 +960,8 @@ void gfxUserFontSet::Destroy() { } already_AddRefed gfxUserFontSet::FindOrCreateUserFontEntry( - const nsACString& aFamilyName, - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) { + nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) { RefPtr entry; // If there's already a userfont entry in the family whose descriptors all @@ -992,22 +970,13 @@ already_AddRefed gfxUserFontSet::FindOrCreateUserFontEntry( // Note that we can't do this for platform font entries, even if the // style descriptors match, as they might have had a different source list, // but we no longer have the old source list available to check. - gfxUserFontFamily* family = LookupFamily(aFamilyName); + RefPtr family = LookupFamily(aAttr.mFamilyName); if (family) { - entry = FindExistingUserFontEntry( - family, aFontFaceSrcList, aWeight, aStretch, aStyle, aFeatureSettings, - aVariationSettings, aLanguageOverride, aUnicodeRanges, aFontDisplay, - aRangeFlags, aAscentOverride, aDescentOverride, aLineGapOverride, - aSizeAdjust); + entry = FindExistingUserFontEntry(family, aFontFaceSrcList, aAttr); } if (!entry) { - entry = CreateUserFontEntry(aFontFaceSrcList, aWeight, aStretch, aStyle, - aFeatureSettings, aVariationSettings, - aLanguageOverride, aUnicodeRanges, aFontDisplay, - aRangeFlags, aAscentOverride, aDescentOverride, - aLineGapOverride, aSizeAdjust); - entry->mFamilyName = aFamilyName; + entry = CreateUserFontEntry(std::move(aFontFaceSrcList), std::move(aAttr)); } return entry.forget(); @@ -1015,14 +984,8 @@ already_AddRefed gfxUserFontSet::FindOrCreateUserFontEntry( gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry( gfxUserFontFamily* aFamily, - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) { + const nsTArray& aFontFaceSrcList, + const gfxUserFontAttributes& aAttr) { aFamily->ReadLock(); const auto& fontList = aFamily->GetFontList(); gfxUserFontEntry* result = nullptr; @@ -1033,10 +996,7 @@ gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry( } gfxUserFontEntry* ufe = static_cast(font.get()); - if (ufe->Matches(aFontFaceSrcList, aWeight, aStretch, aStyle, - aFeatureSettings, aVariationSettings, aLanguageOverride, - aUnicodeRanges, aFontDisplay, aRangeFlags, aAscentOverride, - aDescentOverride, aLineGapOverride, aSizeAdjust)) { + if (ufe->Matches(aFontFaceSrcList, aAttr)) { result = ufe; break; } @@ -1048,7 +1008,7 @@ gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry( void gfxUserFontSet::AddUserFontEntry(const nsCString& aFamilyName, gfxUserFontEntry* aUserFontEntry) { - gfxUserFontFamily* family = GetFamily(aFamilyName); + RefPtr family = GetFamily(aFamilyName); family->AddFontEntry(aUserFontEntry); if (LOG_ENABLED()) { @@ -1085,44 +1045,49 @@ void gfxUserFontSet::RebuildLocalRules() { } } -gfxUserFontFamily* gfxUserFontSet::LookupFamily( +already_AddRefed gfxUserFontSet::LookupFamily( const nsACString& aFamilyName) const { nsAutoCString key(aFamilyName); ToLowerCase(key); - return mFontFamilies.GetWeak(key); + return mFontFamilies.Get(key); } -gfxUserFontFamily* gfxUserFontSet::GetFamily(const nsACString& aFamilyName) { +already_AddRefed gfxUserFontSet::GetFamily( + const nsACString& aFamilyName) { nsAutoCString key(aFamilyName); ToLowerCase(key); - return mFontFamilies.GetOrInsertNew(key, aFamilyName); + return do_AddRef(mFontFamilies.GetOrInsertNew(key, aFamilyName)); } void gfxUserFontSet::ForgetLocalFaces() { for (const auto& fam : mFontFamilies.Values()) { - fam->ReadLock(); - const auto& fonts = fam->GetFontList(); - for (const auto& f : fonts) { - auto ufe = static_cast(f.get()); - // If the user font entry has loaded an entry using src:local(), - // discard it as no longer valid. - if (ufe->GetPlatformFontEntry() && - ufe->GetPlatformFontEntry()->IsLocalUserFont()) { - ufe->mPlatformFontEntry = nullptr; - } - // We need to re-evaluate the source list in the context of the new - // platform fontlist, whether or not the entry actually used a local() - // source last time, as one might be newly available. - if (ufe->mSeenLocalSource) { - ufe->LoadCanceled(); - } - } - fam->ReadUnlock(); + ForgetLocalFace(fam); } } +void gfxUserFontSet::ForgetLocalFace(gfxUserFontFamily* aFontFamily) { + aFontFamily->ReadLock(); + const auto& fonts = aFontFamily->GetFontList(); + for (const auto& f : fonts) { + auto ufe = static_cast(f.get()); + // If the user font entry has loaded an entry using src:local(), + // discard it as no longer valid. + if (ufe->GetPlatformFontEntry() && + ufe->GetPlatformFontEntry()->IsLocalUserFont()) { + ufe->mPlatformFontEntry = nullptr; + } + // We need to re-evaluate the source list in the context of the new + // platform fontlist, whether or not the entry actually used a local() + // source last time, as one might be newly available. + if (ufe->mSeenLocalSource) { + ufe->LoadCanceled(); + } + } + aFontFamily->ReadUnlock(); +} + /////////////////////////////////////////////////////////////////////////////// // gfxUserFontSet::UserFontCache - re-use platform font entries for user fonts // across pages/fontsets rather than instantiating new platform fonts. diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index 98c1e3b90111..42914d409fc6 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -222,18 +222,48 @@ class gfxUserFontFamily : public gfxFontFamily { class gfxUserFontEntry; class gfxOTSMessageContext; +struct gfxUserFontAttributes { + using FontStretch = mozilla::FontStretch; + using StretchRange = mozilla::StretchRange; + using FontSlantStyle = mozilla::FontSlantStyle; + using SlantStyleRange = mozilla::SlantStyleRange; + using FontWeight = mozilla::FontWeight; + using WeightRange = mozilla::WeightRange; + using StyleFontFaceSourceListComponent = + mozilla::StyleFontFaceSourceListComponent; + using RangeFlags = gfxFontEntry::RangeFlags; + + WeightRange mWeight = WeightRange(FontWeight::NORMAL); + StretchRange mStretch = StretchRange(FontStretch::NORMAL); + SlantStyleRange mStyle = SlantStyleRange(FontSlantStyle::NORMAL); + RangeFlags mRangeFlags = RangeFlags::eAutoWeight | RangeFlags::eAutoStretch | + RangeFlags::eAutoSlantStyle; + mozilla::StyleFontDisplay mFontDisplay = mozilla::StyleFontDisplay::Auto; + float mAscentOverride = -1.0; + float mDescentOverride = -1.0; + float mLineGapOverride = -1.0; + float mSizeAdjust = 1.0; + uint32_t mLanguageOverride = NO_FONT_LANGUAGE_OVERRIDE; + nsTArray mFeatureSettings; + nsTArray mVariationSettings; + RefPtr mUnicodeRanges; + + nsCString mFamilyName; + AutoTArray mSources; +}; + class gfxUserFontSet { friend class gfxUserFontEntry; friend class gfxOTSMessageContext; public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::StretchRange StretchRange; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::SlantStyleRange SlantStyleRange; - typedef mozilla::FontWeight FontWeight; - typedef mozilla::WeightRange WeightRange; - typedef gfxFontEntry::RangeFlags RangeFlags; + using FontStretch = mozilla::FontStretch; + using StretchRange = mozilla::StretchRange; + using FontSlantStyle = mozilla::FontSlantStyle; + using SlantStyleRange = mozilla::SlantStyleRange; + using FontWeight = mozilla::FontWeight; + using WeightRange = mozilla::WeightRange; + using RangeFlags = gfxFontEntry::RangeFlags; NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING @@ -249,40 +279,23 @@ class gfxUserFontSet { // nsLayoutUtils::ParseFontLanguageOverride // TODO: support for unicode ranges not yet implemented virtual already_AddRefed CreateUserFontEntry( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) = 0; + nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) = 0; // creates a font face for the specified family, or returns an existing // matching entry on the family if there is one already_AddRefed FindOrCreateUserFontEntry( - const nsACString& aFamilyName, - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust); + nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr); // add in a font face for which we have the gfxUserFontEntry already void AddUserFontEntry(const nsCString& aFamilyName, gfxUserFontEntry* aUserFontEntry); - // Whether there is a face with this family name - bool HasFamily(const nsACString& aFamilyName) const { - return LookupFamily(aFamilyName) != nullptr; - } - // Look up and return the gfxUserFontFamily in mFontFamilies with // the given name - gfxUserFontFamily* LookupFamily(const nsACString& aName) const; + virtual already_AddRefed LookupFamily( + const nsACString& aName) const; virtual already_AddRefed GetStandardFontLoadPrincipal() const = 0; @@ -315,7 +328,7 @@ class gfxUserFontSet { // be reloaded next time they're needed. This is called when the platform // font list has changed, which means local font entries that were set up // may no longer be valid. - void ForgetLocalFaces(); + virtual void ForgetLocalFaces(); class UserFontCache { public: @@ -510,18 +523,15 @@ class gfxUserFontSet { // helper method for FindOrCreateUserFontEntry gfxUserFontEntry* FindExistingUserFontEntry( gfxUserFontFamily* aFamily, - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust); + const nsTArray& aFontFaceSrcList, + const gfxUserFontAttributes& aAttr); // creates a new gfxUserFontFamily in mFontFamilies, or returns an existing // family if there is one - gfxUserFontFamily* GetFamily(const nsACString& aFamilyName); + virtual already_AddRefed GetFamily( + const nsACString& aFamilyName); + + void ForgetLocalFace(gfxUserFontFamily* aFontFamily); // font families defined by @font-face rules nsRefPtrHashtable mFontFamilies; @@ -558,39 +568,18 @@ class gfxUserFontEntry : public gfxFontEntry { STATUS_FAILED }; - gfxUserFontEntry( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust); + gfxUserFontEntry(nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr); - virtual ~gfxUserFontEntry(); + ~gfxUserFontEntry() override; // Update the attributes of the entry to the given values, without disturbing // the associated platform font entry or in-progress downloads. - void UpdateAttributes( - WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust); + void UpdateAttributes(gfxUserFontAttributes&& aAttr); // Return whether the entry matches the given list of attributes bool Matches(const nsTArray& aFontFaceSrcList, - WeightRange aWeight, StretchRange aStretch, - SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, - float aLineGapOverride, float aSizeAdjust); + const gfxUserFontAttributes& aAttr); gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override; @@ -628,12 +617,14 @@ class gfxUserFontEntry : public gfxFontEntry { } gfxCharacterMap* GetUnicodeRangeMap() const { return GetCharacterMap(); } - void SetUnicodeRangeMap(gfxCharacterMap* aCharMap) { + void SetUnicodeRangeMap(RefPtr&& aCharMap) { auto* oldCmap = GetUnicodeRangeMap(); if (oldCmap != aCharMap) { - if (mCharacterMap.compareExchange(oldCmap, aCharMap)) { + auto* newCmap = aCharMap.forget().take(); + if (mCharacterMap.compareExchange(oldCmap, newCmap)) { NS_IF_RELEASE(oldCmap); - NS_IF_ADDREF(aCharMap); + } else { + NS_IF_RELEASE(newCmap); } } } diff --git a/layout/style/FontFaceImpl.cpp b/layout/style/FontFaceImpl.cpp index 7b9d44bd73a1..b463f9f4b009 100644 --- a/layout/style/FontFaceImpl.cpp +++ b/layout/style/FontFaceImpl.cpp @@ -287,11 +287,16 @@ void FontFaceImpl::DescriptorUpdated() { return; } + gfxUserFontAttributes attr; + RefPtr newEntry; + if (GetAttributes(attr)) { + newEntry = mFontFaceSet->FindOrCreateUserFontEntryFromFontFace( + this, std::move(attr), StyleOrigin::Author); + } + SetUserFontEntry(newEntry); + // Behind the scenes, this will actually update the existing entry and return // it, rather than create a new one. - RefPtr newEntry = - mFontFaceSet->FindOrCreateUserFontEntryFromFontFace(this); - SetUserFontEntry(newEntry); if (mInFontFaceSet) { mFontFaceSet->MarkUserFontSetDirty(); @@ -328,10 +333,14 @@ gfxUserFontEntry* FontFaceImpl::CreateUserFontEntry() { "Rule backed FontFace objects should already have a user font " "entry by the time Load() can be called on them"); - RefPtr newEntry = - mFontFaceSet->FindOrCreateUserFontEntryFromFontFace(this); - if (newEntry) { - SetUserFontEntry(newEntry); + gfxUserFontAttributes attr; + if (GetAttributes(attr)) { + RefPtr newEntry = + mFontFaceSet->FindOrCreateUserFontEntryFromFontFace( + this, std::move(attr), StyleOrigin::Author); + if (newEntry) { + SetUserFontEntry(newEntry); + } } } @@ -553,81 +562,88 @@ void FontFaceImpl::SetUserFontEntry(gfxUserFontEntry* aEntry) { } } -Maybe FontFaceImpl::GetFontWeight() const { - StyleComputedFontWeightRange range; - if (!Servo_FontFaceRule_GetFontWeight(GetData(), &range)) { - return Nothing(); +bool FontFaceImpl::GetAttributes(gfxUserFontAttributes& aAttr) { + RawServoFontFaceRule* data = GetData(); + if (!data) { + return false; } - return Some(range); -} -Maybe FontFaceImpl::GetFontStretch() const { - StyleComputedFontStretchRange range; - if (!Servo_FontFaceRule_GetFontStretch(GetData(), &range)) { - return Nothing(); + nsAtom* fontFamily = Servo_FontFaceRule_GetFamilyName(data); + if (!fontFamily) { + return false; } - return Some(range); -} -Maybe FontFaceImpl::GetFontStyle() const { - auto descriptor = StyleComputedFontStyleDescriptor::Normal(); - if (!Servo_FontFaceRule_GetFontStyle(GetData(), &descriptor)) { - return Nothing(); + aAttr.mFamilyName = nsAtomCString(fontFamily); + + StyleComputedFontWeightRange weightRange; + if (Servo_FontFaceRule_GetFontWeight(data, &weightRange)) { + aAttr.mRangeFlags &= ~gfxFontEntry::RangeFlags::eAutoWeight; + aAttr.mWeight = WeightRange(FontWeight::FromFloat(weightRange._0), + FontWeight::FromFloat(weightRange._1)); } - return Some(descriptor); -} -Maybe FontFaceImpl::GetFontDisplay() const { - StyleFontDisplay display; - if (!Servo_FontFaceRule_GetFontDisplay(GetData(), &display)) { - return Nothing(); + StyleComputedFontStretchRange stretchRange; + if (Servo_FontFaceRule_GetFontStretch(data, &stretchRange)) { + aAttr.mRangeFlags &= ~gfxFontEntry::RangeFlags::eAutoStretch; + aAttr.mStretch = StretchRange(stretchRange._0, stretchRange._1); } - return Some(display); -} -Maybe FontFaceImpl::GetFontLanguageOverride() const { - StyleFontLanguageOverride langOverride; - if (!Servo_FontFaceRule_GetFontLanguageOverride(GetData(), &langOverride)) { - return Nothing(); + auto styleDesc = StyleComputedFontStyleDescriptor::Normal(); + if (Servo_FontFaceRule_GetFontStyle(data, &styleDesc)) { + aAttr.mRangeFlags &= ~gfxFontEntry::RangeFlags::eAutoSlantStyle; + switch (styleDesc.tag) { + case StyleComputedFontStyleDescriptor::Tag::Normal: + aAttr.mStyle = SlantStyleRange(FontSlantStyle::NORMAL); + break; + case StyleComputedFontStyleDescriptor::Tag::Italic: + aAttr.mStyle = SlantStyleRange(FontSlantStyle::ITALIC); + break; + case StyleComputedFontStyleDescriptor::Tag::Oblique: + aAttr.mStyle = SlantStyleRange( + FontSlantStyle::FromFloat(styleDesc.AsOblique()._0), + FontSlantStyle::FromFloat(styleDesc.AsOblique()._1)); + break; + default: + MOZ_ASSERT_UNREACHABLE("Unhandled tag"); + } } - return Some(langOverride); -} -Maybe FontFaceImpl::GetAscentOverride() const { StylePercentage ascent{0}; - if (!Servo_FontFaceRule_GetAscentOverride(GetData(), &ascent)) { - return Nothing(); + if (Servo_FontFaceRule_GetAscentOverride(data, &ascent)) { + aAttr.mAscentOverride = ascent._0; } - return Some(ascent); -} -Maybe FontFaceImpl::GetDescentOverride() const { StylePercentage descent{0}; - if (!Servo_FontFaceRule_GetDescentOverride(GetData(), &descent)) { - return Nothing(); + if (Servo_FontFaceRule_GetDescentOverride(data, &descent)) { + aAttr.mDescentOverride = descent._0; } - return Some(descent); -} -Maybe FontFaceImpl::GetLineGapOverride() const { StylePercentage lineGap{0}; - if (!Servo_FontFaceRule_GetLineGapOverride(GetData(), &lineGap)) { - return Nothing(); + if (Servo_FontFaceRule_GetLineGapOverride(data, &lineGap)) { + aAttr.mLineGapOverride = lineGap._0; } - return Some(lineGap); -} -Maybe FontFaceImpl::GetSizeAdjust() const { StylePercentage sizeAdjust; - if (!Servo_FontFaceRule_GetSizeAdjust(GetData(), &sizeAdjust)) { - return Nothing(); + if (Servo_FontFaceRule_GetSizeAdjust(data, &sizeAdjust)) { + aAttr.mSizeAdjust = sizeAdjust._0; } - return Some(sizeAdjust); + + StyleFontLanguageOverride langOverride; + if (Servo_FontFaceRule_GetFontLanguageOverride(data, &langOverride)) { + aAttr.mLanguageOverride = langOverride._0; + } + + Servo_FontFaceRule_GetFontDisplay(data, &aAttr.mFontDisplay); + Servo_FontFaceRule_GetFeatureSettings(data, &aAttr.mFeatureSettings); + Servo_FontFaceRule_GetVariationSettings(data, &aAttr.mVariationSettings); + Servo_FontFaceRule_GetSources(data, &aAttr.mSources); + aAttr.mUnicodeRanges = GetUnicodeRangeAsCharacterMap(); + return true; } bool FontFaceImpl::HasLocalSrc() const { AutoTArray components; - GetSources(components); + Servo_FontFaceRule_GetSources(GetData(), &components); for (auto& component : components) { if (component.tag == StyleFontFaceSourceListComponent::Tag::Local) { return true; @@ -636,21 +652,6 @@ bool FontFaceImpl::HasLocalSrc() const { return false; } -void FontFaceImpl::GetFontFeatureSettings( - nsTArray& aFeatures) const { - Servo_FontFaceRule_GetFeatureSettings(GetData(), &aFeatures); -} - -void FontFaceImpl::GetFontVariationSettings( - nsTArray& aVariations) const { - Servo_FontFaceRule_GetVariationSettings(GetData(), &aVariations); -} - -void FontFaceImpl::GetSources( - nsTArray& aSources) const { - Servo_FontFaceRule_GetSources(GetData(), &aSources); -} - nsAtom* FontFaceImpl::GetFamilyName() const { return Servo_FontFaceRule_GetFamilyName(GetData()); } diff --git a/layout/style/FontFaceImpl.h b/layout/style/FontFaceImpl.h index eb5bd52395c6..9ef367700ffd 100644 --- a/layout/style/FontFaceImpl.h +++ b/layout/style/FontFaceImpl.h @@ -47,20 +47,9 @@ class FontFaceImpl final { friend class FontFaceImpl; public: - Entry(gfxUserFontSet* aFontSet, - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) - : gfxUserFontEntry(aFontFaceSrcList, aWeight, aStretch, aStyle, - aFeatureSettings, aVariationSettings, - aLanguageOverride, aUnicodeRanges, aFontDisplay, - aRangeFlags, aAscentOverride, aDescentOverride, - aLineGapOverride, aSizeAdjust), + Entry(gfxUserFontSet* aFontSet, nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) + : gfxUserFontEntry(std::move(aFontFaceSrcList), std::move(aAttr)), mMutex("FontFaceImpl::Entry::mMutex"), mFontSet(aFontSet) {} @@ -90,7 +79,7 @@ class FontFaceImpl final { mutable Mutex mMutex; // Font set which owns this entry; - gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet; + gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mMutex); // The FontFace objects that use this user font entry. We need to store // an array of these, not just a single pointer, since the user font @@ -117,19 +106,8 @@ class FontFaceImpl final { RawServoFontFaceRule* GetRule() { return mRule; } bool HasLocalSrc() const; - Maybe GetFontWeight() const; - Maybe GetFontStretch() const; - Maybe GetFontStyle() const; - Maybe GetFontDisplay() const; - void GetFontFeatureSettings(nsTArray&) const; - void GetFontVariationSettings(nsTArray&) const; - void GetSources(nsTArray&) const; - Maybe GetFontLanguageOverride() const; - Maybe GetAscentOverride() const; - Maybe GetDescentOverride() const; - Maybe GetLineGapOverride() const; - Maybe GetSizeAdjust() const; + bool GetAttributes(gfxUserFontAttributes& aAttr); gfxUserFontEntry* CreateUserFontEntry(); gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; } void SetUserFontEntry(gfxUserFontEntry* aEntry); diff --git a/layout/style/FontFaceSetDocumentImpl.cpp b/layout/style/FontFaceSetDocumentImpl.cpp index 3c7f9a9fc126..5328cf179a5e 100644 --- a/layout/style/FontFaceSetDocumentImpl.cpp +++ b/layout/style/FontFaceSetDocumentImpl.cpp @@ -520,8 +520,8 @@ void FontFaceSetDocumentImpl::InsertRuleFontFace( nsTArray& aOldRecords, bool& aFontSetModified) { RecursiveMutexAutoLock lock(mMutex); - nsAtom* fontFamily = aFontFace->GetFamilyName(); - if (!fontFamily) { + gfxUserFontAttributes attr; + if (!aFontFace->GetAttributes(attr)) { // If there is no family name, this rule cannot contribute a // usable font, so there is no point in processing it further. return; @@ -530,8 +530,6 @@ void FontFaceSetDocumentImpl::InsertRuleFontFace( bool remove = false; size_t removeIndex; - nsAtomCString family(fontFamily); - // This is a rule backed FontFace. First, we check in aOldRecords; if // the FontFace for the rule exists there, just move it to the new record // list, and put the entry into the appropriate family. @@ -554,7 +552,7 @@ void FontFaceSetDocumentImpl::InsertRuleFontFace( gfxUserFontEntry* entry = rec.mFontFace->GetUserFontEntry(); MOZ_ASSERT(entry, "FontFace should have a gfxUserFontEntry by now"); - AddUserFontEntry(family, entry); + AddUserFontEntry(attr.mFamilyName, entry); MOZ_ASSERT(!HasRuleFontFace(rec.mFontFace), "FontFace should not occur in mRuleFaces twice"); @@ -576,8 +574,9 @@ void FontFaceSetDocumentImpl::InsertRuleFontFace( } // this is a new rule: - RefPtr entry = - FindOrCreateUserFontEntryFromFontFace(family, aFontFace, aSheetType); + nsAutoCString family(attr.mFamilyName); + RefPtr entry = FindOrCreateUserFontEntryFromFontFace( + aFontFace, std::move(attr), aSheetType); if (!entry) { return; diff --git a/layout/style/FontFaceSetImpl.cpp b/layout/style/FontFaceSetImpl.cpp index af0768751f25..13bdd7306058 100644 --- a/layout/style/FontFaceSetImpl.cpp +++ b/layout/style/FontFaceSetImpl.cpp @@ -10,6 +10,7 @@ #include "gfxFontSrcPrincipal.h" #include "gfxFontSrcURI.h" #include "gfxFontUtils.h" +#include "gfxPlatformFontList.h" #include "mozilla/css/Loader.h" #include "mozilla/dom/CSSFontFaceRule.h" #include "mozilla/dom/DocumentInlines.h" @@ -21,6 +22,7 @@ #include "mozilla/dom/FontFaceSetLoadEventBinding.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/WorkerCommon.h" +#include "mozilla/dom/WorkerRunnable.h" #include "mozilla/FontPropertyTypes.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/BasePrincipal.h" @@ -86,16 +88,25 @@ FontFaceSetImpl::~FontFaceSetImpl() { } void FontFaceSetImpl::Destroy() { - RecursiveMutexAutoLock lock(mMutex); + nsTArray nonRuleFaces; + nsRefPtrHashtable fontFamilies; - for (const auto& key : mLoaders.Keys()) { - key->Cancel(); + { + RecursiveMutexAutoLock lock(mMutex); + for (const auto& key : mLoaders.Keys()) { + key->Cancel(); + } + + mLoaders.Clear(); + nonRuleFaces = std::move(mNonRuleFaces); + fontFamilies = std::move(mFontFamilies); + mOwner = nullptr; } - mLoaders.Clear(); - mNonRuleFaces.Clear(); - gfxUserFontSet::Destroy(); - mOwner = nullptr; + gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList(); + if (fp) { + fp->RemoveUserFontSet(this); + } } void FontFaceSetImpl::ParseFontShorthandForMatching( @@ -303,20 +314,20 @@ void FontFaceSetImpl::RemoveLoader(nsFontFaceLoader* aLoader) { void FontFaceSetImpl::InsertNonRuleFontFace(FontFaceImpl* aFontFace, bool& aFontSetModified) { - nsAtom* fontFamily = aFontFace->GetFamilyName(); - if (!fontFamily) { + gfxUserFontAttributes attr; + if (!aFontFace->GetAttributes(attr)) { // If there is no family name, this rule cannot contribute a // usable font, so there is no point in processing it further. return; } - nsAtomCString family(fontFamily); + nsAutoCString family(attr.mFamilyName); // Just create a new font entry if we haven't got one already. if (!aFontFace->GetUserFontEntry()) { // XXX Should we be checking mLocalRulesUsed like InsertRuleFontFace does? RefPtr entry = FindOrCreateUserFontEntryFromFontFace( - family, aFontFace, StyleOrigin::Author); + aFontFace, std::move(attr), StyleOrigin::Author); if (!entry) { return; } @@ -327,62 +338,49 @@ void FontFaceSetImpl::InsertNonRuleFontFace(FontFaceImpl* aFontFace, AddUserFontEntry(family, aFontFace->GetUserFontEntry()); } -/* static */ -already_AddRefed -FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( - FontFaceImpl* aFontFace) { - nsAtom* fontFamily = aFontFace->GetFamilyName(); - if (!fontFamily) { - // If there is no family name, this rule cannot contribute a - // usable font, so there is no point in processing it further. - return nullptr; - } +void FontFaceSetImpl::UpdateUserFontEntry(gfxUserFontEntry* aEntry, + gfxUserFontAttributes&& aAttr) { + MOZ_ASSERT(NS_IsMainThread()); - return FindOrCreateUserFontEntryFromFontFace(nsAtomCString(fontFamily), - aFontFace, StyleOrigin::Author); + bool resetFamilyName = !aEntry->mFamilyName.IsEmpty() && + aEntry->mFamilyName != aAttr.mFamilyName; + // aFontFace already has a user font entry, so we update its attributes + // rather than creating a new one. + aEntry->UpdateAttributes(std::move(aAttr)); + // If the family name has changed, remove the entry from its current family + // and clear the mFamilyName field so it can be reset when added to a new + // family. + if (resetFamilyName) { + RefPtr family = LookupFamily(aEntry->mFamilyName); + if (family) { + family->RemoveFontEntry(aEntry); + } + aEntry->mFamilyName.Truncate(0); + } } -static WeightRange GetWeightRangeForDescriptor( - const Maybe& aVal, - gfxFontEntry::RangeFlags& aRangeFlags) { - if (!aVal) { - aRangeFlags |= gfxFontEntry::RangeFlags::eAutoWeight; - return WeightRange(FontWeight::NORMAL); - } - return WeightRange(FontWeight::FromFloat(aVal->_0), - FontWeight::FromFloat(aVal->_1)); -} +class FontFaceSetImpl::UpdateUserFontEntryRunnable final + : public WorkerMainThreadRunnable { + public: + UpdateUserFontEntryRunnable(FontFaceSetImpl* aSet, gfxUserFontEntry* aEntry, + gfxUserFontAttributes& aAttr) + : WorkerMainThreadRunnable( + GetCurrentThreadWorkerPrivate(), + "FontFaceSetImpl :: FindOrCreateUserFontEntryFromFontFace"_ns), + mSet(aSet), + mEntry(aEntry), + mAttr(aAttr) {} -static SlantStyleRange GetStyleRangeForDescriptor( - const Maybe& aVal, - gfxFontEntry::RangeFlags& aRangeFlags) { - if (!aVal) { - aRangeFlags |= gfxFontEntry::RangeFlags::eAutoSlantStyle; - return SlantStyleRange(FontSlantStyle::NORMAL); + bool MainThreadRun() override { + mSet->UpdateUserFontEntry(mEntry, std::move(mAttr)); + return true; } - auto& val = *aVal; - switch (val.tag) { - case StyleComputedFontStyleDescriptor::Tag::Normal: - return SlantStyleRange(FontSlantStyle::NORMAL); - case StyleComputedFontStyleDescriptor::Tag::Italic: - return SlantStyleRange(FontSlantStyle::ITALIC); - case StyleComputedFontStyleDescriptor::Tag::Oblique: - return SlantStyleRange(FontSlantStyle::FromFloat(val.AsOblique()._0), - FontSlantStyle::FromFloat(val.AsOblique()._1)); - } - MOZ_ASSERT_UNREACHABLE("How?"); - return SlantStyleRange(FontSlantStyle::NORMAL); -} -static StretchRange GetStretchRangeForDescriptor( - const Maybe& aVal, - gfxFontEntry::RangeFlags& aRangeFlags) { - if (!aVal) { - aRangeFlags |= gfxFontEntry::RangeFlags::eAutoStretch; - return StretchRange(FontStretch::NORMAL); - } - return StretchRange(aVal->_0, aVal->_1); -} + private: + FontFaceSetImpl* mSet; + gfxUserFontEntry* mEntry; + gfxUserFontAttributes& mAttr; +}; // TODO(emilio): Should this take an nsAtom* aFamilyName instead? // @@ -390,87 +388,19 @@ static StretchRange GetStretchRangeForDescriptor( /* static */ already_AddRefed FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( - const nsACString& aFamilyName, FontFaceImpl* aFontFace, + FontFaceImpl* aFontFace, gfxUserFontAttributes&& aAttr, StyleOrigin aOrigin) { FontFaceSetImpl* set = aFontFace->GetPrimaryFontFaceSet(); - uint32_t languageOverride = NO_FONT_LANGUAGE_OVERRIDE; - StyleFontDisplay fontDisplay = StyleFontDisplay::Auto; - float ascentOverride = -1.0; - float descentOverride = -1.0; - float lineGapOverride = -1.0; - float sizeAdjust = 1.0; - - gfxFontEntry::RangeFlags rangeFlags = gfxFontEntry::RangeFlags::eNoFlags; - - // set up weight - WeightRange weight = - GetWeightRangeForDescriptor(aFontFace->GetFontWeight(), rangeFlags); - - // set up stretch - StretchRange stretch = - GetStretchRangeForDescriptor(aFontFace->GetFontStretch(), rangeFlags); - - // set up font style - SlantStyleRange italicStyle = - GetStyleRangeForDescriptor(aFontFace->GetFontStyle(), rangeFlags); - - // set up font display - if (Maybe display = aFontFace->GetFontDisplay()) { - fontDisplay = *display; - } - - // set up font metrics overrides - if (Maybe ascent = aFontFace->GetAscentOverride()) { - ascentOverride = ascent->_0; - } - if (Maybe descent = aFontFace->GetDescentOverride()) { - descentOverride = descent->_0; - } - if (Maybe lineGap = aFontFace->GetLineGapOverride()) { - lineGapOverride = lineGap->_0; - } - - // set up size-adjust scaling factor - if (Maybe percentage = aFontFace->GetSizeAdjust()) { - sizeAdjust = percentage->_0; - } - - // set up font features - nsTArray featureSettings; - aFontFace->GetFontFeatureSettings(featureSettings); - - // set up font variations - nsTArray variationSettings; - aFontFace->GetFontVariationSettings(variationSettings); - - // set up font language override - if (Maybe descriptor = - aFontFace->GetFontLanguageOverride()) { - languageOverride = descriptor->_0; - } - - // set up unicode-range - gfxCharacterMap* unicodeRanges = aFontFace->GetUnicodeRangeAsCharacterMap(); - RefPtr existingEntry = aFontFace->GetUserFontEntry(); if (existingEntry) { - // aFontFace already has a user font entry, so we update its attributes - // rather than creating a new one. - existingEntry->UpdateAttributes( - weight, stretch, italicStyle, featureSettings, variationSettings, - languageOverride, unicodeRanges, fontDisplay, rangeFlags, - ascentOverride, descentOverride, lineGapOverride, sizeAdjust); - // If the family name has changed, remove the entry from its current family - // and clear the mFamilyName field so it can be reset when added to a new - // family. - if (!existingEntry->mFamilyName.IsEmpty() && - existingEntry->mFamilyName != aFamilyName) { - gfxUserFontFamily* family = set->LookupFamily(existingEntry->mFamilyName); - if (family) { - family->RemoveFontEntry(existingEntry); - } - existingEntry->mFamilyName.Truncate(0); + if (NS_IsMainThread()) { + set->UpdateUserFontEntry(existingEntry, std::move(aAttr)); + } else { + auto task = + MakeRefPtr(set, existingEntry, aAttr); + IgnoredErrorResult ignoredRv; + task->Dispatch(Canceling, ignoredRv); } return existingEntry.forget(); } @@ -487,12 +417,10 @@ FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( face->mSourceType = gfxFontFaceSrc::eSourceType_Buffer; face->mBuffer = aFontFace->TakeBufferSource(); } else { - AutoTArray sourceListComponents; - aFontFace->GetSources(sourceListComponents); - size_t len = sourceListComponents.Length(); + size_t len = aAttr.mSources.Length(); for (size_t i = 0; i < len; ++i) { gfxFontFaceSrc* face = srcArray.AppendElement(); - const auto& component = sourceListComponents[i]; + const auto& component = aAttr.mSources[i]; switch (component.tag) { case StyleFontFaceSourceListComponent::Tag::Local: { nsAtom* atom = component.AsLocal(); @@ -528,7 +456,7 @@ FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( if (i + 1 < len) { // Check for a format hint. - const auto& next = sourceListComponents[i + 1]; + const auto& next = aAttr.mSources[i + 1]; switch (next.tag) { case StyleFontFaceSourceListComponent::Tag::FormatHintKeyword: face->mFormatHint = next.format_hint_keyword._0; @@ -596,7 +524,7 @@ FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( if (i + 1 < len) { // Check for a set of font-technologies flags. - const auto& next = sourceListComponents[i + 1]; + const auto& next = aAttr.mSources[i + 1]; if (next.IsTechFlags()) { face->mTechFlags = next.AsTechFlags(); i++; @@ -626,12 +554,7 @@ FontFaceSetImpl::FindOrCreateUserFontEntryFromFontFace( return nullptr; } - RefPtr entry = set->FindOrCreateUserFontEntry( - aFamilyName, srcArray, weight, stretch, italicStyle, featureSettings, - variationSettings, languageOverride, unicodeRanges, fontDisplay, - rangeFlags, ascentOverride, descentOverride, lineGapOverride, sizeAdjust); - - return entry.forget(); + return set->FindOrCreateUserFontEntry(std::move(srcArray), std::move(aAttr)); } nsresult FontFaceSetImpl::LogMessage(gfxUserFontEntry* aUserFontEntry, @@ -967,21 +890,35 @@ void FontFaceSetImpl::RecordFontLoadDone(uint32_t aFontSize, void FontFaceSetImpl::DoRebuildUserFontSet() { MarkUserFontSetDirty(); } already_AddRefed FontFaceSetImpl::CreateUserFontEntry( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) { + nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) { RefPtr entry = new FontFaceImpl::Entry( - this, aFontFaceSrcList, aWeight, aStretch, aStyle, aFeatureSettings, - aVariationSettings, aLanguageOverride, aUnicodeRanges, aFontDisplay, - aRangeFlags, aAscentOverride, aDescentOverride, aLineGapOverride, - aSizeAdjust); + this, std::move(aFontFaceSrcList), std::move(aAttr)); return entry.forget(); } +void FontFaceSetImpl::ForgetLocalFaces() { + // We cannot hold our lock at the same time as the gfxUserFontFamily lock, so + // we need to make a copy of the table first. + nsTArray> fontFamilies; + { + RecursiveMutexAutoLock lock(mMutex); + fontFamilies.SetCapacity(mFontFamilies.Count()); + for (const auto& fam : mFontFamilies.Values()) { + fontFamilies.AppendElement(fam); + } + } + + for (const auto& fam : fontFamilies) { + ForgetLocalFace(fam); + } +} + +already_AddRefed FontFaceSetImpl::GetFamily( + const nsACString& aFamilyName) { + RecursiveMutexAutoLock lock(mMutex); + return gfxUserFontSet::GetFamily(aFamilyName); +} + #undef LOG_ENABLED #undef LOG diff --git a/layout/style/FontFaceSetImpl.h b/layout/style/FontFaceSetImpl.h index 3aa17bd762a6..1bffe9814155 100644 --- a/layout/style/FontFaceSetImpl.h +++ b/layout/style/FontFaceSetImpl.h @@ -51,6 +51,8 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { bool BypassCache() final { return mBypassCache; } + void ForgetLocalFaces() final; + protected: virtual nsresult CreateChannelForSyncLoadFontData( nsIChannel** aOutChannel, gfxUserFontEntry* aFontToLoad, @@ -69,14 +71,11 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { nsresult aStatus = NS_OK) override; void DoRebuildUserFontSet() override; already_AddRefed CreateUserFontEntry( - const nsTArray& aFontFaceSrcList, WeightRange aWeight, - StretchRange aStretch, SlantStyleRange aStyle, - const nsTArray& aFeatureSettings, - const nsTArray& aVariationSettings, - uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, - StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags, - float aAscentOverride, float aDescentOverride, float aLineGapOverride, - float aSizeAdjust) override; + nsTArray&& aFontFaceSrcList, + gfxUserFontAttributes&& aAttr) override; + + already_AddRefed GetFamily( + const nsACString& aFamilyName) final; explicit FontFaceSetImpl(FontFaceSet* aOwner); @@ -111,7 +110,9 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { * font entry for the given FontFace object. */ static already_AddRefed - FindOrCreateUserFontEntryFromFontFace(FontFaceImpl* aFontFace); + FindOrCreateUserFontEntryFromFontFace(FontFaceImpl* aFontFace, + gfxUserFontAttributes&& aAttr, + StyleOrigin); /** * Notification method called by a FontFace to indicate that its loading @@ -207,10 +208,6 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { Maybe mOrigin; // only relevant for mRuleFaces entries }; - static already_AddRefed - FindOrCreateUserFontEntryFromFontFace(const nsACString& aFamilyName, - FontFaceImpl* aFontFace, StyleOrigin); - // search for @font-face rule that matches a userfont font entry virtual RawServoFontFaceRule* FindRuleForUserFontEntry( gfxUserFontEntry* aUserFontEntry) { @@ -221,6 +218,10 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { const nsTHashSet& aMatchingFaces, nsTArray& aFontFaces); + class UpdateUserFontEntryRunnable; + void UpdateUserFontEntry(gfxUserFontEntry* aEntry, + gfxUserFontAttributes&& aAttr); + nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc, gfxFontSrcPrincipal** aPrincipal, bool* aBypassCache); diff --git a/layout/style/FontFaceSetWorkerImpl.cpp b/layout/style/FontFaceSetWorkerImpl.cpp index 29f30408f0da..d09bafc63028 100644 --- a/layout/style/FontFaceSetWorkerImpl.cpp +++ b/layout/style/FontFaceSetWorkerImpl.cpp @@ -262,6 +262,12 @@ void FontFaceSetWorkerImpl::FlushUserFontSet() { } } +already_AddRefed FontFaceSetWorkerImpl::LookupFamily( + const nsACString& aName) const { + RecursiveMutexAutoLock lock(mMutex); + return gfxUserFontSet::LookupFamily(aName); +} + nsresult FontFaceSetWorkerImpl::StartLoad(gfxUserFontEntry* aUserFontEntry, uint32_t aSrcIndex) { RecursiveMutexAutoLock lock(mMutex); diff --git a/layout/style/FontFaceSetWorkerImpl.h b/layout/style/FontFaceSetWorkerImpl.h index 4be9ad86952c..b699f8d52dde 100644 --- a/layout/style/FontFaceSetWorkerImpl.h +++ b/layout/style/FontFaceSetWorkerImpl.h @@ -35,6 +35,9 @@ class FontFaceSetWorkerImpl final : public FontFaceSetImpl { // gfxUserFontSet + already_AddRefed LookupFamily( + const nsACString& aName) const override; + nsresult StartLoad(gfxUserFontEntry* aUserFontEntry, uint32_t aSrcIndex) override;