Commit e53b42f1 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃 Committed by Richard Pospesel
Browse files

Bug 41004: Bundled fonts are not picked up on macOS

Fixes Bug 1774413: https://bugzilla.mozilla.org/show_bug.cgi?id=1774413
Drop this once patch is accepted upstream
parent 2dba6080
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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_ */
+83 −0
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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;
+4 −69
Original line number Diff line number Diff line
@@ -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
  }
}

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