Bug 1756474 - Add locking to gfxPlatformFontList and gfxFontFamily, to allow use from worker threads. r=lsalzman

We use a recursive-mutex in gfxPlatformFontList as some of its methods may be called from
classes like gfxFontEntry that are used both from layout code (which does not explictly
lock the font-list) and internally by font-list code that is already holding the lock.

Differential Revision: https://phabricator.services.mozilla.com/D143869
This commit is contained in:
Jonathan Kew 2022-04-19 14:20:21 +00:00
Родитель 0e84325b5d
Коммит 0fd7a7ea1a
19 изменённых файлов: 600 добавлений и 341 удалений

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

@ -132,11 +132,13 @@ static HRESULT GetDirectWriteFaceName(IDWriteFont* aFont,
return S_OK;
}
void gfxDWriteFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
void gfxDWriteFontFamily::FindStyleVariationsLocked(
FontInfoData* aFontInfoData) {
HRESULT hr;
if (mHasStyles) {
return;
}
mHasStyles = true;
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();
@ -188,7 +190,7 @@ void gfxDWriteFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
fe->SetupVariationRanges();
AddFontEntry(fe);
AddFontEntryLocked(fe);
// postscript/fullname if needed
nsAutoCString psname, fullname;
@ -1839,7 +1841,7 @@ void gfxDWriteFontList::GetFontsFromCollection(
// if this fails/doesn't exist, we'll have used name index 0,
// so that's the one we'll want to skip here
names->FindLocaleName(L"en-us", &englishIdx, &exists);
AutoTArray<nsCString, 4> otherFamilyNames;
for (nameIndex = 0; nameIndex < nameCount; nameIndex++) {
UINT32 nameLen;
AutoTArray<WCHAR, 32> localizedName;
@ -1866,9 +1868,12 @@ void gfxDWriteFontList::GetFontsFromCollection(
NS_ConvertUTF16toUTF8 locName(localizedName.Elements());
if (!familyName.Equals(locName)) {
AddOtherFamilyName(fam, locName);
otherFamilyNames.AppendElement(locName);
}
}
if (!otherFamilyNames.IsEmpty()) {
AddOtherFamilyNames(fam, otherFamilyNames);
}
}
// at this point, all family names have been read in
@ -2010,7 +2015,7 @@ void gfxDWriteFontList::GetDirectWriteSubstitutes() {
}
}
bool gfxDWriteFontList::FindAndAddFamilies(
bool gfxDWriteFontList::FindAndAddFamiliesLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle, nsAtom* aLanguage,
@ -2037,7 +2042,7 @@ bool gfxDWriteFontList::FindAndAddFamilies(
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(
return gfxPlatformFontList::FindAndAddFamiliesLocked(
aPresContext, aGeneric, keyName, aOutput, aFlags, aStyle, aLanguage,
aDevToCssSize);
}
@ -2046,6 +2051,8 @@ void gfxDWriteFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
AutoLock lock(mLock);
// We are a singleton, so include the font loader singleton's memory.
MOZ_ASSERT(static_cast<const gfxPlatformFontList*>(this) ==
gfxPlatformFontList::PlatformFontList());

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

@ -63,7 +63,7 @@ class gfxDWriteFontFamily final : public gfxFontFamily {
mForceGDIClassic(false) {}
virtual ~gfxDWriteFontFamily();
void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) final;
void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr) final;
void LocalizedName(nsACString& aLocalizedName) final;
@ -194,7 +194,7 @@ class gfxDWriteFontEntry final : public gfxFontEntry {
hb_blob_t* GetFontTable(uint32_t aTableTag) override;
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr);
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
bool IsCJKFont();
@ -387,7 +387,8 @@ class gfxDWriteFontList final : public gfxPlatformFontList {
const mozilla::fontlist::Family* aFamily) override;
void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
bool aNeedFullnamePostscriptNames) override;
bool aNeedFullnamePostscriptNames)
REQUIRES(mLock) override;
bool ReadFaceNames(mozilla::fontlist::Family* aFamily,
mozilla::fontlist::Face* aFace, nsCString& aPSName,
@ -414,7 +415,7 @@ class gfxDWriteFontList final : public gfxPlatformFontList {
IDWriteGdiInterop* GetGDIInterop() { return mGDIInterop; }
bool UseGDIFontTableAccess() const;
bool FindAndAddFamilies(
bool FindAndAddFamiliesLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,

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

@ -618,6 +618,7 @@ void FT2FontEntry::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
*/
void FT2FontFamily::AddFacesToFontList(nsTArray<FontListEntry>* aFontList) {
AutoReadLock lock(mLock);
for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) {
const FT2FontEntry* fe =
static_cast<const FT2FontEntry*>(mAvailableFonts[i].get());
@ -1168,7 +1169,9 @@ void gfxFT2FontList::AppendFacesFromFontFile(const nsCString& aFileName,
CollectFunc unshared =
[](const FontListEntry& aFLE, const nsCString& aPSName,
const nsCString& aFullName, StandardFile aStdFile) {
PlatformFontList()->AppendFaceFromFontListEntry(aFLE, aStdFile);
auto* pfl = PlatformFontList();
pfl->mLock.AssertCurrentThreadIn();
pfl->AppendFaceFromFontListEntry(aFLE, aStdFile);
};
CollectFunc shared = [](const FontListEntry& aFLE, const nsCString& aPSName,
const nsCString& aFullName, StandardFile aStdFile) {
@ -1339,7 +1342,9 @@ void gfxFT2FontList::AppendFacesFromOmnijarEntry(nsZipArchive* aArchive,
CollectFunc unshared =
[](const FontListEntry& aFLE, const nsCString& aPSName,
const nsCString& aFullName, StandardFile aStdFile) {
PlatformFontList()->AppendFaceFromFontListEntry(aFLE, aStdFile);
auto* pfl = PlatformFontList();
pfl->mLock.AssertCurrentThreadIn();
pfl->AppendFaceFromFontListEntry(aFLE, aStdFile);
};
CollectFunc shared = [](const FontListEntry& aFLE,
const nsCString& aPSName,
@ -1382,17 +1387,15 @@ void gfxFT2FontList::AppendFacesFromOmnijarEntry(nsZipArchive* aArchive,
// Called on each family after all fonts are added to the list;
// if aSortFaces is true this will sort faces to give priority to "standard"
// font files.
static void FinalizeFamilyMemberList(nsCStringHashKey::KeyType aKey,
const RefPtr<gfxFontFamily>& aFamily,
bool aSortFaces) {
gfxFontFamily* family = aFamily.get();
void FT2FontFamily::FinalizeMemberList(bool aSortFaces) {
AutoWriteLock lock(mLock);
family->SetHasStyles(true);
SetHasStyles(true);
if (aSortFaces) {
family->SortAvailableFonts();
SortAvailableFonts();
}
family->CheckForSimpleFamily();
CheckForSimpleFamily();
}
void gfxFT2FontList::FindFonts() {
@ -1640,6 +1643,7 @@ void gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
}
void gfxFT2FontList::ReadSystemFontList(dom::SystemFontList* aList) {
AutoLock lock(mLock);
for (const auto& entry : mFontFamilies) {
auto family = static_cast<FT2FontFamily*>(entry.GetData().get());
family->AddFacesToFontList(&aList->entries());
@ -1669,9 +1673,8 @@ nsresult gfxFT2FontList::InitFontListForPlatform() {
// Finalize the families by sorting faces into standard order
// and marking "simple" families.
for (const auto& entry : mFontFamilies) {
nsCStringHashKey::KeyType key = entry.GetKey();
const RefPtr<gfxFontFamily>& family = entry.GetData();
FinalizeFamilyMemberList(key, family, /* aSortFaces */ true);
auto* family = static_cast<FT2FontFamily*>(entry.GetData().get());
family->FinalizeMemberList(/* aSortFaces */ true);
}
return NS_OK;
@ -1689,9 +1692,8 @@ nsresult gfxFT2FontList::InitFontListForPlatform() {
// We don't need to sort faces (because they were already sorted by the
// chrome process, so we just maintain the existing order)
for (const auto& entry : mFontFamilies) {
nsCStringHashKey::KeyType key = entry.GetKey();
const RefPtr<gfxFontFamily>& family = entry.GetData();
FinalizeFamilyMemberList(key, family, /* aSortFaces */ false);
auto* family = static_cast<FT2FontFamily*>(entry.GetData().get());
family->FinalizeMemberList(/* aSortFaces */ false);
}
LOG(("got font list from chrome process: %" PRIdPTR " faces in %" PRIu32
@ -1747,10 +1749,13 @@ gfxFontEntry* gfxFT2FontList::LookupLocalFont(nsPresContext* aPresContext,
WeightRange aWeightForEntry,
StretchRange aStretchForEntry,
SlantStyleRange aStyleForEntry) {
AutoLock lock(mLock);
if (SharedFontList()) {
return LookupInSharedFaceNameList(aPresContext, aFontName, aWeightForEntry,
aStretchForEntry, aStyleForEntry);
}
// walk over list of names
FT2FontEntry* fontEntry = nullptr;
FontVisibility level =

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

@ -128,6 +128,8 @@ class FT2FontFamily final : public gfxFontFamily {
// Append this family's faces to the IPC fontlist
void AddFacesToFontList(nsTArray<FontListEntry>* aFontList);
void FinalizeMemberList(bool aSortFaces);
};
class gfxFT2FontList final : public gfxPlatformFontList {
@ -172,23 +174,26 @@ class gfxFT2FontList final : public gfxPlatformFontList {
typedef enum { kUnknown, kStandard } StandardFile;
// initialize font lists
nsresult InitFontListForPlatform() override;
nsresult InitFontListForPlatform() REQUIRES(mLock) override;
void AppendFaceFromFontListEntry(const FontListEntry& aFLE,
StandardFile aStdFile);
StandardFile aStdFile) REQUIRES(mLock);
void AppendFacesFromBlob(const nsCString& aFileName, StandardFile aStdFile,
hb_blob_t* aBlob, FontNameCache* aCache,
uint32_t aTimestamp, uint32_t aFilesize);
uint32_t aTimestamp, uint32_t aFilesize)
REQUIRES(mLock);
void AppendFacesFromFontFile(const nsCString& aFileName,
FontNameCache* aCache, StandardFile aStdFile);
FontNameCache* aCache, StandardFile aStdFile)
REQUIRES(mLock);
void AppendFacesFromOmnijarEntry(nsZipArchive* aReader,
const nsCString& aEntryName,
FontNameCache* aCache, bool aJarChanged);
FontNameCache* aCache, bool aJarChanged)
REQUIRES(mLock);
void InitSharedFontListForPlatform() override;
void InitSharedFontListForPlatform() REQUIRES(mLock) override;
void CollectInitData(const FontListEntry& aFLE, const nsCString& aPSName,
const nsCString& aFullName, StandardFile aStdFile);
@ -212,21 +217,23 @@ class gfxFT2FontList final : public gfxPlatformFontList {
bool AppendFacesFromCachedFaceList(CollectFunc aCollectFace,
const nsCString& aFileName,
const nsCString& aFaceList,
StandardFile aStdFile);
StandardFile aStdFile) REQUIRES(mLock);
void AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
StandardFile aStdFile, hb_face_t* aFace,
nsCString& aFaceList);
nsCString& aFaceList) REQUIRES(mLock);
void FindFonts();
void FindFonts() REQUIRES(mLock);
void FindFontsInOmnijar(FontNameCache* aCache);
void FindFontsInOmnijar(FontNameCache* aCache) REQUIRES(mLock);
void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC);
void FindFontsInDir(const nsCString& aDir, FontNameCache* aFNC)
REQUIRES(mLock);
FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
const gfxFontStyle* aStyle,
nsAtom* aLanguage = nullptr) override;
nsAtom* aLanguage = nullptr)
REQUIRES(mLock) override;
nsTHashSet<nsCString> mSkipSpaceLookupCheckFamilies;

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

@ -1015,7 +1015,8 @@ nsresult gfxFontconfigFontEntry::CopyFontTable(uint32_t aTableTag,
return gfxFT2FontEntryBase::CopyFaceTable(GetFTFace(), aTableTag, aBuffer);
}
void gfxFontconfigFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
void gfxFontconfigFontFamily::FindStyleVariationsLocked(
FontInfoData* aFontInfoData) {
if (mHasStyles) {
return;
}
@ -1039,7 +1040,7 @@ void gfxFontconfigFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
fontEntry->SetupVariationRanges();
}
AddFontEntry(fontEntry);
AddFontEntryLocked(fontEntry);
if (fontEntry->IsNormalStyle()) {
numRegularFaces++;
@ -1226,6 +1227,7 @@ bool gfxFontconfigFontFamily::SupportsLangGroup(nsAtom* aLangGroup) const {
// will contain the font entries, each of which holds a reference to its
// pattern. We only check the first pattern in each list, because support
// for langs is considered to be consistent across all faces in a family.
AutoReadLock lock(mLock);
FcPattern* fontPattern;
if (mFontPatterns.Length()) {
fontPattern = mFontPatterns[0];
@ -1248,6 +1250,7 @@ gfxFontconfigFontFamily::~gfxFontconfigFontFamily() {
template <typename Func>
void gfxFontconfigFontFamily::AddFacesToFontList(Func aAddPatternFunc) {
AutoReadLock lock(mLock);
if (HasStyles()) {
for (auto& fe : mAvailableFonts) {
if (!fe) {
@ -1431,14 +1434,17 @@ void gfxFcPlatformFontList::AddPatternToFontList(
// will usually not match
FcChar8* otherName;
int n = (cIndex == 0 ? 1 : 0);
AutoTArray<nsCString, 4> otherFamilyNames;
while (FcPatternGetString(aFont, FC_FAMILY, n, &otherName) == FcResultMatch) {
nsAutoCString otherFamilyName(ToCharPtr(otherName));
AddOtherFamilyName(aFontFamily, otherFamilyName);
otherFamilyNames.AppendElement(nsCString(ToCharPtr(otherName)));
n++;
if (n == int(cIndex)) {
n++; // skip over canonical name
}
}
if (!otherFamilyNames.IsEmpty()) {
AddOtherFamilyNames(aFontFamily, otherFamilyNames);
}
const bool singleName = n == 1;
@ -1576,6 +1582,8 @@ nsresult gfxFcPlatformFontList::InitFontListForPlatform() {
}
void gfxFcPlatformFontList::ReadSystemFontList(dom::SystemFontList* retValue) {
AutoLock lock(mLock);
// Fontconfig versions below 2.9 drop the FC_FILE element in FcNameUnparse
// (see https://bugs.freedesktop.org/show_bug.cgi?id=26718), so when using
// an older version, we manually append it to the unparsed pattern.
@ -2039,6 +2047,8 @@ gfxFontEntry* gfxFcPlatformFontList::LookupLocalFont(
nsPresContext* aPresContext, const nsACString& aFontName,
WeightRange aWeightForEntry, StretchRange aStretchForEntry,
SlantStyleRange aStyleForEntry) {
AutoLock lock(mLock);
nsAutoCString keyName(aFontName);
ToLowerCase(keyName);
@ -2071,7 +2081,7 @@ gfxFontEntry* gfxFcPlatformFontList::MakePlatformFont(
std::move(face));
}
bool gfxFcPlatformFontList::FindAndAddFamilies(
bool gfxFcPlatformFontList::FindAndAddFamiliesLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle, nsAtom* aLanguage,
@ -2184,7 +2194,7 @@ bool gfxFcPlatformFontList::FindAndAddFamilies(
if (terminator && FcStrCmp(substName, terminator) == 0) {
break;
}
gfxPlatformFontList::FindAndAddFamilies(
gfxPlatformFontList::FindAndAddFamiliesLocked(
aPresContext, aGeneric, nsDependentCString(ToCharPtr(substName)),
&cachedFamilies, aFlags, aStyle, aLanguage);
}
@ -2340,6 +2350,7 @@ void gfxFcPlatformFontList::AddGenericFonts(
}
}
AutoLock lock(mLock);
PrefFontList* prefFonts =
FindGenericFamilies(aPresContext, genericToLookup, aLanguage);
NS_ASSERTION(prefFonts, "null generic font list");
@ -2349,9 +2360,9 @@ void gfxFcPlatformFontList::AddGenericFonts(
}
}
void gfxFcPlatformFontList::ClearLangGroupPrefFonts() {
ClearGenericMappings();
gfxPlatformFontList::ClearLangGroupPrefFonts();
void gfxFcPlatformFontList::ClearLangGroupPrefFontsLocked() {
ClearGenericMappingsLocked();
gfxPlatformFontList::ClearLangGroupPrefFontsLocked();
mAlwaysUseFontconfigGenerics = PrefFontListsUseOnlyGenerics();
}
@ -2411,9 +2422,10 @@ gfxPlatformFontList::PrefFontList* gfxFcPlatformFontList::FindGenericFamilies(
FcPatternGetString(font, FC_FAMILY, 0, &mappedGeneric);
if (mappedGeneric) {
mLock.AssertCurrentThreadIn();
nsAutoCString mappedGenericName(ToCharPtr(mappedGeneric));
AutoTArray<FamilyAndGeneric, 1> genericFamilies;
if (gfxPlatformFontList::FindAndAddFamilies(
if (gfxPlatformFontList::FindAndAddFamiliesLocked(
aPresContext, StyleGenericFontFamily::None,
mappedGenericName, &genericFamilies,
FindFamiliesFlags(0))) {

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

@ -175,7 +175,8 @@ class gfxFontconfigFontFamily final : public gfxFontFamily {
template <typename Func>
void AddFacesToFontList(Func aAddPatternFunc);
void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) override;
void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
REQUIRES(mLock) override;
// Families are constructed initially with just references to patterns.
// When necessary, these are enumerated within FindStyleVariations.
@ -244,8 +245,8 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
}
// initialize font lists
nsresult InitFontListForPlatform() override;
void InitSharedFontListForPlatform() override;
nsresult InitFontListForPlatform() REQUIRES(mLock) override;
void InitSharedFontListForPlatform() REQUIRES(mLock) override;
void GetFontList(nsAtom* aLangGroup, const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts) override;
@ -269,11 +270,12 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
const uint8_t* aFontData,
uint32_t aLength) override;
bool FindAndAddFamilies(
bool FindAndAddFamiliesLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0) override;
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
REQUIRES(mLock) override;
bool GetStandardFamilyName(const nsCString& aFontName,
nsACString& aFamilyName) override;
@ -285,10 +287,16 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
mozilla::StyleGenericFontFamily, nsAtom* aLanguage,
nsTArray<FamilyAndGeneric>& aFamilyList) override;
void ClearLangGroupPrefFonts() override;
void ClearLangGroupPrefFontsLocked() REQUIRES(mLock) override;
// clear out cached generic-lang ==> family-list mappings
void ClearGenericMappings() { mGenericMappings.Clear(); }
void ClearGenericMappings() {
AutoLock lock(mLock);
ClearGenericMappingsLocked();
}
void ClearGenericMappingsLocked() REQUIRES(mLock) {
mGenericMappings.Clear();
}
// map lang group ==> lang string
// When aForFontEnumerationThread is true, this method will avoid using
@ -310,28 +318,29 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
// Add all the font families found in a font set.
// aAppFonts indicates whether this is the system or application fontset.
void AddFontSetFamilies(FcFontSet* aFontSet, const SandboxPolicy* aPolicy,
bool aAppFonts);
bool aAppFonts) REQUIRES(mLock);
// Helper for above, to add a single font pattern.
void AddPatternToFontList(FcPattern* aFont, FcChar8*& aLastFamilyName,
nsACString& aFamilyName,
RefPtr<gfxFontconfigFontFamily>& aFontFamily,
bool aAppFonts);
bool aAppFonts) REQUIRES(mLock);
// figure out which families fontconfig maps a generic to
// (aGeneric assumed already lowercase)
PrefFontList* FindGenericFamilies(nsPresContext* aPresContext,
const nsCString& aGeneric,
nsAtom* aLanguage);
nsAtom* aLanguage) REQUIRES(mLock);
// are all pref font settings set to use fontconfig generics?
bool PrefFontListsUseOnlyGenerics();
bool PrefFontListsUseOnlyGenerics() REQUIRES(mLock);
static void CheckFontUpdates(nsITimer* aTimer, void* aThis);
FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
const gfxFontStyle* aStyle,
nsAtom* aLanguage = nullptr) override;
nsAtom* aLanguage = nullptr)
REQUIRES(mLock) override;
enum class DistroID : int8_t {
Unknown = 0,

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

@ -234,7 +234,7 @@ bool gfxFontCache::HashEntry::KeyEquals(const KeyTypePointer aKey) const {
gfxFont* gfxFontCache::Lookup(const gfxFontEntry* aFontEntry,
const gfxFontStyle* aStyle,
const gfxCharacterMap* aUnicodeRangeMap) {
AutoReadLock lock(mCacheLock);
MutexAutoLock lock(mMutex);
Key key(aFontEntry, aStyle, aUnicodeRangeMap);
HashEntry* entry = mFonts.GetEntry(key);
@ -247,7 +247,7 @@ gfxFont* gfxFontCache::Lookup(const gfxFontEntry* aFontEntry,
void gfxFontCache::AddNew(gfxFont* aFont) {
gfxFont* oldFont;
{
AutoWriteLock lock(mCacheLock);
MutexAutoLock lock(mMutex);
Key key(aFont->GetFontEntry(), aFont->GetStyle(),
aFont->GetUnicodeRangeMap());
@ -287,7 +287,7 @@ void gfxFontCache::NotifyReleased(gfxFont* aFont) {
void gfxFontCache::NotifyExpiredLocked(gfxFont* aFont, const AutoLock& aLock) {
aFont->ClearCachedWords();
RemoveObjectLocked(aFont, aLock);
DestroyFont(aFont);
DestroyFontLocked(aFont);
}
void gfxFontCache::NotifyExpired(gfxFont* aFont) {
@ -296,14 +296,29 @@ void gfxFontCache::NotifyExpired(gfxFont* aFont) {
DestroyFont(aFont);
}
void gfxFontCache::DestroyFont(gfxFont* aFont) {
AutoWriteLock lock(mCacheLock);
void gfxFontCache::DestroyFontLocked(gfxFont* aFont) {
Key key(aFont->GetFontEntry(), aFont->GetStyle(),
aFont->GetUnicodeRangeMap());
HashEntry* entry = mFonts.GetEntry(key);
if (entry && entry->mFont == aFont) {
mFonts.RemoveEntry(entry);
}
NS_ASSERTION(aFont->GetRefCount() == 0,
"Destroying with non-zero ref count!");
MutexAutoUnlock unlock(mMutex);
delete aFont;
}
void gfxFontCache::DestroyFont(gfxFont* aFont) {
{
MutexAutoLock lock(mMutex);
Key key(aFont->GetFontEntry(), aFont->GetStyle(),
aFont->GetUnicodeRangeMap());
HashEntry* entry = mFonts.GetEntry(key);
if (entry && entry->mFont == aFont) {
mFonts.RemoveEntry(entry);
}
}
NS_ASSERTION(aFont->GetRefCount() == 0,
"Destroying with non-zero ref count!");
delete aFont;
@ -319,7 +334,7 @@ void gfxFontCache::WordCacheExpirationTimerCallback(nsITimer* aTimer,
void gfxFontCache::AgeCachedWords() {
bool allEmpty = true;
{
AutoReadLock lock(mCacheLock);
MutexAutoLock lock(mMutex);
for (const auto& entry : mFonts) {
allEmpty = entry.mFont->AgeCachedWords() && allEmpty;
}
@ -331,7 +346,7 @@ void gfxFontCache::AgeCachedWords() {
void gfxFontCache::FlushShapedWordCaches() {
{
AutoReadLock lock(mCacheLock);
MutexAutoLock lock(mMutex);
for (const auto& entry : mFonts) {
entry.mFont->ClearCachedWords();
}
@ -340,7 +355,7 @@ void gfxFontCache::FlushShapedWordCaches() {
}
void gfxFontCache::NotifyGlyphsChanged() {
AutoReadLock lock(mCacheLock);
MutexAutoLock lock(mMutex);
for (const auto& entry : mFonts) {
entry.mFont->NotifyGlyphsChanged();
}
@ -350,7 +365,7 @@ void gfxFontCache::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontCacheSizes* aSizes) const {
// TODO: add the overhead of the expiration tracker (generation arrays)
AutoReadLock lock(mCacheLock);
MutexAutoLock lock(*const_cast<Mutex*>(&mMutex));
aSizes->mFontInstances += mFonts.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const auto& entry : mFonts) {
entry.mFont->AddSizeOfExcludingThis(aMallocSizeOf, aSizes);

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

@ -348,7 +348,7 @@ class gfxFontCache final
// into the expiration queues and removed.
void Flush() {
{
mozilla::AutoWriteLock lock(mCacheLock);
mozilla::MutexAutoLock lock(mMutex);
mFonts.Clear();
}
AgeAllGenerations();
@ -361,7 +361,7 @@ class gfxFontCache final
void RunWordCacheExpirationTimer() {
if (!mTimerRunning) {
mozilla::AutoWriteLock lock(mCacheLock);
mozilla::MutexAutoLock lock(mMutex);
if (!mTimerRunning && mWordCacheExpirationTimer) {
mWordCacheExpirationTimer->InitWithNamedFuncCallback(
WordCacheExpirationTimerCallback, this,
@ -373,7 +373,7 @@ class gfxFontCache final
}
void PauseWordCacheExpirationTimer() {
if (mTimerRunning) {
mozilla::AutoWriteLock lock(mCacheLock);
mozilla::MutexAutoLock lock(mMutex);
if (mTimerRunning && mWordCacheExpirationTimer) {
mWordCacheExpirationTimer->Cancel();
mTimerRunning = false;
@ -396,13 +396,7 @@ class gfxFontCache final
RemoveObjectLocked(aFont, lock);
}
mozilla::RWLock& GetCacheLock() { return mCacheLock; }
protected:
// Guards the global font hashtable, separately from the expiration-tracker
// records.
mutable mozilla::RWLock mCacheLock = mozilla::RWLock("fontCacheLock");
class MemoryReporter final : public nsIMemoryReporter {
~MemoryReporter() = default;
@ -427,10 +421,12 @@ class gfxFontCache final
// This gets called when the timeout has expired on a zero-refcount
// font; we just delete it.
void NotifyExpiredLocked(gfxFont* aFont, const AutoLock&) override;
void NotifyExpiredLocked(gfxFont* aFont, const AutoLock&)
REQUIRES(mMutex) override;
void NotifyExpired(gfxFont* aFont);
void DestroyFont(gfxFont* aFont);
void DestroyFontLocked(gfxFont* aFont) REQUIRES(mMutex);
static gfxFontCache* gGlobalCache;
@ -469,11 +465,11 @@ class gfxFontCache final
gfxFont* MOZ_UNSAFE_REF("tracking for deferred deletion") mFont;
};
nsTHashtable<HashEntry> mFonts GUARDED_BY(mCacheLock);
nsTHashtable<HashEntry> mFonts GUARDED_BY(mMutex);
static void WordCacheExpirationTimerCallback(nsITimer* aTimer, void* aCache);
nsCOMPtr<nsITimer> mWordCacheExpirationTimer GUARDED_BY(mCacheLock);
nsCOMPtr<nsITimer> mWordCacheExpirationTimer GUARDED_BY(mMutex);
std::atomic<bool> mTimerRunning = false;
};

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

@ -56,9 +56,8 @@ using namespace mozilla::unicode;
using mozilla::services::GetObserverService;
void gfxCharacterMap::NotifyReleased() {
gfxPlatformFontList* fontlist = gfxPlatformFontList::PlatformFontList();
if (mShared) {
fontlist->RemoveCmap(this);
gfxPlatformFontList::PlatformFontList()->RemoveCmap(this);
}
delete this;
}
@ -1541,12 +1540,14 @@ class FontEntryStandardFaceComparator {
};
void gfxFontFamily::SortAvailableFonts() {
MOZ_ASSERT(mLock.LockedForWritingByCurrentThread());
mAvailableFonts.Sort(FontEntryStandardFaceComparator());
}
bool gfxFontFamily::HasOtherFamilyNames() {
// need to read in other family names to determine this
if (!mOtherFamilyNamesInitialized) {
AutoWriteLock lock(mLock);
ReadOtherFamilyNames(
gfxPlatformFontList::PlatformFontList()); // sets mHasOtherFamilyNames
}
@ -1588,9 +1589,12 @@ void gfxFontFamily::FindAllFontsForStyle(
const gfxFontStyle& aFontStyle, nsTArray<gfxFontEntry*>& aFontEntryList,
bool aIgnoreSizeTolerance) {
if (!mHasStyles) {
FindStyleVariations(); // collect faces for the family, if not already done
FindStyleVariations(); // collect faces for the family, if not already
// done
}
AutoReadLock lock(mLock);
NS_ASSERTION(mAvailableFonts.Length() > 0, "font family with no faces!");
NS_ASSERTION(aFontEntryList.IsEmpty(), "non-empty fontlist passed in");
@ -1696,6 +1700,7 @@ void gfxFontFamily::FindAllFontsForStyle(
}
void gfxFontFamily::CheckForSimpleFamily() {
MOZ_ASSERT(mLock.LockedForWritingByCurrentThread());
// already checked this family
if (mIsSimpleFamily) {
return;
@ -1749,6 +1754,8 @@ void gfxFontFamily::CheckForSimpleFamily() {
#ifdef DEBUG
bool gfxFontFamily::ContainsFace(gfxFontEntry* aFontEntry) {
AutoReadLock lock(mLock);
uint32_t i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
if (mAvailableFonts[i] == aFontEntry) {
@ -1773,10 +1780,15 @@ void gfxFontFamily::LocalizedName(nsACString& aLocalizedName) {
}
void gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData) {
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
// none of the faces in the family support the required char,
// so bail out immediately
return;
gfxPlatformFontList::PlatformFontList()->mLock.AssertCurrentThreadIn();
{
AutoReadLock lock(mLock);
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
// none of the faces in the family support the required char,
// so bail out immediately
return;
}
}
nsCString charAndName;
@ -1866,6 +1878,7 @@ void gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData) {
if (!mFamilyCharacterMapInitialized) {
ReadAllCMAPs();
}
AutoReadLock lock(mLock);
if (!mFamilyCharacterMap.test(aMatchData->mCh)) {
return;
}
@ -1914,20 +1927,27 @@ bool gfxFontFamily::ReadOtherFamilyNamesForFace(
gfxFontUtils::ReadOtherFamilyNamesForFace(mName, nameData, dataLength,
otherFamilyNames, useFullName);
uint32_t n = otherFamilyNames.Length();
for (uint32_t i = 0; i < n; i++) {
aPlatformFontList->AddOtherFamilyName(this, otherFamilyNames[i]);
if (!otherFamilyNames.IsEmpty()) {
aPlatformFontList->AddOtherFamilyNames(this, otherFamilyNames);
}
return n != 0;
return !otherFamilyNames.IsEmpty();
}
void gfxFontFamily::ReadOtherFamilyNames(
gfxPlatformFontList* aPlatformFontList) {
if (mOtherFamilyNamesInitialized) return;
if (mOtherFamilyNamesInitialized) {
return;
}
AutoWriteLock lock(mLock);
if (mOtherFamilyNamesInitialized) {
return;
}
mOtherFamilyNamesInitialized = true;
FindStyleVariations();
FindStyleVariationsLocked();
// read in other family names for the first face in the list
uint32_t i, numFonts = mAvailableFonts.Length();
@ -1950,7 +1970,9 @@ void gfxFontFamily::ReadOtherFamilyNames(
// read in other names for the first face in the list with the assumption
// that if extra names don't exist in that face then they don't exist in
// other faces for the same font
if (!mHasOtherFamilyNames) return;
if (!mHasOtherFamilyNames) {
return;
}
// read in names for all faces, needed to catch cases where fonts have
// family names for individual weights (e.g. Hiragino Kaku Gothic Pro W6)
@ -2012,6 +2034,8 @@ bool gfxFontFamily::CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList) {
// we already did this, so there's nothing more to add
return false;
}
aFontList->mLock.AssertCurrentThreadIn();
AutoWriteLock lock(mLock);
mCheckedForLegacyFamilyNames = true;
bool added = false;
const uint32_t kNAME = TRUETYPE_TAG('n', 'a', 'm', 'e');
@ -2041,22 +2065,23 @@ bool gfxFontFamily::CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList) {
void gfxFontFamily::ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
bool aNeedFullnamePostscriptNames,
FontInfoData* aFontInfoData) {
aPlatformFontList->mLock.AssertCurrentThreadIn();
// if all needed names have already been read, skip
if (mOtherFamilyNamesInitialized &&
(mFaceNamesInitialized || !aNeedFullnamePostscriptNames)) {
return;
}
AutoWriteLock lock(mLock);
bool asyncFontLoaderDisabled = false;
if (!mOtherFamilyNamesInitialized && aFontInfoData &&
aFontInfoData->mLoadOtherNames && !asyncFontLoaderDisabled) {
const auto* otherFamilyNames = aFontInfoData->GetOtherFamilyNames(mName);
if (otherFamilyNames) {
uint32_t i, n = otherFamilyNames->Length();
for (i = 0; i < n; i++) {
aPlatformFontList->AddOtherFamilyName(this, (*otherFamilyNames)[i]);
}
if (otherFamilyNames && otherFamilyNames->Length()) {
aPlatformFontList->AddOtherFamilyNames(this, *otherFamilyNames);
}
mOtherFamilyNamesInitialized = true;
}
@ -2067,7 +2092,7 @@ void gfxFontFamily::ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
return;
}
FindStyleVariations(aFontInfoData);
FindStyleVariationsLocked(aFontInfoData);
// check again, as style enumeration code may have loaded names
if (mOtherFamilyNamesInitialized &&
@ -2091,10 +2116,10 @@ void gfxFontFamily::ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
aFontInfoData && aFontInfoData->mLoadFaceNames) {
aFontInfoData->GetFaceNames(fe->Name(), fullname, psname);
if (!fullname.IsEmpty()) {
aPlatformFontList->AddFullname(fe, fullname);
aPlatformFontList->AddFullnameLocked(fe, fullname);
}
if (!psname.IsEmpty()) {
aPlatformFontList->AddPostscriptName(fe, psname);
aPlatformFontList->AddPostscriptNameLocked(fe, psname);
}
foundFaceNames = true;
@ -2113,12 +2138,12 @@ void gfxFontFamily::ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
if (aNeedFullnamePostscriptNames && !foundFaceNames) {
if (gfxFontUtils::ReadCanonicalName(nameTable, gfxFontUtils::NAME_ID_FULL,
fullname) == NS_OK) {
aPlatformFontList->AddFullname(fe, fullname);
aPlatformFontList->AddFullnameLocked(fe, fullname);
}
if (gfxFontUtils::ReadCanonicalName(
nameTable, gfxFontUtils::NAME_ID_POSTSCRIPT, psname) == NS_OK) {
aPlatformFontList->AddPostscriptName(fe, psname);
aPlatformFontList->AddPostscriptNameLocked(fe, psname);
}
}
@ -2147,16 +2172,20 @@ void gfxFontFamily::ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
gfxFontEntry* gfxFontFamily::FindFont(const nsACString& aPostscriptName) {
// find the font using a simple linear search
AutoReadLock lock(mLock);
uint32_t numFonts = mAvailableFonts.Length();
for (uint32_t i = 0; i < numFonts; i++) {
gfxFontEntry* fe = mAvailableFonts[i].get();
if (fe && fe->Name() == aPostscriptName) return fe;
if (fe && fe->Name() == aPostscriptName) {
return fe;
}
}
return nullptr;
}
void gfxFontFamily::ReadAllCMAPs(FontInfoData* aFontInfoData) {
FindStyleVariations(aFontInfoData);
AutoWriteLock lock(mLock);
FindStyleVariationsLocked(aFontInfoData);
uint32_t i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
@ -2174,6 +2203,7 @@ void gfxFontFamily::ReadAllCMAPs(FontInfoData* aFontInfoData) {
void gfxFontFamily::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
AutoReadLock lock(mLock);
aSizes->mFontListSize += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize +=
mFamilyCharacterMap.SizeOfExcludingThis(aMallocSizeOf);

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

@ -790,10 +790,8 @@ class gfxFontEntry {
};
using FontTableCache = nsTHashtable<FontTableHashEntry>;
mozilla::Atomic<FontTableCache*> mFontTableCache GUARDED_BY(mLock);
FontTableCache* GetFontTableCache() const NO_THREAD_SAFETY_ANALYSIS {
return mFontTableCache;
}
mozilla::Atomic<FontTableCache*> mFontTableCache;
FontTableCache* GetFontTableCache() const { return mFontTableCache; }
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxFontEntry::RangeFlags)
@ -851,17 +849,12 @@ class gfxFontFamily {
gfxFontFamily(const nsACString& aName, FontVisibility aVisibility)
: mName(aName),
mLock("gfxFontFamily lock"),
mVisibility(aVisibility),
mOtherFamilyNamesInitialized(false),
mHasOtherFamilyNames(false),
mFaceNamesInitialized(false),
mHasStyles(false),
mIsSimpleFamily(false),
mIsBadUnderlineFamily(false),
mFamilyCharacterMapInitialized(false),
mSkipDefaultFeatureSpaceCheck(false),
mCheckForFallbackFaces(false),
mCheckedForLegacyFamilyNames(false) {}
mCheckForFallbackFaces(false) {}
const nsCString& Name() const { return mName; }
@ -874,11 +867,20 @@ class gfxFontFamily {
// faces in a large family into separate "styled families" because of
// GDI's 4-faces-per-family limitation). If found, the styled family
// name will be added to the font list's "other family names" table.
// Note that the caller must already hold the gfxPlatformFontList lock.
bool CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList);
nsTArray<RefPtr<gfxFontEntry>>& GetFontList() { return mAvailableFonts; }
nsTArray<RefPtr<gfxFontEntry>>& GetFontList() {
mozilla::AutoReadLock lock(mLock);
return mAvailableFonts;
}
void AddFontEntry(RefPtr<gfxFontEntry> aFontEntry) {
mozilla::AutoWriteLock lock(mLock);
AddFontEntryLocked(aFontEntry);
}
void AddFontEntryLocked(RefPtr<gfxFontEntry> aFontEntry) REQUIRES(mLock) {
// bug 589682 - set the IgnoreGDEF flag on entries for Italic faces
// of Times New Roman, because of buggy table in those fonts
if (aFontEntry->IsItalic() && !aFontEntry->IsUserFont() &&
@ -916,8 +918,10 @@ class gfxFontFamily {
nsTArray<gfxFontEntry*>& aFontEntryList,
bool aIgnoreSizeTolerance = false);
// checks for a matching font within the family
// used as part of the font fallback process
// Checks for a matching font within the family; used as part of the font
// fallback process.
// Note that when this is called, the caller must already be holding the
// gfxPlatformFontList lock.
void FindFontForChar(GlobalFontMatch* aMatchData);
// checks all fonts for a matching font within the family
@ -929,36 +933,51 @@ class gfxFontFamily {
// set when other family names have been read in
void SetOtherFamilyNamesInitialized() { mOtherFamilyNamesInitialized = true; }
// read in other localized family names, fullnames and Postscript names
// for all faces and append to lookup tables
// Read in other localized family names, fullnames and Postscript names
// for all faces and append to lookup tables.
// Note that when this is called, the caller must already be holding the
// gfxPlatformFontList lock.
virtual void ReadFaceNames(gfxPlatformFontList* aPlatformFontList,
bool aNeedFullnamePostscriptNames,
FontInfoData* aFontInfoData = nullptr);
// find faces belonging to this family (platform implementations override
// this; should be made pure virtual once all subclasses have been updated)
virtual void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) {}
// Find faces belonging to this family (platform implementations override).
// This is a no-op in cases where the family is explicitly populated by other
// means, rather than being asked to find its faces via system API.
virtual void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
REQUIRES(mLock){};
void FindStyleVariations(FontInfoData* aFontInfoData = nullptr) {
if (mHasStyles) {
return;
}
mozilla::AutoWriteLock lock(mLock);
FindStyleVariationsLocked(aFontInfoData);
}
// search for a specific face using the Postscript name
gfxFontEntry* FindFont(const nsACString& aPostscriptName);
// read in cmaps for all the faces
// Read in cmaps for all the faces.
// Note that when this is called, the caller must already be holding the
// gfxPlatformFontList lock.
void ReadAllCMAPs(FontInfoData* aFontInfoData = nullptr);
bool TestCharacterMap(uint32_t aCh) {
if (!mFamilyCharacterMapInitialized) {
ReadAllCMAPs();
}
mozilla::AutoReadLock lock(mLock);
return mFamilyCharacterMap.test(aCh);
}
void ResetCharacterMap() {
void ResetCharacterMap() REQUIRES(mLock) {
mFamilyCharacterMap.reset();
mFamilyCharacterMapInitialized = false;
}
// mark this family as being in the "bad" underline offset blocklist
void SetBadUnderlineFamily() {
mozilla::AutoWriteLock lock(mLock);
mIsBadUnderlineFamily = true;
if (mHasStyles) {
SetBadUnderlineFonts();
@ -971,12 +990,12 @@ class gfxFontFamily {
bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
// sort available fonts to put preferred (standard) faces towards the end
void SortAvailableFonts();
void SortAvailableFonts() REQUIRES(mLock);
// check whether the family fits into the simple 4-face model,
// so we can use simplified style-matching;
// if so set the mIsSimpleFamily flag (defaults to False before we've checked)
void CheckForSimpleFamily();
void CheckForSimpleFamily() REQUIRES(mLock);
// For memory reporter
virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
@ -1019,31 +1038,33 @@ class gfxFontFamily {
bool useFullName = false);
// set whether this font family is in "bad" underline offset blocklist.
void SetBadUnderlineFonts() {
uint32_t i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
if (mAvailableFonts[i]) {
mAvailableFonts[i]->mIsBadUnderlineFont = true;
void SetBadUnderlineFonts() REQUIRES(mLock) {
for (auto& f : mAvailableFonts) {
if (f) {
f->mIsBadUnderlineFont = true;
}
}
}
nsCString mName;
nsTArray<RefPtr<gfxFontEntry>> mAvailableFonts;
gfxSparseBitSet mFamilyCharacterMap;
nsTArray<RefPtr<gfxFontEntry>> mAvailableFonts GUARDED_BY(mLock);
gfxSparseBitSet mFamilyCharacterMap GUARDED_BY(mLock);
mutable mozilla::RWLock mLock;
FontVisibility mVisibility;
bool mOtherFamilyNamesInitialized : 1;
bool mHasOtherFamilyNames : 1;
bool mFaceNamesInitialized : 1;
bool mHasStyles : 1;
bool mIsSimpleFamily : 1;
mozilla::Atomic<bool> mOtherFamilyNamesInitialized;
mozilla::Atomic<bool> mFaceNamesInitialized;
mozilla::Atomic<bool> mHasStyles;
mozilla::Atomic<bool> mFamilyCharacterMapInitialized;
mozilla::Atomic<bool> mCheckedForLegacyFamilyNames;
mozilla::Atomic<bool> mHasOtherFamilyNames;
bool mIsSimpleFamily : 1 GUARDED_BY(mLock);
bool mIsBadUnderlineFamily : 1;
bool mFamilyCharacterMapInitialized : 1;
bool mSkipDefaultFeatureSpaceCheck : 1;
bool mCheckForFallbackFaces : 1; // check other faces for character
bool mCheckedForLegacyFamilyNames : 1;
enum {
// for "simple" families, the faces are stored in mAvailableFonts

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

@ -143,14 +143,24 @@ void gfxFontInfoLoader::StartLoader(uint32_t aDelay) {
return;
}
NS_ASSERTION(!mFontInfo, "fontinfo should be null when starting font loader");
// sanity check
if (mState != stateInitial && mState != stateTimerOff &&
mState != stateTimerOnDelay) {
CancelLoader();
}
// Create mFontInfo when we're initially called to set up the delay, rather
// than when called by the DelayedStartCallback, because on the initial call
// we know we'll be holding the gfxPlatformFontList lock.
if (!mFontInfo) {
mFontInfo = CreateFontInfoData();
if (!mFontInfo) {
// The platform doesn't want anything loaded, so just bail out.
mState = stateTimerOff;
return;
}
}
AddShutdownObserver();
// Caller asked for a delay? ==> start async thread after a delay
@ -195,13 +205,6 @@ void gfxFontInfoLoader::StartLoader(uint32_t aDelay) {
"Bug 1508626 - Initializing font loader after shutdown but "
"before observer");
mFontInfo = CreateFontInfoData();
if (!mFontInfo) {
// The platform doesn't want anything loaded, so just bail out.
mState = stateTimerOff;
return;
}
// initialize
InitLoader();

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

@ -119,7 +119,9 @@ GDIFontEntry::GDIFontEntry(const nsACString& aFaceName,
mStyleRange = aStyle;
mWeightRange = aWeight;
mStretchRange = aStretch;
if (IsType1()) mForceGDI = true;
if (IsType1()) {
mForceGDI = true;
}
mIsDataUserFont = aUserFontData != nullptr;
InitLogFont(aFaceName, aFontType);
@ -372,10 +374,8 @@ GDIFontEntry* GDIFontEntry::CreateFontEntry(const nsACString& aName,
gfxUserFontData* aUserFontData) {
// jtdfix - need to set charset, unicode ranges, pitch/family
GDIFontEntry* fe = new GDIFontEntry(aName, aFontType, aStyle, aWeight,
aStretch, aUserFontData);
return fe;
return new GDIFontEntry(aName, aFontType, aStyle, aWeight, aStretch,
aUserFontData);
}
void GDIFontEntry::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
@ -454,9 +454,12 @@ int CALLBACK GDIFontFamily::FamilyAddStylesProc(
SlantStyleRange(italicStyle),
WeightRange(FontWeight(int32_t(logFont.lfWeight))),
StretchRange(FontStretch::Normal()), nullptr);
if (!fe) return 1;
if (!fe) {
return 1;
}
ff->AddFontEntry(fe);
MOZ_ASSERT(ff->mLock.LockedForWritingByCurrentThread());
ff->AddFontEntryLocked(fe);
if (nmetrics->ntmFontSig.fsUsb[0] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[1] != 0x00000000 &&
@ -482,8 +485,10 @@ int CALLBACK GDIFontFamily::FamilyAddStylesProc(
return 1;
}
void GDIFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
if (mHasStyles) return;
void GDIFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
if (mHasStyles) {
return;
}
mHasStyles = true;
HDC hdc = GetDC(nullptr);
@ -838,13 +843,11 @@ gfxFontEntry* gfxGDIFontList::MakePlatformFont(const nsACString& aFontName,
return fe;
}
bool gfxGDIFontList::FindAndAddFamilies(nsPresContext* aPresContext,
StyleGenericFontFamily aGeneric,
const nsACString& aFamily,
nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags,
gfxFontStyle* aStyle, nsAtom* aLanguage,
gfxFloat aDevToCssSize) {
bool gfxGDIFontList::FindAndAddFamiliesLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle, nsAtom* aLanguage,
gfxFloat aDevToCssSize) {
NS_ConvertUTF8toUTF16 key16(aFamily);
BuildKeyNameFromFontName(key16);
NS_ConvertUTF16toUTF8 keyName(key16);
@ -861,7 +864,7 @@ bool gfxGDIFontList::FindAndAddFamilies(nsPresContext* aPresContext,
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(
return gfxPlatformFontList::FindAndAddFamiliesLocked(
aPresContext, aGeneric, aFamily, aOutput, aFlags, aStyle, aLanguage,
aDevToCssSize);
}
@ -897,6 +900,9 @@ FontFamily gfxGDIFontList::GetDefaultFontForPlatform(
void gfxGDIFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
AutoLock lock(mLock);
aSizes->mFontListSize +=
SizeOfFontFamilyTableExcludingThis(mFontSubstitutes, aMallocSizeOf);
aSizes->mFontListSize +=

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

@ -193,7 +193,8 @@ class GDIFontFamily final : public gfxFontFamily {
mWindowsPitch(0),
mCharset() {}
virtual void FindStyleVariations(FontInfoData* aFontInfoData = nullptr);
void FindStyleVariationsLocked(
FontInfoData* aFontInfoData = nullptr) override;
bool FilterForFontList(nsAtom* aLangGroup,
const nsACString& aGeneric) const final {
@ -304,7 +305,7 @@ class gfxGDIFontList final : public gfxPlatformFontList {
gfxFontFamily* CreateFontFamily(const nsACString& aName,
FontVisibility aVisibility) const override;
bool FindAndAddFamilies(
bool FindAndAddFamiliesLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,

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

@ -140,11 +140,12 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
const uint8_t* aFontData,
uint32_t aLength) override;
bool FindAndAddFamilies(
bool FindAndAddFamiliesLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0) override;
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
REQUIRES(mLock) override;
// lookup the system font for a particular system font type and set
// the name and style characteristics
@ -163,7 +164,8 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
protected:
FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
const gfxFontStyle* aStyle,
nsAtom* aLanguage = nullptr) override;
nsAtom* aLanguage = nullptr)
REQUIRES(mLock) override;
private:
friend class gfxPlatformMac;
@ -172,22 +174,23 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
virtual ~gfxMacPlatformFontList();
// initialize font lists
nsresult InitFontListForPlatform() override;
void InitSharedFontListForPlatform() override;
nsresult InitFontListForPlatform() REQUIRES(mLock) override;
void InitSharedFontListForPlatform() REQUIRES(mLock) override;
// handle commonly used fonts for which the name table should be loaded at
// startup
void PreloadNamesList();
void PreloadNamesList() REQUIRES(mLock);
// special case font faces treated as font families (set via prefs)
void InitSingleFaceList();
void InitAliasesForSingleFaceList();
void InitSingleFaceList() REQUIRES(mLock);
void InitAliasesForSingleFaceList() REQUIRES(mLock);
// initialize system fonts
void InitSystemFontNames();
void InitSystemFontNames() REQUIRES(mLock);
// helper function to lookup in both hidden system fonts and normal fonts
gfxFontFamily* FindSystemFontFamily(const nsACString& aFamily);
gfxFontFamily* FindSystemFontFamily(const nsACString& aFamily)
REQUIRES(mLock);
FontVisibility GetVisibilityForFamily(const nsACString& aName) const;
@ -201,7 +204,8 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
const uint32_t aCh,
Script aRunScript,
const gfxFontStyle* aMatchStyle,
FontFamily& aMatchedFamily) override;
FontFamily& aMatchedFamily)
REQUIRES(mLock) override;
bool UsesSystemFallback() override { return true; }
@ -212,9 +216,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
// file is included in .cpp files, so we can't use objective C classes here.
// But CFStringRef and NSString* are the same thing anyway (they're
// toll-free bridged).
void AddFamily(CFStringRef aFamily);
void AddFamily(CFStringRef aFamily) REQUIRES(mLock);
void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility);
void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility)
REQUIRES(mLock);
gfxFontEntry* CreateFontEntry(
mozilla::fontlist::Face* aFace,
@ -226,7 +231,8 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
bool aLoadCmaps) const override;
void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
bool aNeedFullnamePostscriptNames) override;
bool aNeedFullnamePostscriptNames)
REQUIRES(mLock) override;
enum { kATSGenerationInitial = -1 };

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

@ -583,14 +583,14 @@ void MacOSFontEntry::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
class gfxMacFontFamily final : public gfxFontFamily {
public:
gfxMacFontFamily(const nsACString& aName, FontVisibility aVisibility, double aSizeHint)
gfxMacFontFamily(const nsACString& aName, FontVisibility aVisibility, double aSizeHint = 0.0)
: gfxFontFamily(aName, aVisibility), mSizeHint(aSizeHint) {}
virtual ~gfxMacFontFamily() = default;
virtual void LocalizedName(nsACString& aLocalizedName);
void LocalizedName(nsACString& aLocalizedName) override;
virtual void FindStyleVariations(FontInfoData* aFontInfoData = nullptr);
void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr) REQUIRES(mLock) override;
protected:
double mSizeHint;
@ -634,7 +634,7 @@ static inline int GetWeightOverride(const nsAString& aPSName) {
return Preferences::GetInt(prefName.get(), 0);
}
void gfxMacFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
if (mHasStyles) {
return;
}
@ -735,7 +735,7 @@ void gfxMacFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
}
// insert into font entry array of family
AddFontEntry(fontEntry);
AddFontEntryLocked(fontEntry);
}
SortAvailableFonts();
@ -760,16 +760,20 @@ class gfxSingleFaceMacFontFamily final : public gfxFontFamily {
virtual ~gfxSingleFaceMacFontFamily() = default;
virtual void LocalizedName(nsACString& aLocalizedName);
void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr) REQUIRES(mLock) override{};
virtual void ReadOtherFamilyNames(gfxPlatformFontList* aPlatformFontList);
void LocalizedName(nsACString& aLocalizedName) override;
virtual bool IsSingleFaceFamily() const { return true; }
void ReadOtherFamilyNames(gfxPlatformFontList* aPlatformFontList) override;
bool IsSingleFaceFamily() const override { return true; }
};
void gfxSingleFaceMacFontFamily::LocalizedName(nsACString& aLocalizedName) {
nsAutoreleasePool localPool;
AutoReadLock lock(mLock);
if (!HasOtherFamilyNames()) {
aLocalizedName = mName;
return;
@ -797,6 +801,7 @@ void gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(gfxPlatformFontList* aPlat
return;
}
AutoWriteLock lock(mLock);
gfxFontEntry* fe = mAvailableFonts[0];
if (!fe) {
return;
@ -888,7 +893,8 @@ void gfxMacPlatformFontList::AddFamily(CFStringRef aFamily) {
AddFamily(nameUtf8, GetVisibilityForFamily(nameUtf8));
}
void gfxMacPlatformFontList::ReadSystemFontList(dom::SystemFontList* aList) {
void gfxMacPlatformFontList::ReadSystemFontList(dom::SystemFontList* aList)
NO_THREAD_SAFETY_ANALYSIS {
// Note: We rely on the records for mSystemTextFontFamilyName and
// mSystemDisplayFontFamilyName (if present) being *before* the main
// font list, so that those names are known in the content process
@ -1203,7 +1209,7 @@ static NSString* GetRealFamilyName(NSFont* aFont) {
// so we expect the system font to be a variable-weight face rather than requiring
// a number of discrete faces of different weights.
static gfxFontFamily* CreateFamilyForSystemFont(NSFont* aFont, const nsACString& aFamilyName) {
gfxFontFamily* familyEntry = new gfxFontFamily(aFamilyName, FontVisibility::Unknown);
gfxFontFamily* familyEntry = new gfxMacFontFamily(aFamilyName, FontVisibility::Unknown);
NSString* psNameNS = [[aFont fontDescriptor] postscriptName];
nsAutoString nameUTF16;
@ -1366,7 +1372,7 @@ gfxFontEntry* gfxMacPlatformFontList::PlatformGlobalFontFallback(nsPresContext*
if (family) {
fontlist::Face* face = family->FindFaceForStyle(SharedFontList(), *aMatchStyle);
if (face) {
fontEntry = GetOrCreateFontEntry(face, family);
fontEntry = GetOrCreateFontEntryLocked(face, family);
}
if (fontEntry) {
if (fontEntry->HasCharacter(aCh)) {
@ -1437,6 +1443,8 @@ gfxFontEntry* gfxMacPlatformFontList::LookupLocalFont(nsPresContext* aPresContex
return nullptr;
}
AutoLock lock(mLock);
nsAutoreleasePool localPool;
NSString* faceName = GetNSStringForString(NS_ConvertUTF8toUTF16(aFontName));
@ -1521,12 +1529,10 @@ gfxFontEntry* gfxMacPlatformFontList::MakePlatformFont(const nsACString& aFontNa
// WebCore/platform/graphics/mac/FontCacheMac.mm
static const char kSystemFont_system[] = "-apple-system";
bool gfxMacPlatformFontList::FindAndAddFamilies(nsPresContext* aPresContext,
StyleGenericFontFamily aGeneric,
const nsACString& aFamily,
nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle,
nsAtom* aLanguage, gfxFloat aDevToCssSize) {
bool gfxMacPlatformFontList::FindAndAddFamiliesLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGeneric, const nsACString& aFamily,
nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags, gfxFontStyle* aStyle,
nsAtom* aLanguage, gfxFloat aDevToCssSize) {
if (aFamily.EqualsLiteral(kSystemFont_system)) {
// Search for special system font name, -apple-system. This is not done via
// the shared fontlist on Catalina or later, because the hidden system font
@ -1539,9 +1545,9 @@ bool gfxMacPlatformFontList::FindAndAddFamilies(nsPresContext* aPresContext,
: mSystemTextFontFamilyName;
if (SharedFontList() && !nsCocoaFeatures::OnCatalinaOrLater()) {
FindFamiliesFlags flags = aFlags | FindFamiliesFlags::eSearchHiddenFamilies;
return gfxPlatformFontList::FindAndAddFamilies(aPresContext, aGeneric, systemFontFamilyName,
aOutput, flags, aStyle, aLanguage,
aDevToCssSize);
return gfxPlatformFontList::FindAndAddFamiliesLocked(aPresContext, aGeneric,
systemFontFamilyName, aOutput, flags,
aStyle, aLanguage, aDevToCssSize);
} else {
if (auto* fam = FindSystemFontFamily(systemFontFamilyName)) {
aOutput->AppendElement(fam);
@ -1551,8 +1557,8 @@ bool gfxMacPlatformFontList::FindAndAddFamilies(nsPresContext* aPresContext,
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(aPresContext, aGeneric, aFamily, aOutput, aFlags,
aStyle, aLanguage, aDevToCssSize);
return gfxPlatformFontList::FindAndAddFamiliesLocked(aPresContext, aGeneric, aFamily, aOutput,
aFlags, aStyle, aLanguage, aDevToCssSize);
}
void gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID,
@ -1730,6 +1736,7 @@ already_AddRefed<FontInfoData> gfxMacPlatformFontList::CreateFontInfoData() {
bool loadCmaps =
!UsesSystemFallback() || gfxPlatform::GetPlatform()->UseCmapsDuringSystemFallback();
mLock.AssertCurrentThreadIn();
RefPtr<MacFontInfo> fi = new MacFontInfo(true, NeedFullnamePostscriptNames(), loadCmaps);
return fi.forget();
}

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

@ -264,7 +264,7 @@ bool gfxPlatformFontList::Initialize(gfxPlatformFontList* aList) {
}
gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
: mFontFamiliesMutex("gfxPlatformFontList::mFontFamiliesMutex"),
: mLock("gfxPlatformFontList lock"),
mFontFamilies(64),
mOtherFamilyNames(16),
mSharedCmaps(8) {
@ -305,7 +305,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
gfxPlatformFontList::~gfxPlatformFontList() {
mSharedCmaps.Clear();
ClearLangGroupPrefFonts();
ClearLangGroupPrefFontsLocked();
NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
@ -375,6 +375,7 @@ void gfxPlatformFontList::ApplyWhitelist() {
void gfxPlatformFontList::ApplyWhitelist(
nsTArray<fontlist::Family::InitData>& aFamilies) {
mLock.AssertCurrentThreadIn();
mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
if (!mFontFamilyWhitelistActive) {
return;
@ -435,6 +436,7 @@ void gfxPlatformFontList::CheckFamilyList(const char* aList[], size_t aCount) {
bool gfxPlatformFontList::AddWithLegacyFamilyName(const nsACString& aLegacyName,
gfxFontEntry* aFontEntry,
FontVisibility aVisibility) {
mLock.AssertCurrentThreadIn();
bool added = false;
nsAutoCString key;
ToLowerCase(aLegacyName, key);
@ -455,7 +457,14 @@ bool gfxPlatformFontList::AddWithLegacyFamilyName(const nsACString& aLegacyName,
}
bool gfxPlatformFontList::InitFontList() {
MutexAutoLock lock(mFontFamiliesMutex);
// If the startup font-list-init thread is still running, we need to wait
// for it to finish before trying to reinitialize here.
if (sInitFontListThread && !IsInitFontListThread()) {
PR_JoinThread(sInitFontListThread);
sInitFontListThread = nullptr;
}
AutoLock lock(mLock);
if (LOG_FONTINIT_ENABLED()) {
LOG_FONTINIT(("(fontinit) system fontlist initialization\n"));
@ -507,7 +516,7 @@ bool gfxPlatformFontList::InitFontList() {
mExtraNames->mPostscriptNames.Clear();
}
mFaceNameListsInitialized = false;
ClearLangGroupPrefFonts();
ClearLangGroupPrefFontsLocked();
CancelLoader();
// Clear cached family records that will no longer be valid.
@ -576,14 +585,15 @@ bool gfxPlatformFontList::InitFontList() {
// Set up mDefaultFontEntry as a "last resort" default that we can use
// to avoid crashing if the font list is otherwise unusable.
gfxFontStyle defStyle;
FontFamily fam = GetDefaultFont(nullptr, &defStyle);
FontFamily fam = GetDefaultFontLocked(nullptr, &defStyle);
gfxFontEntry* fe;
if (fam.mIsShared) {
auto face = fam.mShared->FindFaceForStyle(SharedFontList(), defStyle);
mDefaultFontEntry =
face ? GetOrCreateFontEntry(face, fam.mShared) : nullptr;
fe = face ? GetOrCreateFontEntryLocked(face, fam.mShared) : nullptr;
} else {
mDefaultFontEntry = fam.mUnshared->FindFontForStyle(defStyle);
fe = fam.mUnshared->FindFontForStyle(defStyle);
}
mDefaultFontEntry = fe;
return true;
}
@ -610,6 +620,7 @@ void gfxPlatformFontList::InitializeCodepointsWithNoFonts() {
void gfxPlatformFontList::FontListChanged() {
MOZ_ASSERT(!XRE_IsParentProcess());
AutoLock lock(mLock);
InitializeCodepointsWithNoFonts();
if (SharedFontList()) {
// If we're using a shared local face-name list, this may have changed
@ -641,8 +652,10 @@ class InitOtherFamilyNamesForStylo : public mozilla::Runnable {
if (!list) {
return NS_OK;
}
bool initialized = false;
dom::ContentChild::GetSingleton()->SendInitOtherFamilyNames(
list->GetGeneration(), mDefer, &pfl->mOtherFamilyNamesInitialized);
list->GetGeneration(), mDefer, &initialized);
pfl->mOtherFamilyNamesInitialized.compareExchange(false, initialized);
return NS_OK;
}
@ -660,9 +673,11 @@ bool gfxPlatformFontList::InitOtherFamilyNames(
if (SharedFontList() && !XRE_IsParentProcess()) {
if (NS_IsMainThread()) {
bool initialized;
dom::ContentChild::GetSingleton()->SendInitOtherFamilyNames(
SharedFontList()->GetGeneration(), aDeferOtherFamilyNamesLoading,
&mOtherFamilyNamesInitialized);
&initialized);
mOtherFamilyNamesInitialized.compareExchange(false, initialized);
} else {
NS_DispatchToMainThread(
new InitOtherFamilyNamesForStylo(aDeferOtherFamilyNamesLoading));
@ -836,6 +851,7 @@ void gfxPlatformFontList::UpdateFontList(bool aFullRebuild) {
MOZ_ASSERT(NS_IsMainThread());
if (aFullRebuild) {
InitFontList();
AutoLock lock(mLock);
RebuildLocalFonts();
} else {
// The font list isn't being fully rebuilt, we're just being notified that
@ -843,6 +859,7 @@ void gfxPlatformFontList::UpdateFontList(bool aFullRebuild) {
// done. We only care about this if we have previously encountered a
// fallback that required cmaps that were not yet available, and so we
// asked for the async cmap loader to run.
AutoLock lock(mLock);
if (mStartedLoadingCmapsFrom != 0xffffffffu) {
InitializeCodepointsWithNoFonts();
mStartedLoadingCmapsFrom = 0xffffffffu;
@ -864,6 +881,8 @@ bool gfxPlatformFontList::IsVisibleToCSS(const fontlist::Family& aFamily,
void gfxPlatformFontList::GetFontList(nsAtom* aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts) {
AutoLock lock(mLock);
if (SharedFontList()) {
fontlist::FontList* list = SharedFontList();
const fontlist::Family* families = list->Families();
@ -882,7 +901,6 @@ void gfxPlatformFontList::GetFontList(nsAtom* aLangGroup,
return;
}
MutexAutoLock lock(mFontFamiliesMutex);
for (const RefPtr<gfxFontFamily>& family : mFontFamilies.Values()) {
if (!IsVisibleToCSS(*family, FontVisibility::User)) {
continue;
@ -900,6 +918,7 @@ void gfxPlatformFontList::GetFontList(nsAtom* aLangGroup,
void gfxPlatformFontList::GetFontFamilyList(
nsTArray<RefPtr<gfxFontFamily>>& aFamilyArray) {
AutoLock lock(mLock);
MOZ_ASSERT(aFamilyArray.IsEmpty());
// This doesn't use ToArray, because the caller passes an AutoTArray.
aFamilyArray.SetCapacity(mFontFamilies.Count());
@ -912,6 +931,7 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
nsPresContext* aPresContext, uint32_t aCh, uint32_t aNextCh,
Script aRunScript, eFontPresentation aPresentation,
const gfxFontStyle* aStyle, FontVisibility* aVisibility) {
AutoLock lock(mLock);
FontVisibility level =
aPresContext ? aPresContext->GetFontVisibility() : FontVisibility::User;
MOZ_ASSERT(!mCodepointsWithNoFonts[level].test(aCh),
@ -928,7 +948,7 @@ gfxFont* gfxPlatformFontList::SystemFindFontForChar(
fontlist::Face* face =
fallbackFamily.mShared->FindFaceForStyle(SharedFontList(), *aStyle);
if (face) {
fontEntry = GetOrCreateFontEntry(face, fallbackFamily.mShared);
fontEntry = GetOrCreateFontEntryLocked(face, fallbackFamily.mShared);
*aVisibility = fallbackFamily.mShared->Visibility();
}
} else if (!fallbackFamily.mIsShared && fallbackFamily.mUnshared) {
@ -1357,9 +1377,11 @@ class LoadCmapsRunnable : public CancelableRunnable {
RefPtr<CancelableRunnable> task = this;
NS_DispatchToMainThreadQueue(task.forget(), EventQueuePriority::Idle);
} else {
pfl->Lock();
pfl->CancelLoadCmapsTask();
pfl->InitializeCodepointsWithNoFonts();
dom::ContentParent::NotifyUpdatedFonts(false);
pfl->Unlock();
}
return NS_OK;
}
@ -1416,7 +1438,7 @@ gfxFontFamily* gfxPlatformFontList::CheckFamily(gfxFontFamily* aFamily) {
}
if (aFamily && aFamily->GetFontList().Length() == 0) {
// failed to load any faces for this family, so discard it
// Failed to load any faces for this family, so discard it.
nsAutoCString key;
GenerateFontListKey(aFamily->Name(), key);
mFontFamilies.Remove(key);
@ -1426,7 +1448,7 @@ gfxFontFamily* gfxPlatformFontList::CheckFamily(gfxFontFamily* aFamily) {
return aFamily;
}
bool gfxPlatformFontList::FindAndAddFamilies(
bool gfxPlatformFontList::FindAndAddFamiliesLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle, nsAtom* aLanguage,
@ -1437,6 +1459,7 @@ bool gfxPlatformFontList::FindAndAddFamilies(
bool allowHidden = bool(aFlags & FindFamiliesFlags::eSearchHiddenFamilies);
FontVisibility visibilityLevel =
aPresContext ? aPresContext->GetFontVisibility() : FontVisibility::User;
if (SharedFontList()) {
fontlist::Family* family = SharedFontList()->FindFamily(key);
// If not found, and other family names have not yet been initialized,
@ -1471,12 +1494,7 @@ bool gfxPlatformFontList::FindAndAddFamilies(
}
if (!family && !mOtherFamilyNamesInitialized &&
!(aFlags & FindFamiliesFlags::eNoAddToNamesMissedWhenSearching)) {
// localized family names load timed out, add name to list of
// names to check after localized names are loaded
if (!mOtherNamesMissed) {
mOtherNamesMissed = MakeUnique<nsTHashSet<nsCString>>(2);
}
mOtherNamesMissed->Insert(key);
AddToMissedNames(key);
}
}
// Check whether the family we found is actually allowed to be looked up,
@ -1539,10 +1557,7 @@ bool gfxPlatformFontList::FindAndAddFamilies(
!(aFlags & FindFamiliesFlags::eNoAddToNamesMissedWhenSearching)) {
// localized family names load timed out, add name to list of
// names to check after localized names are loaded
if (!mOtherNamesMissed) {
mOtherNamesMissed = MakeUnique<nsTHashSet<nsCString>>(2);
}
mOtherNamesMissed->Insert(key);
AddToMissedNames(key);
}
if (familyEntry) {
if (isBlockedByVisibilityLevel(familyEntry)) {
@ -1594,6 +1609,13 @@ bool gfxPlatformFontList::FindAndAddFamilies(
return false;
}
void gfxPlatformFontList::AddToMissedNames(const nsCString& aKey) {
if (!mOtherNamesMissed) {
mOtherNamesMissed = MakeUnique<nsTHashSet<nsCString>>(2);
}
mOtherNamesMissed->Insert(aKey);
}
fontlist::Family* gfxPlatformFontList::FindSharedFamily(
nsPresContext* aPresContext, const nsACString& aFamily,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle, nsAtom* aLanguage,
@ -1602,8 +1624,9 @@ fontlist::Family* gfxPlatformFontList::FindSharedFamily(
return nullptr;
}
AutoTArray<FamilyAndGeneric, 1> families;
if (!FindAndAddFamilies(aPresContext, StyleGenericFontFamily::None, aFamily,
&families, aFlags, aStyle, aLanguage, aDevToCss) ||
if (!FindAndAddFamiliesLocked(aPresContext, StyleGenericFontFamily::None,
aFamily, &families, aFlags, aStyle, aLanguage,
aDevToCss) ||
!families[0].mFamily.mIsShared) {
return nullptr;
}
@ -1707,6 +1730,7 @@ gfxFontEntry* gfxPlatformFontList::FindFontForFamily(
const gfxFontStyle* aStyle) {
nsAutoCString key;
GenerateFontListKey(aFamily, key);
FontFamily family = FindFamily(aPresContext, key);
if (family.IsNull()) {
return nullptr;
@ -1716,12 +1740,12 @@ gfxFontEntry* gfxPlatformFontList::FindFontForFamily(
if (!face) {
return nullptr;
}
return GetOrCreateFontEntry(face, family.mShared);
return GetOrCreateFontEntryLocked(face, family.mShared);
}
return family.mUnshared->FindFontForStyle(*aStyle);
}
gfxFontEntry* gfxPlatformFontList::GetOrCreateFontEntry(
gfxFontEntry* gfxPlatformFontList::GetOrCreateFontEntryLocked(
fontlist::Face* aFace, const fontlist::Family* aFamily) {
return mFontEntries
.LookupOrInsertWith(aFace,
@ -1729,25 +1753,28 @@ gfxFontEntry* gfxPlatformFontList::GetOrCreateFontEntry(
.get();
}
void gfxPlatformFontList::AddOtherFamilyName(
gfxFontFamily* aFamilyEntry, const nsCString& aOtherFamilyName) {
nsAutoCString key;
GenerateFontListKey(aOtherFamilyName, key);
void gfxPlatformFontList::AddOtherFamilyNames(
gfxFontFamily* aFamilyEntry, const nsTArray<nsCString>& aOtherFamilyNames) {
AutoLock lock(mLock);
mOtherFamilyNames.LookupOrInsertWith(key, [&] {
LOG_FONTLIST(
("(fontlist-otherfamily) canonical family: %s, "
"other family: %s\n",
aFamilyEntry->Name().get(), aOtherFamilyName.get()));
if (mBadUnderlineFamilyNames.ContainsSorted(key)) {
aFamilyEntry->SetBadUnderlineFamily();
}
return RefPtr{aFamilyEntry};
});
for (const auto& name : aOtherFamilyNames) {
nsAutoCString key;
GenerateFontListKey(name, key);
mOtherFamilyNames.LookupOrInsertWith(key, [&] {
LOG_FONTLIST(
("(fontlist-otherfamily) canonical family: %s, other family: %s\n",
aFamilyEntry->Name().get(), name.get()));
if (mBadUnderlineFamilyNames.ContainsSorted(key)) {
aFamilyEntry->SetBadUnderlineFamily();
}
return RefPtr{aFamilyEntry};
});
}
}
void gfxPlatformFontList::AddFullname(gfxFontEntry* aFontEntry,
const nsCString& aFullname) {
void gfxPlatformFontList::AddFullnameLocked(gfxFontEntry* aFontEntry,
const nsCString& aFullname) {
mExtraNames->mFullnames.LookupOrInsertWith(aFullname, [&] {
LOG_FONTLIST(("(fontlist-fullname) name: %s, fullname: %s\n",
aFontEntry->Name().get(), aFullname.get()));
@ -1755,8 +1782,8 @@ void gfxPlatformFontList::AddFullname(gfxFontEntry* aFontEntry,
});
}
void gfxPlatformFontList::AddPostscriptName(gfxFontEntry* aFontEntry,
const nsCString& aPostscriptName) {
void gfxPlatformFontList::AddPostscriptNameLocked(
gfxFontEntry* aFontEntry, const nsCString& aPostscriptName) {
mExtraNames->mPostscriptNames.LookupOrInsertWith(aPostscriptName, [&] {
LOG_FONTLIST(("(fontlist-postscript) name: %s, psname: %s\n",
aFontEntry->Name().get(), aPostscriptName.get()));
@ -1766,6 +1793,7 @@ void gfxPlatformFontList::AddPostscriptName(gfxFontEntry* aFontEntry,
bool gfxPlatformFontList::GetStandardFamilyName(const nsCString& aFontName,
nsACString& aFamilyName) {
AutoLock lock(mLock);
FontFamily family = FindFamily(nullptr, aFontName);
if (family.IsNull()) {
return false;
@ -1794,6 +1822,8 @@ FamilyAndGeneric gfxPlatformFontList::GetDefaultFontFamily(
return FamilyAndGeneric();
}
AutoLock lock(mLock);
nsAutoCString value;
AutoTArray<nsCString, 4> names;
if (mFontPrefs->LookupNameList(PrefName(aGenericFamily, aLangGroup), value)) {
@ -1819,7 +1849,7 @@ ShmemCharMapHashEntry::ShmemCharMapHashEntry(const gfxSparseBitSet* aCharMap)
SharedBitSet::Create(mCharMap.ToPtr(mList), len, *aCharMap);
}
fontlist::Pointer gfxPlatformFontList::GetShmemCharMap(
fontlist::Pointer gfxPlatformFontList::GetShmemCharMapLocked(
const gfxSparseBitSet* aCmap) {
auto* entry = mShmemCharMaps.GetEntry(aCmap);
if (!entry) {
@ -1828,22 +1858,18 @@ fontlist::Pointer gfxPlatformFontList::GetShmemCharMap(
return entry->GetCharMap();
}
// lookup cmap in the shared cmap set, adding if not already present
gfxCharacterMap* gfxPlatformFontList::FindCharMap(gfxCharacterMap* aCmap) {
AutoLock lock(mLock);
aCmap->CalcHash();
gfxCharacterMap* cmap = AddCmap(aCmap);
gfxCharacterMap* cmap = mSharedCmaps.PutEntry(aCmap)->GetKey();
cmap->mShared = true;
return cmap;
}
// add a cmap to the shared cmap set
gfxCharacterMap* gfxPlatformFontList::AddCmap(const gfxCharacterMap* aCharMap) {
CharMapHashKey* found =
mSharedCmaps.PutEntry(const_cast<gfxCharacterMap*>(aCharMap));
return found->GetKey();
}
// remove the cmap from the shared cmap set
void gfxPlatformFontList::RemoveCmap(const gfxCharacterMap* aCharMap) {
AutoLock lock(mLock);
// skip lookups during teardown
if (mSharedCmaps.Count() == 0) {
return;
@ -1939,8 +1965,9 @@ void gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(
// lookup and add platform fonts uniquely
for (const nsCString& genericFamily : aGenericNameFamilies) {
AutoTArray<FamilyAndGeneric, 10> families;
FindAndAddFamilies(aPresContext, aGenericType, genericFamily, &families,
FindFamiliesFlags(0), nullptr, aLangGroup);
FindAndAddFamiliesLocked(aPresContext, aGenericType, genericFamily,
&families, FindFamiliesFlags(0), nullptr,
aLangGroup);
for (const FamilyAndGeneric& f : families) {
if (!aGenericFamilies->Contains(f.mFamily)) {
aGenericFamilies->AppendElement(f.mFamily);
@ -1949,7 +1976,8 @@ void gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(
}
}
gfxPlatformFontList::PrefFontList* gfxPlatformFontList::GetPrefFontsLangGroup(
gfxPlatformFontList::PrefFontList*
gfxPlatformFontList::GetPrefFontsLangGroupLocked(
nsPresContext* aPresContext, StyleGenericFontFamily aGenericType,
eFontPrefLang aPrefLang) {
if (aGenericType == StyleGenericFontFamily::MozEmoji ||
@ -1977,6 +2005,8 @@ gfxPlatformFontList::PrefFontList* gfxPlatformFontList::GetPrefFontsLangGroup(
void gfxPlatformFontList::AddGenericFonts(
nsPresContext* aPresContext, StyleGenericFontFamily aGenericType,
nsAtom* aLanguage, nsTArray<FamilyAndGeneric>& aFamilyList) {
AutoLock lock(mLock);
// map lang ==> langGroup
nsAtom* langGroup = GetLangGroup(aLanguage);
@ -1985,7 +2015,7 @@ void gfxPlatformFontList::AddGenericFonts(
// lookup pref fonts
PrefFontList* prefFonts =
GetPrefFontsLangGroup(aPresContext, aGenericType, prefLang);
GetPrefFontsLangGroupLocked(aPresContext, aGenericType, prefLang);
if (!prefFonts->IsEmpty()) {
aFamilyList.SetCapacity(aFamilyList.Length() + prefFonts->Length());
@ -2181,6 +2211,7 @@ bool gfxPlatformFontList::IsLangCJK(eFontPrefLang aLang) {
void gfxPlatformFontList::GetLangPrefs(eFontPrefLang aPrefLangs[],
uint32_t& aLen, eFontPrefLang aCharLang,
eFontPrefLang aPageLang) {
AutoLock lock(mLock);
if (IsLangCJK(aCharLang)) {
AppendCJKPrefLangs(aPrefLangs, aLen, aCharLang, aPageLang);
} else {
@ -2351,6 +2382,8 @@ StyleGenericFontFamily gfxPlatformFontList::GetDefaultGeneric(
return StyleGenericFontFamily::MozEmoji;
}
AutoLock lock(mLock);
// initialize lang group pref font defaults (i.e. serif/sans-serif)
if (MOZ_UNLIKELY(mDefaultGenericsLangGroup.IsEmpty())) {
mDefaultGenericsLangGroup.AppendElements(ArrayLength(gPrefLangNames));
@ -2375,6 +2408,12 @@ StyleGenericFontFamily gfxPlatformFontList::GetDefaultGeneric(
FontFamily gfxPlatformFontList::GetDefaultFont(nsPresContext* aPresContext,
const gfxFontStyle* aStyle) {
AutoLock lock(mLock);
return GetDefaultFontLocked(aPresContext, aStyle);
}
FontFamily gfxPlatformFontList::GetDefaultFontLocked(
nsPresContext* aPresContext, const gfxFontStyle* aStyle) {
FontFamily family = GetDefaultFontForPlatform(aPresContext, aStyle);
if (!family.IsNull()) {
return family;
@ -2461,6 +2500,7 @@ void gfxPlatformFontList::InitLoader() {
20 // max time for one pass through RunLoader = 20ms
bool gfxPlatformFontList::LoadFontInfo() {
AutoLock lock(mLock);
TimeStamp start = TimeStamp::Now();
uint32_t i, endIndex = mNumFamilies;
fontlist::FontList* list = SharedFontList();
@ -2528,6 +2568,8 @@ bool gfxPlatformFontList::LoadFontInfo() {
}
void gfxPlatformFontList::CleanupLoader() {
AutoLock lock(mLock);
mFontFamiliesToLoad.Clear();
mNumFamilies = 0;
bool rebuilt = false, forceReflow = false;
@ -2535,7 +2577,10 @@ void gfxPlatformFontList::CleanupLoader() {
// if had missed face names that are now available, force reflow all
if (mFaceNamesMissed) {
rebuilt = std::any_of(mFaceNamesMissed->cbegin(), mFaceNamesMissed->cend(),
[&](const auto& key) { return FindFaceName(key); });
[&](const auto& key) {
mLock.AssertCurrentThreadIn();
return FindFaceName(key);
});
if (rebuilt) {
RebuildLocalFonts();
}
@ -2547,6 +2592,7 @@ void gfxPlatformFontList::CleanupLoader() {
forceReflow = std::any_of(
mOtherNamesMissed->cbegin(), mOtherNamesMissed->cend(),
[&](const auto& key) {
mLock.AssertCurrentThreadIn();
return FindUnsharedFamily(
nullptr, key,
(FindFamiliesFlags::eForceOtherFamilyNamesLoading |
@ -2580,8 +2626,11 @@ void gfxPlatformFontList::GetPrefsAndStartLoader() {
StartLoader(delay);
} else {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"StartLoader callback",
[delay, fontList = this] { fontList->StartLoader(delay); }));
"StartLoader callback", [delay, fontList = this] {
fontList->Lock();
fontList->StartLoader(delay);
fontList->Unlock();
}));
}
}
@ -2594,7 +2643,7 @@ void gfxPlatformFontList::RebuildLocalFonts(bool aForgetLocalFaces) {
}
}
void gfxPlatformFontList::ClearLangGroupPrefFonts() {
void gfxPlatformFontList::ClearLangGroupPrefFontsLocked() {
for (uint32_t i = eFontPrefLang_First;
i < eFontPrefLang_First + eFontPrefLang_Count; i++) {
auto& prefFontsLangGroup = mLangGroupPrefFonts[i];
@ -2642,6 +2691,8 @@ size_t gfxPlatformFontList::SizeOfFontEntryTableExcludingThis(
void gfxPlatformFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
AutoLock lock(mLock);
aSizes->mFontListSize +=
mFontFamilies.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (const auto& entry : mFontFamilies) {
@ -2717,6 +2768,8 @@ void gfxPlatformFontList::InitOtherFamilyNamesInternal(
return;
}
AutoLock lock(mLock);
if (aDeferOtherFamilyNamesLoading) {
TimeStamp start = TimeStamp::Now();
bool timedOut = false;

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

@ -24,8 +24,8 @@
#include "mozilla/EnumeratedArray.h"
#include "mozilla/FontPropertyTypes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Mutex.h"
#include "mozilla/RangedArray.h"
#include "mozilla/RecursiveMutex.h"
#include "nsLanguageAtomService.h"
#include "base/shared_memory.h"
@ -164,6 +164,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
typedef mozilla::WeightRange WeightRange;
typedef mozilla::intl::Script Script;
using AutoLock = mozilla::RecursiveMutexAutoLock;
// 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
// Preferences service.
@ -265,7 +267,11 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// but not completely invalidated.
void UpdateFontList(bool aFullRebuild = true);
virtual void ClearLangGroupPrefFonts();
void ClearLangGroupPrefFonts() {
AutoLock lock(mLock);
ClearLangGroupPrefFontsLocked();
}
virtual void ClearLangGroupPrefFontsLocked() REQUIRES(mLock);
void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily>>& aFamilyArray);
@ -307,15 +313,25 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// Find family(ies) matching aFamily and append to the aOutput array
// (there may be multiple results in the case of fontconfig aliases, etc).
// Return true if any match was found and appended, false if none.
virtual bool FindAndAddFamilies(
bool FindAndAddFamilies(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0);
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0) {
AutoLock lock(mLock);
return FindAndAddFamiliesLocked(aPresContext, aGeneric, aFamily, aOutput,
aFlags, aStyle, aLanguage, aDevToCssSize);
}
virtual bool FindAndAddFamiliesLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
REQUIRES(mLock);
gfxFontEntry* FindFontForFamily(nsPresContext* aPresContext,
const nsACString& aFamily,
const gfxFontStyle* aStyle);
const gfxFontStyle* aStyle) REQUIRES(mLock);
mozilla::fontlist::FontList* SharedFontList() const {
return mSharedFontList.get();
@ -371,13 +387,24 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// name lookup table methods
void AddOtherFamilyName(gfxFontFamily* aFamilyEntry,
const nsCString& aOtherFamilyName);
void AddOtherFamilyNames(gfxFontFamily* aFamilyEntry,
const nsTArray<nsCString>& aOtherFamilyNames);
void AddFullname(gfxFontEntry* aFontEntry, const nsCString& aFullname);
void AddFullname(gfxFontEntry* aFontEntry, const nsCString& aFullname) {
AutoLock lock(mLock);
AddFullnameLocked(aFontEntry, aFullname);
}
void AddFullnameLocked(gfxFontEntry* aFontEntry, const nsCString& aFullname)
REQUIRES(mLock);
void AddPostscriptName(gfxFontEntry* aFontEntry,
const nsCString& aPostscriptName);
const nsCString& aPostscriptName) {
AutoLock lock(mLock);
AddPostscriptNameLocked(aFontEntry, aPostscriptName);
}
void AddPostscriptNameLocked(gfxFontEntry* aFontEntry,
const nsCString& aPostscriptName)
REQUIRES(mLock);
bool NeedFullnamePostscriptNames() { return mExtraNames != nullptr; }
@ -400,10 +427,15 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// get the system default font family
FontFamily GetDefaultFont(nsPresContext* aPresContext,
const gfxFontStyle* aStyle);
FontFamily GetDefaultFontLocked(nsPresContext* aPresContext,
const gfxFontStyle* aStyle) REQUIRES(mLock);
// get the "ultimate" default font, for use if the font list is otherwise
// unusable (e.g. in the middle of being updated)
gfxFontEntry* GetDefaultFontEntry() { return mDefaultFontEntry.get(); }
gfxFontEntry* GetDefaultFontEntry() {
AutoLock lock(mLock);
return mDefaultFontEntry.get();
}
/**
* Look up a font by name on the host platform.
@ -456,24 +488,28 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const;
mozilla::fontlist::Pointer GetShmemCharMap(const gfxSparseBitSet* aCmap);
mozilla::fontlist::Pointer GetShmemCharMap(const gfxSparseBitSet* aCmap) {
AutoLock lock(mLock);
return GetShmemCharMapLocked(aCmap);
}
mozilla::fontlist::Pointer GetShmemCharMapLocked(const gfxSparseBitSet* aCmap)
REQUIRES(mLock);
// search for existing cmap that matches the input
// return the input if no match is found
// Search for existing cmap that matches the input; return the input if no
// match is found.
gfxCharacterMap* FindCharMap(gfxCharacterMap* aCmap);
// add a cmap to the shared cmap set
gfxCharacterMap* AddCmap(const gfxCharacterMap* aCharMap);
// remove the cmap from the shared cmap set
// Remove the cmap from the shared cmap set.
void RemoveCmap(const gfxCharacterMap* aCharMap);
// keep track of userfont sets to notify when global fontlist changes occur
// Keep track of userfont sets to notify when global fontlist changes occur.
void AddUserFontSet(gfxUserFontSet* aUserFontSet) {
AutoLock lock(mLock);
mUserFontSetList.Insert(aUserFontSet);
}
void RemoveUserFontSet(gfxUserFontSet* aUserFontSet) {
AutoLock lock(mLock);
mUserFontSetList.Remove(aUserFontSet);
}
@ -496,15 +532,32 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
* make one, and adds it to the cache.
*/
gfxFontEntry* GetOrCreateFontEntry(mozilla::fontlist::Face* aFace,
const mozilla::fontlist::Family* aFamily);
const mozilla::fontlist::Family* aFamily) {
AutoLock lock(mLock);
return GetOrCreateFontEntryLocked(aFace, aFamily);
}
gfxFontEntry* GetOrCreateFontEntryLocked(
mozilla::fontlist::Face* aFace, const mozilla::fontlist::Family* aFamily)
REQUIRES(mLock);
const FontPrefs* GetFontPrefs() const { return mFontPrefs.get(); }
const FontPrefs* GetFontPrefs() const REQUIRES(mLock) {
return mFontPrefs.get();
}
bool EmojiPrefHasUserValue() const { return mFontPrefs->EmojiHasUserValue(); }
bool EmojiPrefHasUserValue() const {
AutoLock lock(mLock);
return mFontPrefs->EmojiHasUserValue();
}
PrefFontList* GetPrefFontsLangGroup(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGenericType,
eFontPrefLang aPrefLang);
eFontPrefLang aPrefLang) {
AutoLock lock(mLock);
return GetPrefFontsLangGroupLocked(aPresContext, aGenericType, aPrefLang);
}
PrefFontList* GetPrefFontsLangGroupLocked(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGenericType,
eFontPrefLang aPrefLang) REQUIRES(mLock);
// in some situations, need to make decisions about ambiguous characters, may
// need to look at multiple pref langs
@ -555,6 +608,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
mozilla::StyleGenericFontFamily aGenericType);
bool SkipFontFallbackForChar(FontVisibility aVisibility, uint32_t aCh) const {
AutoLock lock(mLock);
return mCodepointsWithNoFonts[aVisibility].test(aCh);
}
@ -566,7 +620,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
FontVisibility aVisibility) const;
// (Re-)initialize the set of codepoints that we know cannot be rendered.
void InitializeCodepointsWithNoFonts();
void InitializeCodepointsWithNoFonts() REQUIRES(mLock);
// If using the shared font list, returns a generation count that is
// incremented if/when the platform list is reinitialized (e.g. because
@ -581,6 +635,13 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
return PR_GetCurrentThread() == sInitFontListThread;
}
void Lock() CAPABILITY_ACQUIRE(mLock) { mLock.Lock(); }
void Unlock() CAPABILITY_RELEASE(mLock) { mLock.Unlock(); }
// This is only public because some external callers want to be able to
// assert about the locked status.
mutable mozilla::RecursiveMutex mLock;
protected:
friend class mozilla::fontlist::FontList;
friend class InitOtherFamilyNamesForStylo;
@ -680,20 +741,20 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
nsPresContext* aPresContext, const nsACString& aFamily,
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
gfxFloat aDevToCssSize = 1.0);
gfxFloat aDevToCssSize = 1.0) REQUIRES(mLock);
gfxFontFamily* FindUnsharedFamily(
nsPresContext* aPresContext, const nsACString& aFamily,
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
gfxFloat aDevToCssSize = 1.0) {
gfxFloat aDevToCssSize = 1.0) REQUIRES(mLock) {
if (SharedFontList()) {
return nullptr;
}
AutoTArray<FamilyAndGeneric, 1> families;
if (FindAndAddFamilies(aPresContext, mozilla::StyleGenericFontFamily::None,
aFamily, &families, aFlags, aStyle, aLanguage,
aDevToCssSize)) {
if (FindAndAddFamiliesLocked(
aPresContext, mozilla::StyleGenericFontFamily::None, aFamily,
&families, aFlags, aStyle, aLanguage, aDevToCssSize)) {
return families[0].mFamily.mUnshared;
}
return nullptr;
@ -703,7 +764,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
FindFamiliesFlags aFlags = FindFamiliesFlags(0),
gfxFontStyle* aStyle = nullptr,
nsAtom* aLanguage = nullptr,
gfxFloat aDevToCssSize = 1.0) {
gfxFloat aDevToCssSize = 1.0) REQUIRES(mLock) {
if (SharedFontList()) {
return FontFamily(FindSharedFamily(aPresContext, aFamily, aFlags, aStyle,
aLanguage, aDevToCssSize));
@ -714,7 +775,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// Lookup family name in global family list without substitutions or
// localized family name lookup. Used for common font fallback families.
gfxFontFamily* FindFamilyByCanonicalName(const nsACString& aFamily) {
gfxFontFamily* FindFamilyByCanonicalName(const nsACString& aFamily)
REQUIRES(mLock) {
nsAutoCString key;
gfxFontFamily* familyEntry;
GenerateFontListKey(aFamily, key);
@ -729,14 +791,15 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
uint32_t aNextCh, Script aRunScript,
eFontPresentation aPresentation,
const gfxFontStyle* aMatchStyle,
FontFamily& aMatchedFamily);
FontFamily& aMatchedFamily) REQUIRES(mLock);
// Search fonts system-wide for a given character, null if not found.
gfxFont* GlobalFontFallback(nsPresContext* aPresContext, uint32_t aCh,
uint32_t aNextCh, Script aRunScript,
eFontPresentation aPresentation,
const gfxFontStyle* aMatchStyle,
uint32_t& aCmapCount, FontFamily& aMatchedFamily);
uint32_t& aCmapCount, FontFamily& aMatchedFamily)
REQUIRES(mLock);
// Platform-specific implementation of global font fallback, if any;
// this may return nullptr in which case the default cmap-based fallback
@ -752,45 +815,52 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
virtual bool UsesSystemFallback() { return false; }
void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t& aLen,
eFontPrefLang aCharLang, eFontPrefLang aPageLang);
eFontPrefLang aCharLang, eFontPrefLang aPageLang)
REQUIRES(mLock);
// verifies that a family contains a non-zero font count
gfxFontFamily* CheckFamily(gfxFontFamily* aFamily);
gfxFontFamily* CheckFamily(gfxFontFamily* aFamily) REQUIRES(mLock);
// initialize localized family names
void InitOtherFamilyNamesInternal(bool aDeferOtherFamilyNamesLoading);
void CancelInitOtherFamilyNamesTask();
void AddToMissedNames(const nsCString& aKey) REQUIRES(mLock);
// search through font families, looking for a given name, initializing
// facename lists along the way. first checks all families with names
// close to face name, then searchs all families if not found.
gfxFontEntry* SearchFamiliesForFaceName(const nsACString& aFaceName);
gfxFontEntry* SearchFamiliesForFaceName(const nsACString& aFaceName)
REQUIRES(mLock);
// helper method for finding fullname/postscript names in facename lists
gfxFontEntry* FindFaceName(const nsACString& aFaceName);
gfxFontEntry* FindFaceName(const nsACString& aFaceName) REQUIRES(mLock);
// look up a font by name, for cases where platform font list
// maintains explicit mappings of fullname/psname ==> font
virtual gfxFontEntry* LookupInFaceNameLists(const nsACString& aFontName);
virtual gfxFontEntry* LookupInFaceNameLists(const nsACString& aFaceName)
REQUIRES(mLock);
gfxFontEntry* LookupInSharedFaceNameList(nsPresContext* aPresContext,
const nsACString& aFaceName,
WeightRange aWeightForEntry,
StretchRange aStretchForEntry,
SlantStyleRange aStyleForEntry);
SlantStyleRange aStyleForEntry)
REQUIRES(mLock);
// load the bad underline blocklist from pref.
void LoadBadUnderlineList();
void GenerateFontListKey(const nsACString& aKeyName, nsACString& aResult);
virtual void GetFontFamilyNames(nsTArray<nsCString>& aFontFamilyNames);
virtual void GetFontFamilyNames(nsTArray<nsCString>& aFontFamilyNames)
REQUIRES(mLock);
// helper function to map lang to lang group
nsAtom* GetLangGroup(nsAtom* aLanguage);
// gfxFontInfoLoader overrides, used to load in font cmaps
void InitLoader() override;
void InitLoader() REQUIRES(mLock) override;
bool LoadFontInfo() override;
void CleanupLoader() override;
@ -800,23 +870,23 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// If aForgetLocalFaces is true, all gfxFontEntries for src:local fonts must
// be discarded (not potentially reused to satisfy the rebuilt rules),
// because they may no longer be valid.
void RebuildLocalFonts(bool aForgetLocalFaces = false);
void RebuildLocalFonts(bool aForgetLocalFaces = false) REQUIRES(mLock);
void ResolveGenericFontNames(nsPresContext* aPresContext,
mozilla::StyleGenericFontFamily aGenericType,
eFontPrefLang aPrefLang,
PrefFontList* aGenericFamilies);
PrefFontList* aGenericFamilies) REQUIRES(mLock);
void ResolveEmojiFontNames(nsPresContext* aPresContext,
PrefFontList* aGenericFamilies);
PrefFontList* aGenericFamilies) REQUIRES(mLock);
void GetFontFamiliesFromGenericFamilies(
nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGenericType,
nsTArray<nsCString>& aGenericNameFamilies, nsAtom* aLangGroup,
PrefFontList* aFontFamilies);
PrefFontList* aFontFamilies) REQUIRES(mLock);
virtual nsresult InitFontListForPlatform() = 0;
virtual void InitSharedFontListForPlatform() {}
virtual nsresult InitFontListForPlatform() REQUIRES(mLock) = 0;
virtual void InitSharedFontListForPlatform() REQUIRES(mLock) {}
virtual gfxFontEntry* CreateFontEntry(
mozilla::fontlist::Face* aFace,
@ -831,7 +901,7 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
* There are separate implementations of this for the per-process font list
* and for the shared-memory font list.
*/
void ApplyWhitelist();
void ApplyWhitelist() REQUIRES(mLock);
void ApplyWhitelist(nsTArray<mozilla::fontlist::Family::InitData>& aFamilies);
// Create a new gfxFontFamily of the appropriate subclass for the platform,
@ -850,7 +920,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
* case this method is unused.
*/
virtual void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
bool aNeedFullnamePostscriptNames) {}
bool aNeedFullnamePostscriptNames)
REQUIRES(mLock) {}
typedef nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> FontFamilyTable;
typedef nsRefPtrHashtable<nsCStringHashKey, gfxFontEntry> FontEntryTable;
@ -864,26 +935,24 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// Platform-specific helper for GetDefaultFont(...).
virtual FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
const gfxFontStyle* aStyle,
nsAtom* aLanguage = nullptr) = 0;
// Protects mFontFamilies.
mozilla::Mutex mFontFamiliesMutex MOZ_UNANNOTATED;
nsAtom* aLanguage = nullptr)
REQUIRES(mLock) = 0;
// canonical family name ==> family entry (unique, one name per family entry)
FontFamilyTable mFontFamilies;
FontFamilyTable mFontFamilies GUARDED_BY(mLock);
// other family name ==> family entry (not unique, can have multiple names per
// family entry, only names *other* than the canonical names are stored here)
FontFamilyTable mOtherFamilyNames;
FontFamilyTable mOtherFamilyNames GUARDED_BY(mLock);
// flag set after InitOtherFamilyNames is called upon first name lookup miss
bool mOtherFamilyNamesInitialized = false;
mozilla::Atomic<bool> mOtherFamilyNamesInitialized;
// The pending InitOtherFamilyNames() task.
RefPtr<mozilla::CancelableRunnable> mPendingOtherFamilyNameTask;
// flag set after fullname and Postcript name lists are populated
bool mFaceNameListsInitialized = false;
mozilla::Atomic<bool> mFaceNameListsInitialized;
struct ExtraNames {
ExtraNames() = default;
@ -893,13 +962,16 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// Postscript name ==> font entry (unique, one name per font entry)
FontEntryTable mPostscriptNames{64};
};
mozilla::UniquePtr<ExtraNames> mExtraNames;
// The lock is needed to guard access to the actual name tables, but does not
// need to be held to just test whether mExtraNames is non-null as it is set
// during initialization before other threads have a chance to see it.
mozilla::UniquePtr<ExtraNames> mExtraNames PT_GUARDED_BY(mLock);
// face names missed when face name loading takes a long time
mozilla::UniquePtr<nsTHashSet<nsCString>> mFaceNamesMissed;
mozilla::UniquePtr<nsTHashSet<nsCString>> mFaceNamesMissed GUARDED_BY(mLock);
// localized family names missed when face name loading takes a long time
mozilla::UniquePtr<nsTHashSet<nsCString>> mOtherNamesMissed;
mozilla::UniquePtr<nsTHashSet<nsCString>> mOtherNamesMissed GUARDED_BY(mLock);
typedef mozilla::RangedArray<mozilla::UniquePtr<PrefFontList>,
size_t(mozilla::StyleGenericFontFamily::None),
@ -908,28 +980,28 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
PrefFontsForLangGroup;
mozilla::RangedArray<PrefFontsForLangGroup, eFontPrefLang_First,
eFontPrefLang_Count>
mLangGroupPrefFonts;
mozilla::UniquePtr<PrefFontList> mEmojiPrefFont;
mLangGroupPrefFonts GUARDED_BY(mLock);
mozilla::UniquePtr<PrefFontList> mEmojiPrefFont GUARDED_BY(mLock);
// When system-wide font lookup fails for a character, cache it to skip future
// searches. This is an array of bitsets, one for each FontVisibility level.
mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count,
gfxSparseBitSet>
mCodepointsWithNoFonts;
mCodepointsWithNoFonts GUARDED_BY(mLock);
// the family to use for U+FFFD fallback, to avoid expensive search every time
// on pages with lots of problems
mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count, FontFamily>
mReplacementCharFallbackFamily;
mReplacementCharFallbackFamily GUARDED_BY(mLock);
// Sorted array of lowercased family names; use ContainsSorted to test
nsTArray<nsCString> mBadUnderlineFamilyNames;
// character map data shared across families
// contains weak ptrs to cmaps shared by font entry objects
nsTHashtable<CharMapHashKey> mSharedCmaps;
nsTHashtable<CharMapHashKey> mSharedCmaps GUARDED_BY(mLock);
nsTHashtable<ShmemCharMapHashEntry> mShmemCharMaps;
nsTHashtable<ShmemCharMapHashEntry> mShmemCharMaps GUARDED_BY(mLock);
// data used as part of the font cmap loading process
nsTArray<RefPtr<gfxFontFamily>> mFontFamiliesToLoad;
@ -940,12 +1012,13 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// see bugs 636957, 1070983, 1189129
uint32_t mFontlistInitCount = 0; // num times InitFontList called
nsTHashSet<gfxUserFontSet*> mUserFontSetList;
nsTHashSet<gfxUserFontSet*> mUserFontSetList GUARDED_BY(mLock);
nsLanguageAtomService* mLangService = nullptr;
nsTArray<uint32_t> mCJKPrefLangs;
nsTArray<mozilla::StyleGenericFontFamily> mDefaultGenericsLangGroup;
nsTArray<uint32_t> mCJKPrefLangs GUARDED_BY(mLock);
nsTArray<mozilla::StyleGenericFontFamily> mDefaultGenericsLangGroup
GUARDED_BY(mLock);
nsTArray<nsCString> mEnabledFontsList;
@ -956,11 +1029,11 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
mLocalNameTable;
nsRefPtrHashtable<nsPtrHashKey<mozilla::fontlist::Face>, gfxFontEntry>
mFontEntries;
mFontEntries GUARDED_BY(mLock);
mozilla::UniquePtr<FontPrefs> mFontPrefs;
RefPtr<gfxFontEntry> mDefaultFontEntry;
RefPtr<gfxFontEntry> mDefaultFontEntry GUARDED_BY(mLock);
RefPtr<mozilla::CancelableRunnable> mLoadCmapsRunnable;
uint32_t mStartedLoadingCmapsFrom = 0xffffffffu;

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

@ -172,6 +172,7 @@ class gfxUserFontFamily : public gfxFontFamily {
// add the given font entry to the end of the family's list
void AddFontEntry(gfxFontEntry* aFontEntry) {
mozilla::AutoWriteLock lock(mLock);
MOZ_ASSERT(!mIsSimpleFamily, "not valid for user-font families");
// keep ref while removing existing entry
RefPtr<gfxFontEntry> fe = aFontEntry;
@ -196,12 +197,16 @@ class gfxUserFontFamily : public gfxFontFamily {
}
void RemoveFontEntry(gfxFontEntry* aFontEntry) {
mozilla::AutoWriteLock lock(mLock);
MOZ_ASSERT(!mIsSimpleFamily, "not valid for user-font families");
mAvailableFonts.RemoveElement(aFontEntry);
}
// Remove all font entries from the family
void DetachFontEntries() { mAvailableFonts.Clear(); }
void DetachFontEntries() {
mozilla::AutoWriteLock lock(mLock);
mAvailableFonts.Clear();
}
};
class gfxUserFontEntry;

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

@ -1493,12 +1493,14 @@ nsresult nsMathMLChar::StretchInternal(
AutoTArray<nsCString, 16> mathFallbacks;
nsAutoCString value;
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
pfl->Lock();
if (pfl->GetFontPrefs()->LookupName("serif.x-math"_ns, value)) {
gfxFontUtils::ParseFontList(value, mathFallbacks);
}
if (pfl->GetFontPrefs()->LookupNameList("serif.x-math"_ns, value)) {
gfxFontUtils::ParseFontList(value, mathFallbacks);
}
pfl->Unlock();
InsertMathFallbacks(font.family.families, mathFallbacks);
#ifdef NOISY_SEARCH