Use pdfium::span<>/UnownedPtr in CFX_Font.

Move some platform-specific ifdefs so the come last in each
section as it is easier to read, perhaps.

Change-Id: Ic1c2652c46ecebc63b66213735ed6d94737a7f32
Reviewed-on: https://pdfium-review.googlesource.com/41630
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 9b83733..298911e 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -208,9 +208,7 @@
   if (!m_pFontFile)
     return;
 
-  const uint8_t* pFontData = m_pFontFile->GetData();
-  uint32_t dwFontSize = m_pFontFile->GetSize();
-  if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
+  if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan())) {
     m_pDocument->GetPageData()->MaybePurgeFontFileStreamAcc(
         m_pFontFile->GetStream()->AsStream());
     m_pFontFile = nullptr;
diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp
index 44e6b3e..7fb7ce6 100644
--- a/core/fpdfapi/font/cpdf_type1font.cpp
+++ b/core/fpdfapi/font/cpdf_type1font.cpp
@@ -129,8 +129,8 @@
     if (m_Font.GetPsName() == "DFHeiStd-W5")
       bCoreText = false;
 
-    m_Font.SetPlatformFont(
-        quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
+    pdfium::span<const uint8_t> span = m_Font.GetFontSpan();
+    m_Font.SetPlatformFont(quartz2d.CreateFont(span.data(), span.size()));
     if (!m_Font.GetPlatformFont())
       bCoreText = false;
   }
diff --git a/core/fxge/apple/fx_apple_platform.cpp b/core/fxge/apple/fx_apple_platform.cpp
index cafe447..aad97ee 100644
--- a/core/fxge/apple/fx_apple_platform.cpp
+++ b/core/fxge/apple/fx_apple_platform.cpp
@@ -20,6 +20,7 @@
 #include "core/fxge/cfx_gemodule.h"
 #include "core/fxge/cfx_renderdevice.h"
 #include "core/fxge/fx_freetype.h"
+#include "third_party/base/span.h"
 
 #ifndef _SKIA_SUPPORT_
 
@@ -52,8 +53,8 @@
     if (pFont->GetPsName() == "DFHeiStd-W5")
       return false;
 
-    pFont->SetPlatformFont(
-        quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize()));
+    pdfium::span<const uint8_t> span = pFont->GetFontSpan();
+    pFont->SetPlatformFont(quartz2d.CreateFont(span.data(), span.size()));
     if (!pFont->GetPlatformFont())
       return false;
   }
diff --git a/core/fxge/cfx_facecache.cpp b/core/fxge/cfx_facecache.cpp
index c2051c3..08d95a0 100644
--- a/core/fxge/cfx_facecache.cpp
+++ b/core/fxge/cfx_facecache.cpp
@@ -315,14 +315,16 @@
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
 CFX_TypeFace* CFX_FaceCache::GetDeviceCache(const CFX_Font* pFont) {
   if (!m_pTypeface) {
+    pdfium::span<const uint8_t> span = pFont->GetFontSpan();
     m_pTypeface = SkTypeface::MakeFromStream(
-        new SkMemoryStream(pFont->GetFontData(), pFont->GetSize()));
+        new SkMemoryStream(span.data(), span.size()));
   }
 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
   if (!m_pTypeface) {
     sk_sp<SkFontMgr> customMgr(SkFontMgr_New_Custom_Empty());
-    m_pTypeface = customMgr->makeFromStream(pdfium::MakeUnique<SkMemoryStream>(
-        pFont->GetFontData(), pFont->GetSize()));
+    pdfium::span<const uint8_t> span = pFont->GetFontSpan();
+    m_pTypeface = customMgr->makeFromStream(
+        pdfium::MakeUnique<SkMemoryStream>(span.data(), span.size()));
   }
 #endif
   return m_pTypeface.get();
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index bda5767..3c2b48d 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -54,11 +54,10 @@
 
 void FTStreamClose(FXFT_Stream stream) {}
 
-bool LoadFileImp(FXFT_Library library,
-                 FXFT_Face* Face,
-                 const RetainPtr<IFX_SeekableReadStream>& pFile,
-                 int32_t faceIndex,
-                 std::unique_ptr<FXFT_StreamRec>* stream) {
+FXFT_Face LoadFileImp(FXFT_Library library,
+                      const RetainPtr<IFX_SeekableReadStream>& pFile,
+                      int32_t faceIndex,
+                      std::unique_ptr<FXFT_StreamRec>* stream) {
   auto stream1 = pdfium::MakeUnique<FXFT_StreamRec>();
   stream1->base = nullptr;
   stream1->size = static_cast<unsigned long>(pFile->GetSize());
@@ -66,21 +65,22 @@
   stream1->descriptor.pointer = static_cast<void*>(pFile.Get());
   stream1->close = FTStreamClose;
   stream1->read = FTStreamRead;
+
   FXFT_Open_Args args;
   args.flags = FT_OPEN_STREAM;
   args.stream = stream1.get();
-  if (FXFT_Open_Face(library, &args, faceIndex, Face))
-    return false;
+
+  FXFT_Face face;
+  if (FXFT_Open_Face(library, &args, faceIndex, &face))
+    return nullptr;
+
   if (stream)
     *stream = std::move(stream1);
-  return true;
+
+  return face;
 }
 #endif  // PDF_ENABLE_XFA
 
-FXFT_Face FT_LoadFont(const uint8_t* pData, int size) {
-  return CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(pData, size, 0);
-}
-
 void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
   std::vector<FX_PATHPOINT>& points = param->m_pPath->GetPoints();
   size_t size = points.size();
@@ -291,19 +291,7 @@
   return FX_CHARSET_ANSI;
 }
 
-CFX_Font::CFX_Font()
-    :
-      m_Face(nullptr),
-      m_FaceCache(nullptr),
-      m_pFontData(nullptr),
-      m_pGsubData(nullptr),
-      m_dwSize(0),
-#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
-      m_pPlatformFont(nullptr),
-#endif
-      m_bEmbedded(false),
-      m_bVertical(false) {
-}
+CFX_Font::CFX_Font() = default;
 
 #ifdef PDF_ENABLE_XFA
 bool CFX_Font::LoadFile(const RetainPtr<IFX_SeekableReadStream>& pFile,
@@ -313,13 +301,13 @@
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   pFontMgr->InitFTLibrary();
 
-  FXFT_Library library = pFontMgr->GetFTLibrary();
   std::unique_ptr<FXFT_StreamRec> stream;
-  if (!LoadFileImp(library, &m_Face, pFile, nFaceIndex, &stream))
+  m_Face = LoadFileImp(pFontMgr->GetFTLibrary(), pFile, nFaceIndex, &stream);
+  if (!m_Face)
     return false;
 
   m_pOwnedStream = std::move(stream);
-  FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
+  FXFT_Set_Pixel_Sizes(m_Face.Get(), 0, 64);
   return true;
 }
 
@@ -336,6 +324,7 @@
 #endif  // PDF_ENABLE_XFA
 
 CFX_Font::~CFX_Font() {
+  m_FontData = {};  // m_FontData can't outive m_Face.
   if (m_Face)
     DeleteFace();
 
@@ -347,10 +336,9 @@
 void CFX_Font::DeleteFace() {
   ClearFaceCache();
   if (m_bEmbedded)
-    FXFT_Done_Face(m_Face);
+    FXFT_Done_Face(m_Face.Release());
   else
-    CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
-  m_Face = nullptr;
+    CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face.Release());
 }
 
 void CFX_Font::LoadSubst(const ByteString& face_name,
@@ -367,8 +355,8 @@
       face_name, bTrueType, flags, weight, italic_angle, CharsetCP,
       m_pSubstFont.get());
   if (m_Face) {
-    m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
-    m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
+    m_FontData = {FXFT_Get_Face_Stream_Base(m_Face.Get()),
+                  FXFT_Get_Face_Stream_Size(m_Face.Get())};
   }
 }
 
@@ -378,64 +366,64 @@
   if (m_pSubstFont && m_pSubstFont->m_bFlagMM)
     AdjustMMParams(glyph_index, 0, 0);
   int err = FXFT_Load_Glyph(
-      m_Face, glyph_index,
+      m_Face.Get(), glyph_index,
       FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
   if (err)
     return 0;
 
-  int horiAdvance = FXFT_Get_Glyph_HoriAdvance(m_Face);
+  int horiAdvance = FXFT_Get_Glyph_HoriAdvance(m_Face.Get());
   if (horiAdvance < 0 || horiAdvance > kThousandthMaxInt)
     return 0;
 
-  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), horiAdvance);
+  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face.Get()), horiAdvance);
 }
 
-bool CFX_Font::LoadEmbedded(const uint8_t* data, uint32_t size) {
-  std::vector<uint8_t> temp(data, data + size);
-  m_pFontDataAllocation.swap(temp);
-  m_Face = FT_LoadFont(m_pFontDataAllocation.data(), size);
-  m_pFontData = m_pFontDataAllocation.data();
+bool CFX_Font::LoadEmbedded(pdfium::span<const uint8_t> src_span) {
+  m_pFontDataAllocation =
+      std::vector<uint8_t>(src_span.begin(), src_span.end());
+  m_Face = CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(
+      m_pFontDataAllocation.data(), m_pFontDataAllocation.size(), 0);
   m_bEmbedded = true;
-  m_dwSize = size;
+  m_FontData = m_pFontDataAllocation;
   return !!m_Face;
 }
 
 bool CFX_Font::IsTTFont() const {
-  return m_Face && FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
+  return m_Face && FXFT_Is_Face_TT_OT(m_Face.Get()) == FXFT_FACE_FLAG_SFNT;
 }
 
 int CFX_Font::GetAscent() const {
   if (!m_Face)
     return 0;
 
-  int ascender = FXFT_Get_Face_Ascender(m_Face);
+  int ascender = FXFT_Get_Face_Ascender(m_Face.Get());
   if (ascender < kThousandthMinInt || ascender > kThousandthMaxInt)
     return 0;
 
-  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), ascender);
+  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face.Get()), ascender);
 }
 
 int CFX_Font::GetDescent() const {
   if (!m_Face)
     return 0;
 
-  int descender = FXFT_Get_Face_Descender(m_Face);
+  int descender = FXFT_Get_Face_Descender(m_Face.Get());
   if (descender < kThousandthMinInt || descender > kThousandthMaxInt)
     return 0;
 
-  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), descender);
+  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face.Get()), descender);
 }
 
 bool CFX_Font::GetGlyphBBox(uint32_t glyph_index, FX_RECT* pBBox) {
   if (!m_Face)
     return false;
 
-  if (FXFT_Is_Face_Tricky(m_Face)) {
-    int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
+  if (FXFT_Is_Face_Tricky(m_Face.Get())) {
+    int error = FXFT_Set_Char_Size(m_Face.Get(), 0, 1000 * 64, 72, 72);
     if (error)
       return false;
 
-    error = FXFT_Load_Glyph(m_Face, glyph_index,
+    error = FXFT_Load_Glyph(m_Face.Get(), glyph_index,
                             FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
     if (error)
       return false;
@@ -460,33 +448,34 @@
       pBBox->top = cbox.yMax * 1000 / pixel_size_y;
       pBBox->bottom = cbox.yMin * 1000 / pixel_size_y;
     }
-    pBBox->top = std::min(pBBox->top,
-                          static_cast<int32_t>(FXFT_Get_Face_Ascender(m_Face)));
-    pBBox->bottom = std::max(
-        pBBox->bottom, static_cast<int32_t>(FXFT_Get_Face_Descender(m_Face)));
+    pBBox->top = std::min(
+        pBBox->top, static_cast<int32_t>(FXFT_Get_Face_Ascender(m_Face.Get())));
+    pBBox->bottom =
+        std::max(pBBox->bottom,
+                 static_cast<int32_t>(FXFT_Get_Face_Descender(m_Face.Get())));
     FT_Done_Glyph(glyph);
-    return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
+    return FXFT_Set_Pixel_Sizes(m_Face.Get(), 0, 64) == 0;
   }
   if (FXFT_Load_Glyph(
-          m_Face, glyph_index,
+          m_Face.Get(), glyph_index,
           FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
     return false;
   }
-  int em = FXFT_Get_Face_UnitsPerEM(m_Face);
+  int em = FXFT_Get_Face_UnitsPerEM(m_Face.Get());
   if (em == 0) {
-    pBBox->left = FXFT_Get_Glyph_HoriBearingX(m_Face);
-    pBBox->bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
-    pBBox->top = pBBox->bottom - FXFT_Get_Glyph_Height(m_Face);
-    pBBox->right = pBBox->left + FXFT_Get_Glyph_Width(m_Face);
+    pBBox->left = FXFT_Get_Glyph_HoriBearingX(m_Face.Get());
+    pBBox->bottom = FXFT_Get_Glyph_HoriBearingY(m_Face.Get());
+    pBBox->top = pBBox->bottom - FXFT_Get_Glyph_Height(m_Face.Get());
+    pBBox->right = pBBox->left + FXFT_Get_Glyph_Width(m_Face.Get());
   } else {
-    pBBox->left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
-    pBBox->top =
-        (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) *
-        1000 / em;
-    pBBox->right =
-        (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) *
-        1000 / em;
-    pBBox->bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
+    pBBox->left = FXFT_Get_Glyph_HoriBearingX(m_Face.Get()) * 1000 / em;
+    pBBox->top = (FXFT_Get_Glyph_HoriBearingY(m_Face.Get()) -
+                  FXFT_Get_Glyph_Height(m_Face.Get())) *
+                 1000 / em;
+    pBBox->right = (FXFT_Get_Glyph_HoriBearingX(m_Face.Get()) +
+                    FXFT_Get_Glyph_Width(m_Face.Get())) *
+                   1000 / em;
+    pBBox->bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face.Get())) * 1000 / em;
   }
   return true;
 }
@@ -494,27 +483,27 @@
 bool CFX_Font::IsItalic() const {
   if (!m_Face)
     return false;
-  if (FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC)
+  if (FXFT_Is_Face_Italic(m_Face.Get()) == FXFT_STYLE_FLAG_ITALIC)
     return true;
 
-  ByteString str(FXFT_Get_Face_Style_Name(m_Face));
+  ByteString str(FXFT_Get_Face_Style_Name(m_Face.Get()));
   str.MakeLower();
   return str.Contains("italic");
 }
 
 bool CFX_Font::IsBold() const {
-  return m_Face && FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
+  return m_Face && FXFT_Is_Face_Bold(m_Face.Get()) == FXFT_STYLE_FLAG_BOLD;
 }
 
 bool CFX_Font::IsFixedWidth() const {
-  return m_Face && FXFT_Is_Face_fixedwidth(m_Face) != 0;
+  return m_Face && FXFT_Is_Face_fixedwidth(m_Face.Get()) != 0;
 }
 
 ByteString CFX_Font::GetPsName() const {
   if (!m_Face)
     return ByteString();
 
-  ByteString psName = FXFT_Get_Postscript_Name(m_Face);
+  ByteString psName = FXFT_Get_Postscript_Name(m_Face.Get());
   if (psName.IsEmpty())
     psName = "Untitled";
   return psName;
@@ -524,7 +513,7 @@
   if (!m_Face && !m_pSubstFont)
     return ByteString();
   if (m_Face)
-    return ByteString(FXFT_Get_Face_Family_Name(m_Face));
+    return ByteString(FXFT_Get_Face_Family_Name(m_Face.Get()));
 
   return m_pSubstFont->m_Family;
 }
@@ -533,7 +522,7 @@
   if (!m_Face && !m_pSubstFont)
     return ByteString();
   if (m_Face) {
-    ByteString style = ByteString(FXFT_Get_Face_Style_Name(m_Face));
+    ByteString style = ByteString(FXFT_Get_Face_Style_Name(m_Face.Get()));
     ByteString facename = GetFamilyName();
     if (facename.IsEmpty())
       facename = "Untitled";
@@ -548,17 +537,17 @@
   if (!m_Face)
     return false;
 
-  int em = FXFT_Get_Face_UnitsPerEM(m_Face);
+  int em = FXFT_Get_Face_UnitsPerEM(m_Face.Get());
   if (em == 0) {
-    pBBox->left = FXFT_Get_Face_xMin(m_Face);
-    pBBox->bottom = FXFT_Get_Face_yMax(m_Face);
-    pBBox->top = FXFT_Get_Face_yMin(m_Face);
-    pBBox->right = FXFT_Get_Face_xMax(m_Face);
+    pBBox->left = FXFT_Get_Face_xMin(m_Face.Get());
+    pBBox->bottom = FXFT_Get_Face_yMax(m_Face.Get());
+    pBBox->top = FXFT_Get_Face_yMin(m_Face.Get());
+    pBBox->right = FXFT_Get_Face_xMax(m_Face.Get());
   } else {
-    pBBox->left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
-    pBBox->top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
-    pBBox->right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
-    pBBox->bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
+    pBBox->left = FXFT_Get_Face_xMin(m_Face.Get()) * 1000 / em;
+    pBBox->top = FXFT_Get_Face_yMin(m_Face.Get()) * 1000 / em;
+    pBBox->right = FXFT_Get_Face_xMax(m_Face.Get()) * 1000 / em;
+    pBBox->bottom = FXFT_Get_Face_yMax(m_Face.Get()) * 1000 / em;
   }
   return true;
 }
@@ -582,7 +571,7 @@
                               int weight) const {
   ASSERT(dest_width >= 0);
   FXFT_MM_Var pMasters = nullptr;
-  FXFT_Get_MM_Var(m_Face, &pMasters);
+  FXFT_Get_MM_Var(m_Face.Get(), &pMasters);
   if (!pMasters)
     return;
 
@@ -598,34 +587,35 @@
     int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
     int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
     coords[1] = min_param;
-    FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
-    FXFT_Load_Glyph(m_Face, glyph_index,
+    FXFT_Set_MM_Design_Coordinates(m_Face.Get(), 2, coords);
+    FXFT_Load_Glyph(m_Face.Get(), glyph_index,
                     FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
-    int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 /
-                    FXFT_Get_Face_UnitsPerEM(m_Face);
+    int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face.Get()) * 1000 /
+                    FXFT_Get_Face_UnitsPerEM(m_Face.Get());
     coords[1] = max_param;
-    FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
-    FXFT_Load_Glyph(m_Face, glyph_index,
+    FXFT_Set_MM_Design_Coordinates(m_Face.Get(), 2, coords);
+    FXFT_Load_Glyph(m_Face.Get(), glyph_index,
                     FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
-    int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 /
-                    FXFT_Get_Face_UnitsPerEM(m_Face);
+    int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face.Get()) * 1000 /
+                    FXFT_Get_Face_UnitsPerEM(m_Face.Get());
     if (max_width == min_width) {
-      FXFT_Free(m_Face, pMasters);
+      FXFT_Free(m_Face.Get(), pMasters);
       return;
     }
     int param = min_param + (max_param - min_param) * (dest_width - min_width) /
                                 (max_width - min_width);
     coords[1] = param;
   }
-  FXFT_Free(m_Face, pMasters);
-  FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
+  FXFT_Free(m_Face.Get(), pMasters);
+  FXFT_Set_MM_Design_Coordinates(m_Face.Get(), 2, coords);
 }
 
 CFX_PathData* CFX_Font::LoadGlyphPathImpl(uint32_t glyph_index,
                                           uint32_t dest_width) const {
   if (!m_Face)
     return nullptr;
-  FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
+
+  FXFT_Set_Pixel_Sizes(m_Face.Get(), 0, 64);
   FXFT_Matrix ft_matrix = {65536, 0, 0, 65536};
   if (m_pSubstFont) {
     if (m_pSubstFont->m_ItalicAngle) {
@@ -646,11 +636,11 @@
     if (m_pSubstFont->m_bFlagMM)
       AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
   }
-  ScopedFontTransform scoped_transform(m_Face, &ft_matrix);
+  ScopedFontTransform scoped_transform(m_Face.Get(), &ft_matrix);
   int load_flags = FXFT_LOAD_NO_BITMAP;
-  if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face))
+  if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face.Get()))
     load_flags |= FT_LOAD_NO_HINTING;
-  if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags))
+  if (FXFT_Load_Glyph(m_Face.Get(), glyph_index, load_flags))
     return nullptr;
   if (m_pSubstFont && !m_pSubstFont->m_bFlagMM &&
       m_pSubstFont->m_Weight > 400) {
@@ -661,7 +651,7 @@
       level = s_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655;
     else
       level = s_WeightPow[index] * 2;
-    FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
+    FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face.Get()), level);
   }
 
   FXFT_Outline_Funcs funcs;
@@ -678,7 +668,7 @@
   params.m_CurX = params.m_CurY = 0;
   params.m_CoordUnit = 64 * 64.0;
 
-  FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
+  FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face.Get()), &funcs, &params);
   if (pPath->GetPoints().empty())
     return nullptr;
 
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index 5bd93ea..9293fd7 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -14,6 +14,7 @@
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/fx_freetype.h"
+#include "third_party/base/span.h"
 
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
 #include "core/fxge/fx_font.h"
@@ -43,8 +44,8 @@
                  int CharsetCP,
                  bool bVertical);
 
-  bool LoadEmbedded(const uint8_t* data, uint32_t size);
-  FXFT_Face GetFace() const { return m_Face; }
+  bool LoadEmbedded(pdfium::span<const uint8_t> src_span);
+  FXFT_Face GetFace() const { return m_Face.Get(); }
   CFX_SubstFont* GetSubstFont() const { return m_pSubstFont.get(); }
 
 #ifdef PDF_ENABLE_XFA
@@ -85,16 +86,14 @@
   bool IsEmbedded() const { return m_bEmbedded; }
   uint8_t* GetSubData() const { return m_pGsubData.get(); }
   void SetSubData(uint8_t* data) { m_pGsubData.reset(data); }
+  pdfium::span<uint8_t> GetFontSpan() const { return m_FontData; }
+  void AdjustMMParams(int glyph_index, int dest_width, int weight) const;
+  CFX_PathData* LoadGlyphPathImpl(uint32_t glyph_index,
+                                  uint32_t dest_width) const;
 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
   void* GetPlatformFont() const { return m_pPlatformFont; }
   void SetPlatformFont(void* font) { m_pPlatformFont = font; }
 #endif
-  uint8_t* GetFontData() const { return m_pFontData; }
-  uint32_t GetSize() const { return m_dwSize; }
-  void AdjustMMParams(int glyph_index, int dest_width, int weight) const;
-
-  CFX_PathData* LoadGlyphPathImpl(uint32_t glyph_index,
-                                  uint32_t dest_width) const;
 
   static const size_t kAngleSkewArraySize = 30;
   static const char s_AngleSkew[kAngleSkewArraySize];
@@ -123,24 +122,23 @@
 
  private:
   CFX_FaceCache* GetFaceCache() const;
+  void DeleteFace();
+  void ClearFaceCache();
 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
   void ReleasePlatformResource();
 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
-  void DeleteFace();
-  void ClearFaceCache();
 
-  FXFT_Face m_Face;
+  mutable UnownedPtr<FXFT_FaceRec> m_Face;
   mutable UnownedPtr<CFX_FaceCache> m_FaceCache;
   std::unique_ptr<CFX_SubstFont> m_pSubstFont;
-  std::vector<uint8_t> m_pFontDataAllocation;
-  uint8_t* m_pFontData;
   std::unique_ptr<uint8_t, FxFreeDeleter> m_pGsubData;
-  uint32_t m_dwSize;
+  std::vector<uint8_t> m_pFontDataAllocation;
+  pdfium::span<uint8_t> m_FontData;
+  bool m_bEmbedded = false;
+  bool m_bVertical = false;
 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
-  void* m_pPlatformFont;
+  void* m_pPlatformFont = nullptr;
 #endif
-  bool m_bEmbedded;
-  bool m_bVertical;
 };
 
 #endif  // CORE_FXGE_CFX_FONT_H_
diff --git a/core/fxge/fx_freetype.h b/core/fxge/fx_freetype.h
index 4ce9139..026987c 100644
--- a/core/fxge/fx_freetype.h
+++ b/core/fxge/fx_freetype.h
@@ -15,7 +15,8 @@
 #include FT_OUTLINE_H
 #include FT_TRUETYPE_TABLES_H
 
-using FXFT_Face = struct FT_FaceRec_*;
+using FXFT_FaceRec = struct FT_FaceRec_;
+using FXFT_Face = FXFT_FaceRec*;
 using FXFT_Library = void*;
 
 using FXFT_MM_Var = FT_MM_Var*;
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index b957ca3..9c51c7c 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -39,8 +39,7 @@
                            int font_type,
                            bool bold,
                            bool italic,
-                           uint32_t size,
-                           const uint8_t* data) {
+                           pdfium::span<const uint8_t> span) {
     const CPDF_Dictionary* font_desc = font_dict->GetDictFor("FontDescriptor");
     ASSERT_TRUE(font_desc);
     EXPECT_EQ("FontDescriptor", font_desc->GetStringFor("Type"));
@@ -82,15 +81,15 @@
     streamAcc->LoadAllDataRaw();
 
     // Check that the font stream is the one that was provided
-    ASSERT_EQ(size, streamAcc->GetSize());
+    ASSERT_EQ(span.size(), streamAcc->GetSize());
     if (font_type == FPDF_FONT_TRUETYPE) {
-      ASSERT_EQ(static_cast<int>(size),
+      ASSERT_EQ(static_cast<int>(span.size()),
                 streamAcc->GetDict()->GetIntegerFor("Length1"));
     }
 
     const uint8_t* stream_data = streamAcc->GetData();
-    for (size_t j = 0; j < size; j++)
-      EXPECT_EQ(data[j], stream_data[j]) << " at byte " << j;
+    for (size_t j = 0; j < span.size(); j++)
+      EXPECT_EQ(span[j], stream_data[j]) << " at byte " << j;
   }
 
   void CheckCompositeFontWidths(const CPDF_Array* widths_array,
@@ -2052,10 +2051,9 @@
   // TODO(npm): use other fonts after disallowing loading any font as any type
   const CPDF_Font* stock_font =
       CPDF_Font::GetStockFont(cpdf_doc(), "Times-Bold");
-  const uint8_t* data = stock_font->GetFont()->GetFontData();
-  const uint32_t size = stock_font->GetFont()->GetSize();
-  ScopedFPDFFont font(
-      FPDFText_LoadFont(document(), data, size, FPDF_FONT_TYPE1, false));
+  pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+  ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                        FPDF_FONT_TYPE1, false));
   ASSERT_TRUE(font.get());
   CPDF_Font* typed_font = CPDFFontFromFPDFFont(font.get());
   EXPECT_TRUE(typed_font->IsType1Font());
@@ -2075,16 +2073,15 @@
   EXPECT_EQ(250, widths_array->GetNumberAt(0));
   EXPECT_EQ(569, widths_array->GetNumberAt(11));
   EXPECT_EQ(500, widths_array->GetNumberAt(223));
-  CheckFontDescriptor(font_dict, FPDF_FONT_TYPE1, true, false, size, data);
+  CheckFontDescriptor(font_dict, FPDF_FONT_TYPE1, true, false, span);
 }
 
 TEST_F(FPDFEditEmbeddertest, LoadSimpleTrueTypeFont) {
   CreateNewDocument();
   const CPDF_Font* stock_font = CPDF_Font::GetStockFont(cpdf_doc(), "Courier");
-  const uint8_t* data = stock_font->GetFont()->GetFontData();
-  const uint32_t size = stock_font->GetFont()->GetSize();
-  ScopedFPDFFont font(
-      FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, false));
+  pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+  ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                        FPDF_FONT_TRUETYPE, false));
   ASSERT_TRUE(font.get());
   CPDF_Font* typed_font = CPDFFontFromFPDFFont(font.get());
   EXPECT_TRUE(typed_font->IsTrueTypeFont());
@@ -2104,17 +2101,16 @@
   EXPECT_EQ(600, widths_array->GetNumberAt(33));
   EXPECT_EQ(600, widths_array->GetNumberAt(74));
   EXPECT_EQ(600, widths_array->GetNumberAt(223));
-  CheckFontDescriptor(font_dict, FPDF_FONT_TRUETYPE, false, false, size, data);
+  CheckFontDescriptor(font_dict, FPDF_FONT_TRUETYPE, false, false, span);
 }
 
 TEST_F(FPDFEditEmbeddertest, LoadCIDType0Font) {
   CreateNewDocument();
   const CPDF_Font* stock_font =
       CPDF_Font::GetStockFont(cpdf_doc(), "Times-Roman");
-  const uint8_t* data = stock_font->GetFont()->GetFontData();
-  const uint32_t size = stock_font->GetFont()->GetSize();
-  ScopedFPDFFont font(
-      FPDFText_LoadFont(document(), data, size, FPDF_FONT_TYPE1, 1));
+  pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+  ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                        FPDF_FONT_TYPE1, 1));
   ASSERT_TRUE(font.get());
   CPDF_Font* typed_font = CPDFFontFromFPDFFont(font.get());
   EXPECT_TRUE(typed_font->IsCIDFont());
@@ -2141,7 +2137,7 @@
   EXPECT_EQ("Adobe", cidinfo_dict->GetStringFor("Registry"));
   EXPECT_EQ("Identity", cidinfo_dict->GetStringFor("Ordering"));
   EXPECT_EQ(0, cidinfo_dict->GetNumberFor("Supplement"));
-  CheckFontDescriptor(cidfont_dict, FPDF_FONT_TYPE1, false, false, size, data);
+  CheckFontDescriptor(cidfont_dict, FPDF_FONT_TYPE1, false, false, span);
 
   // Check widths
   const CPDF_Array* widths_array = cidfont_dict->GetArrayFor("W");
@@ -2154,11 +2150,9 @@
   CreateNewDocument();
   const CPDF_Font* stock_font =
       CPDF_Font::GetStockFont(cpdf_doc(), "Helvetica-Oblique");
-  const uint8_t* data = stock_font->GetFont()->GetFontData();
-  const uint32_t size = stock_font->GetFont()->GetSize();
-
-  ScopedFPDFFont font(
-      FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 1));
+  pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+  ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                        FPDF_FONT_TRUETYPE, 1));
   ASSERT_TRUE(font.get());
   CPDF_Font* typed_font = CPDFFontFromFPDFFont(font.get());
   EXPECT_TRUE(typed_font->IsCIDFont());
@@ -2185,8 +2179,7 @@
   EXPECT_EQ("Adobe", cidinfo_dict->GetStringFor("Registry"));
   EXPECT_EQ("Identity", cidinfo_dict->GetStringFor("Ordering"));
   EXPECT_EQ(0, cidinfo_dict->GetNumberFor("Supplement"));
-  CheckFontDescriptor(cidfont_dict, FPDF_FONT_TRUETYPE, false, true, size,
-                      data);
+  CheckFontDescriptor(cidfont_dict, FPDF_FONT_TRUETYPE, false, true, span);
 
   // Check widths
   const CPDF_Array* widths_array = cidfont_dict->GetArrayFor("W");
@@ -2209,10 +2202,9 @@
   FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
   {
     const CPDF_Font* stock_font = CPDF_Font::GetStockFont(cpdf_doc(), "Arial");
-    const uint8_t* data = stock_font->GetFont()->GetFontData();
-    const uint32_t size = stock_font->GetFont()->GetSize();
-    ScopedFPDFFont font(
-        FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 0));
+    pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+    ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                          FPDF_FONT_TRUETYPE, 0));
     ASSERT_TRUE(font.get());
 
     // Add some text to the page
@@ -2289,12 +2281,11 @@
     // First, get the data from the font
     CIDfont.LoadSubst("IPAGothic", 1, 0, 400, 0, 932, 0);
     EXPECT_EQ("IPAGothic", CIDfont.GetFaceName());
-    const uint8_t* data = CIDfont.GetFontData();
-    const uint32_t size = CIDfont.GetSize();
+    pdfium::span<const uint8_t> span = CIDfont.GetFontSpan();
 
     // Load the data into a FPDF_Font.
-    ScopedFPDFFont font(
-        FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 1));
+    ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                          FPDF_FONT_TRUETYPE, 1));
     ASSERT_TRUE(font.get());
 
     // Add some text to the page
@@ -2469,10 +2460,9 @@
   FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
 
   const CPDF_Font* stock_font = CPDF_Font::GetStockFont(cpdf_doc(), "Arial");
-  const uint8_t* data = stock_font->GetFont()->GetFontData();
-  const uint32_t size = stock_font->GetFont()->GetSize();
-  ScopedFPDFFont font(
-      FPDFText_LoadFont(document(), data, size, FPDF_FONT_TRUETYPE, 0));
+  pdfium::span<const uint8_t> span = stock_font->GetFont()->GetFontSpan();
+  ScopedFPDFFont font(FPDFText_LoadFont(document(), span.data(), span.size(),
+                                        FPDF_FONT_TRUETYPE, 0));
   ASSERT_TRUE(font.get());
 
   // Add some text to the page.
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index 4dc293b..e99f00a 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -486,7 +486,7 @@
   // TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? Otherwise, we
   // are allowing giving any font that can be loaded on freetype and setting it
   // as any font type.
-  if (!pFont->LoadEmbedded(data, size))
+  if (!pFont->LoadEmbedded({data, size}))
     return nullptr;
 
   return FPDFFontFromCPDFFont(