Replace implicit dependency on global SkFontMgr

Skia's default SkFontMgr is going away, so clients need to
explicitly use the font managers they want to use. This CL
attempts to preserve the existing behavior.

Bug: b:305780908
Change-Id: I42819fecf0ae53b0a5a9cead6b81aa3880027f61
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/113750
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index 2ca7c1e..f3971f5 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -31,11 +31,15 @@
 #if defined(_SKIA_SUPPORT_)
 #include "third_party/skia/include/core/SkStream.h"  // nogncheck
 #include "third_party/skia/include/core/SkTypeface.h"  // nogncheck
-
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
 #include "third_party/skia/include/core/SkFontMgr.h"  // nogncheck
 #include "third_party/skia/include/ports/SkFontMgr_empty.h"  // nogncheck
+
+#if BUILDFLAG(IS_WIN)
+#include "include/ports/SkTypeface_win.h"  // nogncheck
+#elif BUILDFLAG(IS_APPLE)
+#include "include/ports/SkFontMgr_mac_ct.h"  // nogncheck
 #endif
+
 #endif
 
 #if BUILDFLAG(IS_APPLE)
@@ -336,17 +340,45 @@
 }
 
 #if defined(_SKIA_SUPPORT_)
+
+namespace {
+// A singleton SkFontMgr which can be used to decode raw font data or
+// otherwise get access to system fonts.
+SkFontMgr* g_fontmgr = nullptr;
+}  // namespace
+
+// static
+void CFX_GlyphCache::InitializeGlobals() {
+  CHECK(!g_fontmgr);
+#if BUILDFLAG(IS_WIN)
+  g_fontmgr = SkFontMgr_New_DirectWrite().release();
+#elif BUILDFLAG(IS_APPLE)
+  g_fontmgr = SkFontMgr_New_CoreText(nullptr).release();
+#else
+  // This is a SkFontMgr which will use FreeType to decode font data.
+  g_fontmgr = SkFontMgr_New_Custom_Empty().release();
+#endif
+}
+
+// static
+void CFX_GlyphCache::DestroyGlobals() {
+  CHECK(g_fontmgr);
+  delete g_fontmgr;
+  g_fontmgr = nullptr;
+}
+
 CFX_TypeFace* CFX_GlyphCache::GetDeviceCache(const CFX_Font* pFont) {
-  if (!m_pTypeface) {
+  if (!m_pTypeface && g_fontmgr) {
     pdfium::span<const uint8_t> span = pFont->GetFontSpan();
-    m_pTypeface = SkTypeface::MakeFromStream(
+    m_pTypeface = g_fontmgr->makeFromStream(
         std::make_unique<SkMemoryStream>(span.data(), span.size()));
   }
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
+  // If DirectWrite or CoreText didn't work, try FreeType.
   if (!m_pTypeface) {
-    sk_sp<SkFontMgr> customMgr(SkFontMgr_New_Custom_Empty());
+    sk_sp<SkFontMgr> freetype_mgr = SkFontMgr_New_Custom_Empty();
     pdfium::span<const uint8_t> span = pFont->GetFontSpan();
-    m_pTypeface = customMgr->makeFromStream(
+    m_pTypeface = freetype_mgr->makeFromStream(
         std::make_unique<SkMemoryStream>(span.data(), span.size()));
   }
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
diff --git a/core/fxge/cfx_glyphcache.h b/core/fxge/cfx_glyphcache.h
index c71ae3c..6297809 100644
--- a/core/fxge/cfx_glyphcache.h
+++ b/core/fxge/cfx_glyphcache.h
@@ -51,6 +51,8 @@
 
 #if defined(_SKIA_SUPPORT_)
   CFX_TypeFace* GetDeviceCache(const CFX_Font* pFont);
+  static void InitializeGlobals();
+  static void DestroyGlobals();
 #endif
 
  private:
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index fbe75d9..e0eb81a 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -40,6 +40,7 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
 #include "core/fxge/cfx_gemodule.h"
+#include "core/fxge/cfx_glyphcache.h"
 #include "core/fxge/cfx_renderdevice.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "fpdfsdk/cpdfsdk_customaccess.h"
@@ -234,6 +235,10 @@
   CFX_GEModule::Create(config ? config->m_pUserFontPaths : nullptr);
   CPDF_PageModule::Create();
 
+#if defined(_SKIA_SUPPORT_)
+  CFX_GlyphCache::InitializeGlobals();
+#endif
+
 #ifdef PDF_ENABLE_XFA
   CPDFXFA_ModuleInit();
 #endif  // PDF_ENABLE_XFA
@@ -253,6 +258,7 @@
   if (!g_bLibraryInitialized)
     return;
 
+  // Note: we teardown/destroy things in reverse order.
   ResetRendererType();
 
   IJS_Runtime::Destroy();
@@ -261,6 +267,10 @@
   CPDFXFA_ModuleDestroy();
 #endif  // PDF_ENABLE_XFA
 
+#if defined(_SKIA_SUPPORT_)
+  CFX_GlyphCache::DestroyGlobals();
+#endif
+
   CPDF_PageModule::Destroy();
   CFX_GEModule::Destroy();
   CFX_Timer::DestroyGlobals();
diff --git a/xfa/fde/cfde_textout_unittest.cpp b/xfa/fde/cfde_textout_unittest.cpp
index 6971f03..01f9f99 100644
--- a/xfa/fde/cfde_textout_unittest.cpp
+++ b/xfa/fde/cfde_textout_unittest.cpp
@@ -13,6 +13,7 @@
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
+#include "core/fxge/cfx_glyphcache.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/utils/hash.h"
@@ -26,6 +27,9 @@
   ~CFDETextOutTest() override = default;
 
   void SetUp() override {
+#if defined(_SKIA_SUPPORT_)
+  CFX_GlyphCache::InitializeGlobals();
+#endif
     CFX_Size bitmap_size = GetBitmapSize();
     bitmap_ = pdfium::MakeRetain<CFX_DIBitmap>();
     ASSERT_TRUE(bitmap_->Create(bitmap_size.width, bitmap_size.height,
@@ -45,10 +49,14 @@
   }
 
   void TearDown() override {
+    // reverse order form SetUp()
     text_out_.reset();
     font_.Reset();
     device_.reset();
     bitmap_.Reset();
+#if defined(_SKIA_SUPPORT_)
+  CFX_GlyphCache::DestroyGlobals();
+#endif
   }
 
   virtual RetainPtr<CFGAS_GEFont> LoadFont() {