Differential Revision: https://phabricator.services.mozilla.com/D163295
This commit is contained in:
Andrew Osmond 2022-12-14 17:50:54 +00:00
Родитель 6b4c2ff29f
Коммит b8b20f1afe
14 изменённых файлов: 413 добавлений и 521 удалений

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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<gfxFontFamily>&& 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<gfxFontFamily> 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<gfxFontFamily>&& 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))

Просмотреть файл

@ -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<gfxFont> 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<gfxFont> 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<gfxFont> gfxPlatformFontList::GlobalFontFallback(
gfxFontEntry* fe = PlatformGlobalFontFallback(aPresContext, aCh, aRunScript,
aMatchStyle, aMatchedFamily);
if (fe) {
if (aMatchedFamily.mIsShared) {
if (aMatchedFamily.mShared) {
if (IsVisibleToCSS(*aMatchedFamily.mShared, level)) {
RefPtr<gfxFont> 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.

Просмотреть файл

@ -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();

Просмотреть файл

@ -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<gfxFontFamily> family = mUserFontSet->LookupFamily(aName);
if (family) {
aFamilyList.AppendElement(family);
aFamilyList.AppendElement(std::move(family));
return;
}
}
@ -2166,7 +2166,7 @@ already_AddRefed<gfxFont> 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<gfxFont> 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<gfxFont> 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,

Просмотреть файл

@ -37,64 +37,53 @@ mozilla::LogModule* gfxUserFontSet::GetUserFontsLog() {
static Atomic<uint64_t> sFontSetGeneration(0);
gfxUserFontEntry::gfxUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust)
gfxUserFontEntry::gfxUserFontEntry(nsTArray<gfxFontFaceSrc>&& 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<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& 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<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& 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<gfxFontFaceSrc>& 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<gfxUserFontEntry> gfxUserFontSet::FindOrCreateUserFontEntry(
const nsACString& aFamilyName,
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust) {
nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList,
gfxUserFontAttributes&& aAttr) {
RefPtr<gfxUserFontEntry> entry;
// If there's already a userfont entry in the family whose descriptors all
@ -992,22 +970,13 @@ already_AddRefed<gfxUserFontEntry> 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<gfxUserFontFamily> 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<gfxUserFontEntry> gfxUserFontSet::FindOrCreateUserFontEntry(
gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry(
gfxUserFontFamily* aFamily,
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust) {
const nsTArray<gfxFontFaceSrc>& 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<gfxUserFontEntry*>(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<gfxUserFontFamily> family = GetFamily(aFamilyName);
family->AddFontEntry(aUserFontEntry);
if (LOG_ENABLED()) {
@ -1085,44 +1045,49 @@ void gfxUserFontSet::RebuildLocalRules() {
}
}
gfxUserFontFamily* gfxUserFontSet::LookupFamily(
already_AddRefed<gfxUserFontFamily> 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<gfxUserFontFamily> 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<gfxUserFontEntry*>(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<gfxUserFontEntry*>(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.

Просмотреть файл

@ -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<gfxFontFeature> mFeatureSettings;
nsTArray<gfxFontVariation> mVariationSettings;
RefPtr<gfxCharacterMap> mUnicodeRanges;
nsCString mFamilyName;
AutoTArray<StyleFontFaceSourceListComponent, 8> 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<gfxUserFontEntry> CreateUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust) = 0;
nsTArray<gfxFontFaceSrc>&& 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<gfxUserFontEntry> FindOrCreateUserFontEntry(
const nsACString& aFamilyName,
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust);
nsTArray<gfxFontFaceSrc>&& 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<gfxUserFontFamily> LookupFamily(
const nsACString& aName) const;
virtual already_AddRefed<gfxFontSrcPrincipal> 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<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust);
const nsTArray<gfxFontFaceSrc>& 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<gfxUserFontFamily> GetFamily(
const nsACString& aFamilyName);
void ForgetLocalFace(gfxUserFontFamily* aFontFamily);
// font families defined by @font-face rules
nsRefPtrHashtable<nsCStringHashKey, gfxUserFontFamily> mFontFamilies;
@ -558,39 +568,18 @@ class gfxUserFontEntry : public gfxFontEntry {
STATUS_FAILED
};
gfxUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
mozilla::StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust);
gfxUserFontEntry(nsTArray<gfxFontFaceSrc>&& 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<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& 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<gfxFontFaceSrc>& aFontFaceSrcList,
WeightRange aWeight, StretchRange aStretch,
SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<mozilla::gfx::FontVariation>& 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<gfxCharacterMap>&& 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);
}
}
}

Просмотреть файл

@ -287,11 +287,16 @@ void FontFaceImpl::DescriptorUpdated() {
return;
}
gfxUserFontAttributes attr;
RefPtr<gfxUserFontEntry> 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<gfxUserFontEntry> 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<gfxUserFontEntry> newEntry =
mFontFaceSet->FindOrCreateUserFontEntryFromFontFace(this);
if (newEntry) {
SetUserFontEntry(newEntry);
gfxUserFontAttributes attr;
if (GetAttributes(attr)) {
RefPtr<gfxUserFontEntry> newEntry =
mFontFaceSet->FindOrCreateUserFontEntryFromFontFace(
this, std::move(attr), StyleOrigin::Author);
if (newEntry) {
SetUserFontEntry(newEntry);
}
}
}
@ -553,81 +562,88 @@ void FontFaceImpl::SetUserFontEntry(gfxUserFontEntry* aEntry) {
}
}
Maybe<StyleComputedFontWeightRange> 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<StyleComputedFontStretchRange> 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<StyleComputedFontStyleDescriptor> 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<StyleFontDisplay> 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<StyleFontLanguageOverride> 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<StylePercentage> 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<StylePercentage> 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<StylePercentage> 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<StylePercentage> 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<StyleFontFaceSourceListComponent, 8> 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<gfxFontFeature>& aFeatures) const {
Servo_FontFaceRule_GetFeatureSettings(GetData(), &aFeatures);
}
void FontFaceImpl::GetFontVariationSettings(
nsTArray<gfxFontVariation>& aVariations) const {
Servo_FontFaceRule_GetVariationSettings(GetData(), &aVariations);
}
void FontFaceImpl::GetSources(
nsTArray<StyleFontFaceSourceListComponent>& aSources) const {
Servo_FontFaceRule_GetSources(GetData(), &aSources);
}
nsAtom* FontFaceImpl::GetFamilyName() const {
return Servo_FontFaceRule_GetFamilyName(GetData());
}

Просмотреть файл

@ -47,20 +47,9 @@ class FontFaceImpl final {
friend class FontFaceImpl;
public:
Entry(gfxUserFontSet* aFontSet,
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& 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<gfxFontFaceSrc>&& 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<StyleComputedFontWeightRange> GetFontWeight() const;
Maybe<StyleComputedFontStretchRange> GetFontStretch() const;
Maybe<StyleComputedFontStyleDescriptor> GetFontStyle() const;
Maybe<StyleFontDisplay> GetFontDisplay() const;
void GetFontFeatureSettings(nsTArray<gfxFontFeature>&) const;
void GetFontVariationSettings(nsTArray<gfxFontVariation>&) const;
void GetSources(nsTArray<StyleFontFaceSourceListComponent>&) const;
Maybe<StyleFontLanguageOverride> GetFontLanguageOverride() const;
Maybe<StylePercentage> GetAscentOverride() const;
Maybe<StylePercentage> GetDescentOverride() const;
Maybe<StylePercentage> GetLineGapOverride() const;
Maybe<StylePercentage> GetSizeAdjust() const;
bool GetAttributes(gfxUserFontAttributes& aAttr);
gfxUserFontEntry* CreateUserFontEntry();
gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
void SetUserFontEntry(gfxUserFontEntry* aEntry);

Просмотреть файл

@ -520,8 +520,8 @@ void FontFaceSetDocumentImpl::InsertRuleFontFace(
nsTArray<FontFaceRecord>& 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<gfxUserFontEntry> entry =
FindOrCreateUserFontEntryFromFontFace(family, aFontFace, aSheetType);
nsAutoCString family(attr.mFamilyName);
RefPtr<gfxUserFontEntry> entry = FindOrCreateUserFontEntryFromFontFace(
aFontFace, std::move(attr), aSheetType);
if (!entry) {
return;

Просмотреть файл

@ -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<FontFaceRecord> nonRuleFaces;
nsRefPtrHashtable<nsCStringHashKey, gfxUserFontFamily> 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<gfxUserFontEntry> 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<gfxUserFontEntry>
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<gfxUserFontFamily> family = LookupFamily(aEntry->mFamilyName);
if (family) {
family->RemoveFontEntry(aEntry);
}
aEntry->mFamilyName.Truncate(0);
}
}
static WeightRange GetWeightRangeForDescriptor(
const Maybe<StyleComputedFontWeightRange>& 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<StyleComputedFontStyleDescriptor>& 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<StyleComputedFontStretchRange>& 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<gfxUserFontEntry>
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<StyleFontDisplay> display = aFontFace->GetFontDisplay()) {
fontDisplay = *display;
}
// set up font metrics overrides
if (Maybe<StylePercentage> ascent = aFontFace->GetAscentOverride()) {
ascentOverride = ascent->_0;
}
if (Maybe<StylePercentage> descent = aFontFace->GetDescentOverride()) {
descentOverride = descent->_0;
}
if (Maybe<StylePercentage> lineGap = aFontFace->GetLineGapOverride()) {
lineGapOverride = lineGap->_0;
}
// set up size-adjust scaling factor
if (Maybe<StylePercentage> percentage = aFontFace->GetSizeAdjust()) {
sizeAdjust = percentage->_0;
}
// set up font features
nsTArray<gfxFontFeature> featureSettings;
aFontFace->GetFontFeatureSettings(featureSettings);
// set up font variations
nsTArray<gfxFontVariation> variationSettings;
aFontFace->GetFontVariationSettings(variationSettings);
// set up font language override
if (Maybe<StyleFontLanguageOverride> descriptor =
aFontFace->GetFontLanguageOverride()) {
languageOverride = descriptor->_0;
}
// set up unicode-range
gfxCharacterMap* unicodeRanges = aFontFace->GetUnicodeRangeAsCharacterMap();
RefPtr<gfxUserFontEntry> 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<UpdateUserFontEntryRunnable>(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<StyleFontFaceSourceListComponent, 8> 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<gfxUserFontEntry> 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<gfxUserFontEntry> FontFaceSetImpl::CreateUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust) {
nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList,
gfxUserFontAttributes&& aAttr) {
RefPtr<gfxUserFontEntry> 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<RefPtr<gfxUserFontFamily>> 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<gfxUserFontFamily> FontFaceSetImpl::GetFamily(
const nsACString& aFamilyName) {
RecursiveMutexAutoLock lock(mMutex);
return gfxUserFontSet::GetFamily(aFamilyName);
}
#undef LOG_ENABLED
#undef LOG

Просмотреть файл

@ -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<gfxUserFontEntry> CreateUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight,
StretchRange aStretch, SlantStyleRange aStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
const nsTArray<gfxFontVariation>& aVariationSettings,
uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges,
StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags,
float aAscentOverride, float aDescentOverride, float aLineGapOverride,
float aSizeAdjust) override;
nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList,
gfxUserFontAttributes&& aAttr) override;
already_AddRefed<gfxUserFontFamily> 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<gfxUserFontEntry>
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<StyleOrigin> mOrigin; // only relevant for mRuleFaces entries
};
static already_AddRefed<gfxUserFontEntry>
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<FontFace*>& aMatchingFaces,
nsTArray<FontFace*>& aFontFaces);
class UpdateUserFontEntryRunnable;
void UpdateUserFontEntry(gfxUserFontEntry* aEntry,
gfxUserFontAttributes&& aAttr);
nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
gfxFontSrcPrincipal** aPrincipal, bool* aBypassCache);

Просмотреть файл

@ -262,6 +262,12 @@ void FontFaceSetWorkerImpl::FlushUserFontSet() {
}
}
already_AddRefed<gfxUserFontFamily> FontFaceSetWorkerImpl::LookupFamily(
const nsACString& aName) const {
RecursiveMutexAutoLock lock(mMutex);
return gfxUserFontSet::LookupFamily(aName);
}
nsresult FontFaceSetWorkerImpl::StartLoad(gfxUserFontEntry* aUserFontEntry,
uint32_t aSrcIndex) {
RecursiveMutexAutoLock lock(mMutex);

Просмотреть файл

@ -35,6 +35,9 @@ class FontFaceSetWorkerImpl final : public FontFaceSetImpl {
// gfxUserFontSet
already_AddRefed<gfxUserFontFamily> LookupFamily(
const nsACString& aName) const override;
nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
uint32_t aSrcIndex) override;