Bug 1694123 - Ensure user fonts with src:local() are refreshed after a font-list update, even if the local font lookup previously failed. r=jwatt

Differential Revision: https://phabricator.services.mozilla.com/D106511
This commit is contained in:
Jonathan Kew 2021-04-01 17:25:19 +00:00
Родитель ad756592f0
Коммит b13708fd11
2 изменённых файлов: 34 добавлений и 13 удалений

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

@ -49,6 +49,7 @@ gfxUserFontEntry::gfxUserFontEntry(
: gfxFontEntry("userfont"_ns),
mUserFontLoadState(STATUS_NOT_LOADED),
mFontDataLoadingState(NOT_LOADING),
mSeenLocalSource(false),
mUnsupportedFormat(false),
mFontDisplay(aFontDisplay),
mLoader(nullptr),
@ -355,6 +356,13 @@ void CopyWOFFMetadata(const uint8_t* aFontData, uint32_t aLength,
}
void gfxUserFontEntry::LoadNextSrc() {
// If LoadCanceled was called, we need to reset mSrcIndex so that all
// potential sources are re-considered.
if (mFontDataLoadingState == NOT_LOADING) {
mSrcIndex = 0;
mSeenLocalSource = false;
}
NS_ASSERTION(mSrcIndex < mSrcList.Length(),
"already at the end of the src list for user font");
NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED ||
@ -419,17 +427,20 @@ void gfxUserFontEntry::DoLoadNextSrc(bool aForceAsync) {
if (currSrc.mSourceType == gfxFontFaceSrc::eSourceType_Local) {
// Don't look up local fonts if the font whitelist is being used.
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
gfxFontEntry* fe =
pfl && pfl->IsFontFamilyWhitelistActive()
? nullptr
: gfxPlatform::GetPlatform()->LookupLocalFont(
currSrc.mLocalName, Weight(), Stretch(), SlantStyle());
nsTArray<gfxUserFontSet*> fontSets;
GetUserFontSets(fontSets);
for (gfxUserFontSet* fontSet : fontSets) {
// We need to note on each gfxUserFontSet that contains the user
// font entry that we used a local() rule.
fontSet->SetLocalRulesUsed();
gfxFontEntry* fe = nullptr;
if (!pfl->IsFontFamilyWhitelistActive()) {
fe = gfxPlatform::GetPlatform()->LookupLocalFont(
currSrc.mLocalName, Weight(), Stretch(), SlantStyle());
// Note that we've attempted a local lookup, even if it failed,
// as this means we are dependent on any updates to the font list.
mSeenLocalSource = true;
nsTArray<gfxUserFontSet*> fontSets;
GetUserFontSets(fontSets);
for (gfxUserFontSet* fontSet : fontSets) {
// We need to note on each gfxUserFontSet that contains the user
// font entry that we used a local() rule.
fontSet->SetLocalRulesUsed();
}
}
if (fe) {
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
@ -1059,11 +1070,15 @@ void gfxUserFontSet::ForgetLocalFaces() {
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, and reset the load state so that
// the load will be re-done based on the updated font list.
// 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();
}
}

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

@ -618,6 +618,11 @@ class gfxUserFontEntry : public gfxFontEntry {
mUserFontLoadState = STATUS_NOT_LOADED;
mFontDataLoadingState = NOT_LOADING;
mLoader = nullptr;
// We must not reset mSrcIndex here because there may be an
// off-main-thread font load currently in progress that will
// depend on it being correct when it calls CacheFont.
// It will get reset to 0 on the next call to LoadNextSrc()
// because we have reset mFontDataLoadingState here.
}
// whether to wait before using fallback font or not
@ -768,6 +773,7 @@ class gfxUserFontEntry : public gfxFontEntry {
};
FontDataLoadingState mFontDataLoadingState;
bool mSeenLocalSource;
bool mUnsupportedFormat;
mozilla::StyleFontDisplay mFontDisplay; // timing of userfont fallback