Encapsulate FT_Load_Sfnt_Table() calls

Implement CFX_Face::GetSfntTable() and switch FT_Load_Sfnt_Table()
callers to use it.

Bug: pdfium:2037
Change-Id: I999e5bfc485ec2995faf56eac8577da72e90164f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/114776
Reviewed-by: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 88a5686..0961ccc 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -654,17 +654,14 @@
 
   static constexpr uint32_t kGsubTag =
       CFX_FontMapper::MakeTag('G', 'S', 'U', 'B');
-  FXFT_FaceRec* face = m_Font.GetFaceRec();
-  unsigned long length = 0;
-  int error = FT_Load_Sfnt_Table(face, kGsubTag, 0, nullptr, &length);
-  if (error || !length) {
+  RetainPtr<CFX_Face> face = m_Font.GetFace();
+  size_t length = face->GetSfntTable(kGsubTag, {});
+  if (!length) {
     return index;
   }
 
   FixedUninitDataVector<uint8_t> sub_data(length);
-  error = FT_Load_Sfnt_Table(face, kGsubTag, 0, sub_data.writable_span().data(),
-                             nullptr);
-  if (error) {
+  if (!face->GetSfntTable(kGsubTag, sub_data.writable_span())) {
     return index;
   }
 
diff --git a/core/fxge/android/cfpf_skiafont.cpp b/core/fxge/android/cfpf_skiafont.cpp
index ede116f..df46d94 100644
--- a/core/fxge/android/cfpf_skiafont.cpp
+++ b/core/fxge/android/cfpf_skiafont.cpp
@@ -13,7 +13,6 @@
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/android/cfpf_skiafontmgr.h"
 #include "core/fxge/android/cfpf_skiapathfont.h"
-#include "core/fxge/freetype/fx_freetype.h"
 #include "core/fxge/fx_fontencoding.h"
 #include "third_party/base/numerics/safe_conversions.h"
 
@@ -38,10 +37,6 @@
   if (!m_Face)
     return 0;
 
-  FT_ULong ulSize = pdfium::base::checked_cast<FT_ULong>(pBuffer.size());
-  if (FT_Load_Sfnt_Table(m_Face->GetRec(), dwTable, 0, pBuffer.data(),
-                         &ulSize)) {
-    return 0;
-  }
-  return pdfium::base::checked_cast<uint32_t>(ulSize);
+  return pdfium::base::checked_cast<uint32_t>(
+      m_Face->GetSfntTable(dwTable, pBuffer));
 }
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index f335d42..c9bcd33 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -314,6 +314,24 @@
   return {GetRec()->stream->base, GetRec()->stream->size};
 }
 
+size_t CFX_Face::GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer) {
+  unsigned long length =
+      pdfium::base::checked_cast<unsigned long>(buffer.size());
+  if (length) {
+    int error = FT_Load_Sfnt_Table(GetRec(), table, 0, buffer.data(), &length);
+    if (error || length != buffer.size()) {
+      return 0;
+    }
+    return buffer.size();
+  }
+
+  int error = FT_Load_Sfnt_Table(GetRec(), table, 0, nullptr, &length);
+  if (error || !length) {
+    return 0;
+  }
+  return pdfium::base::checked_cast<size_t>(length);
+}
+
 std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph(const CFX_Font* pFont,
                                                        uint32_t glyph_index,
                                                        bool bFontStyle,
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index b9e5aba..4a0ee5d 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -68,6 +68,10 @@
 
   pdfium::span<uint8_t> GetData() const;
 
+  // Returns the size of the data, or 0 on failure. Only write into `buffer` if
+  // it is large enough to hold the data.
+  size_t GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer);
+
   std::unique_ptr<CFX_GlyphBitmap> RenderGlyph(const CFX_Font* pFont,
                                                uint32_t glyph_index,
                                                bool bFontStyle,
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index e117b5e..1bb2375 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -739,17 +739,16 @@
 
   GetUSBCSB(pFace->GetRec(), pFont->m_dwUsb, pFont->m_dwCsb);
 
-  FT_ULong dwTag;
-  FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
+  static constexpr uint32_t kNameTag =
+      CFX_FontMapper::MakeTag('n', 'a', 'm', 'e');
 
   DataVector<uint8_t> table;
-  unsigned long nLength = 0;
-  unsigned int error =
-      FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, nullptr, &nLength);
-  if (error == 0 && nLength != 0) {
-    table.resize(nLength);
-    if (FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, table.data(), nullptr))
+  size_t table_size = pFace->GetSfntTable(kNameTag, table);
+  if (table_size) {
+    table.resize(table_size);
+    if (!pFace->GetSfntTable(kNameTag, table)) {
       table.clear();
+    }
   }
   pFont->m_wsFamilyNames = GetNames(table);
   pFont->m_wsFamilyNames.push_back(