Move some CFGAS_FontMgr methods into an anonymous namespace.

They do not have to be part of the class. Fix nits and lint errors too.

Change-Id: Ie8f745f378beeebf05841ff17a98141924999613
Reviewed-on: https://pdfium-review.googlesource.com/42890
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index d0a6127..ed1fe78 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -389,159 +389,122 @@
 
 };  // extern "C"
 
-}  // namespace
+// TODO(thestig): Pass in |name_table| as a std::vector?
+std::vector<WideString> GetNames(const uint8_t* name_table) {
+  std::vector<WideString> results;
+  if (!name_table)
+    return results;
 
-CFX_FontDescriptor::CFX_FontDescriptor()
-    : m_nFaceIndex(0), m_dwFontStyles(0), m_dwUsb(), m_dwCsb() {}
+  const uint8_t* lpTable = name_table;
+  WideString wsFamily;
+  const uint8_t* sp = lpTable + 2;
+  const uint8_t* lpNameRecord = lpTable + 6;
+  uint16_t nNameCount = GetUInt16(sp);
+  const uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
+  for (uint16_t j = 0; j < nNameCount; j++) {
+    uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
+    if (nNameID != 1)
+      continue;
 
-CFX_FontDescriptor::~CFX_FontDescriptor() {}
-
-CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
-  for (size_t i = 0; i < FX_ArraySize(g_FontFolders); ++i)
-    m_FolderPaths.push_back(g_FontFolders[i]);
-}
-
-CFX_FontSourceEnum_File::~CFX_FontSourceEnum_File() {}
-
-ByteString CFX_FontSourceEnum_File::GetNextFile() {
-  FX_FileHandle* pCurHandle =
-      !m_FolderQueue.empty() ? m_FolderQueue.back().pFileHandle : nullptr;
-  if (!pCurHandle) {
-    if (m_FolderPaths.empty())
-      return "";
-    pCurHandle = FX_OpenFolder(m_FolderPaths.back().c_str());
-    HandleParentPath hpp;
-    hpp.pFileHandle = pCurHandle;
-    hpp.bsParentPath = m_FolderPaths.back();
-    m_FolderQueue.push_back(hpp);
-  }
-  ByteString bsName;
-  bool bFolder;
-  ByteString bsFolderSeparator = WideString(kFolderSeparator).ToDefANSI();
-  while (true) {
-    if (!FX_GetNextFile(pCurHandle, &bsName, &bFolder)) {
-      FX_CloseFolder(pCurHandle);
-      if (!m_FolderQueue.empty())
-        m_FolderQueue.pop_back();
-      if (m_FolderQueue.empty()) {
-        if (!m_FolderPaths.empty())
-          m_FolderPaths.pop_back();
-        return !m_FolderPaths.empty() ? GetNextFile() : "";
+    uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
+    uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
+    uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
+    wsFamily.clear();
+    if (nPlatformID != 1) {
+      for (uint16_t k = 0; k < nNameLength / 2; k++) {
+        wchar_t wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
+        wsFamily += wcTemp;
       }
-      pCurHandle = m_FolderQueue.back().pFileHandle;
+      results.push_back(wsFamily);
       continue;
     }
-    if (bsName == "." || bsName == "..")
-      continue;
-    if (bFolder) {
-      HandleParentPath hpp;
-      hpp.bsParentPath =
-          m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
-      hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath.c_str());
-      if (!hpp.pFileHandle)
-        continue;
-      m_FolderQueue.push_back(hpp);
-      pCurHandle = hpp.pFileHandle;
-      continue;
+    for (uint16_t k = 0; k < nNameLength; k++) {
+      wchar_t wcTemp = GetUInt8(lpStr + nNameOffset + k);
+      wsFamily += wcTemp;
     }
-    bsName = m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
-    break;
+    results.push_back(wsFamily);
   }
-  return bsName;
+  return results;
 }
 
-bool CFX_FontSourceEnum_File::HasStartPosition() {
-  m_wsNext = GetNextFile().UTF8Decode();
-  return m_wsNext.GetLength() != 0;
-}
-
-// <next exists, stream for next>
-std::pair<bool, RetainPtr<IFX_SeekableStream>>
-CFX_FontSourceEnum_File::GetNext() {
-  if (m_wsNext.GetLength() == 0)
-    return {false, nullptr};
-
-  auto stream = IFX_SeekableStream::CreateFromFilename(m_wsNext.c_str(),
-                                                       FX_FILEMODE_ReadOnly);
-  m_wsNext = GetNextFile().UTF8Decode();
-  return {true, stream};
-}
-
-CFGAS_FontMgr::CFGAS_FontMgr()
-    : m_pFontSource(pdfium::MakeUnique<CFX_FontSourceEnum_File>()) {}
-
-CFGAS_FontMgr::~CFGAS_FontMgr() {}
-
-bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
-  CFX_FontMapper* pFontMapper =
-      CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
-  if (!pFontMapper)
-    return false;
-
-  pFontMapper->LoadInstalledFonts();
-
-  SystemFontInfoIface* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
-  if (!pSystemFontInfo)
-    return false;
-
-  pSystemFontInfo->EnumFontList(pFontMapper);
-  for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
-    RetainPtr<IFX_SeekableReadStream> pFontStream =
-        CreateFontStream(pFontMapper, pSystemFontInfo, i);
-    if (!pFontStream)
-      continue;
-
-    WideString wsFaceName =
-        WideString::FromLocal(pFontMapper->GetFaceName(i).AsStringView());
-    RegisterFaces(pFontStream, &wsFaceName);
+std::vector<uint16_t> GetCharsets(FXFT_Face pFace) {
+  std::vector<uint16_t> charsets;
+  TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
+  if (!pOS2) {
+    charsets.push_back(FX_CHARSET_Default);
+    return charsets;
   }
-
-  return !m_InstalledFonts.empty();
-}
-
-bool CFGAS_FontMgr::EnumFontsFromFiles() {
-  CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
-  if (!m_pFontSource->HasStartPosition())
-    return !m_InstalledFonts.empty();
-
-  bool has_next;
-  RetainPtr<IFX_SeekableStream> stream;
-  std::tie(has_next, stream) = m_pFontSource->GetNext();
-  while (has_next) {
-    if (stream)
-      RegisterFaces(stream, nullptr);
-    std::tie(has_next, stream) = m_pFontSource->GetNext();
+  uint16_t a[4] = {
+      pOS2->ulCodePageRange1 & 0xffff, (pOS2->ulCodePageRange1 >> 16) & 0xffff,
+      pOS2->ulCodePageRange2 & 0xffff, (pOS2->ulCodePageRange2 >> 16) & 0xffff};
+  for (int n = 0; n < 4; n++) {
+    for (int32_t i = 0; i < 16; i++) {
+      if ((a[n] & g_FX_Bit2Charset[n][i].wBit) != 0)
+        charsets.push_back(g_FX_Bit2Charset[n][i].wCharset);
+    }
   }
-  return !m_InstalledFonts.empty();
+  return charsets;
 }
 
-bool CFGAS_FontMgr::EnumFonts() {
-  return EnumFontsFromFontMapper() || EnumFontsFromFiles();
+void GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB) {
+  TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
+  if (!pOS2) {
+    USB[0] = 0;
+    USB[1] = 0;
+    USB[2] = 0;
+    USB[3] = 0;
+    CSB[0] = 0;
+    CSB[1] = 0;
+    return;
+  }
+  USB[0] = pOS2->ulUnicodeRange1;
+  USB[1] = pOS2->ulUnicodeRange2;
+  USB[2] = pOS2->ulUnicodeRange3;
+  USB[3] = pOS2->ulUnicodeRange4;
+  CSB[0] = pOS2->ulCodePageRange1;
+  CSB[1] = pOS2->ulCodePageRange2;
 }
 
-bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc,
-                                  wchar_t wcUnicode) {
-  RetainPtr<IFX_SeekableReadStream> pFileRead =
-      CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
-  if (!pFileRead)
-    return false;
+uint32_t GetFlags(FXFT_Face pFace) {
+  uint32_t flag = 0;
+  if (FT_IS_FIXED_WIDTH(pFace))
+    flag |= FXFONT_FIXED_PITCH;
+  TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
+  if (!pOS2)
+    return flag;
 
-  FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
-  FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
-  FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
-  if (!pFace)
-    return false;
-
-  if (FXFT_Get_Face_External_Stream(pFace))
-    FXFT_Clear_Face_External_Stream(pFace);
-
-  FXFT_Done_Face(pFace);
-  return !retCharmap && retIndex;
+  if (pOS2->ulCodePageRange1 & (1 << 31))
+    flag |= FXFONT_SYMBOLIC;
+  if (pOS2->panose[0] == 2) {
+    uint8_t uSerif = pOS2->panose[1];
+    if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
+      flag |= FXFONT_SERIF;
+  }
+  return flag;
 }
 
-RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(const WideString& wsFaceName,
-                                                int32_t iFaceIndex,
-                                                int32_t* pFaceCount) {
+RetainPtr<IFX_SeekableReadStream> CreateFontStream(
+    CFX_FontMapper* pFontMapper,
+    SystemFontInfoIface* pSystemFontInfo,
+    uint32_t index) {
+  void* hFont = pSystemFontInfo->MapFont(
+      0, 0, FX_CHARSET_Default, 0, pFontMapper->GetFaceName(index).c_str());
+  if (!hFont)
+    return nullptr;
+
+  uint32_t dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
+  if (dwFileSize == 0)
+    return nullptr;
+
+  std::unique_ptr<uint8_t, FxFreeDeleter> pBuffer(
+      FX_Alloc(uint8_t, dwFileSize + 1));
+  dwFileSize =
+      pSystemFontInfo->GetFontData(hFont, 0, pBuffer.get(), dwFileSize);
+  return pdfium::MakeRetain<CFX_MemoryStream>(std::move(pBuffer), dwFileSize);
+}
+
+RetainPtr<IFX_SeekableReadStream> CreateFontStream(
+    const ByteString& bsFaceName) {
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
   if (!pFontMapper)
@@ -551,29 +514,16 @@
   if (!pSystemFontInfo)
     return nullptr;
 
-  RetainPtr<IFX_SeekableReadStream> pFontStream =
-      CreateFontStream(wsFaceName.UTF8Encode());
-  if (!pFontStream)
-    return nullptr;
-
-  auto pInternalFont = pdfium::MakeUnique<CFX_Font>();
-  if (!pInternalFont->LoadFile(pFontStream, iFaceIndex))
-    return nullptr;
-
-  RetainPtr<CFGAS_GEFont> pFont =
-      CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
-  if (!pFont)
-    return nullptr;
-
-  m_IFXFont2FileRead[pFont] = pFontStream;
-  if (pFaceCount)
-    *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;
-  return pFont;
+  pSystemFontInfo->EnumFontList(pFontMapper);
+  for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
+    if (pFontMapper->GetFaceName(i) == bsFaceName)
+      return CreateFontStream(pFontMapper, pSystemFontInfo, i);
+  }
+  return nullptr;
 }
 
-FXFT_Face CFGAS_FontMgr::LoadFace(
-    const RetainPtr<IFX_SeekableReadStream>& pFontStream,
-    int32_t iFaceIndex) {
+FXFT_Face LoadFace(const RetainPtr<IFX_SeekableReadStream>& pFontStream,
+                   int32_t iFaceIndex) {
   if (!pFontStream)
     return nullptr;
 
@@ -613,69 +563,35 @@
   return pFace;
 }
 
-RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
-    CFX_FontMapper* pFontMapper,
-    SystemFontInfoIface* pSystemFontInfo,
-    uint32_t index) {
-  void* hFont = pSystemFontInfo->MapFont(
-      0, 0, FX_CHARSET_Default, 0, pFontMapper->GetFaceName(index).c_str());
-  if (!hFont)
-    return nullptr;
+bool VerifyUnicodeForFontDescriptor(CFX_FontDescriptor* pDesc,
+                                    wchar_t wcUnicode) {
+  RetainPtr<IFX_SeekableReadStream> pFileRead =
+      CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
+  if (!pFileRead)
+    return false;
 
-  uint32_t dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
-  if (dwFileSize == 0)
-    return nullptr;
+  FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
+  FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
+  FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
+  if (!pFace)
+    return false;
 
-  std::unique_ptr<uint8_t, FxFreeDeleter> pBuffer(
-      FX_Alloc(uint8_t, dwFileSize + 1));
-  dwFileSize =
-      pSystemFontInfo->GetFontData(hFont, 0, pBuffer.get(), dwFileSize);
-  return pdfium::MakeRetain<CFX_MemoryStream>(std::move(pBuffer), dwFileSize);
+  if (FXFT_Get_Face_External_Stream(pFace))
+    FXFT_Clear_Face_External_Stream(pFace);
+
+  FXFT_Done_Face(pFace);
+  return !retCharmap && retIndex;
 }
 
-RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
-    const ByteString& bsFaceName) {
-  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
-  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
-  if (!pFontMapper)
-    return nullptr;
-
-  SystemFontInfoIface* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
-  if (!pSystemFontInfo)
-    return nullptr;
-
-  pSystemFontInfo->EnumFontList(pFontMapper);
-  for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
-    if (pFontMapper->GetFaceName(i) == bsFaceName)
-      return CreateFontStream(pFontMapper, pSystemFontInfo, i);
-  }
-  return nullptr;
+bool IsPartName(const WideString& name1, const WideString& name2) {
+  return name1.Contains(name2.AsStringView());
 }
 
-void CFGAS_FontMgr::MatchFonts(
-    std::vector<CFX_FontDescriptorInfo>* pMatchedFonts,
-    uint16_t wCodePage,
-    uint32_t dwFontStyles,
-    const WideString& FontName,
-    wchar_t wcUnicode) {
-  pMatchedFonts->clear();
-  for (const auto& pFont : m_InstalledFonts) {
-    int32_t nPenalty =
-        CalcPenalty(pFont.get(), wCodePage, dwFontStyles, FontName, wcUnicode);
-    if (nPenalty >= 0xffff)
-      continue;
-    pMatchedFonts->push_back({pFont.get(), nPenalty});
-    if (pMatchedFonts->size() == 0xffff)
-      break;
-  }
-  std::sort(pMatchedFonts->begin(), pMatchedFonts->end());
-}
-
-int32_t CFGAS_FontMgr::CalcPenalty(CFX_FontDescriptor* pInstalled,
-                                   uint16_t wCodePage,
-                                   uint32_t dwFontStyles,
-                                   const WideString& FontName,
-                                   wchar_t wcUnicode) {
+int32_t CalcPenalty(CFX_FontDescriptor* pInstalled,
+                    uint16_t wCodePage,
+                    uint32_t dwFontStyles,
+                    const WideString& FontName,
+                    wchar_t wcUnicode) {
   int32_t nPenalty = 30000;
   if (FontName.GetLength() != 0) {
     if (FontName != pInstalled->m_wsFaceName) {
@@ -741,6 +657,186 @@
   return nPenalty;
 }
 
+}  // namespace
+
+CFX_FontDescriptor::CFX_FontDescriptor()
+    : m_nFaceIndex(0), m_dwFontStyles(0), m_dwUsb(), m_dwCsb() {}
+
+CFX_FontDescriptor::~CFX_FontDescriptor() {}
+
+CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
+  for (size_t i = 0; i < FX_ArraySize(g_FontFolders); ++i)
+    m_FolderPaths.push_back(g_FontFolders[i]);
+}
+
+CFX_FontSourceEnum_File::~CFX_FontSourceEnum_File() {}
+
+ByteString CFX_FontSourceEnum_File::GetNextFile() {
+  FX_FileHandle* pCurHandle =
+      !m_FolderQueue.empty() ? m_FolderQueue.back().pFileHandle : nullptr;
+  if (!pCurHandle) {
+    if (m_FolderPaths.empty())
+      return "";
+    pCurHandle = FX_OpenFolder(m_FolderPaths.back().c_str());
+    HandleParentPath hpp;
+    hpp.pFileHandle = pCurHandle;
+    hpp.bsParentPath = m_FolderPaths.back();
+    m_FolderQueue.push_back(hpp);
+  }
+  ByteString bsName;
+  bool bFolder;
+  ByteString bsFolderSeparator = WideString(kFolderSeparator).ToDefANSI();
+  while (true) {
+    if (!FX_GetNextFile(pCurHandle, &bsName, &bFolder)) {
+      FX_CloseFolder(pCurHandle);
+      if (!m_FolderQueue.empty())
+        m_FolderQueue.pop_back();
+      if (m_FolderQueue.empty()) {
+        if (!m_FolderPaths.empty())
+          m_FolderPaths.pop_back();
+        return !m_FolderPaths.empty() ? GetNextFile() : "";
+      }
+      pCurHandle = m_FolderQueue.back().pFileHandle;
+      continue;
+    }
+    if (bsName == "." || bsName == "..")
+      continue;
+    if (bFolder) {
+      HandleParentPath hpp;
+      hpp.bsParentPath =
+          m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
+      hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath.c_str());
+      if (!hpp.pFileHandle)
+        continue;
+      m_FolderQueue.push_back(hpp);
+      pCurHandle = hpp.pFileHandle;
+      continue;
+    }
+    bsName = m_FolderQueue.back().bsParentPath + bsFolderSeparator + bsName;
+    break;
+  }
+  return bsName;
+}
+
+bool CFX_FontSourceEnum_File::HasStartPosition() {
+  m_wsNext = GetNextFile().UTF8Decode();
+  return !m_wsNext.IsEmpty();
+}
+
+std::pair<bool, RetainPtr<IFX_SeekableStream>>
+CFX_FontSourceEnum_File::GetNext() {
+  if (m_wsNext.IsEmpty())
+    return {false, nullptr};
+
+  auto stream = IFX_SeekableStream::CreateFromFilename(m_wsNext.c_str(),
+                                                       FX_FILEMODE_ReadOnly);
+  m_wsNext = GetNextFile().UTF8Decode();
+  return {true, stream};
+}
+
+CFGAS_FontMgr::CFGAS_FontMgr()
+    : m_pFontSource(pdfium::MakeUnique<CFX_FontSourceEnum_File>()) {}
+
+CFGAS_FontMgr::~CFGAS_FontMgr() {}
+
+bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
+  CFX_FontMapper* pFontMapper =
+      CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
+  if (!pFontMapper)
+    return false;
+
+  pFontMapper->LoadInstalledFonts();
+
+  SystemFontInfoIface* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
+  if (!pSystemFontInfo)
+    return false;
+
+  pSystemFontInfo->EnumFontList(pFontMapper);
+  for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
+    RetainPtr<IFX_SeekableReadStream> pFontStream =
+        CreateFontStream(pFontMapper, pSystemFontInfo, i);
+    if (!pFontStream)
+      continue;
+
+    WideString wsFaceName =
+        WideString::FromLocal(pFontMapper->GetFaceName(i).AsStringView());
+    RegisterFaces(pFontStream, &wsFaceName);
+  }
+
+  return !m_InstalledFonts.empty();
+}
+
+bool CFGAS_FontMgr::EnumFontsFromFiles() {
+  CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
+  if (!m_pFontSource->HasStartPosition())
+    return !m_InstalledFonts.empty();
+
+  bool has_next;
+  RetainPtr<IFX_SeekableStream> stream;
+  std::tie(has_next, stream) = m_pFontSource->GetNext();
+  while (has_next) {
+    if (stream)
+      RegisterFaces(stream, nullptr);
+    std::tie(has_next, stream) = m_pFontSource->GetNext();
+  }
+  return !m_InstalledFonts.empty();
+}
+
+bool CFGAS_FontMgr::EnumFonts() {
+  return EnumFontsFromFontMapper() || EnumFontsFromFiles();
+}
+
+RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(const WideString& wsFaceName,
+                                                int32_t iFaceIndex,
+                                                int32_t* pFaceCount) {
+  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
+  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
+  if (!pFontMapper)
+    return nullptr;
+
+  SystemFontInfoIface* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
+  if (!pSystemFontInfo)
+    return nullptr;
+
+  RetainPtr<IFX_SeekableReadStream> pFontStream =
+      CreateFontStream(wsFaceName.UTF8Encode());
+  if (!pFontStream)
+    return nullptr;
+
+  auto pInternalFont = pdfium::MakeUnique<CFX_Font>();
+  if (!pInternalFont->LoadFile(pFontStream, iFaceIndex))
+    return nullptr;
+
+  RetainPtr<CFGAS_GEFont> pFont =
+      CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
+  if (!pFont)
+    return nullptr;
+
+  m_IFXFont2FileRead[pFont] = pFontStream;
+  if (pFaceCount)
+    *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;
+  return pFont;
+}
+
+void CFGAS_FontMgr::MatchFonts(
+    std::vector<CFX_FontDescriptorInfo>* pMatchedFonts,
+    uint16_t wCodePage,
+    uint32_t dwFontStyles,
+    const WideString& FontName,
+    wchar_t wcUnicode) {
+  pMatchedFonts->clear();
+  for (const auto& pFont : m_InstalledFonts) {
+    int32_t nPenalty =
+        CalcPenalty(pFont.get(), wCodePage, dwFontStyles, FontName, wcUnicode);
+    if (nPenalty >= 0xffff)
+      continue;
+    pMatchedFonts->push_back({pFont.get(), nPenalty});
+    if (pMatchedFonts->size() == 0xffff)
+      break;
+  }
+  std::sort(pMatchedFonts->begin(), pMatchedFonts->end());
+}
+
 void CFGAS_FontMgr::RegisterFace(FXFT_Face pFace, const WideString* pFaceName) {
   if ((pFace->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
     return;
@@ -764,7 +860,7 @@
     if (FXFT_Load_Sfnt_Table(pFace, dwTag, 0, table.data(), nullptr))
       table.clear();
   }
-  GetNames(table.empty() ? nullptr : table.data(), pFont->m_wsFamilyNames);
+  pFont->m_wsFamilyNames = GetNames(table.empty() ? nullptr : table.data());
   pFont->m_wsFamilyNames.push_back(ByteString(pFace->family_name).UTF8Decode());
   pFont->m_wsFaceName =
       pFaceName ? *pFaceName
@@ -792,105 +888,28 @@
   } while (index < num_faces);
 }
 
-uint32_t CFGAS_FontMgr::GetFlags(FXFT_Face pFace) {
-  uint32_t flag = 0;
-  if (FT_IS_FIXED_WIDTH(pFace))
-    flag |= FXFONT_FIXED_PITCH;
-  TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
-  if (!pOS2)
-    return flag;
-
-  if (pOS2->ulCodePageRange1 & (1 << 31))
-    flag |= FXFONT_SYMBOLIC;
-  if (pOS2->panose[0] == 2) {
-    uint8_t uSerif = pOS2->panose[1];
-    if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
-      flag |= FXFONT_SERIF;
-  }
-  return flag;
-}
-
-void CFGAS_FontMgr::GetNames(const uint8_t* name_table,
-                             std::vector<WideString>& Names) {
-  if (!name_table)
-    return;
-
-  uint8_t* lpTable = (uint8_t*)name_table;
-  WideString wsFamily;
-  uint8_t* sp = lpTable + 2;
-  uint8_t* lpNameRecord = lpTable + 6;
-  uint16_t nNameCount = GetUInt16(sp);
-  uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
-  for (uint16_t j = 0; j < nNameCount; j++) {
-    uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
-    if (nNameID != 1)
-      continue;
-
-    uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
-    uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
-    uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
-    wsFamily.clear();
-    if (nPlatformID != 1) {
-      for (uint16_t k = 0; k < nNameLength / 2; k++) {
-        wchar_t wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
-        wsFamily += wcTemp;
-      }
-      Names.push_back(wsFamily);
-      continue;
-    }
-    for (uint16_t k = 0; k < nNameLength; k++) {
-      wchar_t wcTemp = GetUInt8(lpStr + nNameOffset + k);
-      wsFamily += wcTemp;
-    }
-    Names.push_back(wsFamily);
-  }
-}
-
-std::vector<uint16_t> CFGAS_FontMgr::GetCharsets(FXFT_Face pFace) const {
-  std::vector<uint16_t> charsets;
-  TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
-  if (!pOS2) {
-    charsets.push_back(FX_CHARSET_Default);
-    return charsets;
-  }
-  uint16_t a[4] = {
-      pOS2->ulCodePageRange1 & 0xffff, (pOS2->ulCodePageRange1 >> 16) & 0xffff,
-      pOS2->ulCodePageRange2 & 0xffff, (pOS2->ulCodePageRange2 >> 16) & 0xffff};
-  for (int n = 0; n < 4; n++) {
-    for (int32_t i = 0; i < 16; i++) {
-      if ((a[n] & g_FX_Bit2Charset[n][i].wBit) != 0)
-        charsets.push_back(g_FX_Bit2Charset[n][i].wCharset);
-    }
-  }
-  return charsets;
-}
-
-void CFGAS_FontMgr::GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB) {
-  TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
-  if (!pOS2) {
-    USB[0] = 0;
-    USB[1] = 0;
-    USB[2] = 0;
-    USB[3] = 0;
-    CSB[0] = 0;
-    CSB[1] = 0;
-    return;
-  }
-  USB[0] = pOS2->ulUnicodeRange1;
-  USB[1] = pOS2->ulUnicodeRange2;
-  USB[2] = pOS2->ulUnicodeRange3;
-  USB[3] = pOS2->ulUnicodeRange4;
-  CSB[0] = pOS2->ulCodePageRange1;
-  CSB[1] = pOS2->ulCodePageRange2;
-}
-
-bool CFGAS_FontMgr::IsPartName(const WideString& name1,
-                               const WideString& name2) {
-  return name1.Contains(name2.AsStringView());
-}
-
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 
+namespace {
+
+bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode) {
+  if (!pFont)
+    return false;
+
+  FXFT_Face pFace = pFont->GetDevFont()->GetFace();
+  FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
+  if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
+    return false;
+
+  if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
+    FXFT_Set_Charmap(pFace, charmap);
+    return false;
+  }
+  return true;
+}
+
+}  // namespace
+
 RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
     uint16_t wCodePage,
     uint32_t dwFontStyles,
@@ -1003,7 +1022,7 @@
   }
   for (const auto& info : *sortedFontInfos) {
     CFX_FontDescriptor* pDesc = info.pFont;
-    if (!VerifyUnicode(pDesc, wUnicode))
+    if (!VerifyUnicodeForFontDescriptor(pDesc, wUnicode))
       continue;
     RetainPtr<CFGAS_GEFont> pFont =
         LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
@@ -1019,23 +1038,6 @@
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 }
 
-bool CFGAS_FontMgr::VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont,
-                                  wchar_t wcUnicode) {
-  if (!pFont)
-    return false;
-
-  FXFT_Face pFace = pFont->GetDevFont()->GetFace();
-  FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
-  if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0)
-    return false;
-
-  if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) {
-    FXFT_Set_Charmap(pFace, charmap);
-    return false;
-  }
-  return true;
-}
-
 RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(const wchar_t* pszFontFamily,
                                                 uint32_t dwFontStyles,
                                                 uint16_t wCodePage) {
diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h
index 6dda338..01b96a3 100644
--- a/xfa/fgas/font/cfgas_fontmgr.h
+++ b/xfa/fgas/font/cfgas_fontmgr.h
@@ -99,6 +99,8 @@
   ~CFX_FontSourceEnum_File();
 
   bool HasStartPosition();
+
+  // <next exists, stream for next>
   std::pair<bool, RetainPtr<IFX_SeekableStream>> GetNext();
 
  private:
@@ -148,41 +150,27 @@
                                     uint32_t dwUSB,
                                     wchar_t wUnicode);
 
-  std::deque<FX_FONTDESCRIPTOR> m_FontFaces;
 #else   // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
   bool EnumFontsFromFontMapper();
   bool EnumFontsFromFiles();
   void RegisterFace(FXFT_Face pFace, const WideString* pFaceName);
   void RegisterFaces(const RetainPtr<IFX_SeekableReadStream>& pFontStream,
                      const WideString* pFaceName);
-  void GetNames(const uint8_t* name_table, std::vector<WideString>& Names);
-  std::vector<uint16_t> GetCharsets(FXFT_Face pFace) const;
-  void GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB);
-  uint32_t GetFlags(FXFT_Face pFace);
-  bool VerifyUnicode(CFX_FontDescriptor* pDesc, wchar_t wcUnicode);
-  bool IsPartName(const WideString& name1, const WideString& name2);
   void MatchFonts(std::vector<CFX_FontDescriptorInfo>* MatchedFonts,
                   uint16_t wCodePage,
                   uint32_t dwFontStyles,
                   const WideString& FontName,
                   wchar_t wcUnicode);
-  int32_t CalcPenalty(CFX_FontDescriptor* pInstalled,
-                      uint16_t wCodePage,
-                      uint32_t dwFontStyles,
-                      const WideString& FontName,
-                      wchar_t wcUnicode);
   RetainPtr<CFGAS_GEFont> LoadFont(const WideString& wsFaceName,
                                    int32_t iFaceIndex,
                                    int32_t* pFaceCount);
-  FXFT_Face LoadFace(const RetainPtr<IFX_SeekableReadStream>& pFontStream,
-                     int32_t iFaceIndex);
-  RetainPtr<IFX_SeekableReadStream> CreateFontStream(
-      CFX_FontMapper* pFontMapper,
-      SystemFontInfoIface* pSystemFontInfo,
-      uint32_t index);
-  RetainPtr<IFX_SeekableReadStream> CreateFontStream(
-      const ByteString& bsFaceName);
+#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 
+  std::map<uint32_t, std::vector<RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts;
+
+#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+  std::deque<FX_FONTDESCRIPTOR> m_FontFaces;
+#else
   std::unique_ptr<CFX_FontSourceEnum_File> m_pFontSource;
   std::vector<std::unique_ptr<CFX_FontDescriptor>> m_InstalledFonts;
   std::map<uint32_t, std::unique_ptr<std::vector<CFX_FontDescriptorInfo>>>
@@ -191,10 +179,6 @@
       m_IFXFont2FileRead;
   std::set<wchar_t> m_FailedUnicodesSet;
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
-
-  bool VerifyUnicode(const RetainPtr<CFGAS_GEFont>& pFont, wchar_t wcUnicode);
-
-  std::map<uint32_t, std::vector<RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts;
 };
 
 #endif  // XFA_FGAS_FONT_CFGAS_FONTMGR_H_