Bug 1919511 - Rename gfxFontGroup::BuildFontList to EnsureFontList, and defer calling it until we really need the resolved font instances. r=layout-reviewers,emilio
This is preparation for splitting out separate per-script resolved font lists in gfxFontGroup. By itself, it should not change behavior. Differential Revision: https://phabricator.services.mozilla.com/D222748
This commit is contained in:
@@ -4494,7 +4494,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor final
|
||||
mSetTextCount++;
|
||||
auto* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
pfl->Lock();
|
||||
mFontgrp->CheckForUpdatedPlatformList();
|
||||
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
||||
// adjust flags for current direction run
|
||||
gfx::ShapedTextFlags flags = mTextRunFlags;
|
||||
@@ -5128,9 +5127,6 @@ gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() {
|
||||
NS_ERROR("Default canvas font is invalid");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The fontgroup needs to check if its cached families/faces are valid.
|
||||
fontGroup->CheckForUpdatedPlatformList();
|
||||
}
|
||||
|
||||
return fontGroup;
|
||||
|
||||
@@ -1871,9 +1871,8 @@ gfxFontGroup::gfxFontGroup(nsPresContext* aPresContext,
|
||||
break;
|
||||
}
|
||||
// We don't use SetUserFontSet() here, as we want to unconditionally call
|
||||
// BuildFontList() rather than only do UpdateUserFonts() if it changed.
|
||||
mCurrGeneration = GetGeneration();
|
||||
BuildFontList();
|
||||
// EnsureFontList() rather than only do UpdateUserFonts() if it changed.
|
||||
mCurrGeneration = 0;
|
||||
}
|
||||
|
||||
gfxFontGroup::~gfxFontGroup() {
|
||||
@@ -1887,11 +1886,58 @@ static StyleGenericFontFamily GetDefaultGeneric(nsAtom* aLanguage) {
|
||||
->GetDefaultGeneric();
|
||||
}
|
||||
|
||||
void gfxFontGroup::BuildFontList() {
|
||||
// initialize fonts in the font family list
|
||||
class DeferredClearResolvedFonts final : public nsIRunnable {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
DeferredClearResolvedFonts() = delete;
|
||||
explicit DeferredClearResolvedFonts(
|
||||
const DeferredClearResolvedFonts& aOther) = delete;
|
||||
explicit DeferredClearResolvedFonts(
|
||||
nsTArray<gfxFontGroup::FamilyFace>&& aFontList)
|
||||
: mFontList(std::move(aFontList)) {}
|
||||
|
||||
protected:
|
||||
virtual ~DeferredClearResolvedFonts() {}
|
||||
|
||||
NS_IMETHOD Run(void) override {
|
||||
mFontList.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<gfxFontGroup::FamilyFace> mFontList;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(DeferredClearResolvedFonts, nsIRunnable)
|
||||
|
||||
void gfxFontGroup::EnsureFontList() {
|
||||
// Ensure resolved font instances are valid; discard them if necessary.
|
||||
auto* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
if (mFontListGeneration != pfl->GetGeneration()) {
|
||||
// Forget cached fonts that may no longer be valid.
|
||||
mLastPrefFamily = FontFamily();
|
||||
mLastPrefFont = nullptr;
|
||||
mDefaultFont = nullptr;
|
||||
mResolvedFonts = false;
|
||||
}
|
||||
|
||||
// If we have already resolved the font list, just return.
|
||||
if (mResolvedFonts) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Discard existing fonts; but if we're in servo traversal, defer the actual
|
||||
// deletion.
|
||||
// XXX(jfkthame) is this really necessary, or is the assertion in
|
||||
// ~gfxUserFontFamily() obsolete?
|
||||
if (gfxFontUtils::IsInServoTraversal()) {
|
||||
NS_DispatchToMainThread(new DeferredClearResolvedFonts(std::move(mFonts)));
|
||||
} else {
|
||||
mFonts.Clear();
|
||||
}
|
||||
|
||||
// (Re-)build the list of fonts.
|
||||
AutoTArray<FamilyAndGeneric, 10> fonts;
|
||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
mFontListGeneration = pfl->GetGeneration();
|
||||
|
||||
// lookup fonts in the fontlist
|
||||
for (const StyleSingleFontFamily& name : mFamilyList.list.AsSpan()) {
|
||||
@@ -1935,6 +1981,9 @@ void gfxFontGroup::BuildFontList() {
|
||||
AddFamilyToFontList(f.mFamily.mUnshared, f.mGeneric);
|
||||
}
|
||||
}
|
||||
|
||||
mFontListGeneration = pfl->GetGeneration();
|
||||
mResolvedFonts = true;
|
||||
}
|
||||
|
||||
void gfxFontGroup::AddPlatformFont(const nsACString& aName, bool aQuotedName,
|
||||
@@ -2228,8 +2277,7 @@ already_AddRefed<gfxFont> gfxFontGroup::GetDefaultFont() {
|
||||
|
||||
already_AddRefed<gfxFont> gfxFontGroup::GetFirstValidFont(
|
||||
uint32_t aCh, StyleGenericFontFamily* aGeneric, bool* aIsFirst) {
|
||||
// Ensure cached font instances are valid.
|
||||
CheckForUpdatedPlatformList();
|
||||
EnsureFontList();
|
||||
|
||||
uint32_t count = mFonts.Length();
|
||||
bool loading = false;
|
||||
@@ -2313,6 +2361,7 @@ already_AddRefed<gfxFont> gfxFontGroup::GetFirstValidFont(
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont> gfxFontGroup::GetFirstMathFont() {
|
||||
EnsureFontList();
|
||||
uint32_t count = mFonts.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
RefPtr<gfxFont> font = GetFontAt(i);
|
||||
@@ -3625,26 +3674,22 @@ void gfxFontGroup::SetUserFontSet(gfxUserFontSet* aUserFontSet) {
|
||||
}
|
||||
|
||||
uint64_t gfxFontGroup::GetGeneration() {
|
||||
if (!mUserFontSet) return 0;
|
||||
return mUserFontSet->GetGeneration();
|
||||
return mUserFontSet ? mUserFontSet->GetGeneration() : 0;
|
||||
}
|
||||
|
||||
uint64_t gfxFontGroup::GetRebuildGeneration() {
|
||||
if (!mUserFontSet) return 0;
|
||||
return mUserFontSet->GetRebuildGeneration();
|
||||
return mUserFontSet ? mUserFontSet->GetRebuildGeneration() : 0;
|
||||
}
|
||||
|
||||
void gfxFontGroup::UpdateUserFonts() {
|
||||
if (mCurrGeneration < GetRebuildGeneration()) {
|
||||
// fonts in userfont set changed, need to redo the fontlist
|
||||
mFonts.Clear();
|
||||
mResolvedFonts = false;
|
||||
ClearCachedData();
|
||||
BuildFontList();
|
||||
mCurrGeneration = GetGeneration();
|
||||
} else if (mCurrGeneration != GetGeneration()) {
|
||||
// load state change occurred, verify load state and validity of fonts
|
||||
ClearCachedData();
|
||||
|
||||
uint32_t len = mFonts.Length();
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
FamilyFace& ff = mFonts[i];
|
||||
@@ -3653,14 +3698,16 @@ void gfxFontGroup::UpdateUserFonts() {
|
||||
}
|
||||
ff.CheckState(mSkipDrawing);
|
||||
}
|
||||
|
||||
mCurrGeneration = GetGeneration();
|
||||
}
|
||||
}
|
||||
|
||||
bool gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont) {
|
||||
UpdateUserFonts();
|
||||
// search through the fonts list for a specific user font
|
||||
|
||||
// If we have resolved the font list to concrete font faces, search through
|
||||
// the list for a specific user font face.
|
||||
if (mResolvedFonts) {
|
||||
uint32_t len = mFonts.Length();
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
FamilyFace& ff = mFonts[i];
|
||||
@@ -3671,6 +3718,12 @@ bool gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the font list is currently not resolved, we assume it might use the
|
||||
// given face. (This method is only called when we have already seen that
|
||||
// the family name is present in the list.)
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont> gfxFontGroup::WhichPrefFontSupportsChar(
|
||||
uint32_t aCh, uint32_t aNextCh, eFontPresentation aPresentation) {
|
||||
eFontPrefLang charLang;
|
||||
|
||||
@@ -904,6 +904,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||
public:
|
||||
typedef mozilla::intl::Script Script;
|
||||
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
|
||||
friend class MathMLTextRunFactory;
|
||||
friend class nsCaseTransformTextRunFactory;
|
||||
|
||||
static void
|
||||
Shutdown(); // platform must call this to release the languageAtomService
|
||||
@@ -1062,18 +1064,6 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||
int32_t aAppUnitsPerDevPixel, mozilla::gfx::ShapedTextFlags aFlags,
|
||||
LazyReferenceDrawTargetGetter& aRefDrawTargetGetter);
|
||||
|
||||
void CheckForUpdatedPlatformList() {
|
||||
auto* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
if (mFontListGeneration != pfl->GetGeneration()) {
|
||||
// Forget cached fonts that may no longer be valid.
|
||||
mLastPrefFamily = FontFamily();
|
||||
mLastPrefFont = nullptr;
|
||||
mDefaultFont = nullptr;
|
||||
mFonts.Clear();
|
||||
BuildFontList();
|
||||
}
|
||||
}
|
||||
|
||||
nsAtom* Language() const { return mLanguage.get(); }
|
||||
|
||||
// Get font metrics to be used as the basis for CSS font-relative units.
|
||||
@@ -1086,6 +1076,7 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||
|
||||
protected:
|
||||
friend class mozilla::PostTraversalTask;
|
||||
friend class DeferredClearResolvedFonts;
|
||||
|
||||
struct TextRange {
|
||||
TextRange(uint32_t aStart, uint32_t aEnd, gfxFont* aFont,
|
||||
@@ -1401,6 +1392,8 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||
|
||||
bool mExplicitLanguage; // Does mLanguage come from an explicit attribute?
|
||||
|
||||
bool mResolvedFonts = false; // Whether the mFonts array has been set up.
|
||||
|
||||
eFontPresentation mEmojiPresentation = eFontPresentation::Any;
|
||||
|
||||
// Generic font family used to select among font prefs during fallback.
|
||||
@@ -1427,8 +1420,9 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
||||
const T* aString, uint32_t aLength, const Parameters* aParams,
|
||||
mozilla::gfx::ShapedTextFlags aFlags, nsTextFrameUtils::Flags aFlags2);
|
||||
|
||||
// Initialize the list of fonts
|
||||
void BuildFontList();
|
||||
// Ensure the font-family list & style properties from CSS/prefs/defaults is
|
||||
// resolved to the array of available font faces we'll actually use.
|
||||
void EnsureFontList();
|
||||
|
||||
// Get the font at index i within the fontlist, for character aCh (in case
|
||||
// of fonts with multiple resources and unicode-range partitioning).
|
||||
|
||||
@@ -519,8 +519,8 @@ void MathMLTextRunFactory::RebuildTextRun(
|
||||
StyleMathVariant mathVar = StyleMathVariant::None;
|
||||
bool doMathvariantStyling = true;
|
||||
|
||||
// Ensure it will be safe to call FindFontForChar in the loop below.
|
||||
fontGroup->CheckForUpdatedPlatformList();
|
||||
// Ensure the fontGroup is ready to be searched.
|
||||
fontGroup->EnsureFontList();
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
int extraChars = 0;
|
||||
|
||||
@@ -2385,14 +2385,7 @@ already_AddRefed<gfxTextRun> BuildTextRunsScanner::BuildTextRunForFrames(
|
||||
fontInflation = nsLayoutUtils::FontSizeInflationFor(firstFrame);
|
||||
fontGroup = GetInflatedFontGroupForFrame(firstFrame);
|
||||
}
|
||||
|
||||
if (fontGroup) {
|
||||
// Refresh fontgroup if necessary, before trying to build textruns.
|
||||
fontGroup->CheckForUpdatedPlatformList();
|
||||
} else {
|
||||
DestroyUserData(userDataToDestroy);
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(fontGroup);
|
||||
|
||||
if (flags2 & nsTextFrameUtils::Flags::HasTab) {
|
||||
flags |= gfx::ShapedTextFlags::TEXT_ENABLE_SPACING;
|
||||
|
||||
@@ -770,9 +770,10 @@ bool nsCaseTransformTextRunFactory::TransformString(
|
||||
// Bug 930504. Some platforms do not have fonts for Mathematical
|
||||
// Alphanumeric Symbols. Hence we only perform the transform if a
|
||||
// character is actually available.
|
||||
auto* fontGroup = aTextRun->GetFontGroup();
|
||||
fontGroup->EnsureFontList();
|
||||
FontMatchType matchType;
|
||||
RefPtr<gfxFont> mathFont =
|
||||
aTextRun->GetFontGroup()->FindFontForChar(
|
||||
RefPtr<gfxFont> mathFont = fontGroup->FindFontForChar(
|
||||
ch2, 0, 0, intl::Script::COMMON, nullptr, &matchType);
|
||||
if (mathFont) {
|
||||
ch = ch2;
|
||||
|
||||
Reference in New Issue
Block a user