Properly ref-count CFGAS_GEFont with CFX_RetainPtr.

We worry about cyclical references, but no leaks found.

Review-Url: https://codereview.chromium.org/2609423003
diff --git a/xfa/fde/cfde_txtedtengine.cpp b/xfa/fde/cfde_txtedtengine.cpp
index 1d357e92..342913d 100644
--- a/xfa/fde/cfde_txtedtengine.cpp
+++ b/xfa/fde/cfde_txtedtengine.cpp
@@ -34,7 +34,6 @@
       dwLayoutStyles(0),
       dwAlignment(0),
       dwMode(0),
-      pFont(nullptr),
       fFontSize(10.0f),
       dwFontColor(0xff000000),
       fLineSpace(10.0f),
@@ -48,6 +47,8 @@
       fCharSpace(0),
       pEventSink(nullptr) {}
 
+FDE_TXTEDTPARAMS::~FDE_TXTEDTPARAMS() {}
+
 FDE_TXTEDT_TEXTCHANGE_INFO::FDE_TXTEDT_TEXTCHANGE_INFO() {}
 
 FDE_TXTEDT_TEXTCHANGE_INFO::~FDE_TXTEDT_TEXTCHANGE_INFO() {}
diff --git a/xfa/fde/cfde_txtedttextset.cpp b/xfa/fde/cfde_txtedttextset.cpp
index 33da0c5..4149a6d 100644
--- a/xfa/fde/cfde_txtedttextset.cpp
+++ b/xfa/fde/cfde_txtedttextset.cpp
@@ -8,6 +8,7 @@
 
 #include "xfa/fde/cfde_txtedtengine.h"
 #include "xfa/fde/cfde_txtedtpage.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
 
 CFDE_TxtEdtTextSet::CFDE_TxtEdtTextSet(CFDE_TxtEdtPage* pPage)
     : m_pPage(pPage) {}
@@ -25,14 +26,14 @@
 int32_t CFDE_TxtEdtTextSet::GetString(FDE_TEXTEDITPIECE* pPiece,
                                       CFX_WideString& wsText) {
   FX_WCHAR* pBuffer = wsText.GetBuffer(pPiece->nCount);
-  for (int32_t i = 0; i < pPiece->nCount; i++) {
+  for (int32_t i = 0; i < pPiece->nCount; i++)
     pBuffer[i] = m_pPage->GetChar(pPiece, i);
-  }
+
   wsText.ReleaseBuffer(pPiece->nCount);
   return pPiece->nCount;
 }
 
-CFGAS_GEFont* CFDE_TxtEdtTextSet::GetFont() {
+CFX_RetainPtr<CFGAS_GEFont> CFDE_TxtEdtTextSet::GetFont() {
   return m_pPage->GetEngine()->GetEditParams()->pFont;
 }
 
diff --git a/xfa/fde/cfde_txtedttextset.h b/xfa/fde/cfde_txtedttextset.h
index 14979dc..6c62666 100644
--- a/xfa/fde/cfde_txtedttextset.h
+++ b/xfa/fde/cfde_txtedttextset.h
@@ -22,7 +22,7 @@
 
   // IFDE_TextSet
   int32_t GetString(FDE_TEXTEDITPIECE* pPiece, CFX_WideString& wsText) override;
-  CFGAS_GEFont* GetFont() override;
+  CFX_RetainPtr<CFGAS_GEFont> GetFont() override;
   FX_FLOAT GetFontSize() override;
   FX_ARGB GetFontColor() override;
   int32_t GetDisplayPos(FDE_TEXTEDITPIECE* pPiece,
diff --git a/xfa/fde/fde_gedevice.cpp b/xfa/fde/fde_gedevice.cpp
index bf34135..081f00a 100644
--- a/xfa/fde/fde_gedevice.cpp
+++ b/xfa/fde/fde_gedevice.cpp
@@ -105,7 +105,7 @@
   return !!handle;
 }
 bool CFDE_RenderDevice::DrawString(CFDE_Brush* pBrush,
-                                   CFGAS_GEFont* pFont,
+                                   const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                                    const FXTEXT_CHARPOS* pCharPos,
                                    int32_t iCount,
                                    FX_FLOAT fFontSize,
@@ -126,8 +126,8 @@
     }
   }
   FXTEXT_CHARPOS* pCP = (FXTEXT_CHARPOS*)pCharPos;
-  CFGAS_GEFont* pCurFont = nullptr;
-  CFGAS_GEFont* pSTFont = nullptr;
+  CFX_RetainPtr<CFGAS_GEFont> pCurFont;
+  CFX_RetainPtr<CFGAS_GEFont> pSTFont;
   FXTEXT_CHARPOS* pCurCP = nullptr;
   int32_t iCurCount = 0;
 
diff --git a/xfa/fde/fde_gedevice.h b/xfa/fde/fde_gedevice.h
index cb8e3fa..35efab2 100644
--- a/xfa/fde/fde_gedevice.h
+++ b/xfa/fde/fde_gedevice.h
@@ -9,11 +9,11 @@
 
 #include "core/fxge/cfx_renderdevice.h"
 #include "xfa/fgas/crt/fgas_memory.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
 
 class CFDE_Brush;
 class CFDE_Path;
 class CFDE_Pen;
-class CFGAS_GEFont;
 class CFX_GraphStateData;
 
 class CFDE_RenderDevice : public CFX_Target {
@@ -39,7 +39,7 @@
                  const CFX_Matrix* pImgMatrix = nullptr,
                  const CFX_Matrix* pDevMatrix = nullptr);
   bool DrawString(CFDE_Brush* pBrush,
-                  CFGAS_GEFont* pFont,
+                  const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                   const FXTEXT_CHARPOS* pCharPos,
                   int32_t iCount,
                   FX_FLOAT fFontSize,
@@ -100,13 +100,13 @@
                      const CFX_Matrix* pMatrix = nullptr);
 
   bool DrawSolidString(CFDE_Brush* pBrush,
-                       CFGAS_GEFont* pFont,
+                       const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                        const FXTEXT_CHARPOS* pCharPos,
                        int32_t iCount,
                        FX_FLOAT fFontSize,
                        const CFX_Matrix* pMatrix);
   bool DrawStringPath(CFDE_Brush* pBrush,
-                      CFGAS_GEFont* pFont,
+                      const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                       const FXTEXT_CHARPOS* pCharPos,
                       int32_t iCount,
                       FX_FLOAT fFontSize,
diff --git a/xfa/fde/fde_render.cpp b/xfa/fde/fde_render.cpp
index 9528219..1cdea42 100644
--- a/xfa/fde/fde_render.cpp
+++ b/xfa/fde/fde_render.cpp
@@ -108,7 +108,7 @@
   ASSERT(m_pRenderDevice);
   ASSERT(pTextSet && pText);
 
-  CFGAS_GEFont* pFont = pTextSet->GetFont();
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pTextSet->GetFont();
   if (!pFont)
     return;
 
diff --git a/xfa/fde/fde_visualset.h b/xfa/fde/fde_visualset.h
index 481f4a5..77aa6c7 100644
--- a/xfa/fde/fde_visualset.h
+++ b/xfa/fde/fde_visualset.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FDE_FDE_VISUALSET_H_
 #define XFA_FDE_FDE_VISUALSET_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/fx_dib.h"
@@ -48,7 +49,7 @@
  public:
   virtual int32_t GetString(FDE_TEXTEDITPIECE* hText,
                             CFX_WideString& wsText) = 0;
-  virtual CFGAS_GEFont* GetFont() = 0;
+  virtual CFX_RetainPtr<CFGAS_GEFont> GetFont() = 0;
   virtual FX_FLOAT GetFontSize() = 0;
   virtual FX_ARGB GetFontColor() = 0;
   virtual int32_t GetDisplayPos(FDE_TEXTEDITPIECE* hText,
diff --git a/xfa/fde/ifde_txtedtengine.h b/xfa/fde/ifde_txtedtengine.h
index 12f0cd8..6940a8c 100644
--- a/xfa/fde/ifde_txtedtengine.h
+++ b/xfa/fde/ifde_txtedtengine.h
@@ -72,6 +72,7 @@
 
 struct FDE_TXTEDTPARAMS {
   FDE_TXTEDTPARAMS();
+  ~FDE_TXTEDTPARAMS();
 
   FX_FLOAT fPlateWidth;
   FX_FLOAT fPlateHeight;
@@ -79,7 +80,7 @@
   uint32_t dwLayoutStyles;
   uint32_t dwAlignment;
   uint32_t dwMode;
-  CFGAS_GEFont* pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   FX_FLOAT fFontSize;
   FX_ARGB dwFontColor;
   FX_FLOAT fLineSpace;
diff --git a/xfa/fde/tto/fde_textout.cpp b/xfa/fde/tto/fde_textout.cpp
index cf541a2..1081526 100644
--- a/xfa/fde/tto/fde_textout.cpp
+++ b/xfa/fde/tto/fde_textout.cpp
@@ -46,7 +46,7 @@
   m_ttoLines.RemoveAll(false);
 }
 
-void CFDE_TextOut::SetFont(CFGAS_GEFont* pFont) {
+void CFDE_TextOut::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
   ASSERT(pFont);
   m_pFont = pFont;
   m_pTxtBreak->SetFont(pFont);
diff --git a/xfa/fde/tto/fde_textout.h b/xfa/fde/tto/fde_textout.h
index 684a641..f9eeb82 100644
--- a/xfa/fde/tto/fde_textout.h
+++ b/xfa/fde/tto/fde_textout.h
@@ -79,7 +79,7 @@
   CFDE_TextOut();
   ~CFDE_TextOut() override;
 
-  void SetFont(CFGAS_GEFont* pFont);
+  void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
   void SetFontSize(FX_FLOAT fFontSize);
   void SetTextColor(FX_ARGB color);
   void SetStyles(uint32_t dwStyles);
@@ -153,7 +153,7 @@
   void DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen);
 
   std::unique_ptr<CFX_TxtBreak> m_pTxtBreak;
-  CFGAS_GEFont* m_pFont;  // not owned.
+  CFX_RetainPtr<CFGAS_GEFont> m_pFont;
   FX_FLOAT m_fFontSize;
   FX_FLOAT m_fLineSpace;
   FX_FLOAT m_fLinePos;
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index 5cf5a46..1849441 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -15,6 +15,7 @@
 #include "core/fxge/cfx_gemodule.h"
 #include "core/fxge/ifx_systemfontinfo.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
 #include "xfa/fgas/crt/fgas_codepage.h"
 #include "xfa/fgas/font/cfgas_gefont.h"
 #include "xfa/fgas/font/fgas_fontutils.h"
@@ -101,38 +102,25 @@
 }
 
 CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator)
-    : m_pEnumerator(pEnumerator),
-      m_FontFaces(100),
-      m_CPFonts(8),
-      m_FamilyFonts(16),
-      m_UnicodeFonts(16),
-      m_BufferFonts(4),
-      m_StreamFonts(4),
-      m_DeriveFonts(4) {
+    : m_pEnumerator(pEnumerator), m_FontFaces(100) {
   if (m_pEnumerator)
     m_pEnumerator(m_FontFaces, nullptr, 0xFEFF);
 }
 
 CFGAS_FontMgr::~CFGAS_FontMgr() {
   m_FontFaces.RemoveAll(false);
-  m_CPFonts.RemoveAll();
-  m_FamilyFonts.RemoveAll();
-  m_UnicodeFonts.RemoveAll();
-  m_BufferFonts.RemoveAll();
-  m_StreamFonts.RemoveAll();
-  m_DeriveFonts.RemoveAll();
-  for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--)
-    m_Fonts[i]->Release();
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage,
-                                               uint32_t dwFontStyles,
-                                               const FX_WCHAR* pszFontFamily) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
+    uint16_t wCodePage,
+    uint32_t dwFontStyles,
+    const FX_WCHAR* pszFontFamily) {
   uint32_t dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
-  CFGAS_GEFont* pFont = nullptr;
-  if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
-    return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
-  FX_FONTDESCRIPTOR const* pFD =
+  auto it = m_CPFonts.find(dwHash);
+  if (it != m_CPFonts.end()) {
+    return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr;
+  }
+  const FX_FONTDESCRIPTOR* pFD =
       FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
   if (!pFD)
     pFD = FindFont(nullptr, dwFontStyles, true, wCodePage);
@@ -141,32 +129,34 @@
   if (!pFD)
     return nullptr;
 
-  pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
   if (!pFont)
     return nullptr;
 
-  m_Fonts.Add(pFont);
-  m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+  m_Fonts.push_back(pFont);
+  m_CPFonts[dwHash] = pFont;
   dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
-  m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+  m_FamilyFonts[dwHash] = pFont;
   return LoadFont(pFont, dwFontStyles, wCodePage);
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode,
-                                              uint32_t dwFontStyles,
-                                              const FX_WCHAR* pszFontFamily) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode(
+    FX_WCHAR wUnicode,
+    uint32_t dwFontStyles,
+    const FX_WCHAR* pszFontFamily) {
   const FGAS_FONTUSB* pRet = FGAS_GetUnicodeBitField(wUnicode);
   if (pRet->wBitField == 999)
     return nullptr;
 
   uint32_t dwHash =
       FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
-  CFGAS_GEFont* pFont = nullptr;
-  if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
-    return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : nullptr;
-
-  FX_FONTDESCRIPTOR const* pFD =
+  auto it = m_UnicodeFonts.find(dwHash);
+  if (it != m_UnicodeFonts.end()) {
+    return it->second ? LoadFont(it->second, dwFontStyles, pRet->wCodePage)
+                      : nullptr;
+  }
+  const FX_FONTDESCRIPTOR* pFD =
       FindFont(pszFontFamily, dwFontStyles, false, pRet->wCodePage,
                pRet->wBitField, wUnicode);
   if (!pFD && pszFontFamily) {
@@ -178,28 +168,31 @@
 
   uint16_t wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
   const FX_WCHAR* pFontFace = pFD->wsFontFace;
-  pFont = CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
+      CFGAS_GEFont::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
   if (!pFont)
     return nullptr;
 
-  m_Fonts.Add(pFont);
-  m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
-  dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
-  m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
-  dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
-  m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+  m_Fonts.push_back(pFont);
+  m_UnicodeFonts[dwHash] = pFont;
+  m_CPFonts[FGAS_GetFontHashCode(wCodePage, dwFontStyles)] = pFont;
+  m_FamilyFonts[FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage)] =
+      pFont;
   return LoadFont(pFont, dwFontStyles, wCodePage);
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const FX_WCHAR* pszFontFamily,
-                                      uint32_t dwFontStyles,
-                                      uint16_t wCodePage) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
+    const FX_WCHAR* pszFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   uint32_t dwHash =
       FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
-  CFGAS_GEFont* pFont = nullptr;
-  if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont))
-    return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : nullptr;
-  FX_FONTDESCRIPTOR const* pFD =
+  auto it = m_FamilyFonts.find(dwHash);
+  if (it != m_FamilyFonts.end())
+    return it->second ? LoadFont(it->second, dwFontStyles, wCodePage) : nullptr;
+
+  const FX_FONTDESCRIPTOR* pFD =
       FindFont(pszFontFamily, dwFontStyles, true, wCodePage);
   if (!pFD)
     pFD = FindFont(pszFontFamily, dwFontStyles, false, wCodePage);
@@ -208,71 +201,66 @@
 
   if (wCodePage == 0xFFFF)
     wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
+
   pFont =
       CFGAS_GEFont::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
   if (!pFont)
     return nullptr;
 
-  m_Fonts.Add(pFont);
-  m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+  m_Fonts.push_back(pFont);
+  m_FamilyFonts[dwHash] = pFont;
   dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
-  m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+  m_CPFonts[dwHash] = pFont;
   return LoadFont(pFont, dwFontStyles, wCodePage);
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::LoadFont(CFGAS_GEFont* pSrcFont,
-                                      uint32_t dwFontStyles,
-                                      uint16_t wCodePage) {
-  ASSERT(pSrcFont);
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
+    const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
   if (pSrcFont->GetFontStyles() == dwFontStyles)
-    return pSrcFont->Retain();
-  void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles,
+    return pSrcFont;
+
+  void* buffer[3] = {pSrcFont.Get(), (void*)(uintptr_t)dwFontStyles,
                      (void*)(uintptr_t)wCodePage};
   uint32_t dwHash = FX_HashCode_GetA(
       CFX_ByteStringC((uint8_t*)buffer, sizeof(buffer)), false);
-  CFGAS_GEFont* pFont = nullptr;
-  if (m_DeriveFonts.GetCount() > 0) {
-    m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont);
-    if (pFont)
-      return pFont->Retain();
-  }
-  pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
+  auto it = m_DeriveFonts.find(dwHash);
+  if (it != m_DeriveFonts.end() && it->second)
+    return it->second;
+
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
   if (!pFont)
     return nullptr;
 
-  m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
-  int32_t index = m_Fonts.Find(pFont);
-  if (index < 0) {
-    m_Fonts.Add(pFont);
-    pFont->Retain();
-  }
+  m_DeriveFonts[dwHash] = pFont;
+  auto iter = std::find(m_Fonts.begin(), m_Fonts.end(), pFont);
+  if (iter == m_Fonts.end())
+    m_Fonts.push_back(pFont);
   return pFont;
 }
 
-void CFGAS_FontMgr::RemoveFont(CFX_MapPtrToPtr& fontMap, CFGAS_GEFont* pFont) {
-  FX_POSITION pos = fontMap.GetStartPosition();
-  void* pKey;
-  void* pFind;
-  while (pos) {
-    pFind = nullptr;
-    fontMap.GetNextAssoc(pos, pKey, pFind);
-    if (pFind != (void*)pFont)
-      continue;
-    fontMap.RemoveKey(pKey);
-    break;
+void CFGAS_FontMgr::RemoveFont(
+    std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap,
+    const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
+  auto iter = pFontMap->begin();
+  while (iter != pFontMap->end()) {
+    auto old_iter = iter++;
+    if (old_iter->second == pFont)
+      pFontMap->erase(old_iter);
   }
 }
 
-void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pFont) {
-  RemoveFont(m_CPFonts, pFont);
-  RemoveFont(m_FamilyFonts, pFont);
-  RemoveFont(m_UnicodeFonts, pFont);
-  RemoveFont(m_BufferFonts, pFont);
-  RemoveFont(m_StreamFonts, pFont);
-  RemoveFont(m_DeriveFonts, pFont);
-  int32_t iFind = m_Fonts.Find(pFont);
-  if (iFind > -1)
-    m_Fonts.RemoveAt(iFind, 1);
+void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
+  RemoveFont(&m_CPFonts, pFont);
+  RemoveFont(&m_FamilyFonts, pFont);
+  RemoveFont(&m_UnicodeFonts, pFont);
+  RemoveFont(&m_BufferFonts, pFont);
+  RemoveFont(&m_StreamFonts, pFont);
+  RemoveFont(&m_DeriveFonts, pFont);
+  auto it = std::find(m_Fonts.begin(), m_Fonts.end(), pFont);
+  if (it != m_Fonts.end())
+    m_Fonts.erase(it);
 }
 
 FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily,
@@ -594,16 +582,7 @@
     m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
     delete pDescs;
   }
-  pos = m_Hash2Fonts.GetStartPosition();
-  while (pos) {
-    uint32_t dwHash;
-    CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts;
-    m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
-    for (int32_t i = 0; i < pFonts->GetSize(); i++)
-      delete pFonts->GetAt(i);
-    delete pFonts;
-  }
-  m_Hash2Fonts.RemoveAll();
+  m_Hash2Fonts.clear();
 }
 
 bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
@@ -644,31 +623,28 @@
 }
 
 bool CFGAS_FontMgr::EnumFonts() {
-  if (EnumFontsFromFontMapper())
-    return true;
-  return EnumFontsFromFiles();
+  return EnumFontsFromFontMapper() || EnumFontsFromFiles();
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::GetFontByCodePage(uint16_t wCodePage,
-                                               uint32_t dwFontStyles,
-                                               const FX_WCHAR* pszFontFamily) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
+    const FX_WCHAR* pszFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
+  return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
+}
+
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage(
+    uint16_t wCodePage,
+    uint32_t dwFontStyles,
+    const FX_WCHAR* pszFontFamily) {
   CFX_ByteString bsHash;
   bsHash.Format("%d, %d", wCodePage, dwFontStyles);
   bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
   uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
-  CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
-  if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
-    if (!pFonts)
-      return nullptr;
+  std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash];
+  if (!pFontArray->empty())
+    return (*pFontArray)[0];
 
-    if (pFonts->GetSize() != 0)
-      return pFonts->GetAt(0)->Retain();
-  }
-
-  if (!pFonts)
-    pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;
-
-  m_Hash2Fonts.SetAt(dwHash, pFonts);
   CFX_FontDescriptorInfos* sortedFonts = nullptr;
   if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
     sortedFonts = new CFX_FontDescriptorInfos;
@@ -680,21 +656,23 @@
     return nullptr;
 
   CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
-  CFGAS_GEFont* pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
-  if (pFont)
-    pFont->SetLogicalFontStyle(dwFontStyles);
+  if (!pFont)
+    return nullptr;
 
-  pFonts->Add(pFont);
+  pFont->SetLogicalFontStyle(dwFontStyles);
+  pFontArray->push_back(pFont);
   return pFont;
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::GetFontByUnicode(FX_WCHAR wUnicode,
-                                              uint32_t dwFontStyles,
-                                              const FX_WCHAR* pszFontFamily) {
-  CFGAS_GEFont* pFont = nullptr;
-  if (m_FailedUnicodes2Nullptr.Lookup(wUnicode, pFont))
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode(
+    FX_WCHAR wUnicode,
+    uint32_t dwFontStyles,
+    const FX_WCHAR* pszFontFamily) {
+  if (pdfium::ContainsKey(m_FailedUnicodesSet, wUnicode))
     return nullptr;
+
   const FGAS_FONTUSB* x = FGAS_GetUnicodeBitField(wUnicode);
   uint16_t wCodePage = x ? x->wCodePage : 0xFFFF;
   uint16_t wBitField = x ? x->wBitField : 0x03E7;
@@ -705,19 +683,11 @@
     bsHash.Format("%d, %d", wCodePage, dwFontStyles);
   bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
   uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false);
-  CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts = nullptr;
-  if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
-    if (!pFonts)
-      return nullptr;
-
-    for (int32_t i = 0; i < pFonts->GetSize(); ++i) {
-      if (VerifyUnicode(pFonts->GetAt(i), wUnicode))
-        return pFonts->GetAt(i)->Retain();
-    }
+  std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash];
+  for (size_t i = 0; i < pFonts->size(); ++i) {
+    if (VerifyUnicode((*pFonts)[i], wUnicode))
+      return (*pFonts)[i];
   }
-  if (!pFonts)
-    pFonts = new CFX_ArrayTemplate<CFGAS_GEFont*>;
-  m_Hash2Fonts.SetAt(dwHash, pFonts);
   CFX_FontDescriptorInfos* sortedFonts = nullptr;
   if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
     sortedFonts = new CFX_FontDescriptorInfos;
@@ -729,15 +699,16 @@
     CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
     if (!VerifyUnicode(pDesc, wUnicode))
       continue;
-    pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
+    CFX_RetainPtr<CFGAS_GEFont> pFont =
+        LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
     if (!pFont)
       continue;
     pFont->SetLogicalFontStyle(dwFontStyles);
-    pFonts->Add(pFont);
+    pFonts->push_back(pFont);
     return pFont;
   }
   if (!pszFontFamily)
-    m_FailedUnicodes2Nullptr.SetAt(wUnicode, nullptr);
+    m_FailedUnicodesSet.insert(wUnicode);
   return nullptr;
 }
 
@@ -761,7 +732,8 @@
   return !retCharmap && retIndex;
 }
 
-bool CFGAS_FontMgr::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) {
+bool CFGAS_FontMgr::VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+                                  FX_WCHAR wcUnicode) {
   if (!pFont)
     return false;
 
@@ -777,9 +749,10 @@
   return true;
 }
 
-CFGAS_GEFont* CFGAS_FontMgr::LoadFont(const CFX_WideString& wsFaceName,
-                                      int32_t iFaceIndex,
-                                      int32_t* pFaceCount) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::LoadFont(
+    const CFX_WideString& wsFaceName,
+    int32_t iFaceIndex,
+    int32_t* pFaceCount) {
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
   if (!pFontMapper)
@@ -798,14 +771,14 @@
   if (!pInternalFont->LoadFile(pFontStream, iFaceIndex))
     return nullptr;
 
-  CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
+  CFX_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;
 }
 
@@ -1010,26 +983,24 @@
   return nPenalty;
 }
 
-void CFGAS_FontMgr::RemoveFont(CFGAS_GEFont* pEFont) {
+void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pEFont) {
   if (!pEFont)
     return;
 
   m_IFXFont2FileRead.erase(pEFont);
 
-  FX_POSITION pos;
-  pos = m_Hash2Fonts.GetStartPosition();
-  while (pos) {
-    uint32_t dwHash;
-    CFX_ArrayTemplate<CFGAS_GEFont*>* pFonts;
-    m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
-    if (pFonts) {
-      for (int32_t i = 0; i < pFonts->GetSize(); i++) {
-        if (pFonts->GetAt(i) == pEFont)
-          pFonts->SetAt(i, nullptr);
-      }
-    } else {
-      m_Hash2Fonts.RemoveKey(dwHash);
+  auto iter = m_Hash2Fonts.begin();
+  while (iter != m_Hash2Fonts.end()) {
+    auto old_iter = iter++;
+    bool all_empty = true;
+    for (size_t i = 0; i < old_iter->second.size(); i++) {
+      if (old_iter->second[i] == pEFont)
+        old_iter->second[i].Reset();
+      else if (old_iter->second[i])
+        all_empty = false;
     }
+    if (all_empty)
+      m_Hash2Fonts.erase(old_iter);
   }
 }
 
diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h
index 0da84fd..c4030e7 100644
--- a/xfa/fgas/font/cfgas_fontmgr.h
+++ b/xfa/fgas/font/cfgas_fontmgr.h
@@ -9,15 +9,16 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_ext.h"
 #include "core/fxge/cfx_fontmapper.h"
 #include "core/fxge/fx_freetype.h"
 #include "core/fxge/ifx_systemfontinfo.h"
 #include "third_party/freetype/include/freetype/fttypes.h"
 #include "xfa/fgas/crt/fgas_stream.h"
-#include "xfa/fgas/font/cfgas_fontmgr.h"
 
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
 #include "xfa/fgas/crt/fgas_memory.h"
@@ -35,9 +36,9 @@
 #define FX_FONTSTYLE_ExactMatch 0x80000000
 
 class CFX_FontSourceEnum_File;
-class CFGAS_GEFont;
 class CXFA_PDFFontMgr;
 class CFGAS_FontMgr;
+class CFGAS_GEFont;
 
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
 #define FX_FONTMATCHPARA_MatchStyle 0x01
@@ -90,28 +91,30 @@
 
 class CFGAS_FontMgr {
  public:
+  static std::unique_ptr<CFGAS_FontMgr> Create(FX_LPEnumAllFonts pEnumerator);
+
   explicit CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator);
   ~CFGAS_FontMgr();
 
-  static std::unique_ptr<CFGAS_FontMgr> Create(FX_LPEnumAllFonts pEnumerator);
-
-  CFGAS_GEFont* GetFontByCodePage(uint16_t wCodePage,
-                                  uint32_t dwFontStyles,
-                                  const FX_WCHAR* pszFontFamily);
-  CFGAS_GEFont* GetFontByUnicode(FX_WCHAR wUnicode,
-                                 uint32_t dwFontStyles,
-                                 const FX_WCHAR* pszFontFamily);
-  CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily,
-                         uint32_t dwFontStyles,
-                         uint16_t wCodePage);
-  void RemoveFont(CFGAS_GEFont* pFont);
+  CFX_RetainPtr<CFGAS_GEFont> GetFontByCodePage(uint16_t wCodePage,
+                                                uint32_t dwFontStyles,
+                                                const FX_WCHAR* pszFontFamily);
+  CFX_RetainPtr<CFGAS_GEFont> GetFontByUnicode(FX_WCHAR wUnicode,
+                                               uint32_t dwFontStyles,
+                                               const FX_WCHAR* pszFontFamily);
+  CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily,
+                                       uint32_t dwFontStyles,
+                                       uint16_t wCodePage);
+  void RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
 
  private:
-  CFGAS_GEFont* LoadFont(CFGAS_GEFont* pSrcFont,
-                         uint32_t dwFontStyles,
-                         uint16_t wCodePage);
-  void RemoveFont(CFX_MapPtrToPtr& fontMap, CFGAS_GEFont* pFont);
-  FX_FONTDESCRIPTOR const* FindFont(const FX_WCHAR* pszFontFamily,
+  CFX_RetainPtr<CFGAS_GEFont> LoadFont(
+      const CFX_RetainPtr<CFGAS_GEFont>& pSrcFont,
+      uint32_t dwFontStyles,
+      uint16_t wCodePage);
+  void RemoveFont(std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>>* pFontMap,
+                  const CFX_RetainPtr<CFGAS_GEFont>& pFont);
+  const FX_FONTDESCRIPTOR* FindFont(const FX_WCHAR* pszFontFamily,
                                     uint32_t dwFontStyles,
                                     uint32_t dwMatchFlags,
                                     uint16_t wCodePage,
@@ -120,13 +123,13 @@
 
   FX_LPEnumAllFonts m_pEnumerator;
   CFX_FontDescriptors m_FontFaces;
-  CFX_ArrayTemplate<CFGAS_GEFont*> m_Fonts;
-  CFX_MapPtrToPtr m_CPFonts;
-  CFX_MapPtrToPtr m_FamilyFonts;
-  CFX_MapPtrToPtr m_UnicodeFonts;
-  CFX_MapPtrToPtr m_BufferFonts;
-  CFX_MapPtrToPtr m_StreamFonts;
-  CFX_MapPtrToPtr m_DeriveFonts;
+  std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_Fonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_CPFonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_FamilyFonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_UnicodeFonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_BufferFonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_StreamFonts;
+  std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_DeriveFonts;
 };
 
 #else  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
@@ -191,24 +194,22 @@
 
 class CFGAS_FontMgr {
  public:
-  explicit CFGAS_FontMgr(CFX_FontSourceEnum_File* pFontEnum);
-  ~CFGAS_FontMgr();
   static std::unique_ptr<CFGAS_FontMgr> Create(
       CFX_FontSourceEnum_File* pFontEnum);
 
-  CFGAS_GEFont* GetFontByCodePage(uint16_t wCodePage,
-                                  uint32_t dwFontStyles,
-                                  const FX_WCHAR* pszFontFamily);
-  CFGAS_GEFont* GetFontByUnicode(FX_WCHAR wUnicode,
-                                 uint32_t dwFontStyles,
-                                 const FX_WCHAR* pszFontFamily);
-  void RemoveFont(CFGAS_GEFont* pFont);
+  explicit CFGAS_FontMgr(CFX_FontSourceEnum_File* pFontEnum);
+  ~CFGAS_FontMgr();
 
-  inline CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily,
-                                uint32_t dwFontStyles,
-                                uint16_t wCodePage) {
-    return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
-  }
+  CFX_RetainPtr<CFGAS_GEFont> GetFontByCodePage(uint16_t wCodePage,
+                                                uint32_t dwFontStyles,
+                                                const FX_WCHAR* pszFontFamily);
+  CFX_RetainPtr<CFGAS_GEFont> GetFontByUnicode(FX_WCHAR wUnicode,
+                                               uint32_t dwFontStyles,
+                                               const FX_WCHAR* pszFontFamily);
+  CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily,
+                                       uint32_t dwFontStyles,
+                                       uint16_t wCodePage);
+  void RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
 
  private:
   bool EnumFonts();
@@ -222,7 +223,8 @@
   void GetUSBCSB(FXFT_Face pFace, uint32_t* USB, uint32_t* CSB);
   uint32_t GetFlags(FXFT_Face pFace);
   bool VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode);
-  bool VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode);
+  bool VerifyUnicode(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+                     FX_WCHAR wcUnicode);
   int32_t IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2);
   int32_t MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
                      uint16_t wCodePage,
@@ -234,9 +236,9 @@
                       uint32_t dwFontStyles,
                       const CFX_WideString& FontName,
                       FX_WCHAR wcUnicode = 0xFFFE);
-  CFGAS_GEFont* LoadFont(const CFX_WideString& wsFaceName,
-                         int32_t iFaceIndex,
-                         int32_t* pFaceCount);
+  CFX_RetainPtr<CFGAS_GEFont> LoadFont(const CFX_WideString& wsFaceName,
+                                       int32_t iFaceIndex,
+                                       int32_t* pFaceCount);
   FXFT_Face LoadFace(const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
                      int32_t iFaceIndex);
   CFX_RetainPtr<IFX_SeekableReadStream> CreateFontStream(
@@ -248,12 +250,12 @@
 
   CFX_FontDescriptors m_InstalledFonts;
   CFX_MapPtrTemplate<uint32_t, CFX_FontDescriptorInfos*> m_Hash2CandidateList;
-  CFX_MapPtrTemplate<uint32_t, CFX_ArrayTemplate<CFGAS_GEFont*>*> m_Hash2Fonts;
-  std::map<CFGAS_GEFont*, CFX_RetainPtr<IFX_SeekableReadStream> >
+  std::map<uint32_t, std::vector<CFX_RetainPtr<CFGAS_GEFont>>> m_Hash2Fonts;
+  std::map<CFX_RetainPtr<CFGAS_GEFont>, CFX_RetainPtr<IFX_SeekableReadStream>>
       m_IFXFont2FileRead;
-  CFX_MapPtrTemplate<FX_WCHAR, CFGAS_GEFont*> m_FailedUnicodes2Nullptr;
+  std::set<FX_WCHAR> m_FailedUnicodesSet;
   CFX_FontSourceEnum_File* const m_pFontSource;
 };
-#endif
+#endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
 
 #endif  // XFA_FGAS_FONT_CFGAS_FONTMGR_H_
diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp
index bc971f6..fc202f6 100644
--- a/xfa/fgas/font/cfgas_gefont.cpp
+++ b/xfa/fgas/font/cfgas_gefont.cpp
@@ -18,69 +18,63 @@
 #include "xfa/fxfa/xfa_fontmgr.h"
 
 // static
-CFGAS_GEFont* CFGAS_GEFont::LoadFont(const FX_WCHAR* pszFontFamily,
-                                     uint32_t dwFontStyles,
-                                     uint16_t wCodePage,
-                                     CFGAS_FontMgr* pFontMgr) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(
+    const FX_WCHAR* pszFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage,
+    CFGAS_FontMgr* pFontMgr) {
 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
-  if (pFontMgr)
-    return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
-  return nullptr;
-#else
-  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
-  if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) {
-    pFont->Release();
+  if (!pFontMgr)
     return nullptr;
-  }
+
+  return CFX_RetainPtr<CFGAS_GEFont>(
+      pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily));
+#else
+  auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr);
+  if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage))
+    return nullptr;
   return pFont;
 #endif
 }
 
 // static
-CFGAS_GEFont* CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont,
-                                     CFGAS_FontMgr* pFontMgr) {
-  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
-  if (!pFont->LoadFontInternal(pExternalFont)) {
-    pFont->Release();
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont,
+                                                   CFGAS_FontMgr* pFontMgr) {
+  auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr);
+  if (!pFont->LoadFontInternal(pExternalFont))
     return nullptr;
-  }
   return pFont;
 }
 
 // static
-CFGAS_GEFont* CFGAS_GEFont::LoadFont(std::unique_ptr<CFX_Font> pInternalFont,
-                                     CFGAS_FontMgr* pFontMgr) {
-  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
-  if (!pFont->LoadFontInternal(std::move(pInternalFont))) {
-    pFont->Release();
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(
+    std::unique_ptr<CFX_Font> pInternalFont,
+    CFGAS_FontMgr* pFontMgr) {
+  auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr);
+  if (!pFont->LoadFontInternal(std::move(pInternalFont)))
     return nullptr;
-  }
   return pFont;
 }
 
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
 // static
-CFGAS_GEFont* CFGAS_GEFont::LoadFont(const uint8_t* pBuffer,
-                                     int32_t iLength,
-                                     CFGAS_FontMgr* pFontMgr) {
-  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
-  if (!pFont->LoadFontInternal(pBuffer, iLength)) {
-    pFont->Release();
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(const uint8_t* pBuffer,
+                                                   int32_t iLength,
+                                                   CFGAS_FontMgr* pFontMgr) {
+  auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr);
+  if (pFont->LoadFontInternal(pBuffer, iLength))
     return nullptr;
-  }
   return pFont;
 }
 
 // static
-CFGAS_GEFont* CFGAS_GEFont::LoadFont(
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(
     const CFX_RetainPtr<IFGAS_Stream>& pFontStream,
     CFGAS_FontMgr* pFontMgr,
     bool bSaveStream) {
-  CFGAS_GEFont* pFont = new CFGAS_GEFont(pFontMgr);
-  if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) {
-    pFont->Release();
+  auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr);
+  if (!pFont->LoadFontInternal(pFontStream, bSaveStream))
     return nullptr;
-  }
   return pFont;
 }
 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
@@ -92,14 +86,13 @@
       m_dwLogFontStyle(0),
 #endif
       m_pFont(nullptr),
-      m_pSrcFont(nullptr),
       m_pFontMgr(pFontMgr),
-      m_iRefCount(1),
       m_bExternalFont(false),
       m_pProvider(nullptr) {
 }
 
-CFGAS_GEFont::CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles)
+CFGAS_GEFont::CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src,
+                           uint32_t dwFontStyles)
     :
 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
       m_bUseLogFontStyle(false),
@@ -108,11 +101,9 @@
       m_pFont(nullptr),
       m_pSrcFont(src),
       m_pFontMgr(src->m_pFontMgr),
-      m_iRefCount(1),
       m_bExternalFont(false),
       m_pProvider(nullptr) {
   ASSERT(m_pSrcFont->m_pFont);
-  m_pSrcFont->Retain();
   m_pFont = new CFX_Font;
   m_pFont->LoadClone(m_pSrcFont->m_pFont);
   CFX_SubstFont* pSubst = m_pFont->GetSubstFont();
@@ -128,31 +119,11 @@
 }
 
 CFGAS_GEFont::~CFGAS_GEFont() {
-  for (int32_t i = 0; i < m_SubstFonts.GetSize(); i++)
-    m_SubstFonts[i]->Release();
-
-  m_SubstFonts.RemoveAll();
-  m_FontMapper.clear();
+  if (m_pFontMgr)
+    m_pFontMgr->RemoveFont(CFX_RetainPtr<CFGAS_GEFont>(this));
 
   if (!m_bExternalFont)
     delete m_pFont;
-
-  // If it is a shallow copy of another source font,
-  // decrease the refcount of the source font.
-  if (m_pSrcFont)
-    m_pSrcFont->Release();
-}
-
-void CFGAS_GEFont::Release() {
-  if (--m_iRefCount < 1) {
-    if (m_pFontMgr)
-      m_pFontMgr->RemoveFont(this);
-    delete this;
-  }
-}
-CFGAS_GEFont* CFGAS_GEFont::Retain() {
-  ++m_iRefCount;
-  return this;
 }
 
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
@@ -260,10 +231,12 @@
   return true;
 }
 
-CFGAS_GEFont* CFGAS_GEFont::Derive(uint32_t dwFontStyles, uint16_t wCodePage) {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::Derive(uint32_t dwFontStyles,
+                                                 uint16_t wCodePage) {
+  CFX_RetainPtr<CFGAS_GEFont> pFont(this);
   if (GetFontStyles() == dwFontStyles)
-    return Retain();
-  return new CFGAS_GEFont(this, dwFontStyles);
+    return pFont;
+  return pdfium::MakeRetain<CFGAS_GEFont>(pFont, dwFontStyles);
 }
 
 CFX_WideString CFGAS_GEFont::GetFamilyName() const {
@@ -317,11 +290,12 @@
     return true;
 
   if (!m_pProvider ||
-      !m_pProvider->GetCharWidth(this, wUnicode, bCharCode, &iWidth)) {
-    CFGAS_GEFont* pFont = nullptr;
+      !m_pProvider->GetCharWidth(CFX_RetainPtr<CFGAS_GEFont>(this), wUnicode,
+                                 bCharCode, &iWidth)) {
+    CFX_RetainPtr<CFGAS_GEFont> pFont;
     int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode);
     if (iGlyph != 0xFFFF && pFont) {
-      if (pFont == this) {
+      if (pFont.Get() == this) {
         iWidth = m_pFont->GetGlyphWidth(iGlyph);
         if (iWidth < 0)
           iWidth = -1;
@@ -351,10 +325,10 @@
   ASSERT(m_pBBoxMap);
   void* pRect = nullptr;
   if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
-    CFGAS_GEFont* pFont = nullptr;
+    CFX_RetainPtr<CFGAS_GEFont> pFont;
     int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode);
     if (iGlyph != 0xFFFF && pFont) {
-      if (pFont == this) {
+      if (pFont.Get() == this) {
         FX_RECT rtBBox;
         if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
           CFX_Rect rt;
@@ -392,13 +366,12 @@
 
 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode,
                                     bool bRecursive,
-                                    CFGAS_GEFont** ppFont,
+                                    CFX_RetainPtr<CFGAS_GEFont>* ppFont,
                                     bool bCharCode) {
-  ASSERT(m_pFontEncoding);
   int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
   if (iGlyphIndex > 0) {
     if (ppFont)
-      *ppFont = this;
+      ppFont->Reset(this);
     return iGlyphIndex;
   }
   const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
@@ -410,44 +383,41 @@
     return 0xFFFF;
 
   auto it = m_FontMapper.find(wUnicode);
-  CFGAS_GEFont* pFont = it != m_FontMapper.end() ? it->second : nullptr;
-  if (pFont && pFont != this) {
-    iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode);
+  if (it != m_FontMapper.end() && it->second && it->second.Get() != this) {
+    iGlyphIndex =
+        it->second->GetGlyphIndex(wUnicode, false, nullptr, bCharCode);
     if (iGlyphIndex != 0xFFFF) {
-      int32_t i = m_SubstFonts.Find(pFont);
-      if (i > -1) {
-        iGlyphIndex |= ((i + 1) << 24);
-        if (ppFont)
-          *ppFont = pFont;
-        return iGlyphIndex;
+      for (size_t i = 0; i < m_SubstFonts.size(); ++i) {
+        if (m_SubstFonts[i] == it->second) {
+          if (ppFont)
+            *ppFont = it->second;
+          return (iGlyphIndex | ((i + 1) << 24));
+        }
       }
     }
   }
   if (!m_pFontMgr || !bRecursive)
     return 0xFFFF;
+
   CFX_WideString wsFamily = GetFamilyName();
-  pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), wsFamily.c_str());
 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
   if (!pFont)
     pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr);
 #endif
-  if (!pFont)
+  if (!pFont || pFont.Get() == this)  // Avoids direct cycles below.
     return 0xFFFF;
-  if (pFont == this) {
-    pFont->Release();
-    return 0xFFFF;
-  }
+
   m_FontMapper[wUnicode] = pFont;
-  int32_t i = m_SubstFonts.GetSize();
-  m_SubstFonts.Add(pFont);
+  m_SubstFonts.push_back(pFont);
   iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode);
   if (iGlyphIndex == 0xFFFF)
     return 0xFFFF;
-  iGlyphIndex |= ((i + 1) << 24);
+
   if (ppFont)
     *ppFont = pFont;
-  return iGlyphIndex;
+  return (iGlyphIndex | (m_SubstFonts.size() << 24));
 }
 
 int32_t CFGAS_GEFont::GetAscent() const {
@@ -458,8 +428,10 @@
   return m_pFont->GetDescent();
 }
 
-CFGAS_GEFont* CFGAS_GEFont::GetSubstFont(int32_t iGlyphIndex) const {
+CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::GetSubstFont(
+    int32_t iGlyphIndex) const {
   iGlyphIndex = static_cast<uint32_t>(iGlyphIndex) >> 24;
-  return iGlyphIndex == 0 ? const_cast<CFGAS_GEFont*>(this)
-                          : m_SubstFonts[iGlyphIndex - 1];
+  if (iGlyphIndex == 0)
+    return CFX_RetainPtr<CFGAS_GEFont>(const_cast<CFGAS_GEFont*>(this));
+  return m_SubstFonts[iGlyphIndex - 1];
 }
diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h
index 86e5e4c..962b93f 100644
--- a/xfa/fgas/font/cfgas_gefont.h
+++ b/xfa/fgas/font/cfgas_gefont.h
@@ -9,40 +9,47 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_memory.h"
 #include "xfa/fgas/crt/fgas_utils.h"
 #include "xfa/fgas/font/cfgas_fontmgr.h"
 
 #define FXFONT_SUBST_ITALIC 0x02
 
+class CFGAS_FontMgr;
 class CFX_UnicodeEncoding;
 class CXFA_PDFFontMgr;
 
-class CFGAS_GEFont {
+class CFGAS_GEFont : public CFX_Retainable {
  public:
-  static CFGAS_GEFont* LoadFont(const FX_WCHAR* pszFontFamily,
-                                uint32_t dwFontStyles,
-                                uint16_t wCodePage,
-                                CFGAS_FontMgr* pFontMgr);
-  static CFGAS_GEFont* LoadFont(CFX_Font* pExternalFont,
-                                CFGAS_FontMgr* pFontMgr);
-  static CFGAS_GEFont* LoadFont(std::unique_ptr<CFX_Font> pInternalFont,
-                                CFGAS_FontMgr* pFontMgr);
+  template <typename T, typename... Args>
+  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  static CFX_RetainPtr<CFGAS_GEFont> LoadFont(const FX_WCHAR* pszFontFamily,
+                                              uint32_t dwFontStyles,
+                                              uint16_t wCodePage,
+                                              CFGAS_FontMgr* pFontMgr);
+  static CFX_RetainPtr<CFGAS_GEFont> LoadFont(CFX_Font* pExternalFont,
+                                              CFGAS_FontMgr* pFontMgr);
+  static CFX_RetainPtr<CFGAS_GEFont> LoadFont(
+      std::unique_ptr<CFX_Font> pInternalFont,
+      CFGAS_FontMgr* pFontMgr);
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-  static CFGAS_GEFont* LoadFont(const uint8_t* pBuffer,
-                                int32_t iLength,
-                                CFGAS_FontMgr* pFontMgr);
-  static CFGAS_GEFont* LoadFont(const CFX_RetainPtr<IFGAS_Stream>& pFontStream,
-                                CFGAS_FontMgr* pFontMgr,
-                                bool bSaveStream);
+  static CFX_RetainPtr<CFGAS_GEFont> LoadFont(const uint8_t* pBuffer,
+                                              int32_t iLength,
+                                              CFGAS_FontMgr* pFontMgr);
+  static CFX_RetainPtr<CFGAS_GEFont> LoadFont(
+      const CFX_RetainPtr<IFGAS_Stream>& pFontStream,
+      CFGAS_FontMgr* pFontMgr,
+      bool bSaveStream);
 #endif
 
-  ~CFGAS_GEFont();
+  ~CFGAS_GEFont() override;
 
-  void Release();
-  CFGAS_GEFont* Retain();
-  CFGAS_GEFont* Derive(uint32_t dwFontStyles, uint16_t wCodePage = 0);
+  CFX_RetainPtr<CFGAS_GEFont> Derive(uint32_t dwFontStyles,
+                                     uint16_t wCodePage = 0);
   uint32_t GetFontStyles() const;
   bool GetCharWidth(FX_WCHAR wUnicode, int32_t& iWidth, bool bCharCode);
   int32_t GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode = false);
@@ -50,7 +57,7 @@
   int32_t GetDescent() const;
   bool GetCharBBox(FX_WCHAR wUnicode, CFX_Rect& bbox, bool bCharCode = false);
   bool GetBBox(CFX_Rect& bbox);
-  CFGAS_GEFont* GetSubstFont(int32_t iGlyphIndex) const;
+  CFX_RetainPtr<CFGAS_GEFont> GetSubstFont(int32_t iGlyphIndex) const;
   CFX_Font* GetDevFont() const { return m_pFont; }
   void SetFontProvider(CXFA_PDFFontMgr* pProvider) { m_pProvider = pProvider; }
 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
@@ -62,7 +69,7 @@
 
  private:
   explicit CFGAS_GEFont(CFGAS_FontMgr* pFontMgr);
-  CFGAS_GEFont(CFGAS_GEFont* src, uint32_t dwFontStyles);
+  CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src, uint32_t dwFontStyles);
 
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
   bool LoadFontInternal(const FX_WCHAR* pszFontFamily,
@@ -85,7 +92,7 @@
                             bool bCharCode);
   int32_t GetGlyphIndex(FX_WCHAR wUnicode,
                         bool bRecursive,
-                        CFGAS_GEFont** ppFont,
+                        CFX_RetainPtr<CFGAS_GEFont>* ppFont,
                         bool bCharCode = false);
   CFX_WideString GetFamilyName() const;
 
@@ -94,9 +101,8 @@
   uint32_t m_dwLogFontStyle;
 #endif
   CFX_Font* m_pFont;
-  CFGAS_GEFont* const m_pSrcFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pSrcFont;  // Only set by ctor, so no cycles.
   CFGAS_FontMgr* const m_pFontMgr;
-  int32_t m_iRefCount;
   bool m_bExternalFont;
   CFX_RetainPtr<IFGAS_Stream> m_pStream;
   CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
@@ -105,8 +111,8 @@
   std::unique_ptr<CFX_MassArrayTemplate<CFX_Rect>> m_pRectArray;
   std::unique_ptr<CFX_MapPtrToPtr> m_pBBoxMap;
   CXFA_PDFFontMgr* m_pProvider;  // not owned.
-  CFX_ArrayTemplate<CFGAS_GEFont*> m_SubstFonts;
-  std::map<FX_WCHAR, CFGAS_GEFont*> m_FontMapper;
+  std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_SubstFonts;
+  std::map<FX_WCHAR, CFX_RetainPtr<CFGAS_GEFont>> m_FontMapper;
 };
 
 #endif  // XFA_FGAS_FONT_CFGAS_GEFONT_H_
diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp
index 8e4fbf7..cacb77f 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.cpp
+++ b/xfa/fgas/layout/fgas_rtfbreak.cpp
@@ -93,13 +93,10 @@
   m_iRotation %= 4;
 }
 
-void CFX_RTFBreak::SetFont(CFGAS_GEFont* pFont) {
-  if (!pFont) {
+void CFX_RTFBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
+  if (!pFont || pFont == m_pFont)
     return;
-  }
-  if (m_pFont == pFont) {
-    return;
-  }
+
   SetBreakStatus();
   m_pFont = pFont;
   m_iDefChar = 0;
@@ -111,6 +108,7 @@
     }
   }
 }
+
 void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize) {
   int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
   if (m_iFontSize == iFontSize) {
@@ -1184,7 +1182,7 @@
   const FX_WCHAR* pStr = pText->pStr;
   int32_t* pWidths = pText->pWidths;
   int32_t iLength = pText->iLength - 1;
-  CFGAS_GEFont* pFont = pText->pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont;
   uint32_t dwStyles = pText->dwLayoutStyles;
   CFX_RectF rtText(*pText->pRect);
   bool bRTLPiece = FX_IsOdd(pText->iBidiLevel);
@@ -1419,9 +1417,9 @@
 int32_t CFX_RTFBreak::GetCharRects(const FX_RTFTEXTOBJ* pText,
                                    CFX_RectFArray& rtArray,
                                    bool bCharBBox) const {
-  if (!pText || pText->iLength < 1) {
+  if (!pText || pText->iLength < 1)
     return 0;
-  }
+
   ASSERT(pText->pStr && pText->pWidths && pText->pFont && pText->pRect);
   const FX_WCHAR* pStr = pText->pStr;
   int32_t* pWidths = pText->pWidths;
@@ -1431,15 +1429,15 @@
   FX_FLOAT fFontSize = pText->fFontSize;
   int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
   FX_FLOAT fScale = fFontSize / 1000.0f;
-  CFGAS_GEFont* pFont = pText->pFont;
-  if (!pFont) {
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont;
+  if (!pFont)
     bCharBBox = false;
-  }
+
   CFX_Rect bbox;
   bbox.Set(0, 0, 0, 0);
-  if (bCharBBox) {
+  if (bCharBBox)
     bCharBBox = pFont->GetBBox(bbox);
-  }
+
   FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
   FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
   rtArray.RemoveAll();
@@ -1566,3 +1564,5 @@
       wLineBreakChar(L'\n'),
       iHorizontalScale(100),
       iVerticalScale(100) {}
+
+FX_RTFTEXTOBJ::~FX_RTFTEXTOBJ() {}
diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h
index de2497e..c281192 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.h
+++ b/xfa/fgas/layout/fgas_rtfbreak.h
@@ -67,11 +67,12 @@
 
 struct FX_RTFTEXTOBJ {
   FX_RTFTEXTOBJ();
+  ~FX_RTFTEXTOBJ();
 
   const FX_WCHAR* pStr;
   int32_t* pWidths;
   int32_t iLength;
-  CFGAS_GEFont* pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   FX_FLOAT fFontSize;
   uint32_t dwLayoutStyles;
   int32_t iCharRotation;
@@ -222,7 +223,7 @@
   void SetLineStartPos(FX_FLOAT fLinePos);
   uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; }
   void SetLayoutStyles(uint32_t dwLayoutStyles);
-  void SetFont(CFGAS_GEFont* pFont);
+  void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
   void SetFontSize(FX_FLOAT fFontSize);
   void SetTabWidth(FX_FLOAT fTabWidth);
   void AddPositionedTab(FX_FLOAT fTabPos);
@@ -294,7 +295,7 @@
   bool m_bVertical;
   bool m_bSingleLine;
   bool m_bCharCode;
-  CFGAS_GEFont* m_pFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pFont;
   int32_t m_iFontHeight;
   int32_t m_iFontSize;
   int32_t m_iTabWidth;
diff --git a/xfa/fgas/layout/fgas_textbreak.cpp b/xfa/fgas/layout/fgas_textbreak.cpp
index a3f8e98..a9d35a3 100644
--- a/xfa/fgas/layout/fgas_textbreak.cpp
+++ b/xfa/fgas/layout/fgas_textbreak.cpp
@@ -112,13 +112,10 @@
   m_iRotation %= 4;
 }
 
-void CFX_TxtBreak::SetFont(CFGAS_GEFont* pFont) {
-  if (!pFont) {
+void CFX_TxtBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) {
+  if (!pFont || pFont == m_pFont)
     return;
-  }
-  if (m_pFont == pFont) {
-    return;
-  }
+
   SetBreakStatus();
   m_pFont = pFont;
   m_iDefChar = 0;
@@ -1214,7 +1211,7 @@
   const FX_WCHAR* pStr = pTxtRun->wsStr.c_str();
   int32_t* pWidths = pTxtRun->pWidths;
   int32_t iLength = pTxtRun->iLength - 1;
-  CFGAS_GEFont* pFont = pTxtRun->pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont;
   uint32_t dwStyles = pTxtRun->dwStyles;
   CFX_RectF rtText(*pTxtRun->pRect);
   bool bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
@@ -1593,9 +1590,9 @@
 int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun,
                                    CFX_RectFArray& rtArray,
                                    bool bCharBBox) const {
-  if (!pTxtRun || pTxtRun->iLength < 1) {
+  if (!pTxtRun || pTxtRun->iLength < 1)
     return 0;
-  }
+
   IFX_TxtAccess* pAccess = pTxtRun->pAccess;
   const FDE_TEXTEDITPIECE* pIdentity = pTxtRun->pIdentity;
   const FX_WCHAR* pStr = pTxtRun->wsStr.c_str();
@@ -1606,15 +1603,15 @@
   FX_FLOAT fFontSize = pTxtRun->fFontSize;
   int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
   FX_FLOAT fScale = fFontSize / 1000.0f;
-  CFGAS_GEFont* pFont = pTxtRun->pFont;
-  if (!pFont) {
+  CFX_RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont;
+  if (!pFont)
     bCharBBox = false;
-  }
+
   CFX_Rect bbox;
   bbox.Set(0, 0, 0, 0);
-  if (bCharBBox) {
+  if (bCharBBox)
     bCharBBox = pFont->GetBBox(bbox);
-  }
+
   FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
   FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
   rtArray.RemoveAll();
diff --git a/xfa/fgas/layout/fgas_textbreak.h b/xfa/fgas/layout/fgas_textbreak.h
index 7bae6cd..3660274 100644
--- a/xfa/fgas/layout/fgas_textbreak.h
+++ b/xfa/fgas/layout/fgas_textbreak.h
@@ -93,7 +93,7 @@
   CFX_WideString wsStr;
   int32_t* pWidths;
   int32_t iLength;
-  CFGAS_GEFont* pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   FX_FLOAT fFontSize;
   uint32_t dwStyles;
   int32_t iHorizontalScale;
@@ -206,7 +206,7 @@
   void SetLinePos(FX_FLOAT fLinePos);
   uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; }
   void SetLayoutStyles(uint32_t dwLayoutStyles);
-  void SetFont(CFGAS_GEFont* pFont);
+  void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
   void SetFontSize(FX_FLOAT fFontSize);
   void SetTabWidth(FX_FLOAT fTabWidth, bool bEquidistant);
   void SetDefaultChar(FX_WCHAR wch);
@@ -280,7 +280,7 @@
   bool m_bCombText;
   int32_t m_iArabicContext;
   int32_t m_iCurArabicContext;
-  CFGAS_GEFont* m_pFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pFont;
   int32_t m_iFontSize;
   bool m_bEquidistant;
   int32_t m_iTabWidth;
diff --git a/xfa/fgas/layout/fgas_unicode.h b/xfa/fgas/layout/fgas_unicode.h
index f7a0d20..b404d67 100644
--- a/xfa/fgas/layout/fgas_unicode.h
+++ b/xfa/fgas/layout/fgas_unicode.h
@@ -18,11 +18,12 @@
 
 void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd);
 
-typedef bool (*FX_AdjustCharDisplayPos)(FX_WCHAR wch,
-                                        bool bMBCSCode,
-                                        CFGAS_GEFont* pFont,
-                                        FX_FLOAT fFontSize,
-                                        bool bVertical,
-                                        CFX_PointF& ptOffset);
+typedef bool (*FX_AdjustCharDisplayPos)(
+    FX_WCHAR wch,
+    bool bMBCSCode,
+    const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+    FX_FLOAT fFontSize,
+    bool bVertical,
+    CFX_PointF& ptOffset);
 
 #endif  // XFA_FGAS_LAYOUT_FGAS_UNICODE_H_
diff --git a/xfa/fwl/cfwl_barcode.cpp b/xfa/fwl/cfwl_barcode.cpp
index 8b05927..0412b86 100644
--- a/xfa/fwl/cfwl_barcode.cpp
+++ b/xfa/fwl/cfwl_barcode.cpp
@@ -169,8 +169,7 @@
   if (pTheme) {
     CFWL_ThemePart part;
     part.m_pWidget = this;
-
-    if (CFGAS_GEFont* pFont = pTheme->GetFont(&part)) {
+    if (CFX_RetainPtr<CFGAS_GEFont> pFont = pTheme->GetFont(&part)) {
       if (CFX_Font* pCXFont = pFont->GetDevFont())
         m_pBarcodeEngine->SetFont(pCXFont);
     }
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index 79b0b2d..acd5672 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -688,7 +688,7 @@
   params.dwFontColor = theme->GetTextColor(&part);
   params.fLineSpace = theme->GetLineHeight(&part);
 
-  CFGAS_GEFont* pFont = theme->GetFont(&part);
+  CFX_RetainPtr<CFGAS_GEFont> pFont = theme->GetFont(&part);
   if (!pFont)
     return;
 
diff --git a/xfa/fwl/ifwl_themeprovider.h b/xfa/fwl/ifwl_themeprovider.h
index c0460fe..21a12a5 100644
--- a/xfa/fwl/ifwl_themeprovider.h
+++ b/xfa/fwl/ifwl_themeprovider.h
@@ -26,7 +26,8 @@
   virtual float GetCYBorderSize() const = 0;
   virtual CFX_RectF GetUIMargin(CFWL_ThemePart* pThemePart) const = 0;
   virtual float GetFontSize(CFWL_ThemePart* pThemePart) const = 0;
-  virtual CFGAS_GEFont* GetFont(CFWL_ThemePart* pThemePart) const = 0;
+  virtual CFX_RetainPtr<CFGAS_GEFont> GetFont(
+      CFWL_ThemePart* pThemePart) const = 0;
   virtual float GetLineHeight(CFWL_ThemePart* pThemePart) const = 0;
   virtual float GetScrollBarWidth() const = 0;
   virtual FX_COLORREF GetTextColor(CFWL_ThemePart* pThemePart) const = 0;
diff --git a/xfa/fwl/theme/cfwl_widgettp.cpp b/xfa/fwl/theme/cfwl_widgettp.cpp
index 395571c..a0d6b4c 100644
--- a/xfa/fwl/theme/cfwl_widgettp.cpp
+++ b/xfa/fwl/theme/cfwl_widgettp.cpp
@@ -298,8 +298,8 @@
     m_pFontMgr = CFGAS_FontMgr::Create(m_pFontSource.get());
 #endif
   }
-  m_pFont.reset(CFGAS_GEFont::LoadFont(wsFontFamily.c_str(), dwFontStyles,
-                                       dwCodePage, m_pFontMgr.get()));
+  m_pFont = CFGAS_GEFont::LoadFont(wsFontFamily.c_str(), dwFontStyles,
+                                   dwCodePage, m_pFontMgr.get());
   return !!m_pFont;
 }
 
@@ -319,16 +319,18 @@
 
 CFWL_FontManager::~CFWL_FontManager() {}
 
-CFGAS_GEFont* CFWL_FontManager::FindFont(const CFX_WideStringC& wsFontFamily,
-                                         uint32_t dwFontStyles,
-                                         uint16_t wCodePage) {
+CFX_RetainPtr<CFGAS_GEFont> CFWL_FontManager::FindFont(
+    const CFX_WideStringC& wsFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
   for (const auto& pData : m_FontsArray) {
     if (pData->Equal(wsFontFamily, dwFontStyles, wCodePage))
       return pData->GetFont();
   }
-  std::unique_ptr<CFWL_FontData> pFontData(new CFWL_FontData);
+  auto pFontData = pdfium::MakeUnique<CFWL_FontData>();
   if (!pFontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage))
     return nullptr;
+
   m_FontsArray.push_back(std::move(pFontData));
   return m_FontsArray.back()->GetFont();
 }
diff --git a/xfa/fwl/theme/cfwl_widgettp.h b/xfa/fwl/theme/cfwl_widgettp.h
index 33a5feb..794c67b 100644
--- a/xfa/fwl/theme/cfwl_widgettp.h
+++ b/xfa/fwl/theme/cfwl_widgettp.h
@@ -10,8 +10,10 @@
 #include <memory>
 #include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
+#include "xfa/fgas/font/cfgas_gefont.h"
 #include "xfa/fwl/fwl_error.h"
 #include "xfa/fwl/theme/cfwl_utils.h"
 #include "xfa/fxgraphics/cfx_graphics.h"
@@ -38,7 +40,7 @@
   virtual void DrawBackground(CFWL_ThemeBackground* pParams);
   virtual void DrawText(CFWL_ThemeText* pParams);
 
-  CFGAS_GEFont* GetFont() const { return m_pFDEFont; }
+  const CFX_RetainPtr<CFGAS_GEFont>& GetFont() const { return m_pFDEFont; }
 
  protected:
   struct CColorData {
@@ -94,7 +96,7 @@
 
   uint32_t m_dwRefCount;
   std::unique_ptr<CFDE_TextOut> m_pTextOut;
-  CFGAS_GEFont* m_pFDEFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pFDEFont;
   std::unique_ptr<CColorData> m_pColorData;
 };
 
@@ -111,7 +113,7 @@
   bool LoadFont(const CFX_WideStringC& wsFontFamily,
                 uint32_t dwFontStyles,
                 uint16_t wCodePage);
-  CFGAS_GEFont* GetFont() const { return m_pFont.get(); }
+  CFX_RetainPtr<CFGAS_GEFont> GetFont() const { return m_pFont; }
 
  protected:
   CFX_WideString m_wsFamily;
@@ -121,7 +123,7 @@
   std::unique_ptr<CFX_FontSourceEnum_File> m_pFontSource;
 #endif
   std::unique_ptr<CFGAS_FontMgr> m_pFontMgr;
-  std::unique_ptr<CFGAS_GEFont> m_pFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pFont;
 };
 
 class CFWL_FontManager {
@@ -129,9 +131,9 @@
   static CFWL_FontManager* GetInstance();
   static void DestroyInstance();
 
-  CFGAS_GEFont* FindFont(const CFX_WideStringC& wsFontFamily,
-                         uint32_t dwFontStyles,
-                         uint16_t dwCodePage);
+  CFX_RetainPtr<CFGAS_GEFont> FindFont(const CFX_WideStringC& wsFontFamily,
+                                       uint32_t dwFontStyles,
+                                       uint16_t dwCodePage);
 
  protected:
   CFWL_FontManager();
diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.cpp b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
index 13145e6..e62ebca 100644
--- a/xfa/fxfa/app/xfa_ffwidgetacc.cpp
+++ b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
@@ -1498,19 +1498,18 @@
   return m_pLayoutData.get();
 }
 
-CFGAS_GEFont* CXFA_WidgetAcc::GetFDEFont() {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_WidgetAcc::GetFDEFont() {
   CFX_WideStringC wsFontName = FX_WSTRC(L"Courier");
   uint32_t dwFontStyle = 0;
   if (CXFA_Font font = GetFont()) {
-    if (font.IsBold()) {
+    if (font.IsBold())
       dwFontStyle |= FX_FONTSTYLE_Bold;
-    }
-    if (font.IsItalic()) {
+    if (font.IsItalic())
       dwFontStyle |= FX_FONTSTYLE_Italic;
-    }
     font.GetTypeface(wsFontName);
   }
-  CXFA_FFDoc* pDoc = GetDoc();
+
+  auto pDoc = GetDoc();
   return pDoc->GetApp()->GetXFAFontMgr()->GetFont(pDoc, wsFontName,
                                                   dwFontStyle);
 }
diff --git a/xfa/fxfa/app/xfa_fontmgr.cpp b/xfa/fxfa/app/xfa_fontmgr.cpp
index 636017d..5db3896 100644
--- a/xfa/fxfa/app/xfa_fontmgr.cpp
+++ b/xfa/fxfa/app/xfa_fontmgr.cpp
@@ -1740,18 +1740,16 @@
 
 CXFA_DefFontMgr::CXFA_DefFontMgr() {}
 
-CXFA_DefFontMgr::~CXFA_DefFontMgr() {
-  for (int32_t i = 0; i < m_CacheFonts.GetSize(); i++)
-    m_CacheFonts[i]->Release();
-}
+CXFA_DefFontMgr::~CXFA_DefFontMgr() {}
 
-CFGAS_GEFont* CXFA_DefFontMgr::GetFont(CXFA_FFDoc* hDoc,
-                                       const CFX_WideStringC& wsFontFamily,
-                                       uint32_t dwFontStyles,
-                                       uint16_t wCodePage) {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_DefFontMgr::GetFont(
+    CXFA_FFDoc* hDoc,
+    const CFX_WideStringC& wsFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
   CFX_WideString wsFontName(wsFontFamily);
   CFGAS_FontMgr* pFDEFontMgr = hDoc->GetApp()->GetFDEFontMgr();
-  CFGAS_GEFont* pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       pFDEFontMgr->LoadFont(wsFontName.c_str(), dwFontStyles, wCodePage);
   if (!pFont) {
     const XFA_FONTINFO* pCurFont =
@@ -1785,56 +1783,50 @@
     }
   }
   if (pFont)
-    m_CacheFonts.Add(pFont);
+    m_CacheFonts.push_back(pFont);
   return pFont;
 }
 
-CFGAS_GEFont* CXFA_DefFontMgr::GetDefaultFont(
+CFX_RetainPtr<CFGAS_GEFont> CXFA_DefFontMgr::GetDefaultFont(
     CXFA_FFDoc* hDoc,
     const CFX_WideStringC& wsFontFamily,
     uint32_t dwFontStyles,
     uint16_t wCodePage) {
   CFGAS_FontMgr* pFDEFontMgr = hDoc->GetApp()->GetFDEFontMgr();
-  CFGAS_GEFont* pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       pFDEFontMgr->LoadFont(L"Arial Narrow", dwFontStyles, wCodePage);
   if (!pFont) {
     pFont = pFDEFontMgr->LoadFont(static_cast<const FX_WCHAR*>(nullptr),
                                   dwFontStyles, wCodePage);
   }
-
-  ASSERT(pFont);
   if (pFont)
-    m_CacheFonts.Add(pFont);
+    m_CacheFonts.push_back(pFont);
   return pFont;
 }
 
 CXFA_PDFFontMgr::CXFA_PDFFontMgr(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
 
-CXFA_PDFFontMgr::~CXFA_PDFFontMgr() {
-  for (const auto& pair : m_FontMap) {
-    if (pair.second)
-      pair.second->Release();
-  }
-}
+CXFA_PDFFontMgr::~CXFA_PDFFontMgr() {}
 
-CFGAS_GEFont* CXFA_PDFFontMgr::FindFont(const CFX_ByteString& strPsName,
-                                        bool bBold,
-                                        bool bItalic,
-                                        CPDF_Font** pDstPDFFont,
-                                        bool bStrictMatch) {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::FindFont(
+    const CFX_ByteString& strPsName,
+    bool bBold,
+    bool bItalic,
+    CPDF_Font** pDstPDFFont,
+    bool bStrictMatch) {
   CPDF_Document* pDoc = m_pDoc->GetPDFDoc();
-  if (!pDoc) {
+  if (!pDoc)
     return nullptr;
-  }
+
   CPDF_Dictionary* pFontSetDict =
       pDoc->GetRoot()->GetDictFor("AcroForm")->GetDictFor("DR");
-  if (!pFontSetDict) {
+  if (!pFontSetDict)
     return nullptr;
-  }
+
   pFontSetDict = pFontSetDict->GetDictFor("Font");
-  if (!pFontSetDict) {
+  if (!pFontSetDict)
     return nullptr;
-  }
+
   CFX_ByteString name = strPsName;
   name.Remove(' ');
   CFGAS_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
@@ -1862,10 +1854,11 @@
   return nullptr;
 }
 
-CFGAS_GEFont* CXFA_PDFFontMgr::GetFont(const CFX_WideStringC& wsFontFamily,
-                                       uint32_t dwFontStyles,
-                                       CPDF_Font** pPDFFont,
-                                       bool bStrictMatch) {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::GetFont(
+    const CFX_WideStringC& wsFontFamily,
+    uint32_t dwFontStyles,
+    CPDF_Font** pPDFFont,
+    bool bStrictMatch) {
   uint32_t dwHashCode = FX_HashCode_GetW(wsFontFamily, false);
   CFX_ByteString strKey;
   strKey.Format("%u%u", dwHashCode, dwFontStyles);
@@ -1877,7 +1870,7 @@
   bool bBold = (dwFontStyles & FX_FONTSTYLE_Bold) == FX_FONTSTYLE_Bold;
   bool bItalic = (dwFontStyles & FX_FONTSTYLE_Italic) == FX_FONTSTYLE_Italic;
   CFX_ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
-  CFGAS_GEFont* pFont =
+  CFX_RetainPtr<CFGAS_GEFont> pFont =
       FindFont(strFontName, bBold, bItalic, pPDFFont, bStrictMatch);
   if (pFont)
     m_FontMap[strKey] = pFont;
@@ -1975,7 +1968,7 @@
   return true;
 }
 
-bool CXFA_PDFFontMgr::GetCharWidth(const CFGAS_GEFont* pFont,
+bool CXFA_PDFFontMgr::GetCharWidth(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                                    FX_WCHAR wUnicode,
                                    bool bCharCode,
                                    int32_t* pWidth) {
@@ -1991,7 +1984,8 @@
   return true;
 }
 
-void CXFA_PDFFontMgr::SetFont(const CFGAS_GEFont* pFont, CPDF_Font* pPDFFont) {
+void CXFA_PDFFontMgr::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
+                              CPDF_Font* pPDFFont) {
   m_FDE2PDFFont[pFont] = pPDFFont;
 }
 
@@ -1999,10 +1993,11 @@
 
 CXFA_FontMgr::~CXFA_FontMgr() {}
 
-CFGAS_GEFont* CXFA_FontMgr::GetFont(CXFA_FFDoc* hDoc,
-                                    const CFX_WideStringC& wsFontFamily,
-                                    uint32_t dwFontStyles,
-                                    uint16_t wCodePage) {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_FontMgr::GetFont(
+    CXFA_FFDoc* hDoc,
+    const CFX_WideStringC& wsFontFamily,
+    uint32_t dwFontStyles,
+    uint16_t wCodePage) {
   uint32_t dwHash = FX_HashCode_GetW(wsFontFamily, false);
   CFX_ByteString bsKey;
   bsKey.Format("%u%u%u", dwHash, dwFontStyles, wCodePage);
@@ -2015,7 +2010,7 @@
   CXFA_PDFFontMgr* pMgr =
       it != m_PDFFontMgrMap.end() ? it->second.get() : nullptr;
   CPDF_Font* pPDFFont = nullptr;
-  CFGAS_GEFont* pFont = nullptr;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   if (pMgr) {
     pFont =
         pMgr->GetFont(wsEnglishName.AsStringC(), dwFontStyles, &pPDFFont, true);
diff --git a/xfa/fxfa/app/xfa_fwltheme.cpp b/xfa/fxfa/app/xfa_fwltheme.cpp
index d12678e..1de302e 100644
--- a/xfa/fxfa/app/xfa_fwltheme.cpp
+++ b/xfa/fxfa/app/xfa_fwltheme.cpp
@@ -75,10 +75,6 @@
 
 CXFA_FWLTheme::~CXFA_FWLTheme() {
   m_pTextOut.reset();
-  if (m_pCalendarFont) {
-    m_pCalendarFont->Release();
-    m_pCalendarFont = nullptr;
-  }
   FWLTHEME_Release();
 }
 
@@ -193,7 +189,8 @@
   return FWLTHEME_CAPACITY_FontSize;
 }
 
-CFGAS_GEFont* CXFA_FWLTheme::GetFont(CFWL_ThemePart* pThemePart) const {
+CFX_RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont(
+    CFWL_ThemePart* pThemePart) const {
   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
     return pWidget->GetDataAcc()->GetFDEFont();
   return GetTheme(pThemePart->m_pWidget)->GetFont();
diff --git a/xfa/fxfa/app/xfa_fwltheme.h b/xfa/fxfa/app/xfa_fwltheme.h
index f8b8048..a8efad0 100644
--- a/xfa/fxfa/app/xfa_fwltheme.h
+++ b/xfa/fxfa/app/xfa_fwltheme.h
@@ -37,7 +37,8 @@
   float GetCYBorderSize() const override;
   CFX_RectF GetUIMargin(CFWL_ThemePart* pThemePart) const override;
   float GetFontSize(CFWL_ThemePart* pThemePart) const override;
-  CFGAS_GEFont* GetFont(CFWL_ThemePart* pThemePart) const override;
+  CFX_RetainPtr<CFGAS_GEFont> GetFont(
+      CFWL_ThemePart* pThemePart) const override;
   float GetLineHeight(CFWL_ThemePart* pThemePart) const override;
   float GetScrollBarWidth() const override;
   FX_COLORREF GetTextColor(CFWL_ThemePart* pThemePart) const override;
@@ -58,7 +59,7 @@
   std::unique_ptr<CFWL_CaretTP> m_pCaretTP;
   std::unique_ptr<CFWL_BarcodeTP> m_pBarcodeTP;
   std::unique_ptr<CFDE_TextOut> m_pTextOut;
-  CFGAS_GEFont* m_pCalendarFont;
+  CFX_RetainPtr<CFGAS_GEFont> m_pCalendarFont;
   CFX_WideString m_wsResource;
   CXFA_FFApp* const m_pApp;
   CFX_RectF m_Rect;
diff --git a/xfa/fxfa/app/xfa_textlayout.cpp b/xfa/fxfa/app/xfa_textlayout.cpp
index ea4ae4b..826fefc 100644
--- a/xfa/fxfa/app/xfa_textlayout.cpp
+++ b/xfa/fxfa/app/xfa_textlayout.cpp
@@ -376,8 +376,10 @@
   }
   return false;
 }
-CFGAS_GEFont* CXFA_TextParser::GetFont(CXFA_TextProvider* pTextProvider,
-                                       IFDE_CSSComputedStyle* pStyle) const {
+
+CFX_RetainPtr<CFGAS_GEFont> CXFA_TextParser::GetFont(
+    CXFA_TextProvider* pTextProvider,
+    IFDE_CSSComputedStyle* pStyle) const {
   CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
   uint32_t dwStyle = 0;
   CXFA_Font font = pTextProvider->GetFontNode();
diff --git a/xfa/fxfa/app/xfa_textlayout.h b/xfa/fxfa/app/xfa_textlayout.h
index f923c74..fa0ca66 100644
--- a/xfa/fxfa/app/xfa_textlayout.h
+++ b/xfa/fxfa/app/xfa_textlayout.h
@@ -92,8 +92,8 @@
   bool IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const;
   bool GetTabstops(IFDE_CSSComputedStyle* pStyle,
                    CXFA_TextTabstopsContext* pTabstopContext);
-  CFGAS_GEFont* GetFont(CXFA_TextProvider* pTextProvider,
-                        IFDE_CSSComputedStyle* pStyle) const;
+  CFX_RetainPtr<CFGAS_GEFont> GetFont(CXFA_TextProvider* pTextProvider,
+                                      IFDE_CSSComputedStyle* pStyle) const;
   FX_FLOAT GetFontSize(CXFA_TextProvider* pTextProvider,
                        IFDE_CSSComputedStyle* pStyle) const;
   int32_t GetHorScale(CXFA_TextProvider* pTextProvider,
@@ -210,7 +210,7 @@
   int32_t iUnderline;
   int32_t iPeriod;
   int32_t iLineThrough;
-  CFGAS_GEFont* pFont;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
   FX_ARGB dwColor;
   FX_FLOAT fFontSize;
   CFX_RectF rtPiece;
diff --git a/xfa/fxfa/fxfa_widget.h b/xfa/fxfa/fxfa_widget.h
index 9a0e66b..74c63c9 100644
--- a/xfa/fxfa/fxfa_widget.h
+++ b/xfa/fxfa/fxfa_widget.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxge/fx_dib.h"
 #include "xfa/fxfa/parser/cxfa_box.h"
@@ -75,7 +76,7 @@
   void UpdateUIDisplay(CXFA_FFWidget* pExcept = nullptr);
 
   CXFA_Node* GetDatasets();
-  CFGAS_GEFont* GetFDEFont();
+  CFX_RetainPtr<CFGAS_GEFont> GetFDEFont();
   FX_FLOAT GetFontSize();
   FX_ARGB GetTextColor();
   FX_FLOAT GetLineHeight();
diff --git a/xfa/fxfa/xfa_fontmgr.h b/xfa/fxfa/xfa_fontmgr.h
index a6a5822..f00b069 100644
--- a/xfa/fxfa/xfa_fontmgr.h
+++ b/xfa/fxfa/xfa_fontmgr.h
@@ -9,7 +9,9 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_ext.h"
 #include "core/fxcrt/fx_system.h"
 #include "xfa/fgas/font/cfgas_fontmgr.h"
@@ -30,17 +32,18 @@
   CXFA_DefFontMgr();
   ~CXFA_DefFontMgr();
 
-  CFGAS_GEFont* GetFont(CXFA_FFDoc* hDoc,
-                        const CFX_WideStringC& wsFontFamily,
-                        uint32_t dwFontStyles,
-                        uint16_t wCodePage = 0xFFFF);
-  CFGAS_GEFont* GetDefaultFont(CXFA_FFDoc* hDoc,
-                               const CFX_WideStringC& wsFontFamily,
-                               uint32_t dwFontStyles,
-                               uint16_t wCodePage = 0xFFFF);
+  CFX_RetainPtr<CFGAS_GEFont> GetFont(CXFA_FFDoc* hDoc,
+                                      const CFX_WideStringC& wsFontFamily,
+                                      uint32_t dwFontStyles,
+                                      uint16_t wCodePage = 0xFFFF);
+  CFX_RetainPtr<CFGAS_GEFont> GetDefaultFont(
+      CXFA_FFDoc* hDoc,
+      const CFX_WideStringC& wsFontFamily,
+      uint32_t dwFontStyles,
+      uint16_t wCodePage = 0xFFFF);
 
  protected:
-  CFX_ArrayTemplate<CFGAS_GEFont*> m_CacheFonts;
+  std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_CacheFonts;
 };
 
 class CXFA_PDFFontMgr {
@@ -48,22 +51,22 @@
   explicit CXFA_PDFFontMgr(CXFA_FFDoc* pDoc);
   ~CXFA_PDFFontMgr();
 
-  CFGAS_GEFont* GetFont(const CFX_WideStringC& wsFontFamily,
-                        uint32_t dwFontStyles,
-                        CPDF_Font** pPDFFont,
-                        bool bStrictMatch);
-  bool GetCharWidth(const CFGAS_GEFont* pFont,
+  CFX_RetainPtr<CFGAS_GEFont> GetFont(const CFX_WideStringC& wsFontFamily,
+                                      uint32_t dwFontStyles,
+                                      CPDF_Font** pPDFFont,
+                                      bool bStrictMatch);
+  bool GetCharWidth(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                     FX_WCHAR wUnicode,
                     bool bCharCode,
                     int32_t* pWidth);
-  void SetFont(const CFGAS_GEFont* pFont, CPDF_Font* pPDFFont);
+  void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont, CPDF_Font* pPDFFont);
 
  protected:
-  CFGAS_GEFont* FindFont(const CFX_ByteString& strFamilyName,
-                         bool bBold,
-                         bool bItalic,
-                         CPDF_Font** pPDFFont,
-                         bool bStrictMatch);
+  CFX_RetainPtr<CFGAS_GEFont> FindFont(const CFX_ByteString& strFamilyName,
+                                       bool bBold,
+                                       bool bItalic,
+                                       CPDF_Font** pPDFFont,
+                                       bool bStrictMatch);
   CFX_ByteString PsNameToFontName(const CFX_ByteString& strPsName,
                                   bool bBold,
                                   bool bItalic);
@@ -74,8 +77,8 @@
                              bool bStrictMatch);
 
   CXFA_FFDoc* const m_pDoc;
-  std::map<const CFGAS_GEFont*, CPDF_Font*> m_FDE2PDFFont;
-  std::map<CFX_ByteString, CFGAS_GEFont*> m_FontMap;
+  std::map<CFX_RetainPtr<CFGAS_GEFont>, CPDF_Font*> m_FDE2PDFFont;
+  std::map<CFX_ByteString, CFX_RetainPtr<CFGAS_GEFont>> m_FontMap;
 };
 
 class CXFA_FontMgr {
@@ -83,10 +86,10 @@
   CXFA_FontMgr();
   ~CXFA_FontMgr();
 
-  CFGAS_GEFont* GetFont(CXFA_FFDoc* hDoc,
-                        const CFX_WideStringC& wsFontFamily,
-                        uint32_t dwFontStyles,
-                        uint16_t wCodePage = 0xFFFF);
+  CFX_RetainPtr<CFGAS_GEFont> GetFont(CXFA_FFDoc* hDoc,
+                                      const CFX_WideStringC& wsFontFamily,
+                                      uint32_t dwFontStyles,
+                                      uint16_t wCodePage = 0xFFFF);
   void LoadDocFonts(CXFA_FFDoc* hDoc);
   void ReleaseDocFonts(CXFA_FFDoc* hDoc);
   void SetDefFontMgr(std::unique_ptr<CXFA_DefFontMgr> pFontMgr);
@@ -94,7 +97,7 @@
  protected:
   std::unique_ptr<CXFA_DefFontMgr> m_pDefFontMgr;
   std::map<CXFA_FFDoc*, std::unique_ptr<CXFA_PDFFontMgr>> m_PDFFontMgrMap;
-  std::map<CFX_ByteString, CFGAS_GEFont*> m_FontMap;
+  std::map<CFX_ByteString, CFX_RetainPtr<CFGAS_GEFont>> m_FontMap;
 };
 
 #endif  //  XFA_FXFA_XFA_FONTMGR_H_