Remove last usage of IFX_Retainable.

Change-Id: Id2ece818c80e8cce4748b9a237871131a7acd6d1
Reviewed-on: https://pdfium-review.googlesource.com/2354
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/core/fxcrt/fx_basic.h b/core/fxcrt/fx_basic.h
index 31850f5..18413b2 100644
--- a/core/fxcrt/fx_basic.h
+++ b/core/fxcrt/fx_basic.h
@@ -16,6 +16,10 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 
+#ifdef PDF_ENABLE_XFA
+#define FX_IsOdd(a) ((a)&1)
+#endif  // PDF_ENABLE_XFA
+
 class CFX_BinaryBuf {
  public:
   CFX_BinaryBuf();
@@ -352,9 +356,7 @@
 
  protected:
   uint32_t m_BitPos;
-
   uint32_t m_BitSize;
-
   const uint8_t* m_pData;
 };
 
@@ -500,18 +502,6 @@
                               FX_FILESIZE>
     CFX_FileSizeListArray;
 
-#ifdef PDF_ENABLE_XFA
-class IFX_Retainable {
- public:
-  virtual uint32_t Retain() = 0;
-  virtual uint32_t Release() = 0;
-
- protected:
-  virtual ~IFX_Retainable() {}
-};
-#define FX_IsOdd(a) ((a)&1)
-#endif  // PDF_ENABLE_XFA
-
 class CFX_Vector_3by1 {
  public:
   CFX_Vector_3by1() : a(0.0f), b(0.0f), c(0.0f) {}
diff --git a/core/fxcrt/fx_ucd.h b/core/fxcrt/fx_ucd.h
index 798658f..709e788 100644
--- a/core/fxcrt/fx_ucd.h
+++ b/core/fxcrt/fx_ucd.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXCRT_FX_UCD_H_
 #define CORE_FXCRT_FX_UCD_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 
 #define FX_BIDICLASSBITS 6
@@ -170,6 +171,7 @@
  public:
   CFX_RTFChar();
   CFX_RTFChar(const CFX_RTFChar& other);
+  ~CFX_RTFChar();
 
   uint32_t m_dwStatus;
   int32_t m_iFontSize;
@@ -180,7 +182,7 @@
   int16_t m_iBidiOrder;
   uint32_t m_dwLayoutStyles;
   uint32_t m_dwIdentity;
-  IFX_Retainable* m_pUserData;
+  CFX_RetainPtr<CFX_Retainable> m_pUserData;
 };
 
 inline CFX_RTFChar::CFX_RTFChar()
@@ -195,6 +197,7 @@
       m_pUserData(nullptr) {}
 
 inline CFX_RTFChar::CFX_RTFChar(const CFX_RTFChar& other) = default;
+inline CFX_RTFChar::~CFX_RTFChar() = default;
 
 #endif  // PDF_ENABLE_XFA
 
diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp
index e01578b..7463eaa 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.cpp
+++ b/xfa/fgas/layout/fgas_rtfbreak.cpp
@@ -57,8 +57,6 @@
 CFX_RTFBreak::~CFX_RTFBreak() {
   Reset();
   m_PositionedTabs.RemoveAll();
-  if (m_pUserData)
-    m_pUserData->Release();
 }
 
 void CFX_RTFBreak::SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) {
@@ -244,20 +242,17 @@
          iAlignment <= FX_RTFLINEALIGNMENT_Distributed);
   m_iAlignment = iAlignment;
 }
-void CFX_RTFBreak::SetUserData(IFX_Retainable* pUserData) {
-  if (m_pUserData == pUserData) {
+
+void CFX_RTFBreak::SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData) {
+  if (m_pUserData == pUserData)
     return;
-  }
+
   SetBreakStatus();
-  if (m_pUserData) {
-    m_pUserData->Release();
-  }
   m_pUserData = pUserData;
-  if (m_pUserData) {
-    m_pUserData->Retain();
-  }
 }
+
 static const int32_t gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
+
 int32_t CFX_RTFBreak::GetLineRotation(uint32_t dwStyles) const {
   return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1];
 }
@@ -362,9 +357,6 @@
   pCurChar->m_nRotation = m_iCharRotation;
   pCurChar->m_iCharWidth = 0;
   pCurChar->m_dwIdentity = m_dwIdentity;
-  if (m_pUserData) {
-    m_pUserData->Retain();
-  }
   pCurChar->m_pUserData = m_pUserData;
   uint32_t dwRet1 = FX_RTFBREAK_None;
   if (chartype != FX_CHARTYPE_Combination &&
@@ -410,9 +402,6 @@
   pCurChar->m_nRotation = m_iCharRotation;
   pCurChar->m_iCharWidth = 0;
   pCurChar->m_dwIdentity = m_dwIdentity;
-  if (m_pUserData)
-    m_pUserData->Retain();
-
   pCurChar->m_pUserData = m_pUserData;
   int32_t iCharWidth = 0;
   if (m_bVertical != FX_IsOdd(m_iRotation)) {
diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h
index 613156a..15fdbb8 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.h
+++ b/xfa/fgas/layout/fgas_rtfbreak.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 #include "core/fxcrt/fx_ucd.h"
 #include "xfa/fgas/crt/fgas_utils.h"
@@ -163,7 +164,7 @@
   uint32_t m_dwLayoutStyles;
   uint32_t m_dwIdentity;
   std::vector<CFX_RTFChar>* m_pChars;  // not owned.
-  IFX_Retainable* m_pUserData;
+  CFX_RetainPtr<CFX_Retainable> m_pUserData;
 };
 
 typedef CFX_BaseArrayTemplate<CFX_RTFPiece> CFX_RTFPieceArray;
@@ -195,12 +196,6 @@
   }
   int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
   void RemoveAll(bool bLeaveMemory = false) {
-    int32_t iCount = pdfium::CollectionSize<int32_t>(m_LineChars);
-    for (int32_t i = 0; i < iCount; i++) {
-      CFX_RTFChar* pChar = &m_LineChars[i];
-      if (pChar->m_pUserData)
-        pChar->m_pUserData->Release();
-    }
     m_LineChars.clear();
     m_LinePieces.RemoveAll(bLeaveMemory);
     m_iWidth = 0;
@@ -241,7 +236,7 @@
   void SetWordSpace(bool bDefault, FX_FLOAT fWordSpace);
   void SetReadingOrder(bool bRTL = false);
   void SetAlignment(int32_t iAlignment = FX_RTFLINEALIGNMENT_Left);
-  void SetUserData(IFX_Retainable* pUserData);
+  void SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData);
   uint32_t AppendChar(FX_WCHAR wch);
   uint32_t EndBreak(uint32_t dwStatus = FX_RTFBREAK_PieceBreak);
   int32_t CountBreakPieces() const;
@@ -316,7 +311,7 @@
   int32_t m_iWordSpace;
   bool m_bRTL;
   int32_t m_iAlignment;
-  IFX_Retainable* m_pUserData;
+  CFX_RetainPtr<CFX_Retainable> m_pUserData;
   FX_CHARTYPE m_eCharType;
   uint32_t m_dwIdentity;
   CFX_RTFLine m_RTFLine1;
diff --git a/xfa/fxfa/app/cxfa_linkuserdata.cpp b/xfa/fxfa/app/cxfa_linkuserdata.cpp
index f1e15f4..4128cd8 100644
--- a/xfa/fxfa/app/cxfa_linkuserdata.cpp
+++ b/xfa/fxfa/app/cxfa_linkuserdata.cpp
@@ -7,21 +7,6 @@
 #include "xfa/fxfa/app/cxfa_linkuserdata.h"
 
 CXFA_LinkUserData::CXFA_LinkUserData(FX_WCHAR* pszText)
-    : m_dwRefCount(1), m_wsURLContent(pszText) {}
+    : m_wsURLContent(pszText) {}
 
 CXFA_LinkUserData::~CXFA_LinkUserData() {}
-
-uint32_t CXFA_LinkUserData::Retain() {
-  return ++m_dwRefCount;
-}
-
-uint32_t CXFA_LinkUserData::Release() {
-  uint32_t dwRefCount = --m_dwRefCount;
-  if (dwRefCount <= 0)
-    delete this;
-  return dwRefCount;
-}
-
-const FX_WCHAR* CXFA_LinkUserData::GetLinkURL() {
-  return m_wsURLContent.c_str();
-}
diff --git a/xfa/fxfa/app/cxfa_linkuserdata.h b/xfa/fxfa/app/cxfa_linkuserdata.h
index 621398e..852b467 100644
--- a/xfa/fxfa/app/cxfa_linkuserdata.h
+++ b/xfa/fxfa/app/cxfa_linkuserdata.h
@@ -7,23 +7,22 @@
 #ifndef XFA_FXFA_APP_CXFA_LINKUSERDATA_H_
 #define XFA_FXFA_APP_CXFA_LINKUSERDATA_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 
-class CXFA_LinkUserData : public IFX_Retainable {
+class CXFA_LinkUserData : public CFX_Retainable {
  public:
+  template <typename T, typename... Args>
+  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  const FX_WCHAR* GetLinkURL() const { return m_wsURLContent.c_str(); }
+
+ protected:
   explicit CXFA_LinkUserData(FX_WCHAR* pszText);
   ~CXFA_LinkUserData() override;
 
-  // IFX_Retainable:
-  uint32_t Retain() override;
-  uint32_t Release() override;
-
-  const FX_WCHAR* GetLinkURL();
-
- protected:
-  uint32_t m_dwRefCount;
   CFX_WideString m_wsURLContent;
 };
 
diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp
index cc9c653..86f49ed 100644
--- a/xfa/fxfa/app/cxfa_textlayout.cpp
+++ b/xfa/fxfa/app/cxfa_textlayout.cpp
@@ -476,7 +476,7 @@
       for (; pXMLNode;
            pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
         if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
-                          true)) {
+                          true, nullptr)) {
           break;
         }
       }
@@ -495,7 +495,7 @@
         for (; pXMLNode;
              pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
           if (!LoadRichText(pXMLNode, szText, fLinePos,
-                            m_pLoader->m_pParentStyle, true)) {
+                            m_pLoader->m_pParentStyle, true, nullptr)) {
             break;
           }
         }
@@ -655,7 +655,8 @@
         m_textParser.DoParse(pXMLContainer, m_pTextProvider);
 
       auto pRootStyle = m_textParser.CreateRootStyle(m_pTextProvider);
-      LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
+      LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces,
+                   nullptr);
     }
   } else {
     LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces);
@@ -702,7 +703,7 @@
     FX_FLOAT& fLinePos,
     const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle,
     bool bSavePieces,
-    CXFA_LinkUserData* pLinkData,
+    CFX_RetainPtr<CXFA_LinkUserData> pLinkData,
     bool bEndBreak,
     bool bIsOl,
     int32_t iLiCount) {
@@ -764,7 +765,7 @@
           ASSERT(pElement);
           pElement->GetString(L"href", wsLinkContent);
           if (!wsLinkContent.IsEmpty()) {
-            pLinkData = new CXFA_LinkUserData(
+            pLinkData = pdfium::MakeRetain<CXFA_LinkUserData>(
                 wsLinkContent.GetBuffer(wsLinkContent.GetLength()));
             wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
           }
@@ -818,10 +819,7 @@
 
         if (wsText.GetLength() > 0) {
           if (!m_pLoader || m_pLoader->m_iChar == 0) {
-            if (pLinkData)
-              pLinkData->Retain();
-
-            CXFA_TextUserData* pUserData = new CXFA_TextUserData(
+            auto pUserData = pdfium::MakeRetain<CXFA_TextUserData>(
                 bContentNode ? pParentStyle : pStyle, pLinkData);
             m_pBreak->SetUserData(pUserData);
           }
@@ -877,12 +875,6 @@
         if (m_pTabstopContext)
           m_pTabstopContext->RemoveAll();
       }
-      if (wsName == FX_WSTRC(L"a")) {
-        if (pLinkData) {
-          pLinkData->Release();
-          pLinkData = nullptr;
-        }
-      }
       if (IsEnd(bSavePieces)) {
         if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
           m_pLoader->m_pXMLNode =
@@ -1042,7 +1034,8 @@
     int32_t i = 0;
     for (i = 0; i < iPieces; i++) {
       const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
-      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+      CXFA_TextUserData* pUserData =
+          static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get());
       if (pUserData)
         pStyle = pUserData->m_pStyle;
       FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
@@ -1082,12 +1075,7 @@
         fBaseLine = -fBaseLineTemp;
       }
       fLineStep = std::max(fLineStep, fLineHeight);
-      if (pUserData && pUserData->m_pLinkData) {
-        pUserData->m_pLinkData->Retain();
-        pTP->pLinkData = pUserData->m_pLinkData;
-      } else {
-        pTP->pLinkData = nullptr;
-      }
+      pTP->pLinkData = pUserData ? pUserData->m_pLinkData : nullptr;
       pPieceLine->m_textPieces.push_back(std::move(pTP));
       DoTabstops(pStyle.Get(), pPieceLine);
     }
@@ -1103,7 +1091,8 @@
     FX_FLOAT fLineWidth = 0;
     for (int32_t i = 0; i < iPieces; i++) {
       const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
-      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+      CXFA_TextUserData* pUserData =
+          static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get());
       if (pUserData)
         pStyle = pUserData->m_pStyle;
       FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
diff --git a/xfa/fxfa/app/cxfa_textlayout.h b/xfa/fxfa/app/cxfa_textlayout.h
index a9d45f2..1210056 100644
--- a/xfa/fxfa/app/cxfa_textlayout.h
+++ b/xfa/fxfa/app/cxfa_textlayout.h
@@ -84,7 +84,7 @@
                     FX_FLOAT& fLinePos,
                     const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle,
                     bool bSavePieces,
-                    CXFA_LinkUserData* pLinkData = nullptr,
+                    CFX_RetainPtr<CXFA_LinkUserData> pLinkData,
                     bool bEndBreak = true,
                     bool bIsOl = false,
                     int32_t iLiCount = 0);
diff --git a/xfa/fxfa/app/cxfa_textuserdata.cpp b/xfa/fxfa/app/cxfa_textuserdata.cpp
index e436ab2..e4e5493 100644
--- a/xfa/fxfa/app/cxfa_textuserdata.cpp
+++ b/xfa/fxfa/app/cxfa_textuserdata.cpp
@@ -13,25 +13,11 @@
 
 CXFA_TextUserData::CXFA_TextUserData(
     const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle)
-    : m_pStyle(pStyle), m_pLinkData(nullptr), m_dwRefCount(0) {}
+    : m_pStyle(pStyle) {}
 
 CXFA_TextUserData::CXFA_TextUserData(
     const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle,
-    CXFA_LinkUserData* pLinkData)
-    : m_pStyle(pStyle), m_pLinkData(pLinkData), m_dwRefCount(0) {}
+    const CFX_RetainPtr<CXFA_LinkUserData>& pLinkData)
+    : m_pStyle(pStyle), m_pLinkData(pLinkData) {}
 
-CXFA_TextUserData::~CXFA_TextUserData() {
-  if (m_pLinkData)
-    m_pLinkData->Release();
-}
-
-uint32_t CXFA_TextUserData::Retain() {
-  return ++m_dwRefCount;
-}
-
-uint32_t CXFA_TextUserData::Release() {
-  uint32_t dwRefCount = --m_dwRefCount;
-  if (dwRefCount == 0)
-    delete this;
-  return dwRefCount;
-}
+CXFA_TextUserData::~CXFA_TextUserData() {}
diff --git a/xfa/fxfa/app/cxfa_textuserdata.h b/xfa/fxfa/app/cxfa_textuserdata.h
index 1eb3b8a..b0eff73 100644
--- a/xfa/fxfa/app/cxfa_textuserdata.h
+++ b/xfa/fxfa/app/cxfa_textuserdata.h
@@ -7,28 +7,26 @@
 #ifndef XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
 #define XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 
 class CFDE_CSSComputedStyle;
 class CXFA_LinkUserData;
 
-class CXFA_TextUserData : public IFX_Retainable {
+class CXFA_TextUserData : public CFX_Retainable {
  public:
+  template <typename T, typename... Args>
+  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  CFX_RetainPtr<CFDE_CSSComputedStyle> m_pStyle;
+  CFX_RetainPtr<CXFA_LinkUserData> m_pLinkData;
+
+ protected:
   explicit CXFA_TextUserData(
       const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle);
   CXFA_TextUserData(const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle,
-                    CXFA_LinkUserData* pLinkData);
+                    const CFX_RetainPtr<CXFA_LinkUserData>& pLinkData);
   ~CXFA_TextUserData() override;
-
-  // IFX_Retainable:
-  uint32_t Retain() override;
-  uint32_t Release() override;
-
-  CFX_RetainPtr<CFDE_CSSComputedStyle> m_pStyle;
-  CXFA_LinkUserData* m_pLinkData;
-
- protected:
-  uint32_t m_dwRefCount;
 };
 
 #endif  // XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_
diff --git a/xfa/fxfa/app/xfa_textpiece.cpp b/xfa/fxfa/app/xfa_textpiece.cpp
index 933af6c..e65cc16 100644
--- a/xfa/fxfa/app/xfa_textpiece.cpp
+++ b/xfa/fxfa/app/xfa_textpiece.cpp
@@ -9,12 +9,9 @@
 #include "xfa/fxfa/app/cxfa_linkuserdata.h"
 
 XFA_TextPiece::XFA_TextPiece()
-    : pszText(nullptr), pWidths(nullptr), pFont(nullptr), pLinkData(nullptr) {}
+    : pszText(nullptr), pWidths(nullptr), pFont(nullptr) {}
 
 XFA_TextPiece::~XFA_TextPiece() {
-  if (pLinkData)
-    pLinkData->Release();
-
   FX_Free(pszText);
   FX_Free(pWidths);
 }
diff --git a/xfa/fxfa/app/xfa_textpiece.h b/xfa/fxfa/app/xfa_textpiece.h
index 2b74155..6c7b3d4 100644
--- a/xfa/fxfa/app/xfa_textpiece.h
+++ b/xfa/fxfa/app/xfa_textpiece.h
@@ -29,11 +29,11 @@
   int32_t iUnderline;
   int32_t iPeriod;
   int32_t iLineThrough;
-  CFX_RetainPtr<CFGAS_GEFont> pFont;
   FX_ARGB dwColor;
   FX_FLOAT fFontSize;
   CFX_RectF rtPiece;
-  CXFA_LinkUserData* pLinkData;
+  CFX_RetainPtr<CFGAS_GEFont> pFont;
+  CFX_RetainPtr<CXFA_LinkUserData> pLinkData;
 };
 
 #endif  // XFA_FXFA_APP_XFA_TEXTPIECE_H_