Verified Commit 8c3919ab authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame
Browse files

Bug 41004: Bundled fonts are not picked up on macOS

parent 9a8642eb
......@@ -215,6 +215,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility);
static void ActivateFontsFromDir(
const nsACString& aDir,
nsTHashSet<nsCStringHashKey>* aLoadedFamilies = nullptr);
gfxFontEntry* CreateFontEntry(
mozilla::fontlist::Face* aFace,
const mozilla::fontlist::Family* aFamily) override;
......@@ -227,6 +231,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
bool aNeedFullnamePostscriptNames) override;
#ifdef MOZ_BUNDLED_FONTS
void ActivateBundledFonts();
#endif
enum { kATSGenerationInitial = -1 };
// default font for use with system-wide font fallback
......@@ -242,6 +250,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
nsTArray<nsCString> mSingleFaceFonts;
nsTArray<nsCString> mPreloadFonts;
#ifdef MOZ_BUNDLED_FONTS
nsTHashSet<nsCStringHashKey> mBundledFamilies;
#endif
};
#endif /* gfxMacPlatformFontList_H_ */
......@@ -827,6 +827,18 @@ gfxMacPlatformFontList::gfxMacPlatformFontList()
: gfxPlatformFontList(false), mDefaultFont(nullptr), mUseSizeSensitiveSystemFont(false) {
CheckFamilyList(kBaseFonts, ArrayLength(kBaseFonts));
#ifdef MOZ_BUNDLED_FONTS
// We activate bundled fonts if the pref is > 0 (on) or < 0 (auto), only an
// explicit value of 0 (off) will disable them.
if (StaticPrefs::gfx_bundled_fonts_activate_AtStartup() != 0) {
TimeStamp start = TimeStamp::Now();
ActivateBundledFonts();
TimeStamp end = TimeStamp::Now();
Telemetry::Accumulate(Telemetry::FONTLIST_BUNDLEDFONTS_ACTIVATE,
(end - start).ToMilliseconds());
}
#endif
// cache this in a static variable so that MacOSFontFamily objects
// don't have to repeatedly look it up
sFontManager = [NSFontManager sharedFontManager];
......@@ -874,6 +886,11 @@ FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily(const nsACString&
if (FamilyInList(aName, kBaseFonts, ArrayLength(kBaseFonts))) {
return FontVisibility::Base;
}
#ifdef MOZ_BUNDLED_FONTS
if (mBundledFamilies.Contains(aName)) {
return FontVisibility::Base;
}
#endif
return FontVisibility::User;
}
......@@ -894,6 +911,55 @@ void gfxMacPlatformFontList::AddFamily(CFStringRef aFamily) {
AddFamily(nameUtf8, GetVisibilityForFamily(nameUtf8));
}
/* static */
void gfxMacPlatformFontList::ActivateFontsFromDir(const nsACString& aDir,
nsTHashSet<nsCStringHashKey>* aLoadedFamilies) {
AutoCFRelease<CFURLRef> directory = CFURLCreateFromFileSystemRepresentation(
kCFAllocatorDefault, (const UInt8*)nsPromiseFlatCString(aDir).get(), aDir.Length(), true);
if (!directory) {
return;
}
AutoCFRelease<CFURLEnumeratorRef> enumerator = CFURLEnumeratorCreateForDirectoryURL(
kCFAllocatorDefault, directory, kCFURLEnumeratorDefaultBehavior, nullptr);
if (!enumerator) {
return;
}
AutoCFRelease<CFMutableArrayRef> urls =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (!urls) {
return;
}
CFURLRef url;
CFURLEnumeratorResult result;
do {
result = CFURLEnumeratorGetNextURL(enumerator, &url, nullptr);
if (result != kCFURLEnumeratorSuccess) {
continue;
}
CFArrayAppendValue(urls, url);
if (!aLoadedFamilies) {
continue;
}
AutoCFRelease<CFArrayRef> descriptors = CTFontManagerCreateFontDescriptorsFromURL(url);
if (!descriptors || !CFArrayGetCount(descriptors)) {
continue;
}
CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descriptors, 0);
AutoCFRelease<CFStringRef> name =
(CFStringRef)CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
nsAutoCString key;
key.SetLength((CFStringGetLength(name) + 1) * 3);
if (CFStringGetCString(name, key.BeginWriting(), key.Length(), kCFStringEncodingUTF8)) {
key.SetLength(strlen(key.get()));
aLoadedFamilies->Insert(key);
}
} while (result != kCFURLEnumeratorEnd);
CTFontManagerRegisterFontsForURLs(urls, kCTFontManagerScopeProcess, nullptr);
}
void gfxMacPlatformFontList::ReadSystemFontList(dom::SystemFontList* aList) {
// Note: We rely on the records for mSystemTextFontFamilyName and
// mSystemDisplayFontFamilyName (if present) being *before* the main
......@@ -1877,3 +1943,20 @@ void gfxMacPlatformFontList::ReadFaceNamesForFamily(fontlist::Family* aFamily,
}
}
}
#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(u"fonts"_ns))) {
return;
}
nsAutoCString path;
if (NS_FAILED(localDir->GetNativePath(path))) {
return;
}
ActivateFontsFromDir(path, &mBundledFamilies);
}
#endif
......@@ -284,6 +284,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
LoadBadUnderlineList();
gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, mEnabledFontsList);
mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
// pref changes notification setup
NS_ASSERTION(!gFontListPrefObserver,
......@@ -341,7 +342,6 @@ const uint32_t kNumGenerics = 5;
void gfxPlatformFontList::ApplyWhitelist() {
uint32_t numFonts = mEnabledFontsList.Length();
mFontFamilyWhitelistActive = (numFonts > 0);
if (!mFontFamilyWhitelistActive) {
return;
}
......@@ -382,7 +382,6 @@ void gfxPlatformFontList::ApplyWhitelist() {
void gfxPlatformFontList::ApplyWhitelist(
nsTArray<fontlist::Family::InitData>& aFamilies) {
mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
if (!mFontFamilyWhitelistActive) {
return;
}
......@@ -520,6 +519,7 @@ bool gfxPlatformFontList::InitFontList() {
CancelLoader();
gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, mEnabledFontsList);
mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
// Ensure SetVisibilityLevel will clear the mCodepointsWithNoFonts set.
mVisibilityLevel = FontVisibility::Unknown;
......
......@@ -82,56 +82,6 @@ static void DisableFontActivation() {
}
}
// Helpers for gfxPlatformMac::RegisterSupplementalFonts below.
static void ActivateFontsFromDir(const nsACString& aDir) {
AutoCFRelease<CFURLRef> directory = CFURLCreateFromFileSystemRepresentation(
kCFAllocatorDefault, (const UInt8*)nsPromiseFlatCString(aDir).get(),
aDir.Length(), true);
if (!directory) {
return;
}
AutoCFRelease<CFURLEnumeratorRef> enumerator =
CFURLEnumeratorCreateForDirectoryURL(kCFAllocatorDefault, directory,
kCFURLEnumeratorDefaultBehavior,
nullptr);
if (!enumerator) {
return;
}
AutoCFRelease<CFMutableArrayRef> urls =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (!urls) {
return;
}
CFURLRef url;
CFURLEnumeratorResult result;
do {
result = CFURLEnumeratorGetNextURL(enumerator, &url, nullptr);
if (result == kCFURLEnumeratorSuccess) {
CFArrayAppendValue(urls, url);
}
} while (result != kCFURLEnumeratorEnd);
CTFontManagerRegisterFontsForURLs(urls, kCTFontManagerScopeProcess, nullptr);
}
#ifdef MOZ_BUNDLED_FONTS
static void ActivateBundledFonts() {
nsCOMPtr<nsIFile> localDir;
if (NS_FAILED(NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir)))) {
return;
}
if (NS_FAILED(localDir->Append(u"fonts"_ns))) {
return;
}
nsAutoCString path;
if (NS_FAILED(localDir->GetNativePath(path))) {
return;
}
ActivateFontsFromDir(path);
}
#endif
// A bunch of fonts for "additional language support" are shipped in a
// "Language Support" directory, and don't show up in the standard font
// list returned by CTFontManagerCopyAvailableFontFamilyNames unless
......@@ -150,12 +100,13 @@ static const nsLiteralCString kLangFontsDirs[] = {
"/System/Library/Fonts/Supplemental"_ns};
#endif
static void FontRegistrationCallback(void* aUnused) {
/* static */
void gfxPlatformMac::FontRegistrationCallback(void*) {
AUTO_PROFILER_REGISTER_THREAD("RegisterFonts");
PR_SetCurrentThreadName("RegisterFonts");
for (const auto& dir : kLangFontsDirs) {
ActivateFontsFromDir(dir);
gfxMacPlatformFontList::ActivateFontsFromDir(dir);
}
}
......@@ -182,7 +133,7 @@ void gfxPlatformMac::RegisterSupplementalFonts() {
// CTFontManager.h header claiming that it's thread-safe. So we just do it
// immediately on the main thread, and accept the startup-time hit (sigh).
for (const auto& dir : kLangFontsDirs) {
ActivateFontsFromDir(dir);
gfxMacPlatformFontList::ActivateFontsFromDir(dir);
}
}
}
......@@ -192,22 +143,6 @@ void gfxPlatformMac::WaitForFontRegistration() {
if (sFontRegistrationThread) {
PR_JoinThread(sFontRegistrationThread);
sFontRegistrationThread = nullptr;
#ifdef MOZ_BUNDLED_FONTS
// This is not done by the font registration thread because it uses the
// XPCOM directory service, which is not yet available at the time we start
// the registration thread.
//
// We activate bundled fonts if the pref is > 0 (on) or < 0 (auto), only an
// explicit value of 0 (off) will disable them.
if (StaticPrefs::gfx_bundled_fonts_activate_AtStartup() != 0) {
TimeStamp start = TimeStamp::Now();
ActivateBundledFonts();
TimeStamp end = TimeStamp::Now();
Telemetry::Accumulate(Telemetry::FONTLIST_BUNDLEDFONTS_ACTIVATE,
(end - start).ToMilliseconds());
}
#endif
}
}
......
......@@ -94,6 +94,8 @@ class gfxPlatformMac : public gfxPlatform {
// read in the pref value for the lower threshold on font anti-aliasing
static uint32_t ReadAntiAliasingThreshold();
static void FontRegistrationCallback(void* aUnused);
uint32_t mFontAntiAliasingThreshold;
static PRThread* sFontRegistrationThread;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment