Use RetainableTreeNode for LayoutItems.

Removes explicit deletes.

The CL at https://pdfium-review.googlesource.com/c/pdfium/+/54790
fixes a lifetime issue with TT faces that was exposed by this CL.

Update a few places where the FF widgets go away earlier.

Change-Id: I52ba800af7044a418365fa1df6cf56065103fed9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/54190
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_interactiveform.cpp b/fpdfsdk/cpdfsdk_interactiveform.cpp
index 6d65d57..b33bd06 100644
--- a/fpdfsdk/cpdfsdk_interactiveform.cpp
+++ b/fpdfsdk/cpdfsdk_interactiveform.cpp
@@ -235,8 +235,8 @@
 }
 
 void CPDFSDK_InteractiveForm::RemoveXFAMap(CXFA_FFWidget* hWidget) {
-  ASSERT(hWidget);
-  m_XFAMap.erase(hWidget);
+  if (hWidget)
+    m_XFAMap.erase(hWidget);
 }
 
 CPDFSDK_XFAWidget* CPDFSDK_InteractiveForm::GetXFAWidget(
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutitem.h b/xfa/fxfa/layout/cxfa_contentlayoutitem.h
index c83ec3f..063f9a3 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutitem.h
+++ b/xfa/fxfa/layout/cxfa_contentlayoutitem.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
 
@@ -16,8 +17,9 @@
 
 class CXFA_ContentLayoutItem : public CXFA_LayoutItem {
  public:
-  CXFA_ContentLayoutItem(CXFA_Node* pNode,
-                         std::unique_ptr<CXFA_FFWidget> pFFWidget);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CXFA_ContentLayoutItem() override;
 
   CXFA_FFWidget* GetFFWidget() { return m_pFFWidget.get(); }
@@ -41,6 +43,9 @@
   CFX_SizeF m_sSize;
 
  private:
+  CXFA_ContentLayoutItem(CXFA_Node* pNode,
+                         std::unique_ptr<CXFA_FFWidget> pFFWidget);
+
   void RemoveSelf();
 
   mutable uint32_t m_dwStatus = 0;
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
index 866cbdf..52e763b 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
@@ -184,7 +184,7 @@
   return inset;
 }
 
-void RelocateTableRowCells(CXFA_ContentLayoutItem* pLayoutRow,
+void RelocateTableRowCells(const RetainPtr<CXFA_ContentLayoutItem>& pLayoutRow,
                            const std::vector<float>& rgSpecifiedColumnWidths,
                            XFA_AttributeValue eLayout) {
   bool bContainerWidthAutoSize = true;
@@ -436,13 +436,12 @@
   CXFA_NodeIterator sIterator(pGenerateNode);
   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
        pNode = sIterator.MoveToNext()) {
-    CXFA_ContentLayoutItem* pCurLayoutItem =
-        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem());
+    RetainPtr<CXFA_ContentLayoutItem> pCurLayoutItem(
+        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem()));
     while (pCurLayoutItem) {
       CXFA_ContentLayoutItem* pNextLayoutItem = pCurLayoutItem->GetNext();
-      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
-      delete pCurLayoutItem;
-      pCurLayoutItem = pNextLayoutItem;
+      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem.Get());
+      pCurLayoutItem.Reset(pNextLayoutItem);
     }
   }
   pGenerateNode->GetParent()->RemoveChildAndNotify(pGenerateNode, true);
@@ -624,35 +623,34 @@
   ASSERT(GetFormNode());
   ASSERT(GetFormNode()->IsContainerNode() ||
          GetFormNode()->GetElementType() == XFA_Element::Form);
-  m_pOldLayoutItem =
-      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem());
+  m_pOldLayoutItem.Reset(
+      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem()));
 }
 
 CXFA_ContentLayoutProcessor::~CXFA_ContentLayoutProcessor() {}
 
-CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::CreateContentLayoutItem(
-    CXFA_Node* pFormNode) {
+RetainPtr<CXFA_ContentLayoutItem>
+CXFA_ContentLayoutProcessor::CreateContentLayoutItem(CXFA_Node* pFormNode) {
   if (!pFormNode)
     return nullptr;
 
-  CXFA_ContentLayoutItem* pLayoutItem = nullptr;
   if (m_pOldLayoutItem) {
-    pLayoutItem = m_pOldLayoutItem;
-    m_pOldLayoutItem = m_pOldLayoutItem->GetNext();
+    RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pOldLayoutItem;
+    m_pOldLayoutItem.Reset(m_pOldLayoutItem->GetNext());
     return pLayoutItem;
   }
   CXFA_FFNotify* pNotify = pFormNode->GetDocument()->GetNotify();
-  pLayoutItem = pdfium::MakeUnique<CXFA_ContentLayoutItem>(
-                    pFormNode, pNotify->OnCreateContentLayoutItem(pFormNode))
-                    .release();
+  auto pNewLayoutItem = pdfium::MakeRetain<CXFA_ContentLayoutItem>(
+      pFormNode, pNotify->OnCreateContentLayoutItem(pFormNode));
+
   CXFA_ContentLayoutItem* pPrevLayoutItem =
       ToContentLayoutItem(pFormNode->JSObject()->GetLayoutItem());
   if (pPrevLayoutItem) {
-    pPrevLayoutItem->GetLast()->InsertAfter(pLayoutItem);
+    pPrevLayoutItem->GetLast()->InsertAfter(pNewLayoutItem.Get());
   } else {
-    pFormNode->JSObject()->SetLayoutItem(pLayoutItem);
+    pFormNode->JSObject()->SetLayoutItem(pNewLayoutItem.Get());
   }
-  return pLayoutItem;
+  return pNewLayoutItem;
 }
 
 float CXFA_ContentLayoutProcessor::FindSplitPos(float fProposedSplitPos) {
@@ -662,7 +660,7 @@
   bool bCalculateMargin = eLayout != XFA_AttributeValue::Position;
   while (fProposedSplitPos > kXFALayoutPrecision) {
     bool bAppChange = false;
-    if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, &fProposedSplitPos,
+    if (!FindLayoutItemSplitPos(m_pLayoutItem.Get(), 0, &fProposedSplitPos,
                                 &bAppChange, bCalculateMargin)) {
       break;
     }
@@ -692,7 +690,7 @@
         XFA_Attribute::BottomInset, XFA_Unit::Pt);
   }
 
-  CXFA_ContentLayoutItem* pSecondLayoutItem = nullptr;
+  RetainPtr<CXFA_ContentLayoutItem> pSecondLayoutItem;
   if (m_pCurChildPreprocessor &&
       m_pCurChildPreprocessor->GetFormNode() == pLayoutItem->GetFormNode()) {
     pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
@@ -733,16 +731,16 @@
     bOrphanedItem = true;
   }
 
-  std::vector<CXFA_ContentLayoutItem*> children;
+  std::vector<RetainPtr<CXFA_ContentLayoutItem>> children;
   while (auto* pFirst = ToContentLayoutItem(pLayoutItem->GetFirstChild())) {
-    children.push_back(pFirst);
-    pLayoutItem->RemoveChild(pFirst);
+    children.emplace_back(pFirst);
+    pLayoutItem->RemoveChild(children.back());
   }
 
   float lHeightForKeep = 0;
   float fAddMarginHeight = 0;
-  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
-  for (auto* pChildItem : children) {
+  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
+  for (auto& pChildItem : children) {
     if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                          kXFALayoutPrecision) {
       if (!ExistContainerKeep(pChildItem->GetFormNode(), true)) {
@@ -753,7 +751,7 @@
         continue;
       }
       if (lHeightForKeep < kXFALayoutPrecision) {
-        for (auto* pPreItem : keepLayoutItems) {
+        for (auto& pPreItem : keepLayoutItems) {
           pLayoutItem->RemoveChild(pPreItem);
           pPreItem->m_sPos.y -= fSplitPos;
           if (pPreItem->m_sPos.y < 0)
@@ -787,7 +785,7 @@
 
     float fOldHeight = pSecondLayoutItem->m_sSize.height;
     SplitLayoutItem(
-        pChildItem, pSecondLayoutItem,
+        pChildItem.Get(), pSecondLayoutItem.Get(),
         fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
     fAddMarginHeight = pSecondLayoutItem->m_sSize.height - fOldHeight;
     pLayoutItem->AppendLastChild(pChildItem);
@@ -798,13 +796,14 @@
 
 void CXFA_ContentLayoutProcessor::SplitLayoutItem(float fSplitPos) {
   ASSERT(m_pLayoutItem);
-  SplitLayoutItem(m_pLayoutItem, nullptr, fSplitPos);
+  SplitLayoutItem(m_pLayoutItem.Get(), nullptr, fSplitPos);
 }
 
-CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
-  CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
+RetainPtr<CXFA_ContentLayoutItem>
+CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
+  RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pLayoutItem;
   if (pLayoutItem) {
-    m_pLayoutItem = ToContentLayoutItem(pLayoutItem->GetNextSibling());
+    m_pLayoutItem.Reset(ToContentLayoutItem(pLayoutItem->GetNextSibling()));
     pLayoutItem->RemoveSelfIfParented();
   }
   if (m_nCurChildNodeStage != Stage::kDone || !m_pOldLayoutItem)
@@ -816,13 +815,12 @@
       m_pOldLayoutItem->GetFormNode()->GetDocument());
 
   while (m_pOldLayoutItem) {
-    CXFA_ContentLayoutItem* pToDeleteItem = m_pOldLayoutItem;
-    m_pOldLayoutItem = pToDeleteItem->GetNext();
+    RetainPtr<CXFA_ContentLayoutItem> pToDeleteItem = m_pOldLayoutItem;
+    m_pOldLayoutItem.Reset(pToDeleteItem->GetNext());
     if (pToDeleteItem == pLayoutItem)
       break;
-    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem);
+    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem.Get());
     pToDeleteItem->RemoveSelfIfParented();
-    delete pToDeleteItem;
   }
   return pLayoutItem;
 }
@@ -994,21 +992,21 @@
 
     pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos(
         pCurChildNode, pProcessor->GetCurrentComponentSize()));
-    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
+    RetainPtr<CXFA_LayoutItem> pProcessItem = pProcessor->ExtractLayoutItem();
     if (!pBeforeItem)
       pPageAreaLayoutItem->AppendFirstChild(pProcessItem);
     else
       pPageAreaLayoutItem->InsertAfter(pProcessItem, pBeforeItem);
 
-    pBeforeItem = pProcessItem;
+    pBeforeItem = pProcessItem.Get();
   }
 
   pBeforeItem = nullptr;
-  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->GetFirstChild();
+  RetainPtr<CXFA_LayoutItem> pLayoutItem(pPageAreaLayoutItem->GetFirstChild());
   while (pLayoutItem) {
     if (!pLayoutItem->IsContentLayoutItem() ||
         pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw) {
-      pLayoutItem = pLayoutItem->GetNextSibling();
+      pLayoutItem.Reset(pLayoutItem->GetNextSibling());
       continue;
     }
     if (pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw)
@@ -1021,8 +1019,8 @@
     else
       pPageAreaLayoutItem->InsertAfter(pLayoutItem, pBeforeItem);
 
-    pBeforeItem = pLayoutItem;
-    pLayoutItem = pNextLayoutItem;
+    pBeforeItem = pLayoutItem.Get();
+    pLayoutItem.Reset(pNextLayoutItem);
   }
 }
 
@@ -1299,10 +1297,9 @@
   float fCurrentRowY = 0;
   for (CXFA_LayoutItem* pIter = m_pLayoutItem->GetFirstChild(); pIter;
        pIter = pIter->GetNextSibling()) {
-    CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
-    if (!pLayoutChild)
-      continue;
-    if (!pLayoutChild->GetFormNode()->PresenceRequiresSpace())
+    RetainPtr<CXFA_ContentLayoutItem> pLayoutChild(
+        pIter->AsContentLayoutItem());
+    if (!pLayoutChild || !pLayoutChild->GetFormNode()->PresenceRequiresSpace())
       continue;
 
     if (pLayoutChild->GetFormNode()->GetElementType() == XFA_Element::Subform) {
@@ -1371,7 +1368,7 @@
 }
 
 float CXFA_ContentLayoutProcessor::InsertKeepLayoutItems() {
-  if (m_arrayKeepItems.empty())
+  if (m_ArrayKeepItems.empty())
     return 0;
 
   if (!m_pLayoutItem) {
@@ -1380,12 +1377,12 @@
   }
 
   float fTotalHeight = 0;
-  for (auto iter = m_arrayKeepItems.rbegin(); iter != m_arrayKeepItems.rend();
+  for (auto iter = m_ArrayKeepItems.rbegin(); iter != m_ArrayKeepItems.rend();
        iter++) {
     AddLeaderAfterSplit(*iter);
     fTotalHeight += (*iter)->m_sSize.height;
   }
-  m_arrayKeepItems.clear();
+  m_ArrayKeepItems.clear();
 
   return fTotalHeight;
 }
@@ -1393,7 +1390,7 @@
 bool CXFA_ContentLayoutProcessor::ProcessKeepForSplit(
     CXFA_ContentLayoutProcessor* pChildProcessor,
     Result eRetValue,
-    std::vector<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem,
+    std::vector<RetainPtr<CXFA_ContentLayoutItem>>* rgCurLineLayoutItem,
     float* fContentCurRowAvailWidth,
     float* fContentCurRowHeight,
     float* fContentCurRowY,
@@ -1411,14 +1408,14 @@
     return false;
 
   CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize();
-  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
-  if (JudgePutNextPage(m_pLayoutItem, childSize.height, &keepLayoutItems)) {
-    m_arrayKeepItems.clear();
-
-    for (auto* item : keepLayoutItems) {
+  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
+  if (JudgePutNextPage(m_pLayoutItem.Get(), childSize.height,
+                       &keepLayoutItems)) {
+    m_ArrayKeepItems.clear();
+    for (auto& item : keepLayoutItems) {
       m_pLayoutItem->RemoveChild(item);
       *fContentCurRowY -= item->m_sSize.height;
-      m_arrayKeepItems.push_back(item);
+      m_ArrayKeepItems.push_back(item);
     }
     *bAddedItemInRow = true;
     *bForceEndPage = true;
@@ -1437,14 +1434,15 @@
 bool CXFA_ContentLayoutProcessor::JudgePutNextPage(
     CXFA_ContentLayoutItem* pParentLayoutItem,
     float fChildHeight,
-    std::vector<CXFA_ContentLayoutItem*>* pKeepItems) {
+    std::vector<RetainPtr<CXFA_ContentLayoutItem>>* pKeepItems) {
   if (!pParentLayoutItem)
     return false;
 
   float fItemsHeight = 0;
   for (CXFA_LayoutItem* pIter = pParentLayoutItem->GetFirstChild(); pIter;
        pIter = pIter->GetNextSibling()) {
-    CXFA_ContentLayoutItem* pChildLayoutItem = pIter->AsContentLayoutItem();
+    RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem(
+        pIter->AsContentLayoutItem());
     if (!pChildLayoutItem)
       continue;
 
@@ -1481,7 +1479,7 @@
 void CXFA_ContentLayoutProcessor::ProcessUnUseOverFlow(
     CXFA_Node* pLeaderNode,
     CXFA_Node* pTrailerNode,
-    CXFA_ContentLayoutItem* pTrailerItem,
+    const RetainPtr<CXFA_ContentLayoutItem>& pTrailerItem,
     CXFA_Node* pFormNode) {
   ProcessUnUseBinds(pLeaderNode);
   ProcessUnUseBinds(pTrailerNode);
@@ -1561,7 +1559,7 @@
     float fContentCurRowHeight = 0;
     float fContentCurRowAvailWidth = fContentWidthLimit;
     m_fWidthLimit = fContentCurRowAvailWidth;
-    std::vector<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3];
+    std::vector<RetainPtr<CXFA_ContentLayoutItem>> rgCurLineLayoutItems[3];
     uint8_t uCurHAlignState =
         (eFlowStrategy != XFA_AttributeValue::Rl_tb ? 0 : 2);
     if (pLastChild) {
@@ -1574,14 +1572,15 @@
             m_pCurChildPreprocessor->GetFormNode() ==
                 pLayoutNext->GetFormNode()) {
           if (m_pCurChildPreprocessor->m_pLayoutItem)
-            pLayoutNext->InsertAfter(m_pCurChildPreprocessor->m_pLayoutItem);
-          m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
+            pLayoutNext->InsertAfter(
+                m_pCurChildPreprocessor->m_pLayoutItem.Get());
+          m_pCurChildPreprocessor->m_pLayoutItem.Reset(pLayoutNext);
           break;
         }
         uint8_t uHAlign =
             HAlignEnumToInt(pLayoutNext->GetFormNode()->JSObject()->GetEnum(
                 XFA_Attribute::HAlign));
-        rgCurLineLayoutItems[uHAlign].push_back(pLayoutNext);
+        rgCurLineLayoutItems[uHAlign].emplace_back(pLayoutNext);
         if (eFlowStrategy == XFA_AttributeValue::Lr_tb) {
           if (uHAlign > uCurHAlignState)
             uCurHAlignState = uHAlign;
@@ -1595,12 +1594,12 @@
         }
       }
 
-      CXFA_ContentLayoutItem* pLayoutNextTemp = pLastChild;
+      RetainPtr<CXFA_ContentLayoutItem> pLayoutNextTemp(pLastChild);
       while (pLayoutNextTemp) {
         CXFA_ContentLayoutItem* pSaveLayoutNext =
             ToContentLayoutItem(pLayoutNextTemp->GetNextSibling());
         pLayoutNextTemp->RemoveSelfIfParented();
-        pLayoutNextTemp = pSaveLayoutNext;
+        pLayoutNextTemp.Reset(pSaveLayoutNext);
       }
       pLastChild = nullptr;
     }
@@ -1614,7 +1613,7 @@
         case Stage::kNone:
           break;
         case Stage::kBreakBefore: {
-          for (auto* item : m_arrayKeepItems) {
+          for (auto& item : m_ArrayKeepItems) {
             m_pLayoutItem->RemoveChild(item);
             calculated_size.height -= item->m_sSize.height;
           }
@@ -1871,7 +1870,7 @@
 }
 
 bool CXFA_ContentLayoutProcessor::CalculateRowChildPosition(
-    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
+    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
     XFA_AttributeValue eFlowStrategy,
     bool bContainerHeightAutoSize,
     bool bContainerWidthAutoSize,
@@ -2132,7 +2131,7 @@
 }
 
 void CXFA_ContentLayoutProcessor::UpdatePendingItemLayout(
-    CXFA_ContentLayoutItem* pLayoutItem) {
+    const RetainPtr<CXFA_ContentLayoutItem>& pLayoutItem) {
   XFA_AttributeValue eLayout =
       pLayoutItem->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
   switch (eLayout) {
@@ -2147,7 +2146,7 @@
 
 void CXFA_ContentLayoutProcessor::AddTrailerBeforeSplit(
     float fSplitPos,
-    CXFA_ContentLayoutItem* pTrailerLayoutItem,
+    const RetainPtr<CXFA_ContentLayoutItem>& pTrailerLayoutItem,
     bool bUseInherited) {
   if (!pTrailerLayoutItem)
     return;
@@ -2166,7 +2165,7 @@
   CXFA_Margin* pMargin =
       GetFormNode()->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
   CFX_FloatRect inset = GetMarginInset(pMargin);
-  if (!IsAddNewRowForTrailer(pTrailerLayoutItem)) {
+  if (!IsAddNewRowForTrailer(pTrailerLayoutItem.Get())) {
     pTrailerLayoutItem->m_sPos.y = m_fLastRowY;
     pTrailerLayoutItem->m_sPos.x = m_fLastRowWidth;
     m_pLayoutItem->m_sSize.width += pTrailerLayoutItem->m_sSize.width;
@@ -2208,7 +2207,7 @@
 }
 
 void CXFA_ContentLayoutProcessor::AddLeaderAfterSplit(
-    CXFA_ContentLayoutItem* pLeaderLayoutItem) {
+    const RetainPtr<CXFA_ContentLayoutItem>& pLeaderLayoutItem) {
   UpdatePendingItemLayout(pLeaderLayoutItem);
 
   CXFA_Margin* pMarginNode =
@@ -2276,10 +2275,9 @@
         m_PendingNodes.front(), nullptr);
     m_PendingNodes.pop_front();
     pPendingProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
-    CXFA_ContentLayoutItem* pPendingLayoutItem =
-        pPendingProcessor->HasLayoutItem()
-            ? pPendingProcessor->ExtractLayoutItem()
-            : nullptr;
+    RetainPtr<CXFA_ContentLayoutItem> pPendingLayoutItem;
+    if (pPendingProcessor->HasLayoutItem())
+      pPendingLayoutItem = pPendingProcessor->ExtractLayoutItem();
     if (pPendingLayoutItem) {
       AddLeaderAfterSplit(pPendingLayoutItem);
       if (m_bBreakPending)
@@ -2297,7 +2295,7 @@
     float fContainerHeight,
     XFA_AttributeValue eFlowStrategy,
     uint8_t* uCurHAlignState,
-    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
+    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
     bool bUseBreakControl,
     float fAvailHeight,
     float fRealHeight,
@@ -2380,7 +2378,7 @@
   CXFA_Node* pOverflowLeaderNode = nullptr;
   CXFA_Node* pOverflowTrailerNode = nullptr;
   CXFA_Node* pFormNode = nullptr;
-  CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr;
+  RetainPtr<CXFA_ContentLayoutItem> pTrailerLayoutItem;
   bool bIsAddTrailerHeight = false;
   if (m_pViewLayoutProcessor &&
       pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
@@ -2409,8 +2407,8 @@
 
         bIsAddTrailerHeight =
             bUseInherited
-                ? IsAddNewRowForTrailer(pTrailerLayoutItem)
-                : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
+                ? IsAddNewRowForTrailer(pTrailerLayoutItem.Get())
+                : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem.Get());
         if (bIsAddTrailerHeight) {
           childSize.height += pTrailerLayoutItem->m_sSize.height;
           bIsAddTrailerHeight = true;
@@ -2442,13 +2440,13 @@
                                          pTrailerLayoutItem, pFormNode);
       }
 
-      CXFA_ContentLayoutItem* pChildLayoutItem =
+      RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem =
           pProcessor->ExtractLayoutItem();
       if (ExistContainerKeep(pProcessor->GetFormNode(), false) &&
           pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
-        m_arrayKeepItems.push_back(pChildLayoutItem);
+        m_ArrayKeepItems.push_back(pChildLayoutItem);
       } else {
-        m_arrayKeepItems.clear();
+        m_ArrayKeepItems.clear();
       }
       rgCurLineLayoutItems[uHAlign].push_back(pChildLayoutItem);
       *bAddedItemInRow = true;
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
index e8a425c..c4cfbe7 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "third_party/base/optional.h"
 #include "xfa/fxfa/fxfa_basic.h"
@@ -56,7 +57,7 @@
   void DoLayoutPageArea(CXFA_ViewLayoutItem* pPageAreaLayoutItem);
 
   CXFA_Node* GetFormNode() { return m_pFormNode; }
-  CXFA_ContentLayoutItem* ExtractLayoutItem();
+  RetainPtr<CXFA_ContentLayoutItem> ExtractLayoutItem();
 
  private:
   class Context {
@@ -78,27 +79,27 @@
   CFX_SizeF GetCurrentComponentSize();
   bool HasLayoutItem() const { return !!m_pLayoutItem; }
   void SplitLayoutItem(float fSplitPos);
-
   float FindSplitPos(float fProposedSplitPos);
-
   bool ProcessKeepForSplit(
       CXFA_ContentLayoutProcessor* pChildProcessor,
       Result eRetValue,
-      std::vector<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem,
+      std::vector<RetainPtr<CXFA_ContentLayoutItem>>* rgCurLineLayoutItem,
       float* fContentCurRowAvailWidth,
       float* fContentCurRowHeight,
       float* fContentCurRowY,
       bool* bAddedItemInRow,
       bool* bForceEndPage,
       Result* result);
-  void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode,
-                            CXFA_Node* pTrailerNode,
-                            CXFA_ContentLayoutItem* pTrailerItem,
-                            CXFA_Node* pFormNode);
+  void ProcessUnUseOverFlow(
+      CXFA_Node* pLeaderNode,
+      CXFA_Node* pTrailerNode,
+      const RetainPtr<CXFA_ContentLayoutItem>& pTrailerItem,
+      CXFA_Node* pFormNode);
   bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem);
   bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
 
-  CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode);
+  RetainPtr<CXFA_ContentLayoutItem> CreateContentLayoutItem(
+      CXFA_Node* pFormNode);
 
   void SetCurrentComponentPos(const CFX_PointF& pos);
   void SetCurrentComponentSize(const CFX_SizeF& size);
@@ -108,7 +109,7 @@
                        float fSplitPos);
   float InsertKeepLayoutItems();
   bool CalculateRowChildPosition(
-      std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
+      std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
       XFA_AttributeValue eFlowStrategy,
       bool bContainerHeightAutoSize,
       bool bContainerWidthAutoSize,
@@ -119,9 +120,10 @@
       float fContentWidthLimit,
       bool bRootForceTb);
   void ProcessUnUseBinds(CXFA_Node* pFormNode);
-  bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem,
-                        float fChildHeight,
-                        std::vector<CXFA_ContentLayoutItem*>* pKeepItems);
+  bool JudgePutNextPage(
+      CXFA_ContentLayoutItem* pParentLayoutItem,
+      float fChildHeight,
+      std::vector<RetainPtr<CXFA_ContentLayoutItem>>* pKeepItems);
 
   void DoLayoutPositionedContainer(Context* pContext);
   void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
@@ -148,11 +150,14 @@
 
   CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
 
-  void UpdatePendingItemLayout(CXFA_ContentLayoutItem* pLayoutItem);
-  void AddTrailerBeforeSplit(float fSplitPos,
-                             CXFA_ContentLayoutItem* pTrailerLayoutItem,
-                             bool bUseInherited);
-  void AddLeaderAfterSplit(CXFA_ContentLayoutItem* pLeaderLayoutItem);
+  void UpdatePendingItemLayout(
+      const RetainPtr<CXFA_ContentLayoutItem>& pLayoutItem);
+  void AddTrailerBeforeSplit(
+      float fSplitPos,
+      const RetainPtr<CXFA_ContentLayoutItem>& pTrailerLayoutItem,
+      bool bUseInherited);
+  void AddLeaderAfterSplit(
+      const RetainPtr<CXFA_ContentLayoutItem>& pLeaderLayoutItem);
   void AddPendingNode(CXFA_Node* pPendingNode, bool bBreakPending);
   float InsertPendingItems(CXFA_Node* pCurChildNode);
   Result InsertFlowedItem(
@@ -162,7 +167,7 @@
       float fContainerHeight,
       XFA_AttributeValue eFlowStrategy,
       uint8_t* uCurHAlignState,
-      std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
+      std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
       bool bUseBreakControl,
       float fAvailHeight,
       float fRealHeight,
@@ -212,11 +217,11 @@
   CXFA_Node* m_pCurChildNode = nullptr;
   CXFA_Node* m_pKeepHeadNode = nullptr;
   CXFA_Node* m_pKeepTailNode = nullptr;
-  CXFA_ContentLayoutItem* m_pLayoutItem = nullptr;
-  CXFA_ContentLayoutItem* m_pOldLayoutItem = nullptr;
+  RetainPtr<CXFA_ContentLayoutItem> m_pLayoutItem;
+  RetainPtr<CXFA_ContentLayoutItem> m_pOldLayoutItem;
   UnownedPtr<CXFA_ViewLayoutProcessor> m_pViewLayoutProcessor;
   std::vector<float> m_rgSpecifiedColumnWidths;
-  std::vector<CXFA_ContentLayoutItem*> m_arrayKeepItems;
+  std::vector<RetainPtr<CXFA_ContentLayoutItem>> m_ArrayKeepItems;
   std::list<CXFA_Node*> m_PendingNodes;
   std::map<CXFA_Node*, int32_t> m_PendingNodesCount;
   std::unique_ptr<CXFA_ContentLayoutProcessor> m_pCurChildPreprocessor;
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.cpp b/xfa/fxfa/layout/cxfa_layoutitem.cpp
index b4244bed..9ee7b61 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutitem.cpp
@@ -6,6 +6,8 @@
 
 #include "xfa/fxfa/layout/cxfa_layoutitem.h"
 
+#include <utility>
+
 #include "fxjs/xfa/cjx_object.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
@@ -15,23 +17,22 @@
 #include "xfa/fxfa/parser/cxfa_measurement.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 
-void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem) {
-  CXFA_LayoutItem* pNode = pLayoutItem->GetFirstChild();
+void XFA_ReleaseLayoutItem(const RetainPtr<CXFA_LayoutItem>& pLayoutItem) {
+  RetainPtr<CXFA_LayoutItem> pNode(pLayoutItem->GetFirstChild());
   while (pNode) {
-    CXFA_LayoutItem* pNext = pNode->GetNextSibling();
+    RetainPtr<CXFA_LayoutItem> pNext(pNode->GetNextSibling());
     XFA_ReleaseLayoutItem(pNode);
-    pNode = pNext;
+    pNode = std::move(pNext);
   }
   CXFA_Document* pDocument = pLayoutItem->GetFormNode()->GetDocument();
   CXFA_FFNotify* pNotify = pDocument->GetNotify();
   auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
-  pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
+  pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
   if (pLayoutItem->GetFormNode()->GetElementType() == XFA_Element::PageArea) {
-    pNotify->OnPageEvent(ToViewLayoutItem(pLayoutItem),
+    pNotify->OnPageEvent(ToViewLayoutItem(pLayoutItem.Get()),
                          XFA_PAGEVIEWEVENT_PostRemoved);
   }
   pLayoutItem->RemoveSelfIfParented();
-  delete pLayoutItem;
 }
 
 CXFA_LayoutItem::CXFA_LayoutItem(CXFA_Node* pNode, ItemType type)
diff --git a/xfa/fxfa/layout/cxfa_layoutitem.h b/xfa/fxfa/layout/cxfa_layoutitem.h
index b162fc0..034c145 100644
--- a/xfa/fxfa/layout/cxfa_layoutitem.h
+++ b/xfa/fxfa/layout/cxfa_layoutitem.h
@@ -7,7 +7,8 @@
 #ifndef XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
 #define XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
 
-#include "core/fxcrt/tree_node.h"
+#include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/retained_tree_node.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 
@@ -15,7 +16,7 @@
 class CXFA_LayoutProcessor;
 class CXFA_ViewLayoutItem;
 
-class CXFA_LayoutItem : public TreeNode<CXFA_LayoutItem> {
+class CXFA_LayoutItem : public RetainedTreeNode<CXFA_LayoutItem> {
  public:
   ~CXFA_LayoutItem() override;
 
@@ -47,6 +48,6 @@
   return item ? item->AsContentLayoutItem() : nullptr;
 }
 
-void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem);
+void XFA_ReleaseLayoutItem(const RetainPtr<CXFA_LayoutItem>& pLayoutItem);
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_LAYOUTITEM_H_
diff --git a/xfa/fxfa/layout/cxfa_layoutprocessor.cpp b/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
index 0edfefd..b436da5 100644
--- a/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutprocessor.cpp
@@ -81,7 +81,7 @@
     if (eStatus != CXFA_ContentLayoutProcessor::Result::kDone)
       m_nProgressCounter++;
 
-    CXFA_ContentLayoutItem* pLayoutItem =
+    RetainPtr<CXFA_ContentLayoutItem> pLayoutItem =
         m_pContentLayoutProcessor->ExtractLayoutItem();
     if (pLayoutItem)
       pLayoutItem->m_sPos = CFX_PointF(fPosX, fPosY);
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutitem.h b/xfa/fxfa/layout/cxfa_viewlayoutitem.h
index 1ced481..1c9f77c 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutitem.h
+++ b/xfa/fxfa/layout/cxfa_viewlayoutitem.h
@@ -15,8 +15,9 @@
 
 class CXFA_ViewLayoutItem : public CXFA_LayoutItem {
  public:
-  CXFA_ViewLayoutItem(CXFA_Node* pNode,
-                      std::unique_ptr<CXFA_FFPageView> pPageView);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CXFA_ViewLayoutItem() override;
 
   CXFA_FFPageView* GetPageView() const { return m_pFFPageView.get(); }
@@ -28,6 +29,9 @@
   UnownedPtr<CXFA_Node> m_pOldSubform;
 
  private:
+  CXFA_ViewLayoutItem(CXFA_Node* pNode,
+                      std::unique_ptr<CXFA_FFPageView> pPageView);
+
   std::unique_ptr<CXFA_FFPageView> const m_pFFPageView;
 };
 
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index 0605aa6..6e6ba4a 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -158,7 +158,7 @@
   }
 }
 
-void ReorderLayoutItemToTail(CXFA_LayoutItem* pLayoutItem) {
+void ReorderLayoutItemToTail(const RetainPtr<CXFA_LayoutItem>& pLayoutItem) {
   CXFA_LayoutItem* pParentLayoutItem = pLayoutItem->GetParent();
   if (!pParentLayoutItem)
     return;
@@ -246,15 +246,15 @@
 void SyncRemoveLayoutItem(CXFA_LayoutItem* pLayoutItem,
                           CXFA_FFNotify* pNotify,
                           CXFA_LayoutProcessor* pDocLayout) {
-  CXFA_LayoutItem* pCurLayoutItem = pLayoutItem->GetFirstChild();
+  RetainPtr<CXFA_LayoutItem> pCurLayoutItem(pLayoutItem->GetFirstChild());
   while (pCurLayoutItem) {
-    CXFA_LayoutItem* pNextLayoutItem = pCurLayoutItem->GetNextSibling();
-    SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
-    pCurLayoutItem = pNextLayoutItem;
+    RetainPtr<CXFA_LayoutItem> pNextLayoutItem(
+        pCurLayoutItem->GetNextSibling());
+    SyncRemoveLayoutItem(pCurLayoutItem.Get(), pNotify, pDocLayout);
+    pCurLayoutItem = std::move(pNextLayoutItem);
   }
   pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
   pLayoutItem->RemoveSelfIfParented();
-  delete pLayoutItem;
 }
 
 bool RunBreakTestScript(CXFA_Script* pTestScript) {
@@ -338,31 +338,23 @@
         pCurPageArea(pPageArea),
         pCurContentArea(pContentArea) {}
 
-  CXFA_ViewLayoutItem* pCurPageSet;
-  CXFA_ViewLayoutItem* pCurPageArea;
-  CXFA_ViewLayoutItem* pCurContentArea;
+  RetainPtr<CXFA_ViewLayoutItem> pCurPageSet;
+  RetainPtr<CXFA_ViewLayoutItem> pCurPageArea;
+  RetainPtr<CXFA_ViewLayoutItem> pCurContentArea;
 };
 
 CXFA_ViewLayoutProcessor::CXFA_ViewLayoutProcessor(
     CXFA_LayoutProcessor* pLayoutProcessor)
     : m_pLayoutProcessor(pLayoutProcessor),
-      m_pTemplatePageSetRoot(nullptr),
-      m_pPageSetLayoutItemRoot(nullptr),
-      m_pPageSetCurRoot(nullptr),
-      m_CurrentViewRecordIter(m_ProposedViewRecords.end()),
-      m_pCurPageArea(nullptr),
-      m_nAvailPages(0),
-      m_nCurPageCount(0),
-      m_ePageSetMode(XFA_AttributeValue::OrderedOccurrence),
-      m_bCreateOverFlowPage(false) {}
+      m_CurrentViewRecordIter(m_ProposedViewRecords.end()) {}
 
 CXFA_ViewLayoutProcessor::~CXFA_ViewLayoutProcessor() {
   ClearData();
-  CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem();
-  CXFA_LayoutItem* pNextLayout = nullptr;
-  for (; pLayoutItem; pLayoutItem = pNextLayout) {
-    pNextLayout = pLayoutItem->GetNextSibling();
+  RetainPtr<CXFA_LayoutItem> pLayoutItem(GetRootLayoutItem());
+  while (pLayoutItem) {
+    CXFA_LayoutItem* pNextLayout = pLayoutItem->GetNextSibling();
     XFA_ReleaseLayoutItem(pLayoutItem);
+    pLayoutItem.Reset(pNextLayout);
   }
 }
 
@@ -380,11 +372,12 @@
   if (m_pPageSetLayoutItemRoot) {
     m_pPageSetLayoutItemRoot->RemoveSelfIfParented();
   } else {
-    m_pPageSetLayoutItemRoot =
-        new CXFA_ViewLayoutItem(m_pTemplatePageSetRoot, nullptr);
+    m_pPageSetLayoutItemRoot = pdfium::MakeRetain<CXFA_ViewLayoutItem>(
+        m_pTemplatePageSetRoot, nullptr);
   }
   m_pPageSetCurRoot = m_pPageSetLayoutItemRoot;
-  m_pTemplatePageSetRoot->JSObject()->SetLayoutItem(m_pPageSetLayoutItemRoot);
+  m_pTemplatePageSetRoot->JSObject()->SetLayoutItem(
+      m_pPageSetLayoutItemRoot.Get());
 
   XFA_AttributeValue eRelation =
       m_pTemplatePageSetRoot->JSObject()->GetEnum(XFA_Attribute::Relation);
@@ -546,7 +539,7 @@
 }
 
 void CXFA_ViewLayoutProcessor::SubmitContentItem(
-    CXFA_ContentLayoutItem* pContentLayoutItem,
+    const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem,
     CXFA_ContentLayoutProcessor::Result eStatus) {
   if (pContentLayoutItem) {
     GetCurrentViewRecord()->pCurContentArea->AppendLastChild(
@@ -565,7 +558,8 @@
 }
 
 float CXFA_ViewLayoutProcessor::GetAvailHeight() {
-  CXFA_ViewLayoutItem* pLayoutItem = GetCurrentViewRecord()->pCurContentArea;
+  RetainPtr<CXFA_ViewLayoutItem> pLayoutItem =
+      GetCurrentViewRecord()->pCurContentArea;
   if (!pLayoutItem || !pLayoutItem->GetFormNode())
     return 0.0f;
 
@@ -594,11 +588,11 @@
     if (pPageSet == m_pTemplatePageSetRoot) {
       pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
     } else {
-      CXFA_ViewLayoutItem* pPageSetLayoutItem =
-          new CXFA_ViewLayoutItem(pPageSet, nullptr);
-      pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem);
+      auto pPageSetLayoutItem =
+          pdfium::MakeRetain<CXFA_ViewLayoutItem>(pPageSet, nullptr);
+      pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem.Get());
       m_pPageSetLayoutItemRoot->AppendLastChild(pPageSetLayoutItem);
-      pNewRecord->pCurPageSet = pPageSetLayoutItem;
+      pNewRecord->pCurPageSet = std::move(pPageSetLayoutItem);
     }
     return AppendNewRecord(std::move(pNewRecord));
   }
@@ -613,8 +607,8 @@
     if (pPageSet == m_pTemplatePageSetRoot) {
       pNewRecord->pCurPageSet = m_pPageSetCurRoot;
     } else {
-      CXFA_ViewLayoutItem* pParentLayoutItem =
-          ToViewLayoutItem(pPageSet->JSObject()->GetLayoutItem());
+      RetainPtr<CXFA_ViewLayoutItem> pParentLayoutItem(
+          ToViewLayoutItem(pPageSet->JSObject()->GetLayoutItem()));
       if (!pParentLayoutItem)
         pParentLayoutItem = m_pPageSetCurRoot;
 
@@ -631,15 +625,18 @@
     pParentPageSetLayout =
         ToViewLayoutItem(pPageSet->GetParent()->JSObject()->GetLayoutItem());
   }
-  auto* pPageSetLayoutItem = new CXFA_ViewLayoutItem(pPageSet, nullptr);
-  pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem);
+  auto pPageSetLayoutItem =
+      pdfium::MakeRetain<CXFA_ViewLayoutItem>(pPageSet, nullptr);
+  pPageSet->JSObject()->SetLayoutItem(pPageSetLayoutItem.Get());
   if (!pParentPageSetLayout) {
-    CXFA_ViewLayoutItem* pPrePageSet = m_pPageSetLayoutItemRoot;
+    RetainPtr<CXFA_ViewLayoutItem> pPrePageSet(m_pPageSetLayoutItemRoot);
     while (pPrePageSet->GetNextSibling()) {
-      pPrePageSet = pPrePageSet->GetNextSibling()->AsViewLayoutItem();
+      pPrePageSet.Reset(pPrePageSet->GetNextSibling()->AsViewLayoutItem());
     }
-    if (pPrePageSet->GetParent())
-      pPrePageSet->GetParent()->InsertAfter(pPageSetLayoutItem, pPrePageSet);
+    if (pPrePageSet->GetParent()) {
+      pPrePageSet->GetParent()->InsertAfter(pPageSetLayoutItem,
+                                            pPrePageSet.Get());
+    }
     m_pPageSetCurRoot = pPageSetLayoutItem;
   } else {
     pParentPageSetLayout->AppendLastChild(pPageSetLayoutItem);
@@ -660,21 +657,19 @@
 void CXFA_ViewLayoutProcessor::AddPageAreaLayoutItem(
     CXFA_ViewRecord* pNewRecord,
     CXFA_Node* pNewPageArea) {
-  CXFA_ViewLayoutItem* pNewPageAreaLayoutItem = nullptr;
+  RetainPtr<CXFA_ViewLayoutItem> pNewPageAreaLayoutItem;
   if (pdfium::IndexInBounds(m_PageArray, m_nAvailPages)) {
-    CXFA_ViewLayoutItem* pViewItem = m_PageArray[m_nAvailPages];
+    RetainPtr<CXFA_ViewLayoutItem> pViewItem = m_PageArray[m_nAvailPages];
     pViewItem->SetFormNode(pNewPageArea);
     m_nAvailPages++;
-    pNewPageAreaLayoutItem = pViewItem;
+    pNewPageAreaLayoutItem = std::move(pViewItem);
   } else {
     CXFA_FFNotify* pNotify = pNewPageArea->GetDocument()->GetNotify();
-    auto* pViewItem =
-        pdfium::MakeUnique<CXFA_ViewLayoutItem>(
-            pNewPageArea, pNotify->OnCreateViewLayoutItem(pNewPageArea))
-            .release();
+    auto pViewItem = pdfium::MakeRetain<CXFA_ViewLayoutItem>(
+        pNewPageArea, pNotify->OnCreateViewLayoutItem(pNewPageArea));
     m_PageArray.push_back(pViewItem);
     m_nAvailPages++;
-    pNotify->OnPageEvent(pViewItem, XFA_PAGEVIEWEVENT_PostRemoved);
+    pNotify->OnPageEvent(pViewItem.Get(), XFA_PAGEVIEWEVENT_PostRemoved);
     pNewPageAreaLayoutItem = pViewItem;
   }
   pNewRecord->pCurPageSet->AppendLastChild(pNewPageAreaLayoutItem);
@@ -689,15 +684,15 @@
     pNewRecord->pCurContentArea = nullptr;
     return;
   }
-  CXFA_ViewLayoutItem* pNewViewLayoutItem =
-      new CXFA_ViewLayoutItem(pContentArea, nullptr);
-  ASSERT(pNewRecord->pCurPageArea);
+  auto pNewViewLayoutItem =
+      pdfium::MakeRetain<CXFA_ViewLayoutItem>(pContentArea, nullptr);
   pNewRecord->pCurPageArea->AppendLastChild(pNewViewLayoutItem);
-  pNewRecord->pCurContentArea = pNewViewLayoutItem;
+  pNewRecord->pCurContentArea = std::move(pNewViewLayoutItem);
 }
 
 void CXFA_ViewLayoutProcessor::FinishPaginatedPageSets() {
-  for (CXFA_ViewLayoutItem* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot;
+  for (CXFA_ViewLayoutItem* pRootPageSetLayoutItem =
+           m_pPageSetLayoutItemRoot.Get();
        pRootPageSetLayoutItem; pRootPageSetLayoutItem = ToViewLayoutItem(
                                    pRootPageSetLayoutItem->GetNextSibling())) {
     PageSetIterator sIterator(pRootPageSetLayoutItem);
@@ -728,7 +723,7 @@
 CXFA_ViewLayoutItem* CXFA_ViewLayoutProcessor::GetPage(int32_t index) const {
   if (!pdfium::IndexInBounds(m_PageArray, index))
     return nullptr;
-  return m_PageArray[index];
+  return m_PageArray[index].Get();
 }
 
 int32_t CXFA_ViewLayoutProcessor::GetPageIndex(
@@ -1394,7 +1389,7 @@
       return false;
 
     Optional<CXFA_ViewLayoutItem*> pContentAreaLayout = CheckContentAreaNotUsed(
-        GetCurrentViewRecord()->pCurPageArea, pContentArea);
+        GetCurrentViewRecord()->pCurPageArea.Get(), pContentArea);
     if (!pContentAreaLayout.has_value())
       return false;
     if (pContentAreaLayout.value()) {
@@ -1402,7 +1397,7 @@
         return false;
 
       CXFA_ViewRecord* pNewRecord = CreateViewRecordSimple();
-      pNewRecord->pCurContentArea = pContentAreaLayout.value();
+      pNewRecord->pCurContentArea.Reset(pContentAreaLayout.value());
       return true;
     }
   }
@@ -1609,26 +1604,21 @@
   CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
   CXFA_FFNotify* pNotify = pDocument->GetNotify();
   auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
-  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->GetFirstChild();
+  RetainPtr<CXFA_LayoutItem> pCurLayoutItem(pParentLayoutItem->GetFirstChild());
   while (pCurLayoutItem) {
-    CXFA_LayoutItem* pNextLayoutItem = pCurLayoutItem->GetNextSibling();
+    RetainPtr<CXFA_LayoutItem> pNextLayoutItem(
+        pCurLayoutItem->GetNextSibling());
     if (pCurLayoutItem->IsContentLayoutItem()) {
       if (pCurLayoutItem->GetFormNode()->HasRemovedChildren()) {
-        SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
-        pCurLayoutItem = pNextLayoutItem;
+        SyncRemoveLayoutItem(pCurLayoutItem.Get(), pNotify, pDocLayout);
+        pCurLayoutItem = std::move(pNextLayoutItem);
         continue;
       }
       if (pCurLayoutItem->GetFormNode()->IsLayoutGeneratedNode())
         pCurLayoutItem->GetFormNode()->SetNodeAndDescendantsUnused();
     }
-    SaveLayoutItemChildren(pCurLayoutItem);
-    pCurLayoutItem->RemoveSelfIfParented();
-    if (!pCurLayoutItem->IsContentLayoutItem() &&
-        pCurLayoutItem->GetFormNode()->GetElementType() !=
-            XFA_Element::PageArea) {
-      delete pCurLayoutItem;
-    }
-    pCurLayoutItem = pNextLayoutItem;
+    SaveLayoutItemChildren(pCurLayoutItem.Get());
+    pCurLayoutItem = std::move(pNextLayoutItem);
   }
 }
 
@@ -1732,12 +1722,12 @@
               for (CXFA_Node* pIter = sIterator.GetCurrent(); pIter;
                    pIter = sIterator.MoveToNext()) {
                 if (pIter->GetElementType() != XFA_Element::ContentArea) {
-                  CXFA_LayoutItem* pLayoutItem =
-                      pIter->JSObject()->GetLayoutItem();
+                  RetainPtr<CXFA_LayoutItem> pLayoutItem(
+                      pIter->JSObject()->GetLayoutItem());
                   if (pLayoutItem) {
-                    pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
+                    pNotify->OnLayoutItemRemoving(pDocLayout,
+                                                  pLayoutItem.Get());
                     pLayoutItem->RemoveSelfIfParented();
-                    delete pLayoutItem;
                   }
                 }
               }
@@ -1798,20 +1788,19 @@
             CXFA_ContainerIterator iteChild(pNode);
             CXFA_Node* pChildNode = iteChild.MoveToNext();
             for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
-              CXFA_LayoutItem* pLayoutItem =
-                  pChildNode->JSObject()->GetLayoutItem();
+              RetainPtr<CXFA_LayoutItem> pLayoutItem(
+                  pChildNode->JSObject()->GetLayoutItem());
               if (pLayoutItem) {
-                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
+                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
                 pLayoutItem->RemoveSelfIfParented();
-                delete pLayoutItem;
               }
             }
           } else if (eType != XFA_Element::ContentArea) {
-            CXFA_LayoutItem* pLayoutItem = pNode->JSObject()->GetLayoutItem();
+            RetainPtr<CXFA_LayoutItem> pLayoutItem(
+                pNode->JSObject()->GetLayoutItem());
             if (pLayoutItem) {
-              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
+              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem.Get());
               pLayoutItem->RemoveSelfIfParented();
-              delete pLayoutItem;
             }
           }
           CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
@@ -1895,10 +1884,9 @@
 
   int32_t nPage = pdfium::CollectionSize<int32_t>(m_PageArray);
   for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) {
-    CXFA_ViewLayoutItem* pPage = m_PageArray[i];
+    RetainPtr<CXFA_ViewLayoutItem> pPage = m_PageArray[i];
     m_PageArray.erase(m_PageArray.begin() + i);
-    pNotify->OnPageEvent(pPage, XFA_PAGEVIEWEVENT_PostRemoved);
-    delete pPage;
+    pNotify->OnPageEvent(pPage.Get(), XFA_PAGEVIEWEVENT_PostRemoved);
   }
   ClearData();
 }
@@ -1911,7 +1899,7 @@
   if (!m_pPageSetLayoutItemRoot)
     return;
 
-  CXFA_ViewLayoutItem* pRootLayoutItem = m_pPageSetLayoutItemRoot;
+  RetainPtr<CXFA_ViewLayoutItem> pRootLayoutItem = m_pPageSetLayoutItemRoot;
   if (pRootLayoutItem &&
       pRootLayoutItem->GetFormNode()->GetPacketType() == XFA_PacketType::Form) {
     CXFA_Node* pPageSetFormNode = pRootLayoutItem->GetFormNode();
@@ -1937,11 +1925,10 @@
   }
   pRootLayoutItem = m_pPageSetLayoutItemRoot;
   CXFA_ViewLayoutItem* pNextLayout = nullptr;
-  for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
+  for (; pRootLayoutItem; pRootLayoutItem.Reset(pNextLayout)) {
     pNextLayout = ToViewLayoutItem(pRootLayoutItem->GetNextSibling());
-    SaveLayoutItemChildren(pRootLayoutItem);
+    SaveLayoutItemChildren(pRootLayoutItem.Get());
     pRootLayoutItem->RemoveSelfIfParented();
-    delete pRootLayoutItem;
   }
   m_pPageSetLayoutItemRoot = nullptr;
 }
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
index 332cbc0..0e2577b 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
@@ -13,6 +13,7 @@
 #include <memory>
 #include <vector>
 
+#include "core/fxcrt/retain_ptr.h"
 #include "third_party/base/optional.h"
 #include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h"
 
@@ -40,15 +41,16 @@
   bool PrepareFirstPage(CXFA_Node* pRootSubform);
   float GetAvailHeight();
   bool GetNextAvailContentHeight(float fChildHeight);
-  void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
-                         CXFA_ContentLayoutProcessor::Result eStatus);
+  void SubmitContentItem(
+      const RetainPtr<CXFA_ContentLayoutItem>& pContentLayoutItem,
+      CXFA_ContentLayoutProcessor::Result eStatus);
   void FinishPaginatedPageSets();
   void SyncLayoutData();
   int32_t GetPageCount() const;
   CXFA_ViewLayoutItem* GetPage(int32_t index) const;
   int32_t GetPageIndex(const CXFA_ViewLayoutItem* pPage) const;
-  inline CXFA_ViewLayoutItem* GetRootLayoutItem() const {
-    return m_pPageSetLayoutItemRoot;
+  CXFA_ViewLayoutItem* GetRootLayoutItem() const {
+    return m_pPageSetLayoutItemRoot.Get();
   }
   Optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode);
   Optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode);
@@ -150,19 +152,19 @@
   void ProcessSimplexOrDuplexPageSets(CXFA_ViewLayoutItem* pPageSetLayoutItem,
                                       bool bIsSimplex);
 
-  CXFA_LayoutProcessor* m_pLayoutProcessor;
-  CXFA_Node* m_pTemplatePageSetRoot;
-  CXFA_ViewLayoutItem* m_pPageSetLayoutItemRoot;
-  CXFA_ViewLayoutItem* m_pPageSetCurRoot;
+  CXFA_LayoutProcessor* m_pLayoutProcessor = nullptr;
+  CXFA_Node* m_pTemplatePageSetRoot = nullptr;
+  RetainPtr<CXFA_ViewLayoutItem> m_pPageSetLayoutItemRoot;
+  RetainPtr<CXFA_ViewLayoutItem> m_pPageSetCurRoot;
   RecordList m_ProposedViewRecords;
   RecordList::iterator m_CurrentViewRecordIter;
-  CXFA_Node* m_pCurPageArea;
-  int32_t m_nAvailPages;
-  int32_t m_nCurPageCount;
-  XFA_AttributeValue m_ePageSetMode;
-  bool m_bCreateOverFlowPage;
+  CXFA_Node* m_pCurPageArea = nullptr;
+  int32_t m_nAvailPages = 0;
+  int32_t m_nCurPageCount = 0;
+  XFA_AttributeValue m_ePageSetMode = XFA_AttributeValue::OrderedOccurrence;
+  bool m_bCreateOverFlowPage = false;
   std::map<CXFA_Node*, int32_t> m_pPageSetMap;
-  std::vector<CXFA_ViewLayoutItem*> m_PageArray;
+  std::vector<RetainPtr<CXFA_ViewLayoutItem>> m_PageArray;
 };
 
 #endif  // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_