Remove redundant read in CFX_FontMgr and CFX_FontMapper.

Redo the API so that the fontmapper knows about the cached buffer
entries (CTTFontDesc). Previously, this was hidden down a layer and
resulted in strange APIs.

- Move GetTTCIndex() so fontmapper can call it.

Change-Id: I0febfbdca53f3ee444e3624077e8cfcd61439ca0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56534
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/cfx_fontmapper.cpp b/core/fxge/cfx_fontmapper.cpp
index 03425ea..749aa4d 100644
--- a/core/fxge/cfx_fontmapper.cpp
+++ b/core/fxge/cfx_fontmapper.cpp
@@ -17,6 +17,7 @@
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxge/cfx_fontmgr.h"
 #include "core/fxge/cfx_substfont.h"
+#include "core/fxge/cttfontdesc.h"
 #include "core/fxge/fx_font.h"
 #include "core/fxge/systemfontinfo_iface.h"
 #include "third_party/base/stl_util.h"
@@ -682,18 +683,29 @@
     for (int i = 0; i < 256; i++)
       checksum += pBuffer[i];
   }
+  CTTFontDesc* pFontDesc = m_pFontMgr->GetCachedTTCFontDesc(ttc_size, checksum);
+  if (!pFontDesc) {
+    std::unique_ptr<uint8_t, FxFreeDeleter> pFontData(
+        FX_Alloc(uint8_t, ttc_size));
+    m_pFontInfo->GetFontData(hFont, kTableTTCF, pFontData.get(), ttc_size);
+    pFontDesc = m_pFontMgr->AddCachedTTCFontDesc(
+        ttc_size, checksum, std::move(pFontData), ttc_size);
+  }
   ASSERT(ttc_size >= font_size);
   uint32_t font_offset = ttc_size - font_size;
-  RetainPtr<CFX_Face> face =
-      m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, font_offset);
-  if (face)
-    return face;
+  int face_index =
+      GetTTCIndex(pFontDesc->FontData().first(ttc_size), font_offset);
+  RetainPtr<CFX_Face> pFace(pFontDesc->GetFace(face_index));
+  if (pFace)
+    return pFace;
 
-  std::unique_ptr<uint8_t, FxFreeDeleter> pFontData(
-      FX_Alloc(uint8_t, ttc_size));
-  m_pFontInfo->GetFontData(hFont, kTableTTCF, pFontData.get(), ttc_size);
-  return m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, std::move(pFontData),
-                                      ttc_size, font_offset);
+  pFace = m_pFontMgr->NewFixedFace(pFontDesc->FontData().first(ttc_size),
+                                   face_index);
+  if (!pFace)
+    return nullptr;
+
+  pFontDesc->SetFace(face_index, pFace.Get());
+  return pFace;
 }
 
 RetainPtr<CFX_Face> CFX_FontMapper::GetCachedFace(void* hFont,
@@ -701,18 +713,26 @@
                                                   int weight,
                                                   bool bItalic,
                                                   uint32_t font_size) {
-  const uint8_t* pIgnore = nullptr;
-  RetainPtr<CFX_Face> face =
-      m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, &pIgnore);
-  if (face)
-    return face;
+  CTTFontDesc* pFontDesc =
+      m_pFontMgr->GetCachedFontDesc(SubstName, weight, bItalic);
+  if (!pFontDesc) {
+    std::unique_ptr<uint8_t, FxFreeDeleter> pFontData(
+        FX_Alloc(uint8_t, font_size));
+    m_pFontInfo->GetFontData(hFont, 0, pFontData.get(), font_size);
+    pFontDesc = m_pFontMgr->AddCachedFontDesc(SubstName, weight, bItalic,
+                                              std::move(pFontData), font_size);
+  }
+  RetainPtr<CFX_Face> pFace(pFontDesc->GetFace(0));
+  if (pFace)
+    return pFace;
 
-  std::unique_ptr<uint8_t, FxFreeDeleter> pFontData(
-      FX_Alloc(uint8_t, font_size));
-  m_pFontInfo->GetFontData(hFont, 0, pFontData.get(), font_size);
-  return m_pFontMgr->AddCachedFace(SubstName, weight, bItalic,
-                                   std::move(pFontData), font_size,
+  pFace = m_pFontMgr->NewFixedFace(pFontDesc->FontData().first(font_size),
                                    m_pFontInfo->GetFaceIndex(hFont));
+  if (!pFace)
+    return nullptr;
+
+  pFontDesc->SetFace(0, pFace.Get());
+  return pFace;
 }
 
 // static
diff --git a/core/fxge/cfx_fontmgr.cpp b/core/fxge/cfx_fontmgr.cpp
index c261d8f..746c8ba 100644
--- a/core/fxge/cfx_fontmgr.cpp
+++ b/core/fxge/cfx_fontmgr.cpp
@@ -60,18 +60,6 @@
   return ByteString::Format("%d:%d", ttc_size, checksum);
 }
 
-int GetTTCIndex(pdfium::span<const uint8_t> pFontData, uint32_t font_offset) {
-  const uint8_t* p = pFontData.data() + 8;
-  uint32_t nfont = GET_TT_LONG(p);
-  uint32_t index;
-  for (index = 0; index < nfont; index++) {
-    p = pFontData.data() + 12 + index * 4;
-    if (GET_TT_LONG(p) == font_offset)
-      break;
-  }
-  return index < nfont ? index : 0;
-}
-
 FXFT_LibraryRec* FTLibraryInitHelper() {
   FXFT_LibraryRec* pLibrary = nullptr;
   FT_Init_FreeType(&pLibrary);
@@ -104,76 +92,40 @@
                                          italic_angle, CharsetCP, pSubstFont);
 }
 
-RetainPtr<CFX_Face> CFX_FontMgr::GetCachedFace(const ByteString& face_name,
-                                               int weight,
-                                               bool bItalic,
-                                               const uint8_t** pFontData) {
+CTTFontDesc* CFX_FontMgr::GetCachedFontDesc(const ByteString& face_name,
+                                            int weight,
+                                            bool bItalic) {
   auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
-  if (it == m_FaceMap.end())
-    return nullptr;
-
-  CTTFontDesc* pFontDesc = it->second.get();
-  *pFontData = pFontDesc->FontData().data();
-  return pdfium::WrapRetain(pFontDesc->GetFace(0));
+  return it != m_FaceMap.end() ? it->second.get() : nullptr;
 }
 
-RetainPtr<CFX_Face> CFX_FontMgr::AddCachedFace(
+CTTFontDesc* CFX_FontMgr::AddCachedFontDesc(
     const ByteString& face_name,
     int weight,
     bool bItalic,
     std::unique_ptr<uint8_t, FxFreeDeleter> pData,
-    uint32_t size,
-    int face_index) {
-  RetainPtr<CFX_Face> face = NewFixedFace({pData.get(), size}, face_index);
-  if (!face)
-    return nullptr;
-
+    uint32_t size) {
   auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(std::move(pData), size);
-  pFontDesc->SetFace(0, face.Get());
+  auto* result = pFontDesc.get();
   m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = std::move(pFontDesc);
-  return face;
+  return result;
 }
 
-RetainPtr<CFX_Face> CFX_FontMgr::GetCachedTTCFace(int ttc_size,
-                                                  uint32_t checksum,
-                                                  uint32_t font_offset) {
+CTTFontDesc* CFX_FontMgr::GetCachedTTCFontDesc(int ttc_size,
+                                               uint32_t checksum) {
   auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
-  if (it == m_FaceMap.end())
-    return nullptr;
-
-  CTTFontDesc* pFontDesc = it->second.get();
-  int face_index =
-      GetTTCIndex(pFontDesc->FontData().first(ttc_size), font_offset);
-  return pdfium::WrapRetain(pFontDesc->GetFace(face_index));
+  return it != m_FaceMap.end() ? it->second.get() : nullptr;
 }
 
-RetainPtr<CFX_Face> CFX_FontMgr::AddCachedTTCFace(
+CTTFontDesc* CFX_FontMgr::AddCachedTTCFontDesc(
     int ttc_size,
     uint32_t checksum,
     std::unique_ptr<uint8_t, FxFreeDeleter> pData,
-    uint32_t size,
-    uint32_t font_offset) {
-  CTTFontDesc* pFontDesc = nullptr;
-  ByteString keyname = KeyNameFromSize(ttc_size, checksum);
-  auto it = m_FaceMap.find(keyname);
-  if (it != m_FaceMap.end())
-    pFontDesc = it->second.get();
-
-  if (!pFontDesc) {
-    auto pNewDesc = pdfium::MakeUnique<CTTFontDesc>(std::move(pData), size);
-    pFontDesc = pNewDesc.get();
-    m_FaceMap[keyname] = std::move(pNewDesc);
-  }
-
-  int face_index =
-      GetTTCIndex(pFontDesc->FontData().first(ttc_size), font_offset);
-  RetainPtr<CFX_Face> face =
-      NewFixedFace(pFontDesc->FontData().first(ttc_size), face_index);
-  if (!face)
-    return nullptr;
-
-  pFontDesc->SetFace(face_index, face.Get());
-  return face;
+    uint32_t size) {
+  auto pNewDesc = pdfium::MakeUnique<CTTFontDesc>(std::move(pData), size);
+  auto* pResult = pNewDesc.get();
+  m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = std::move(pNewDesc);
+  return pResult;
 }
 
 RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(pdfium::span<const uint8_t> span,
diff --git a/core/fxge/cfx_fontmgr.h b/core/fxge/cfx_fontmgr.h
index 83fa08e..64138c4 100644
--- a/core/fxge/cfx_fontmgr.h
+++ b/core/fxge/cfx_fontmgr.h
@@ -29,29 +29,24 @@
   CFX_FontMgr();
   ~CFX_FontMgr();
 
-  RetainPtr<CFX_Face> GetCachedFace(const ByteString& face_name,
-                                    int weight,
-                                    bool bItalic,
-                                    const uint8_t** pFontData);
-  RetainPtr<CFX_Face> AddCachedFace(
-      const ByteString& face_name,
-      int weight,
-      bool bItalic,
-      std::unique_ptr<uint8_t, FxFreeDeleter> pData,
-      uint32_t size,
-      int face_index);
-  RetainPtr<CFX_Face> GetCachedTTCFace(int ttc_size,
-                                       uint32_t checksum,
-                                       uint32_t font_offset);
-  RetainPtr<CFX_Face> AddCachedTTCFace(
+  CTTFontDesc* GetCachedFontDesc(const ByteString& face_name,
+                                 int weight,
+                                 bool bItalic);
+  CTTFontDesc* AddCachedFontDesc(const ByteString& face_name,
+                                 int weight,
+                                 bool bItalic,
+                                 std::unique_ptr<uint8_t, FxFreeDeleter> pData,
+                                 uint32_t size);
+
+  CTTFontDesc* GetCachedTTCFontDesc(int ttc_size, uint32_t checksum);
+  CTTFontDesc* AddCachedTTCFontDesc(
       int ttc_size,
       uint32_t checksum,
       std::unique_ptr<uint8_t, FxFreeDeleter> pData,
-      uint32_t size,
-      uint32_t font_offset);
+      uint32_t size);
+
   RetainPtr<CFX_Face> NewFixedFace(pdfium::span<const uint8_t> span,
                                    int face_index);
-  void SetSystemFontInfo(std::unique_ptr<SystemFontInfoIface> pFontInfo);
   RetainPtr<CFX_Face> FindSubstFont(const ByteString& face_name,
                                     bool bTrueType,
                                     uint32_t flags,
@@ -60,6 +55,8 @@
                                     int CharsetCP,
                                     CFX_SubstFont* pSubstFont);
 
+  void SetSystemFontInfo(std::unique_ptr<SystemFontInfoIface> pFontInfo);
+
   // Always present.
   CFX_FontMapper* GetBuiltinMapper() const { return m_pBuiltinMapper.get(); }
 
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp
index a79bfca..940f9ea 100644
--- a/core/fxge/fx_font.cpp
+++ b/core/fxge/fx_font.cpp
@@ -102,6 +102,18 @@
   return ByteString();
 }
 
+int GetTTCIndex(pdfium::span<const uint8_t> pFontData, uint32_t font_offset) {
+  const uint8_t* p = pFontData.data() + 8;
+  uint32_t nfont = GET_TT_LONG(p);
+  uint32_t index;
+  for (index = 0; index < nfont; index++) {
+    p = pFontData.data() + 12 + index * 4;
+    if (GET_TT_LONG(p) == font_offset)
+      return index;
+  }
+  return 0;
+}
+
 wchar_t PDF_UnicodeFromAdobeName(const char* name) {
   return (wchar_t)(FXFT_unicode_from_adobe_name(name) & 0x7FFFFFFF);
 }
diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h
index 1b03a6c..f9f33ac 100644
--- a/core/fxge/fx_font.h
+++ b/core/fxge/fx_font.h
@@ -13,6 +13,7 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/fx_freetype.h"
+#include "third_party/base/span.h"
 
 /* Font pitch and family flags */
 #define FXFONT_FF_FIXEDPITCH (1 << 0)
@@ -58,6 +59,8 @@
                          uint32_t name_table_size,
                          uint32_t name);
 
+int GetTTCIndex(pdfium::span<const uint8_t> pFontData, uint32_t font_offset);
+
 inline bool FontStyleIsBold(uint32_t style) {
   return !!(style & FXFONT_BOLD);
 }