Commit 2f55a1a8 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

Bug 1774413: Bundled fonts are not picked up on macOS r=jfkthame

Bundled fonts were not picked up because also child processes need to
register them.
Also, they were assigned User visibility, instead of Base, which was
not coherent with other platforms.

Differential Revision: https://phabricator.services.mozilla.com/D150400
parent ba30834a
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -221,6 +221,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
  void AddFamily(const nsACString& aFamilyName, FontVisibility aVisibility)
      REQUIRES(mLock);

  static void ActivateFontsFromDir(
      const nsACString& aDir,
      nsTHashSet<nsCStringHashKey>* aLoadedFamilies = nullptr);

  gfxFontEntry* CreateFontEntry(
      mozilla::fontlist::Face* aFace,
      const mozilla::fontlist::Family* aFamily) override;
@@ -234,6 +238,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {
                              bool aNeedFullnamePostscriptNames)
      REQUIRES(mLock) override;

#ifdef MOZ_BUNDLED_FONTS
  void ActivateBundledFonts();
#endif

  enum { kATSGenerationInitial = -1 };

  // default font for use with system-wide font fallback
@@ -249,6 +257,10 @@ class gfxMacPlatformFontList final : public gfxPlatformFontList {

  nsTArray<nsCString> mSingleFaceFonts;
  nsTArray<nsCString> mPreloadFonts;

#ifdef MOZ_BUNDLED_FONTS
  nsTHashSet<nsCStringHashKey> mBundledFamilies;
#endif
};

#endif /* gfxMacPlatformFontList_H_ */
+83 −0
Original line number Diff line number Diff line
@@ -995,6 +995,18 @@ gfxMacPlatformFontList::gfxMacPlatformFontList()
    : gfxPlatformFontList(false), mDefaultFont(nullptr), mUseSizeSensitiveSystemFont(false) {
  CheckFamilyList(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];
@@ -1044,6 +1056,11 @@ FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily(const nsACString&
  if (FamilyInList(aName, kBaseFonts)) {
    return FontVisibility::Base;
  }
#ifdef MOZ_BUNDLED_FONTS
  if (mBundledFamilies.Contains(aName)) {
    return FontVisibility::Base;
  }
#endif
  return FontVisibility::User;
}

@@ -1064,6 +1081,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)
    NO_THREAD_SAFETY_ANALYSIS {
  // Note: We rely on the records for mSystemTextFontFamilyName and
@@ -2093,3 +2159,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
+2 −2
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
  mFontPrefs = MakeUnique<FontPrefs>();

  gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, mEnabledFontsList);
  mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();

  // pref changes notification setup
  NS_ASSERTION(!gFontListPrefObserver,
@@ -354,7 +355,6 @@ void gfxPlatformFontList::FontWhitelistPrefChanged(const char* aPref,

void gfxPlatformFontList::ApplyWhitelist() {
  uint32_t numFonts = mEnabledFontsList.Length();
  mFontFamilyWhitelistActive = (numFonts > 0);
  if (!mFontFamilyWhitelistActive) {
    return;
  }
@@ -396,7 +396,6 @@ void gfxPlatformFontList::ApplyWhitelist() {
void gfxPlatformFontList::ApplyWhitelist(
    nsTArray<fontlist::Family::InitData>& aFamilies) {
  mLock.AssertCurrentThreadIn();
  mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
  if (!mFontFamilyWhitelistActive) {
    return;
  }
@@ -548,6 +547,7 @@ bool gfxPlatformFontList::InitFontList() {
    }

    gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, mEnabledFontsList);
    mFontFamilyWhitelistActive = !mEnabledFontsList.IsEmpty();
  }

  // From here, gfxPlatformFontList::IsInitialized will return true,
+4 −69
Original line number Diff line number Diff line
@@ -83,56 +83,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
@@ -141,12 +91,13 @@ static const nsLiteralCString kLangFontsDirs[] = {
    "/Library/Application Support/Apple/Fonts/Language Support"_ns,
    "/System/Library/Fonts/Supplemental"_ns};

static void FontRegistrationCallback(void* aUnused) {
/* static */
void gfxPlatformMac::FontRegistrationCallback(void* aUnused) {
  AUTO_PROFILER_REGISTER_THREAD("RegisterFonts");
  PR_SetCurrentThreadName("RegisterFonts");

  for (const auto& dir : kLangFontsDirs) {
    ActivateFontsFromDir(dir);
    gfxMacPlatformFontList::ActivateFontsFromDir(dir);
  }
}

@@ -173,7 +124,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);
    }
  }
}
@@ -183,22 +134,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
  }
}

+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,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;