Bug 1336208 - Part 2: Making the gfxPlatformFontList to use fonts directory in profile folder if it exists for bundled fonts. r?jfkthame,arthuredelstein
The patch changes the way how gfxPlatformFontList loads bundled fonts. The
gfxPlatformFontList will load additional fonts for fingerprinting resistance.
It will first try to load fonts from 'rfp-fonts' directory in the profile directory
if this directory exists. Otherwise, It will load fonts for fingerprinting
resistance from the 'rfp-fonts' directory in the GRE directory.
MozReview-Commit-ID: GhHp0DAI8pc
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -934,16 +934,22 @@ gfxDWriteFontList::InitFontListForPlatfo
QueryPerformanceCounter(&t4); // iterate over system fonts
#ifdef MOZ_BUNDLED_FONTS
mBundledFonts = CreateBundledFontsCollection(factory);
if (mBundledFonts) {
GetFontsFromCollection(mBundledFonts);
}
+
+ mRFPFonts = CreateRFPFontsCollection(factory);
+ if (mRFPFonts) {
+ mRFPFontsLoaded = true;
+ GetFontsFromCollection(mRFPFonts);
+ }
#endif
mOtherFamilyNamesInitialized = true;
GetFontSubstitutes();
// bug 642093 - DirectWrite does not support old bitmap (.fon)
// font files, but a few of these such as "Courier" and "MS Sans Serif"
// are frequently specified in shoddy CSS, without appropriate fallbacks.
@@ -1507,34 +1513,37 @@ gfxDWriteFontList::PlatformGlobalFontFal
class DirectWriteFontInfo : public FontInfoData {
public:
DirectWriteFontInfo(bool aLoadOtherNames,
bool aLoadFaceNames,
bool aLoadCmaps,
IDWriteFontCollection* aSystemFonts
#ifdef MOZ_BUNDLED_FONTS
, IDWriteFontCollection* aBundledFonts
+ , IDWriteFontCollection* aRFPFonts
#endif
) :
FontInfoData(aLoadOtherNames, aLoadFaceNames, aLoadCmaps)
, mSystemFonts(aSystemFonts)
#ifdef MOZ_BUNDLED_FONTS
, mBundledFonts(aBundledFonts)
+ , mRFPFonts(aRFPFonts)
#endif
{}
virtual ~DirectWriteFontInfo() {}
// loads font data for all members of a given family
virtual void LoadFontFamilyData(const nsAString& aFamilyName);
private:
RefPtr<IDWriteFontCollection> mSystemFonts;
#ifdef MOZ_BUNDLED_FONTS
RefPtr<IDWriteFontCollection> mBundledFonts;
+ RefPtr<IDWriteFontCollection> mRFPFonts;
#endif
};
void
DirectWriteFontInfo::LoadFontFamilyData(const nsAString& aFamilyName)
{
// lookup the family
AutoTArray<wchar_t, 32> famName;
@@ -1561,16 +1570,23 @@ DirectWriteFontInfo::LoadFontFamilyData(
#ifdef MOZ_BUNDLED_FONTS
if (!family && mBundledFonts) {
hr = mBundledFonts->FindFamilyName(famName.Elements(), &index, &exists);
if (SUCCEEDED(hr) && exists) {
mBundledFonts->GetFontFamily(index, getter_AddRefs(family));
}
}
+
+ if (!family && mRFPFonts) {
+ hr = mRFPFonts->FindFamilyName(famName.Elements(), &index, &exists);
+ if (SUCCEEDED(hr) && exists) {
+ mRFPFonts->GetFontFamily(index, getter_AddRefs(family));
+ }
+ }
#endif
if (!family) {
return;
}
// later versions of DirectWrite support querying the fullname/psname
bool loadFaceNamesUsingDirectWrite = mLoadFaceNames;
@@ -1706,16 +1722,17 @@ gfxDWriteFontList::CreateFontInfoData()
bool loadCmaps = !UsesSystemFallback() ||
gfxPlatform::GetPlatform()->UseCmapsDuringSystemFallback();
RefPtr<DirectWriteFontInfo> fi =
new DirectWriteFontInfo(false, NeedFullnamePostscriptNames(), loadCmaps,
mSystemFonts
#ifdef MOZ_BUNDLED_FONTS
, mBundledFonts
+ , mRFPFonts
#endif
);
return fi.forget();
}
gfxFontFamily*
gfxDWriteFontList::CreateFontFamily(const nsAString& aName) const
@@ -1841,44 +1858,94 @@ BundledFontLoader::CreateEnumeratorFromK
{
nsIFile *fontDir = *(nsIFile**)aCollectionKey;
*aFontFileEnumerator = new BundledFontFileEnumerator(aFactory, fontDir);
NS_ADDREF(*aFontFileEnumerator);
return S_OK;
}
already_AddRefed<IDWriteFontCollection>
-gfxDWriteFontList::CreateBundledFontsCollection(IDWriteFactory* aFactory)
+gfxDWriteFontList::CreateBundledFontsCollectionFromDir(IDWriteFactory* aFactory,
+ nsIFile* aDir)
{
- nsCOMPtr<nsIFile> localDir;
- nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
- if (NS_FAILED(rv)) {
- return nullptr;
- }
- if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
- return nullptr;
- }
bool isDir;
- if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) {
+ if (NS_FAILED(aDir->IsDirectory(&isDir)) || !isDir) {
return nullptr;
}
RefPtr<BundledFontLoader> loader = new BundledFontLoader();
if (FAILED(aFactory->RegisterFontCollectionLoader(loader))) {
return nullptr;
}
- const void *key = localDir.get();
+ const void *key = aDir;
RefPtr<IDWriteFontCollection> collection;
HRESULT hr =
aFactory->CreateCustomFontCollection(loader, &key, sizeof(key),
getter_AddRefs(collection));
aFactory->UnregisterFontCollectionLoader(loader);
if (FAILED(hr)) {
return nullptr;
} else {
return collection.forget();
}
}
+already_AddRefed<IDWriteFontCollection>
+gfxDWriteFontList::CreateBundledFontsCollection(IDWriteFactory* aFactory)
+{
+ nsCOMPtr<nsIFile> localDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
+ return nullptr;
+ }
+
+ RefPtr<IDWriteFontCollection> collection =
+ CreateBundledFontsCollectionFromDir(aFactory, localDir);
+
+ return collection.forget();
+
+}
+
+already_AddRefed<IDWriteFontCollection>
+gfxDWriteFontList::CreateRFPFontsCollection(IDWriteFactory* aFactory)
+{
+ // We will first check the font directory in the profile directory. If it
+ // exists we will use it instead of the font directory in GRE folder.
+ nsCOMPtr<nsIFile> rfpFontsDir;
+ bool isExists;
+
+ nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(rfpFontsDir));
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+ if (NS_FAILED(rfpFontsDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return nullptr;
+ }
+ if (NS_FAILED(rfpFontsDir->Exists(&isExists))) {
+ return nullptr;
+ }
+
+ if (!isExists) {
+ rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(rfpFontsDir));
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+ if (NS_FAILED(rfpFontsDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return nullptr;
+ }
+ if (NS_FAILED(rfpFontsDir->Exists(&isExists)) || !isExists) {
+ return nullptr;
+ }
+ }
+
+ RefPtr<IDWriteFontCollection> collection =
+ CreateBundledFontsCollectionFromDir(aFactory, rfpFontsDir);
+
+ return collection.forget();
+}
+
#endif
--- a/gfx/thebes/gfxDWriteFontList.h
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -426,17 +426,23 @@ private:
void GetDirectWriteSubstitutes();
virtual bool UsesSystemFallback() { return true; }
void GetFontsFromCollection(IDWriteFontCollection* aCollection);
#ifdef MOZ_BUNDLED_FONTS
already_AddRefed<IDWriteFontCollection>
+ CreateBundledFontsCollectionFromDir(IDWriteFactory* aFactory, nsIFile* aDir);
+
+ already_AddRefed<IDWriteFontCollection>
CreateBundledFontsCollection(IDWriteFactory* aFactory);
+
+ already_AddRefed<IDWriteFontCollection>
+ CreateRFPFontsCollection(IDWriteFactory* aFactory);
#endif
/**
* Fonts listed in the registry as substitutes but for which no actual
* font family is found.
*/
nsTArray<nsString> mNonExistingFonts;
@@ -455,13 +461,14 @@ private:
RefPtr<IDWriteGdiInterop> mGDIInterop;
RefPtr<DWriteFontFallbackRenderer> mFallbackRenderer;
RefPtr<IDWriteTextFormat> mFallbackFormat;
RefPtr<IDWriteFontCollection> mSystemFonts;
#ifdef MOZ_BUNDLED_FONTS
RefPtr<IDWriteFontCollection> mBundledFonts;
+ RefPtr<IDWriteFontCollection> mRFPFonts;
#endif
};
#endif /* GFX_DWRITEFONTLIST_H */
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -2165,40 +2165,83 @@ gfxFcPlatformFontList::CheckFontUpdates(
gfxFontFamily*
gfxFcPlatformFontList::CreateFontFamily(const nsAString& aName) const
{
return new gfxFontconfigFontFamily(aName);
}
#ifdef MOZ_BUNDLED_FONTS
+bool
+gfxFcPlatformFontList::ActivateFontsFromDir(nsIFile* aDir)
+{
+ bool isDir;
+ bool isExist;
+
+ if (NS_FAILED(aDir->IsDirectory(&isDir)) || !isDir) {
+ return false;
+ }
+
+ if (NS_FAILED(aDir->Exists(&isExist)) || !isExist) {
+ return false;
+ }
+
+ nsCString bundledFontsPath;
+ if (NS_FAILED(aDir->GetNativePath(bundledFontsPath))) {
+ return false;
+ }
+
+ if (bundledFontsPath.IsEmpty()) {
+ return false;
+ }
+
+ FcConfigAppFontAddDir(nullptr, ToFcChar8Ptr(bundledFontsPath.get()));
+ return true;
+}
+
void
gfxFcPlatformFontList::ActivateBundledFonts()
{
if (!mBundledFontsInitialized) {
mBundledFontsInitialized = true;
nsCOMPtr<nsIFile> localDir;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
if (NS_FAILED(rv)) {
return;
}
if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
return;
}
- bool isDir;
- if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) {
+
+ Unused << ActivateFontsFromDir(localDir);
+
+ // We will first load fonts for fingerprinting resistance from profile
+ // directory. If we can't, we will load from the GRE directory.
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
return;
}
- if (NS_FAILED(localDir->GetNativePath(mBundledFontsPath))) {
- return;
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
+
+ if (!mRFPFontsLoaded) {
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_GRE_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return;
+ }
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
}
}
- if (!mBundledFontsPath.IsEmpty()) {
- FcConfigAppFontAddDir(nullptr, ToFcChar8Ptr(mBundledFontsPath.get()));
- }
}
#endif
#ifdef MOZ_WIDGET_GTK
/***************************************************************************
*
* This function must be last in the file because it uses the system cairo
* library. Above this point the cairo library used is the tree cairo if
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -338,18 +338,21 @@ protected:
static void CheckFontUpdates(nsITimer *aTimer, void *aThis);
virtual gfxFontFamily*
GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
gfxFontFamily* CreateFontFamily(const nsAString& aName) const override;
#ifdef MOZ_BUNDLED_FONTS
+ // Activate fonts from the given directory. It returns true if it loads
+ // any font from the given directory.
+ bool ActivateFontsFromDir(nsIFile* aDir);
+
void ActivateBundledFonts();
- nsCString mBundledFontsPath;
bool mBundledFontsInitialized;
#endif
// to avoid enumerating all fonts, maintain a mapping of local font
// names to family
nsBaseHashtable<nsStringHashKey,
nsCountedRef<FcPattern>,
FcPattern*> mLocalNames;
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -1138,49 +1138,84 @@ gfxGDIFontList::CreateFontInfoData()
gfxFontFamily*
gfxGDIFontList::CreateFontFamily(const nsAString& aName) const
{
return new GDIFontFamily(aName);
}
#ifdef MOZ_BUNDLED_FONTS
-void
-gfxGDIFontList::ActivateBundledFonts()
+bool
+gfxGDIFontList::ActivateFontsFromDir(nsIFile* aDir)
{
- nsCOMPtr<nsIFile> localDir;
- nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
- if (NS_FAILED(rv)) {
- return;
- }
- if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
- return;
- }
bool isDir;
- if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) {
- return;
+ if (NS_FAILED(aDir->IsDirectory(&isDir)) || !isDir) {
+ return false;
}
nsCOMPtr<nsISimpleEnumerator> e;
- rv = localDir->GetDirectoryEntries(getter_AddRefs(e));
+ nsresult rv = aDir->GetDirectoryEntries(getter_AddRefs(e));
if (NS_FAILED(rv)) {
- return;
+ return false;
}
bool hasMore;
+ bool loadedFonts = false;
while (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> entry;
if (NS_FAILED(e->GetNext(getter_AddRefs(entry)))) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
if (!file) {
continue;
}
nsAutoString path;
if (NS_FAILED(file->GetPath(path))) {
continue;
}
AddFontResourceExW(path.get(), FR_PRIVATE, nullptr);
+ loadedFonts = true;
+ }
+
+ return loadedFonts;
+}
+
+void
+gfxGDIFontList::ActivateBundledFonts()
+{
+ nsCOMPtr<nsIFile> localDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
+ return;
+ }
+
+ Unused << ActivateFontsFromDir(localDir);
+
+ // We will first load fonts for fingerprinting resistance from profile
+ // directory. If we can't, we will load from the GRE directory.
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return;
+ }
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
+
+ if (!mRFPFontsLoaded) {
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_GRE_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return;
+ }
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
}
}
#endif
--- a/gfx/thebes/gfxGDIFontList.h
+++ b/gfx/thebes/gfxGDIFontList.h
@@ -360,16 +360,20 @@ private:
static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
NEWTEXTMETRICEXW *lpntme,
DWORD fontType,
LPARAM lParam);
virtual already_AddRefed<FontInfoData> CreateFontInfoData();
#ifdef MOZ_BUNDLED_FONTS
+ // Activate fonts from the given directory. It returns true if it loads
+ // any font from the given directory.
+ bool ActivateFontsFromDir(nsIFile* aDir);
+
void ActivateBundledFonts();
#endif
FontFamilyTable mFontSubstitutes;
nsTArray<nsString> mNonExistingFonts;
};
#endif /* GFX_GDIFONTLIST_H */
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -207,17 +207,19 @@ private:
// Ideally we'd use NSString* instead of CFStringRef here, but this header
// file is included in .cpp files, so we can't use objective C classes here.
// But CFStringRef and NSString* are the same thing anyway (they're
// toll-free bridged).
void AddFamily(CFStringRef aFamily);
void AddFamily(const nsAString& aFamilyName, bool aSystemFont);
- void ActivateFontsFromDir(nsIFile* aDir);
+ // Activate fonts from the given directory. It returns true if it loads
+ // any font from the given directory.
+ bool ActivateFontsFromDir(nsIFile* aDir);
#ifdef MOZ_BUNDLED_FONTS
void ActivateBundledFonts();
#endif
enum {
kATSGenerationInitial = -1
};
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -1789,33 +1789,34 @@ gfxMacPlatformFontList::CreateFontInfoDa
}
gfxFontFamily*
gfxMacPlatformFontList::CreateFontFamily(const nsAString& aName) const
{
return new gfxMacFontFamily(aName, 0.0);
}
-void
+bool
gfxMacPlatformFontList::ActivateFontsFromDir(nsIFile* aDir)
{
bool isDir;
if (NS_FAILED(aDir->IsDirectory(&isDir)) || !isDir) {
- return;
+ return false;
}
nsCOMPtr<nsISimpleEnumerator> e;
if (NS_FAILED(aDir->GetDirectoryEntries(getter_AddRefs(e)))) {
- return;
+ return false;
}
CFMutableArrayRef urls =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
bool hasMore;
+ bool loadedFonts = false;
while (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> entry;
if (NS_FAILED(e->GetNext(getter_AddRefs(entry)))) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
if (!file) {
continue;
@@ -1827,35 +1828,62 @@ gfxMacPlatformFontList::ActivateFontsFro
CFURLRef fontURL =
::CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
(uint8_t*)path.get(),
path.Length(),
false);
if (fontURL) {
::CFArrayAppendValue(urls, fontURL);
::CFRelease(fontURL);
+ loadedFonts = true;
}
}
::CTFontManagerRegisterFontsForURLs(urls,
kCTFontManagerScopeProcess,
nullptr);
::CFRelease(urls);
+
+ return loadedFonts;
}
#ifdef MOZ_BUNDLED_FONTS
void
gfxMacPlatformFontList::ActivateBundledFonts()
{
nsCOMPtr<nsIFile> localDir;
if (NS_FAILED(NS_GetSpecialDirectory(NS_GRE_DIR,
getter_AddRefs(localDir)))) {
return;
}
if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
return;
}
- ActivateFontsFromDir(localDir);
+ Unused << ActivateFontsFromDir(localDir);
+
+ // We will first load fonts for fingerprinting resistance from profile
+ // directory. If we can't, we will load from the GRE directory.
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return;
+ }
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
+
+ if (!mRFPFontsLoaded) {
+ if (NS_FAILED(NS_GetSpecialDirectory(NS_GRE_DIR,
+ getter_AddRefs(localDir)))) {
+ return;
+ }
+ if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("rfp-fonts")))) {
+ return;
+ }
+
+ mRFPFontsLoaded = ActivateFontsFromDir(localDir);
+ }
}
#endif
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -183,17 +183,17 @@ gfxPlatformFontList::MemoryReporter::Col
return NS_OK;
}
gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
: mFontFamiliesMutex("gfxPlatformFontList::mFontFamiliesMutex"), mFontFamilies(64),
mOtherFamilyNames(16), mBadUnderlineFamilyNames(8), mSharedCmaps(8),
mStartIndex(0), mIncrement(1), mNumFamilies(0), mFontlistInitCount(0),
- mFontFamilyWhitelistActive(false)
+ mFontFamilyWhitelistActive(false), mRFPFontsLoaded(false)
{
mOtherFamilyNamesInitialized = false;
if (aNeedFullnamePostscriptNames) {
mExtraNames = MakeUnique<ExtraNames>();
}
mFaceNameListsInitialized = false;
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -589,13 +589,14 @@ protected:
nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
nsLanguageAtomService* mLangService;
nsTArray<uint32_t> mCJKPrefLangs;
nsTArray<mozilla::FontFamilyType> mDefaultGenericsLangGroup;
bool mFontFamilyWhitelistActive;
+ bool mRFPFontsLoaded;
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxPlatformFontList::FindFamiliesFlags)
#endif /* GFXPLATFORMFONTLIST_H_ */