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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -143,14 +143,24 @@ void gfxFontInfoLoader::StartLoader(uint32_t aDelay) {
return; return;
} }
NS_ASSERTION(!mFontInfo, "fontinfo should be null when starting font loader");
// sanity check // sanity check
if (mState != stateInitial && mState != stateTimerOff && if (mState != stateInitial && mState != stateTimerOff &&
mState != stateTimerOnDelay) { mState != stateTimerOnDelay) {
CancelLoader(); 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(); AddShutdownObserver();
// Caller asked for a delay? ==> start async thread after a delay // 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 " "Bug 1508626 - Initializing font loader after shutdown but "
"before observer"); "before observer");
mFontInfo = CreateFontInfoData();
if (!mFontInfo) {
// The platform doesn't want anything loaded, so just bail out.
mState = stateTimerOff;
return;
}
// initialize // initialize
InitLoader(); InitLoader();

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

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

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

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

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

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

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

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

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

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

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

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

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

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