1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "xfa/fxfa/parser/cxfa_layoutpagemgr.h"
8
9#include "xfa/fxfa/app/xfa_ffnotify.h"
10#include "xfa/fxfa/parser/cxfa_containerlayoutitem.h"
11#include "xfa/fxfa/parser/cxfa_contentlayoutitem.h"
12#include "xfa/fxfa/parser/cxfa_document.h"
13#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
14#include "xfa/fxfa/parser/cxfa_measurement.h"
15#include "xfa/fxfa/parser/cxfa_scriptcontext.h"
16#include "xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h"
17#include "xfa/fxfa/parser/cxfa_traversestrategy_layoutitem.h"
18#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
19#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
20#include "xfa/fxfa/parser/xfa_localemgr.h"
21#include "xfa/fxfa/parser/xfa_object.h"
22#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
23#include "xfa/fxfa/parser/xfa_utils.h"
24
25namespace {
26
27class PageSetContainerLayoutItem {
28 public:
29  static CXFA_ContainerLayoutItem* GetFirstChild(
30      CXFA_ContainerLayoutItem* pLayoutItem) {
31    if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::PageSet)
32      return nullptr;
33
34    CXFA_ContainerLayoutItem* pChildItem =
35        static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pFirstChild);
36    while (pChildItem &&
37           pChildItem->m_pFormNode->GetElementType() != XFA_Element::PageSet) {
38      pChildItem =
39          static_cast<CXFA_ContainerLayoutItem*>(pChildItem->m_pNextSibling);
40    }
41    return pChildItem;
42  }
43
44  static CXFA_ContainerLayoutItem* GetNextSibling(
45      CXFA_ContainerLayoutItem* pLayoutItem) {
46    CXFA_ContainerLayoutItem* pChildItem =
47        static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pNextSibling);
48    while (pChildItem &&
49           pChildItem->m_pFormNode->GetElementType() != XFA_Element::PageSet) {
50      pChildItem =
51          static_cast<CXFA_ContainerLayoutItem*>(pChildItem->m_pNextSibling);
52    }
53    return pChildItem;
54  }
55
56  static CXFA_ContainerLayoutItem* GetParent(
57      CXFA_ContainerLayoutItem* pLayoutItem) {
58    return static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
59  }
60};
61
62uint32_t GetRelevant(CXFA_Node* pFormItem, uint32_t dwParentRelvant) {
63  uint32_t dwRelevant = XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable;
64  CFX_WideStringC wsRelevant;
65  if (pFormItem->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant)) {
66    if (wsRelevant == L"+print" || wsRelevant == L"print")
67      dwRelevant &= ~XFA_WidgetStatus_Viewable;
68    else if (wsRelevant == L"-print")
69      dwRelevant &= ~XFA_WidgetStatus_Printable;
70  }
71
72  if (!(dwParentRelvant & XFA_WidgetStatus_Viewable) &&
73      (dwRelevant != XFA_WidgetStatus_Viewable)) {
74    dwRelevant &= ~XFA_WidgetStatus_Viewable;
75  }
76
77  if (!(dwParentRelvant & XFA_WidgetStatus_Printable) &&
78      (dwRelevant != XFA_WidgetStatus_Printable)) {
79    dwRelevant &= ~XFA_WidgetStatus_Printable;
80  }
81  return dwRelevant;
82}
83
84void SyncContainer(CXFA_FFNotify* pNotify,
85                   CXFA_LayoutProcessor* pDocLayout,
86                   CXFA_LayoutItem* pContainerItem,
87                   uint32_t dwRelevant,
88                   bool bVisible,
89                   int32_t nPageIndex) {
90  bool bVisibleItem = false;
91  uint32_t dwStatus = 0;
92  uint32_t dwRelevantContainer = 0;
93  if (bVisible) {
94    XFA_ATTRIBUTEENUM eAttributeValue =
95        pContainerItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence);
96    if (eAttributeValue == XFA_ATTRIBUTEENUM_Visible ||
97        eAttributeValue == XFA_ATTRIBUTEENUM_Unknown) {
98      bVisibleItem = true;
99    }
100    dwRelevantContainer = GetRelevant(pContainerItem->m_pFormNode, dwRelevant);
101    dwStatus =
102        (bVisibleItem ? XFA_WidgetStatus_Visible : 0) | dwRelevantContainer;
103  }
104  pNotify->OnLayoutItemAdded(pDocLayout, pContainerItem, nPageIndex, dwStatus);
105  for (CXFA_LayoutItem* pChild = pContainerItem->m_pFirstChild; pChild;
106       pChild = pChild->m_pNextSibling) {
107    if (pChild->IsContentLayoutItem()) {
108      SyncContainer(pNotify, pDocLayout, pChild, dwRelevantContainer,
109                    bVisibleItem, nPageIndex);
110    }
111  }
112}
113
114void ReorderLayoutItemToTail(CXFA_ContainerLayoutItem* pLayoutItem) {
115  CXFA_ContainerLayoutItem* pParentLayoutItem =
116      static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
117  if (!pParentLayoutItem)
118    return;
119
120  pParentLayoutItem->RemoveChild(pLayoutItem);
121  pParentLayoutItem->AddChild(pLayoutItem);
122}
123
124void RemoveLayoutItem(CXFA_ContainerLayoutItem* pLayoutItem) {
125  CXFA_ContainerLayoutItem* pParentLayoutItem =
126      static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
127  if (!pParentLayoutItem)
128    return;
129
130  pParentLayoutItem->RemoveChild(pLayoutItem);
131}
132
133CXFA_Node* ResolveBreakTarget(CXFA_Node* pPageSetRoot,
134                              bool bNewExprStyle,
135                              CFX_WideStringC& wsTargetExpr) {
136  CXFA_Document* pDocument = pPageSetRoot->GetDocument();
137  if (wsTargetExpr.IsEmpty())
138    return nullptr;
139
140  CFX_WideString wsTargetAll(wsTargetExpr);
141  wsTargetAll.TrimLeft();
142  wsTargetAll.TrimRight();
143  int32_t iSplitIndex = 0;
144  bool bTargetAllFind = true;
145  while (iSplitIndex != -1) {
146    CFX_WideString wsExpr;
147    int32_t iSplitNextIndex = 0;
148    if (!bTargetAllFind) {
149      iSplitNextIndex = wsTargetAll.Find(' ', iSplitIndex);
150      wsExpr = wsTargetAll.Mid(iSplitIndex, iSplitNextIndex - iSplitIndex);
151    } else {
152      wsExpr = wsTargetAll;
153    }
154    if (wsExpr.IsEmpty())
155      return nullptr;
156
157    bTargetAllFind = false;
158    if (wsExpr.GetAt(0) == '#') {
159      CXFA_Node* pNode = pDocument->GetNodeByID(
160          ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Template)),
161          wsExpr.Mid(1).AsStringC());
162      if (pNode)
163        return pNode;
164    } else if (bNewExprStyle) {
165      CFX_WideString wsProcessedTarget = wsExpr;
166      if (wsExpr.Left(4) == L"som(" && wsExpr.Right(1) == L")") {
167        wsProcessedTarget = wsExpr.Mid(4, wsExpr.GetLength() - 5);
168      }
169      XFA_RESOLVENODE_RS rs;
170      int32_t iCount = pDocument->GetScriptContext()->ResolveObjects(
171          pPageSetRoot, wsProcessedTarget.AsStringC(), rs,
172          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
173              XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings |
174              XFA_RESOLVENODE_Parent);
175      if (iCount > 0 && rs.nodes[0]->IsNode())
176        return rs.nodes[0]->AsNode();
177    }
178    iSplitIndex = iSplitNextIndex;
179  }
180  return nullptr;
181}
182
183void SetLayoutGeneratedNodeFlag(CXFA_Node* pNode) {
184  pNode->SetFlag(XFA_NodeFlag_LayoutGeneratedNode, false);
185  pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
186}
187
188bool CheckContentAreaNotUsed(
189    CXFA_ContainerLayoutItem* pPageAreaLayoutItem,
190    CXFA_Node* pContentArea,
191    CXFA_ContainerLayoutItem*& pContentAreaLayoutItem) {
192  for (CXFA_ContainerLayoutItem* pLayoutItem =
193           static_cast<CXFA_ContainerLayoutItem*>(
194               pPageAreaLayoutItem->m_pFirstChild);
195       pLayoutItem; pLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
196                        pLayoutItem->m_pNextSibling)) {
197    if (pLayoutItem->m_pFormNode == pContentArea) {
198      if (!pLayoutItem->m_pFirstChild) {
199        pContentAreaLayoutItem = pLayoutItem;
200        return true;
201      }
202      return false;
203    }
204  }
205  return true;
206}
207
208void SyncRemoveLayoutItem(CXFA_LayoutItem* pParentLayoutItem,
209                          CXFA_FFNotify* pNotify,
210                          CXFA_LayoutProcessor* pDocLayout) {
211  CXFA_LayoutItem* pNextLayoutItem;
212  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
213  while (pCurLayoutItem) {
214    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
215    if (pCurLayoutItem->m_pFirstChild)
216      SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
217
218    pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
219    delete pCurLayoutItem;
220    pCurLayoutItem = pNextLayoutItem;
221  }
222}
223
224}  // namespace
225
226class CXFA_ContainerRecord {
227 public:
228  CXFA_ContainerRecord(CXFA_ContainerLayoutItem* pPageSet = nullptr,
229                       CXFA_ContainerLayoutItem* pPageArea = nullptr,
230                       CXFA_ContainerLayoutItem* pContentArea = nullptr)
231      : pCurPageSet(pPageSet),
232        pCurPageArea(pPageArea),
233        pCurContentArea(pContentArea) {}
234
235  CXFA_ContainerLayoutItem* pCurPageSet;
236  CXFA_ContainerLayoutItem* pCurPageArea;
237  CXFA_ContainerLayoutItem* pCurContentArea;
238};
239
240CXFA_LayoutPageMgr::CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor)
241    : m_pLayoutProcessor(pLayoutProcessor),
242      m_pTemplatePageSetRoot(nullptr),
243      m_pPageSetLayoutItemRoot(nullptr),
244      m_pPageSetCurRoot(nullptr),
245      m_CurrentContainerRecordIter(m_ProposedContainerRecords.end()),
246      m_pCurPageArea(nullptr),
247      m_nAvailPages(0),
248      m_nCurPageCount(0),
249      m_ePageSetMode(XFA_ATTRIBUTEENUM_OrderedOccurrence),
250      m_bCreateOverFlowPage(false) {}
251
252CXFA_LayoutPageMgr::~CXFA_LayoutPageMgr() {
253  ClearData();
254  CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem();
255  CXFA_LayoutItem* pNextLayout = nullptr;
256  for (; pLayoutItem; pLayoutItem = pNextLayout) {
257    pNextLayout = pLayoutItem->m_pNextSibling;
258    XFA_ReleaseLayoutItem(pLayoutItem);
259  }
260}
261
262bool CXFA_LayoutPageMgr::InitLayoutPage(CXFA_Node* pFormNode) {
263  PrepareLayout();
264  CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
265  if (!pTemplateNode)
266    return false;
267
268  m_pTemplatePageSetRoot = pTemplateNode->GetProperty(0, XFA_Element::PageSet);
269  ASSERT(m_pTemplatePageSetRoot);
270  if (m_pPageSetLayoutItemRoot) {
271    m_pPageSetLayoutItemRoot->m_pParent = nullptr;
272    m_pPageSetLayoutItemRoot->m_pFirstChild = nullptr;
273    m_pPageSetLayoutItemRoot->m_pNextSibling = nullptr;
274    m_pPageSetLayoutItemRoot->m_pFormNode = m_pTemplatePageSetRoot;
275  } else {
276    m_pPageSetLayoutItemRoot =
277        new CXFA_ContainerLayoutItem(m_pTemplatePageSetRoot);
278  }
279  m_pPageSetCurRoot = m_pPageSetLayoutItemRoot;
280  m_pTemplatePageSetRoot->SetUserData(XFA_LAYOUTITEMKEY,
281                                      (void*)m_pPageSetLayoutItemRoot);
282  XFA_ATTRIBUTEENUM eRelation =
283      m_pTemplatePageSetRoot->GetEnum(XFA_ATTRIBUTE_Relation);
284  if (eRelation != XFA_ATTRIBUTEENUM_Unknown)
285    m_ePageSetMode = eRelation;
286
287  InitPageSetMap();
288  CXFA_Node* pPageArea = nullptr;
289  int32_t iCount = 0;
290  for (pPageArea = m_pTemplatePageSetRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
291       pPageArea;
292       pPageArea = pPageArea->GetNodeItem(XFA_NODEITEM_NextSibling)) {
293    if (pPageArea->GetElementType() == XFA_Element::PageArea) {
294      iCount++;
295      if (pPageArea->GetFirstChildByClass(XFA_Element::ContentArea))
296        return true;
297    }
298  }
299  if (iCount > 0)
300    return false;
301
302  CXFA_Document* pDocument = pTemplateNode->GetDocument();
303  pPageArea = m_pTemplatePageSetRoot->GetChild(0, XFA_Element::PageArea);
304  if (!pPageArea) {
305    pPageArea = pDocument->CreateNode(m_pTemplatePageSetRoot->GetPacketID(),
306                                      XFA_Element::PageArea);
307    if (!pPageArea)
308      return false;
309
310    m_pTemplatePageSetRoot->InsertChild(pPageArea, nullptr);
311    pPageArea->SetFlag(XFA_NodeFlag_Initialized, true);
312  }
313  CXFA_Node* pContentArea = pPageArea->GetChild(0, XFA_Element::ContentArea);
314  if (!pContentArea) {
315    pContentArea = pDocument->CreateNode(pPageArea->GetPacketID(),
316                                         XFA_Element::ContentArea);
317    if (!pContentArea)
318      return false;
319
320    pPageArea->InsertChild(pContentArea, nullptr);
321    pContentArea->SetFlag(XFA_NodeFlag_Initialized, true);
322    pContentArea->SetMeasure(XFA_ATTRIBUTE_X,
323                             CXFA_Measurement(0.25f, XFA_UNIT_In));
324    pContentArea->SetMeasure(XFA_ATTRIBUTE_Y,
325                             CXFA_Measurement(0.25f, XFA_UNIT_In));
326    pContentArea->SetMeasure(XFA_ATTRIBUTE_W,
327                             CXFA_Measurement(8.0f, XFA_UNIT_In));
328    pContentArea->SetMeasure(XFA_ATTRIBUTE_H,
329                             CXFA_Measurement(10.5f, XFA_UNIT_In));
330  }
331  CXFA_Node* pMedium = pPageArea->GetChild(0, XFA_Element::Medium);
332  if (!pMedium) {
333    pMedium =
334        pDocument->CreateNode(pPageArea->GetPacketID(), XFA_Element::Medium);
335    if (!pContentArea)
336      return false;
337
338    pPageArea->InsertChild(pMedium, nullptr);
339    pMedium->SetFlag(XFA_NodeFlag_Initialized, true);
340    pMedium->SetMeasure(XFA_ATTRIBUTE_Short,
341                        CXFA_Measurement(8.5f, XFA_UNIT_In));
342    pMedium->SetMeasure(XFA_ATTRIBUTE_Long,
343                        CXFA_Measurement(11.0f, XFA_UNIT_In));
344  }
345  return true;
346}
347
348bool CXFA_LayoutPageMgr::PrepareFirstPage(CXFA_Node* pRootSubform) {
349  bool bProBreakBefore = false;
350  CXFA_Node* pBreakBeforeNode = nullptr;
351  while (pRootSubform) {
352    for (CXFA_Node* pBreakNode =
353             pRootSubform->GetNodeItem(XFA_NODEITEM_FirstChild);
354         pBreakNode;
355         pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
356      XFA_Element eType = pBreakNode->GetElementType();
357      if (eType == XFA_Element::BreakBefore ||
358          (eType == XFA_Element::Break &&
359           pBreakNode->GetEnum(XFA_ATTRIBUTE_Before) !=
360               XFA_ATTRIBUTEENUM_Auto)) {
361        bProBreakBefore = true;
362        pBreakBeforeNode = pBreakNode;
363        break;
364      }
365    }
366    if (bProBreakBefore)
367      break;
368
369    bProBreakBefore = true;
370    pRootSubform = pRootSubform->GetFirstChildByClass(XFA_Element::Subform);
371    while (pRootSubform &&
372           !XFA_ItemLayoutProcessor_IsTakingSpace(pRootSubform)) {
373      pRootSubform =
374          pRootSubform->GetNextSameClassSibling(XFA_Element::Subform);
375    }
376  }
377  CXFA_Node *pLeader, *pTrailer;
378  if (pBreakBeforeNode &&
379      ExecuteBreakBeforeOrAfter(pBreakBeforeNode, true, pLeader, pTrailer)) {
380    m_CurrentContainerRecordIter = m_ProposedContainerRecords.begin();
381    return true;
382  }
383  return AppendNewPage(true);
384}
385
386bool CXFA_LayoutPageMgr::AppendNewPage(bool bFirstTemPage) {
387  if (m_CurrentContainerRecordIter != GetTailPosition())
388    return true;
389
390  CXFA_Node* pPageNode = GetNextAvailPageArea(nullptr);
391  if (!pPageNode)
392    return false;
393
394  if (bFirstTemPage &&
395      m_CurrentContainerRecordIter == m_ProposedContainerRecords.end()) {
396    m_CurrentContainerRecordIter = m_ProposedContainerRecords.begin();
397  }
398  return !bFirstTemPage ||
399         m_CurrentContainerRecordIter != m_ProposedContainerRecords.end();
400}
401
402void CXFA_LayoutPageMgr::RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
403                                            CXFA_ContainerRecord* pPrevRecord) {
404  if (!pNewRecord || !pPrevRecord)
405    return;
406  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
407    RemoveLayoutItem(pNewRecord->pCurPageSet);
408    return;
409  }
410  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
411    RemoveLayoutItem(pNewRecord->pCurPageArea);
412    return;
413  }
414  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
415    RemoveLayoutItem(pNewRecord->pCurContentArea);
416    return;
417  }
418}
419
420void CXFA_LayoutPageMgr::ReorderPendingLayoutRecordToTail(
421    CXFA_ContainerRecord* pNewRecord,
422    CXFA_ContainerRecord* pPrevRecord) {
423  if (!pNewRecord || !pPrevRecord)
424    return;
425  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
426    ReorderLayoutItemToTail(pNewRecord->pCurPageSet);
427    return;
428  }
429  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
430    ReorderLayoutItemToTail(pNewRecord->pCurPageArea);
431    return;
432  }
433  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
434    ReorderLayoutItemToTail(pNewRecord->pCurContentArea);
435    return;
436  }
437}
438
439void CXFA_LayoutPageMgr::SubmitContentItem(
440    CXFA_ContentLayoutItem* pContentLayoutItem,
441    XFA_ItemLayoutProcessorResult eStatus) {
442  if (pContentLayoutItem) {
443    GetCurrentContainerRecord()->pCurContentArea->AddChild(pContentLayoutItem);
444    m_bCreateOverFlowPage = false;
445  }
446
447  if (eStatus != XFA_ItemLayoutProcessorResult::Done) {
448    if (eStatus == XFA_ItemLayoutProcessorResult::PageFullBreak &&
449        m_CurrentContainerRecordIter == GetTailPosition()) {
450      AppendNewPage();
451    }
452    m_CurrentContainerRecordIter = GetTailPosition();
453    m_pCurPageArea = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
454  }
455}
456
457FX_FLOAT CXFA_LayoutPageMgr::GetAvailHeight() {
458  CXFA_ContainerLayoutItem* pLayoutItem =
459      GetCurrentContainerRecord()->pCurContentArea;
460  if (!pLayoutItem || !pLayoutItem->m_pFormNode)
461    return 0.0f;
462
463  FX_FLOAT fAvailHeight =
464      pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
465  if (fAvailHeight >= XFA_LAYOUT_FLOAT_PERCISION)
466    return fAvailHeight;
467  if (m_CurrentContainerRecordIter == m_ProposedContainerRecords.begin())
468    return 0.0f;
469  return FLT_MAX;
470}
471
472bool XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript) {
473  CFX_WideString wsExpression;
474  pTestScript->TryContent(wsExpression);
475  if (wsExpression.IsEmpty())
476    return true;
477  return pTestScript->GetDocument()->GetNotify()->RunScript(
478      pTestScript, pTestScript->GetNodeItem(XFA_NODEITEM_Parent,
479                                            XFA_ObjectType::ContainerNode));
480}
481
482CXFA_ContainerRecord* CXFA_LayoutPageMgr::CreateContainerRecord(
483    CXFA_Node* pPageNode,
484    bool bCreateNew) {
485  CXFA_ContainerRecord* pNewRecord = new CXFA_ContainerRecord();
486  if (m_CurrentContainerRecordIter != m_ProposedContainerRecords.end()) {
487    if (!IsPageSetRootOrderedOccurrence() || !pPageNode) {
488      *pNewRecord = *GetCurrentContainerRecord();
489      m_ProposedContainerRecords.push_back(pNewRecord);
490      return pNewRecord;
491    }
492    CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
493    if (!bCreateNew) {
494      if (pPageSet == m_pTemplatePageSetRoot) {
495        pNewRecord->pCurPageSet = m_pPageSetCurRoot;
496      } else {
497        CXFA_ContainerLayoutItem* pParentLayoutItem =
498            static_cast<CXFA_ContainerLayoutItem*>(
499                pPageSet->GetUserData(XFA_LAYOUTITEMKEY));
500        if (!pParentLayoutItem)
501          pParentLayoutItem = m_pPageSetCurRoot;
502
503        pNewRecord->pCurPageSet = pParentLayoutItem;
504      }
505    } else {
506      CXFA_ContainerLayoutItem* pParentPageSetLayout = nullptr;
507      if (pPageSet == GetCurrentContainerRecord()->pCurPageSet->m_pFormNode) {
508        pParentPageSetLayout = static_cast<CXFA_ContainerLayoutItem*>(
509            GetCurrentContainerRecord()->pCurPageSet->m_pParent);
510      } else {
511        pParentPageSetLayout = static_cast<CXFA_ContainerLayoutItem*>(
512            pPageSet->GetNodeItem(XFA_NODEITEM_Parent)
513                ->GetUserData(XFA_LAYOUTITEMKEY));
514      }
515      CXFA_ContainerLayoutItem* pPageSetLayoutItem =
516          new CXFA_ContainerLayoutItem(pPageSet);
517      pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem);
518      if (!pParentPageSetLayout) {
519        CXFA_ContainerLayoutItem* pPrePageSet = m_pPageSetLayoutItemRoot;
520        while (pPrePageSet->m_pNextSibling) {
521          pPrePageSet = static_cast<CXFA_ContainerLayoutItem*>(
522              pPrePageSet->m_pNextSibling);
523        }
524
525        pPrePageSet->m_pNextSibling = pPageSetLayoutItem;
526        m_pPageSetCurRoot = pPageSetLayoutItem;
527      } else {
528        pParentPageSetLayout->AddChild(pPageSetLayoutItem);
529      }
530      pNewRecord->pCurPageSet = pPageSetLayoutItem;
531    }
532  } else {
533    if (pPageNode) {
534      CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
535      if (pPageSet == m_pTemplatePageSetRoot) {
536        pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
537      } else {
538        CXFA_ContainerLayoutItem* pPageSetLayoutItem =
539            new CXFA_ContainerLayoutItem(pPageSet);
540        pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem);
541        m_pPageSetLayoutItemRoot->AddChild(pPageSetLayoutItem);
542        pNewRecord->pCurPageSet = pPageSetLayoutItem;
543      }
544    } else {
545      pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
546    }
547  }
548  m_ProposedContainerRecords.push_back(pNewRecord);
549  return pNewRecord;
550}
551
552void CXFA_LayoutPageMgr::AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
553                                               CXFA_Node* pNewPageArea) {
554  CXFA_ContainerLayoutItem* pNewPageAreaLayoutItem = nullptr;
555  if (m_PageArray.GetSize() > m_nAvailPages) {
556    CXFA_ContainerLayoutItem* pContainerItem = m_PageArray[m_nAvailPages];
557    pContainerItem->m_pFormNode = pNewPageArea;
558    m_nAvailPages++;
559    pNewPageAreaLayoutItem = pContainerItem;
560  } else {
561    CXFA_FFNotify* pNotify = pNewPageArea->GetDocument()->GetNotify();
562    CXFA_ContainerLayoutItem* pContainerItem =
563        static_cast<CXFA_ContainerLayoutItem*>(
564            pNotify->OnCreateLayoutItem(pNewPageArea));
565    m_PageArray.Add(pContainerItem);
566    m_nAvailPages++;
567    pNotify->OnPageEvent(pContainerItem, XFA_PAGEVIEWEVENT_PostRemoved);
568    pNewPageAreaLayoutItem = pContainerItem;
569  }
570  pNewRecord->pCurPageSet->AddChild(pNewPageAreaLayoutItem);
571  pNewRecord->pCurPageArea = pNewPageAreaLayoutItem;
572  pNewRecord->pCurContentArea = nullptr;
573}
574
575void CXFA_LayoutPageMgr::AddContentAreaLayoutItem(
576    CXFA_ContainerRecord* pNewRecord,
577    CXFA_Node* pContentArea) {
578  if (!pContentArea) {
579    pNewRecord->pCurContentArea = nullptr;
580    return;
581  }
582  CXFA_ContainerLayoutItem* pNewContentAreaLayoutItem =
583      new CXFA_ContainerLayoutItem(pContentArea);
584  ASSERT(pNewRecord->pCurPageArea);
585  pNewRecord->pCurPageArea->AddChild(pNewContentAreaLayoutItem);
586  pNewRecord->pCurContentArea = pNewContentAreaLayoutItem;
587}
588
589void CXFA_LayoutPageMgr::FinishPaginatedPageSets() {
590  CXFA_ContainerLayoutItem* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot;
591  for (; pRootPageSetLayoutItem;
592       pRootPageSetLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
593           pRootPageSetLayoutItem->m_pNextSibling)) {
594    CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItem,
595                              PageSetContainerLayoutItem>
596        sIterator(pRootPageSetLayoutItem);
597    for (CXFA_ContainerLayoutItem* pPageSetLayoutItem = sIterator.GetCurrent();
598         pPageSetLayoutItem; pPageSetLayoutItem = sIterator.MoveToNext()) {
599      XFA_ATTRIBUTEENUM ePageRelation =
600          pPageSetLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Relation);
601      switch (ePageRelation) {
602        case XFA_ATTRIBUTEENUM_OrderedOccurrence:
603        default: { ProcessLastPageSet(); } break;
604        case XFA_ATTRIBUTEENUM_SimplexPaginated:
605        case XFA_ATTRIBUTEENUM_DuplexPaginated: {
606          CXFA_LayoutItem* pLastPageAreaLayoutItem = nullptr;
607          int32_t nPageAreaCount = 0;
608          for (CXFA_LayoutItem* pPageAreaLayoutItem =
609                   pPageSetLayoutItem->m_pFirstChild;
610               pPageAreaLayoutItem;
611               pPageAreaLayoutItem = pPageAreaLayoutItem->m_pNextSibling) {
612            if (pPageAreaLayoutItem->m_pFormNode->GetElementType() !=
613                XFA_Element::PageArea) {
614              continue;
615            }
616            nPageAreaCount++;
617            pLastPageAreaLayoutItem = pPageAreaLayoutItem;
618          }
619          if (!pLastPageAreaLayoutItem)
620            break;
621
622          if (!FindPageAreaFromPageSet_SimplexDuplex(
623                  pPageSetLayoutItem->m_pFormNode, nullptr, nullptr, nullptr,
624                  true, true, nPageAreaCount == 1 ? XFA_ATTRIBUTEENUM_Only
625                                                  : XFA_ATTRIBUTEENUM_Last) &&
626              (nPageAreaCount == 1 &&
627               !FindPageAreaFromPageSet_SimplexDuplex(
628                   pPageSetLayoutItem->m_pFormNode, nullptr, nullptr, nullptr,
629                   true, true, XFA_ATTRIBUTEENUM_Last))) {
630            break;
631          }
632          CXFA_Node* pNode = m_pCurPageArea;
633          XFA_ATTRIBUTEENUM eCurChoice =
634              pNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
635          if (eCurChoice == XFA_ATTRIBUTEENUM_Last) {
636            XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
637            pNode->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
638            XFA_ATTRIBUTEENUM eLastChoice =
639                pLastPageAreaLayoutItem->m_pFormNode->GetEnum(
640                    XFA_ATTRIBUTE_PagePosition);
641            if (eLastChoice == XFA_ATTRIBUTEENUM_First &&
642                (ePageRelation == XFA_ATTRIBUTEENUM_SimplexPaginated ||
643                 eOddOrEven != XFA_ATTRIBUTEENUM_Odd)) {
644              CXFA_ContainerRecord* pRecord = CreateContainerRecord();
645              AddPageAreaLayoutItem(pRecord, pNode);
646              break;
647            }
648          }
649          bool bUsable = true;
650          CFX_ArrayTemplate<FX_FLOAT> rgUsedHeights;
651          for (CXFA_LayoutItem* pChildLayoutItem =
652                   pLastPageAreaLayoutItem->m_pFirstChild;
653               pChildLayoutItem;
654               pChildLayoutItem = pChildLayoutItem->m_pNextSibling) {
655            if (pChildLayoutItem->m_pFormNode->GetElementType() !=
656                XFA_Element::ContentArea) {
657              continue;
658            }
659            FX_FLOAT fUsedHeight = 0;
660            for (CXFA_LayoutItem* pContentChildLayoutItem =
661                     pChildLayoutItem->m_pFirstChild;
662                 pContentChildLayoutItem;
663                 pContentChildLayoutItem =
664                     pContentChildLayoutItem->m_pNextSibling) {
665              if (CXFA_ContentLayoutItem* pContent =
666                      pContentChildLayoutItem->AsContentLayoutItem()) {
667                fUsedHeight += pContent->m_sSize.height;
668              }
669            }
670            rgUsedHeights.Add(fUsedHeight);
671          }
672          int32_t iCurContentAreaIndex = -1;
673          for (CXFA_Node* pContentAreaNode =
674                   pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
675               pContentAreaNode;
676               pContentAreaNode =
677                   pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
678            if (pContentAreaNode->GetElementType() !=
679                XFA_Element::ContentArea) {
680              continue;
681            }
682            iCurContentAreaIndex++;
683            if (rgUsedHeights[iCurContentAreaIndex] >
684                pContentAreaNode->GetMeasure(XFA_ATTRIBUTE_H)
685                        .ToUnit(XFA_UNIT_Pt) +
686                    XFA_LAYOUT_FLOAT_PERCISION) {
687              bUsable = false;
688              break;
689            }
690          }
691          if (bUsable) {
692            CXFA_LayoutItem* pChildLayoutItem =
693                pLastPageAreaLayoutItem->m_pFirstChild;
694            CXFA_Node* pContentAreaNode =
695                pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
696            pLastPageAreaLayoutItem->m_pFormNode = pNode;
697            while (pChildLayoutItem && pContentAreaNode) {
698              if (pChildLayoutItem->m_pFormNode->GetElementType() !=
699                  XFA_Element::ContentArea) {
700                pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
701                continue;
702              }
703              if (pContentAreaNode->GetElementType() !=
704                  XFA_Element::ContentArea) {
705                pContentAreaNode =
706                    pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
707                continue;
708              }
709              pChildLayoutItem->m_pFormNode = pContentAreaNode;
710              pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
711              pContentAreaNode =
712                  pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
713            }
714          } else if (pNode->GetEnum(XFA_ATTRIBUTE_PagePosition) ==
715                     XFA_ATTRIBUTEENUM_Last) {
716            CXFA_ContainerRecord* pRecord = CreateContainerRecord();
717            AddPageAreaLayoutItem(pRecord, pNode);
718          }
719        } break;
720      }
721    }
722  }
723}
724
725int32_t CXFA_LayoutPageMgr::GetPageCount() const {
726  return m_PageArray.GetSize();
727}
728
729CXFA_ContainerLayoutItem* CXFA_LayoutPageMgr::GetPage(int32_t index) const {
730  if (index < 0 || index >= m_PageArray.GetSize())
731    return nullptr;
732  return m_PageArray[index];
733}
734
735int32_t CXFA_LayoutPageMgr::GetPageIndex(
736    const CXFA_ContainerLayoutItem* pPage) const {
737  // FIXME: Find() method should take const.
738  return m_PageArray.Find(const_cast<CXFA_ContainerLayoutItem*>(pPage));
739}
740
741bool CXFA_LayoutPageMgr::RunBreak(XFA_Element eBreakType,
742                                  XFA_ATTRIBUTEENUM eTargetType,
743                                  CXFA_Node* pTarget,
744                                  bool bStartNew) {
745  bool bRet = false;
746  switch (eTargetType) {
747    case XFA_ATTRIBUTEENUM_ContentArea:
748      if (pTarget && pTarget->GetElementType() != XFA_Element::ContentArea)
749        pTarget = nullptr;
750      if (!pTarget ||
751          m_CurrentContainerRecordIter == m_ProposedContainerRecords.end() ||
752          pTarget !=
753              GetCurrentContainerRecord()->pCurContentArea->m_pFormNode ||
754          bStartNew) {
755        CXFA_Node* pPageArea = nullptr;
756        if (pTarget)
757          pPageArea = pTarget->GetNodeItem(XFA_NODEITEM_Parent);
758
759        pPageArea = GetNextAvailPageArea(pPageArea, pTarget);
760        bRet = !!pPageArea;
761      }
762      break;
763    case XFA_ATTRIBUTEENUM_PageArea:
764      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
765        pTarget = nullptr;
766      if (!pTarget ||
767          m_CurrentContainerRecordIter == m_ProposedContainerRecords.end() ||
768          pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode ||
769          bStartNew) {
770        CXFA_Node* pPageArea = GetNextAvailPageArea(pTarget, nullptr, true);
771        bRet = !!pPageArea;
772      }
773      break;
774    case XFA_ATTRIBUTEENUM_PageOdd:
775      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
776        pTarget = nullptr;
777      break;
778    case XFA_ATTRIBUTEENUM_PageEven:
779      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
780        pTarget = nullptr;
781      break;
782    case XFA_ATTRIBUTEENUM_Auto:
783    default:
784      break;
785  }
786  return bRet;
787}
788
789bool CXFA_LayoutPageMgr::ExecuteBreakBeforeOrAfter(
790    CXFA_Node* pCurNode,
791    bool bBefore,
792    CXFA_Node*& pBreakLeaderTemplate,
793    CXFA_Node*& pBreakTrailerTemplate) {
794  XFA_Element eType = pCurNode->GetElementType();
795  switch (eType) {
796    case XFA_Element::BreakBefore:
797    case XFA_Element::BreakAfter: {
798      CFX_WideStringC wsBreakLeader, wsBreakTrailer;
799      CXFA_Node* pFormNode = pCurNode->GetNodeItem(
800          XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
801      CXFA_Node* pContainer = pFormNode->GetTemplateNode();
802      bool bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
803      CXFA_Node* pScript = pCurNode->GetFirstChildByClass(XFA_Element::Script);
804      if (pScript && !XFA_LayoutPageMgr_RunBreakTestScript(pScript))
805        return false;
806
807      CFX_WideStringC wsTarget = pCurNode->GetCData(XFA_ATTRIBUTE_Target);
808      CXFA_Node* pTarget =
809          ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsTarget);
810      wsBreakTrailer = pCurNode->GetCData(XFA_ATTRIBUTE_Trailer);
811      wsBreakLeader = pCurNode->GetCData(XFA_ATTRIBUTE_Leader);
812      pBreakLeaderTemplate =
813          ResolveBreakTarget(pContainer, true, wsBreakLeader);
814      pBreakTrailerTemplate =
815          ResolveBreakTarget(pContainer, true, wsBreakTrailer);
816      if (RunBreak(eType, pCurNode->GetEnum(XFA_ATTRIBUTE_TargetType), pTarget,
817                   bStartNew)) {
818        return true;
819      }
820      if (!m_ProposedContainerRecords.empty() &&
821          m_CurrentContainerRecordIter == m_ProposedContainerRecords.begin() &&
822          eType == XFA_Element::BreakBefore) {
823        CXFA_Node* pParentNode = pFormNode->GetNodeItem(
824            XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
825        if (!pParentNode ||
826            pFormNode !=
827                pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild,
828                                         XFA_ObjectType::ContainerNode)) {
829          break;
830        }
831        pParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
832        if (!pParentNode ||
833            pParentNode->GetElementType() != XFA_Element::Form) {
834          break;
835        }
836        return true;
837      }
838      break;
839    }
840    case XFA_Element::Break: {
841      bool bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
842      CFX_WideStringC wsTarget = pCurNode->GetCData(
843          bBefore ? XFA_ATTRIBUTE_BeforeTarget : XFA_ATTRIBUTE_AfterTarget);
844      CXFA_Node* pTarget =
845          ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsTarget);
846      if (RunBreak(bBefore ? XFA_Element::BreakBefore : XFA_Element::BreakAfter,
847                   pCurNode->GetEnum(bBefore ? XFA_ATTRIBUTE_Before
848                                             : XFA_ATTRIBUTE_After),
849                   pTarget, bStartNew)) {
850        return true;
851      }
852      break;
853    }
854    default:
855      break;
856  }
857  return false;
858}
859
860bool CXFA_LayoutPageMgr::ProcessBreakBeforeOrAfter(
861    CXFA_Node* pBreakNode,
862    bool bBefore,
863    CXFA_Node*& pBreakLeaderNode,
864    CXFA_Node*& pBreakTrailerNode,
865    bool& bCreatePage) {
866  CXFA_Node* pLeaderTemplate = nullptr;
867  CXFA_Node* pTrailerTemplate = nullptr;
868  CXFA_Node* pFormNode = pBreakNode->GetNodeItem(XFA_NODEITEM_Parent,
869                                                 XFA_ObjectType::ContainerNode);
870  if (XFA_ItemLayoutProcessor_IsTakingSpace(pFormNode)) {
871    bCreatePage = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore,
872                                            pLeaderTemplate, pTrailerTemplate);
873    CXFA_Document* pDocument = pBreakNode->GetDocument();
874    CXFA_Node* pDataScope = nullptr;
875    pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent,
876                                       XFA_ObjectType::ContainerNode);
877    if (pLeaderTemplate) {
878      if (!pDataScope)
879        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
880
881      pBreakLeaderNode = pDocument->DataMerge_CopyContainer(
882          pLeaderTemplate, pFormNode, pDataScope, true, true, true);
883      pDocument->DataMerge_UpdateBindingRelations(pBreakLeaderNode);
884      SetLayoutGeneratedNodeFlag(pBreakLeaderNode);
885    }
886    if (pTrailerTemplate) {
887      if (!pDataScope)
888        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
889
890      pBreakTrailerNode = pDocument->DataMerge_CopyContainer(
891          pTrailerTemplate, pFormNode, pDataScope, true, true, true);
892      pDocument->DataMerge_UpdateBindingRelations(pBreakTrailerNode);
893      SetLayoutGeneratedNodeFlag(pBreakTrailerNode);
894    }
895    return true;
896  }
897  return false;
898}
899
900bool CXFA_LayoutPageMgr::ProcessBookendLeaderOrTrailer(
901    CXFA_Node* pBookendNode,
902    bool bLeader,
903    CXFA_Node*& pBookendAppendNode) {
904  CXFA_Node* pLeaderTemplate = nullptr;
905  CXFA_Node* pFormNode = pBookendNode->GetNodeItem(
906      XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
907  if (ResolveBookendLeaderOrTrailer(pBookendNode, bLeader, pLeaderTemplate)) {
908    CXFA_Document* pDocument = pBookendNode->GetDocument();
909    CXFA_Node* pDataScope = nullptr;
910    if (pLeaderTemplate) {
911      if (!pDataScope)
912        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
913
914      pBookendAppendNode = pDocument->DataMerge_CopyContainer(
915          pLeaderTemplate, pFormNode, pDataScope, true, true, true);
916      pDocument->DataMerge_UpdateBindingRelations(pBookendAppendNode);
917      SetLayoutGeneratedNodeFlag(pBookendAppendNode);
918      return true;
919    }
920  }
921  return false;
922}
923
924CXFA_Node* CXFA_LayoutPageMgr::BreakOverflow(CXFA_Node* pOverflowNode,
925                                             CXFA_Node*& pLeaderTemplate,
926                                             CXFA_Node*& pTrailerTemplate,
927                                             bool bCreatePage) {
928  CXFA_Node* pContainer =
929      pOverflowNode
930          ->GetNodeItem(XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode)
931          ->GetTemplateNode();
932  if (pOverflowNode->GetElementType() == XFA_Element::Break) {
933    CFX_WideStringC wsOverflowLeader;
934    CFX_WideStringC wsOverflowTarget;
935    CFX_WideStringC wsOverflowTrailer;
936    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
937    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
938    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
939    if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() ||
940        !wsOverflowTarget.IsEmpty()) {
941      if (!wsOverflowTarget.IsEmpty() && bCreatePage &&
942          !m_bCreateOverFlowPage) {
943        CXFA_Node* pTarget =
944            ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsOverflowTarget);
945        if (pTarget) {
946          m_bCreateOverFlowPage = true;
947          switch (pTarget->GetElementType()) {
948            case XFA_Element::PageArea:
949              RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_PageArea,
950                       pTarget, true);
951              break;
952            case XFA_Element::ContentArea:
953              RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_ContentArea,
954                       pTarget, true);
955              break;
956            default:
957              break;
958          }
959        }
960      }
961      if (!bCreatePage) {
962        pLeaderTemplate =
963            ResolveBreakTarget(pContainer, true, wsOverflowLeader);
964        pTrailerTemplate =
965            ResolveBreakTarget(pContainer, true, wsOverflowTrailer);
966      }
967      return pOverflowNode;
968    }
969    return nullptr;
970  }
971
972  if (pOverflowNode->GetElementType() != XFA_Element::Overflow)
973    return nullptr;
974
975  CFX_WideStringC wsOverflowLeader;
976  CFX_WideStringC wsOverflowTrailer;
977  CFX_WideStringC wsOverflowTarget;
978  pOverflowNode->TryCData(XFA_ATTRIBUTE_Leader, wsOverflowLeader);
979  pOverflowNode->TryCData(XFA_ATTRIBUTE_Trailer, wsOverflowTrailer);
980  pOverflowNode->TryCData(XFA_ATTRIBUTE_Target, wsOverflowTarget);
981  if (!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
982    CXFA_Node* pTarget =
983        ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsOverflowTarget);
984    if (pTarget) {
985      m_bCreateOverFlowPage = true;
986      switch (pTarget->GetElementType()) {
987        case XFA_Element::PageArea:
988          RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget,
989                   true);
990          break;
991        case XFA_Element::ContentArea:
992          RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_ContentArea,
993                   pTarget, true);
994          break;
995        default:
996          break;
997      }
998    }
999  }
1000  if (!bCreatePage) {
1001    pLeaderTemplate = ResolveBreakTarget(pContainer, true, wsOverflowLeader);
1002    pTrailerTemplate = ResolveBreakTarget(pContainer, true, wsOverflowTrailer);
1003  }
1004  return pOverflowNode;
1005}
1006
1007bool CXFA_LayoutPageMgr::ProcessOverflow(CXFA_Node* pFormNode,
1008                                         CXFA_Node*& pLeaderNode,
1009                                         CXFA_Node*& pTrailerNode,
1010                                         bool bDataMerge,
1011                                         bool bCreatePage) {
1012  if (!pFormNode)
1013    return false;
1014
1015  CXFA_Node* pLeaderTemplate = nullptr;
1016  CXFA_Node* pTrailerTemplate = nullptr;
1017  bool bIsOverflowNode = false;
1018  if (pFormNode->GetElementType() == XFA_Element::Overflow ||
1019      pFormNode->GetElementType() == XFA_Element::Break) {
1020    bIsOverflowNode = true;
1021  }
1022  for (CXFA_Node* pCurNode =
1023           bIsOverflowNode ? pFormNode
1024                           : pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1025       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
1026    if (BreakOverflow(pCurNode, pLeaderTemplate, pTrailerTemplate,
1027                      bCreatePage)) {
1028      if (bIsOverflowNode)
1029        pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent);
1030
1031      CXFA_Document* pDocument = pCurNode->GetDocument();
1032      CXFA_Node* pDataScope = nullptr;
1033      if (pLeaderTemplate) {
1034        if (!pDataScope)
1035          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
1036
1037        pLeaderNode = pDocument->DataMerge_CopyContainer(
1038            pLeaderTemplate, pFormNode, pDataScope, true, true, true);
1039        pDocument->DataMerge_UpdateBindingRelations(pLeaderNode);
1040        SetLayoutGeneratedNodeFlag(pLeaderNode);
1041      }
1042      if (pTrailerTemplate) {
1043        if (!pDataScope)
1044          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
1045
1046        pTrailerNode = pDocument->DataMerge_CopyContainer(
1047            pTrailerTemplate, pFormNode, pDataScope, true, true, true);
1048        pDocument->DataMerge_UpdateBindingRelations(pTrailerNode);
1049        SetLayoutGeneratedNodeFlag(pTrailerNode);
1050      }
1051      return true;
1052    }
1053    if (bIsOverflowNode) {
1054      break;
1055    }
1056  }
1057  return false;
1058}
1059
1060bool CXFA_LayoutPageMgr::ResolveBookendLeaderOrTrailer(
1061    CXFA_Node* pBookendNode,
1062    bool bLeader,
1063    CXFA_Node*& pBookendAppendTemplate) {
1064  CFX_WideStringC wsBookendLeader;
1065  CXFA_Node* pContainer =
1066      pBookendNode
1067          ->GetNodeItem(XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode)
1068          ->GetTemplateNode();
1069  if (pBookendNode->GetElementType() == XFA_Element::Break) {
1070    pBookendNode->TryCData(
1071        bLeader ? XFA_ATTRIBUTE_BookendLeader : XFA_ATTRIBUTE_BookendTrailer,
1072        wsBookendLeader);
1073    if (!wsBookendLeader.IsEmpty()) {
1074      pBookendAppendTemplate =
1075          ResolveBreakTarget(pContainer, false, wsBookendLeader);
1076      return true;
1077    }
1078    return false;
1079  } else if (pBookendNode->GetElementType() == XFA_Element::Bookend) {
1080    pBookendNode->TryCData(
1081        bLeader ? XFA_ATTRIBUTE_Leader : XFA_ATTRIBUTE_Trailer,
1082        wsBookendLeader);
1083    pBookendAppendTemplate =
1084        ResolveBreakTarget(pContainer, true, wsBookendLeader);
1085    return true;
1086  }
1087  return false;
1088}
1089
1090bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet(CXFA_Node* pPageSet,
1091                                                 CXFA_Node* pStartChild,
1092                                                 CXFA_Node* pTargetPageArea,
1093                                                 CXFA_Node* pTargetContentArea,
1094                                                 bool bNewPage,
1095                                                 bool bQuery) {
1096  if (!pPageSet && !pStartChild)
1097    return false;
1098
1099  if (IsPageSetRootOrderedOccurrence()) {
1100    return FindPageAreaFromPageSet_Ordered(pPageSet, pStartChild,
1101                                           pTargetPageArea, pTargetContentArea,
1102                                           bNewPage, bQuery);
1103  }
1104  XFA_ATTRIBUTEENUM ePreferredPosition =
1105      m_CurrentContainerRecordIter != m_ProposedContainerRecords.end()
1106          ? XFA_ATTRIBUTEENUM_Rest
1107          : XFA_ATTRIBUTEENUM_First;
1108  return FindPageAreaFromPageSet_SimplexDuplex(
1109      pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage,
1110      bQuery, ePreferredPosition);
1111}
1112
1113bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet_Ordered(
1114    CXFA_Node* pPageSet,
1115    CXFA_Node* pStartChild,
1116    CXFA_Node* pTargetPageArea,
1117    CXFA_Node* pTargetContentArea,
1118    bool bNewPage,
1119    bool bQuery) {
1120  int32_t iPageSetCount = 0;
1121  if (!pStartChild && !bQuery) {
1122    auto it = m_pPageSetMap.find(pPageSet);
1123    if (it != m_pPageSetMap.end())
1124      iPageSetCount = it->second;
1125    int32_t iMax = -1;
1126    CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_Element::Occur);
1127    if (pOccurNode)
1128      pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, false);
1129    if (iMax >= 0 && iMax <= iPageSetCount)
1130      return false;
1131  }
1132  bool bRes = false;
1133  CXFA_Node* pCurrentNode =
1134      pStartChild ? pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling)
1135                  : pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
1136  for (; pCurrentNode;
1137       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1138    if (pCurrentNode->GetElementType() == XFA_Element::PageArea) {
1139      if ((pTargetPageArea == pCurrentNode || !pTargetPageArea)) {
1140        if (!pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea)) {
1141          if (pTargetPageArea == pCurrentNode) {
1142            CreateMinPageRecord(pCurrentNode, true);
1143            pTargetPageArea = nullptr;
1144          }
1145          continue;
1146        }
1147        if (!bQuery) {
1148          CXFA_ContainerRecord* pNewRecord =
1149              CreateContainerRecord(pCurrentNode, !pStartChild);
1150          AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
1151          if (!pTargetContentArea) {
1152            pTargetContentArea =
1153                pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea);
1154          }
1155          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
1156        }
1157        m_pCurPageArea = pCurrentNode;
1158        m_nCurPageCount = 1;
1159        bRes = true;
1160        break;
1161      }
1162      if (!bQuery)
1163        CreateMinPageRecord(pCurrentNode, false);
1164    } else if (pCurrentNode->GetElementType() == XFA_Element::PageSet) {
1165      if (FindPageAreaFromPageSet_Ordered(pCurrentNode, nullptr,
1166                                          pTargetPageArea, pTargetContentArea,
1167                                          bNewPage, bQuery)) {
1168        bRes = true;
1169        break;
1170      }
1171      if (!bQuery)
1172        CreateMinPageSetRecord(pCurrentNode, true);
1173    }
1174  }
1175  if (!pStartChild && bRes && !bQuery)
1176    m_pPageSetMap[pPageSet] = ++iPageSetCount;
1177  return bRes;
1178}
1179
1180bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet_SimplexDuplex(
1181    CXFA_Node* pPageSet,
1182    CXFA_Node* pStartChild,
1183    CXFA_Node* pTargetPageArea,
1184    CXFA_Node* pTargetContentArea,
1185    bool bNewPage,
1186    bool bQuery,
1187    XFA_ATTRIBUTEENUM ePreferredPosition) {
1188  const XFA_ATTRIBUTEENUM eFallbackPosition = XFA_ATTRIBUTEENUM_Any;
1189  CXFA_Node* pPreferredPageArea = nullptr;
1190  CXFA_Node* pFallbackPageArea = nullptr;
1191  CXFA_Node* pCurrentNode = nullptr;
1192  if (!pStartChild || pStartChild->GetElementType() == XFA_Element::PageArea)
1193    pCurrentNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
1194  else
1195    pCurrentNode = pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1196
1197  for (; pCurrentNode;
1198       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1199    if (pCurrentNode->GetElementType() == XFA_Element::PageArea) {
1200      if (!MatchPageAreaOddOrEven(pCurrentNode, false))
1201        continue;
1202
1203      XFA_ATTRIBUTEENUM eCurPagePosition =
1204          pCurrentNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
1205      if (ePreferredPosition == XFA_ATTRIBUTEENUM_Last) {
1206        if (eCurPagePosition != ePreferredPosition)
1207          continue;
1208        if (m_ePageSetMode == XFA_ATTRIBUTEENUM_SimplexPaginated ||
1209            pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) ==
1210                XFA_ATTRIBUTEENUM_Any) {
1211          pPreferredPageArea = pCurrentNode;
1212          break;
1213        }
1214        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1215        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
1216        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
1217                                                 XFA_Element::ContentArea));
1218        pPreferredPageArea = pCurrentNode;
1219        return false;
1220      }
1221      if (ePreferredPosition == XFA_ATTRIBUTEENUM_Only) {
1222        if (eCurPagePosition != ePreferredPosition)
1223          continue;
1224        if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated ||
1225            pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) ==
1226                XFA_ATTRIBUTEENUM_Any) {
1227          pPreferredPageArea = pCurrentNode;
1228          break;
1229        }
1230        return false;
1231      }
1232      if ((pTargetPageArea == pCurrentNode || !pTargetPageArea)) {
1233        if (!pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea)) {
1234          if (pTargetPageArea == pCurrentNode) {
1235            CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1236            AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
1237            pTargetPageArea = nullptr;
1238          }
1239          continue;
1240        }
1241        if ((ePreferredPosition == XFA_ATTRIBUTEENUM_Rest &&
1242             eCurPagePosition == XFA_ATTRIBUTEENUM_Any) ||
1243            eCurPagePosition == ePreferredPosition) {
1244          pPreferredPageArea = pCurrentNode;
1245          break;
1246        } else if (eCurPagePosition == eFallbackPosition &&
1247                   !pFallbackPageArea) {
1248          pFallbackPageArea = pCurrentNode;
1249        }
1250      } else if (pTargetPageArea &&
1251                 !MatchPageAreaOddOrEven(pTargetPageArea, false)) {
1252        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1253        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
1254        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
1255                                                 XFA_Element::ContentArea));
1256      }
1257    } else if (pCurrentNode->GetElementType() == XFA_Element::PageSet) {
1258      if (FindPageAreaFromPageSet_SimplexDuplex(
1259              pCurrentNode, nullptr, pTargetPageArea, pTargetContentArea,
1260              bNewPage, bQuery, ePreferredPosition)) {
1261        break;
1262      }
1263    }
1264  }
1265
1266  CXFA_Node* pCurPageArea = nullptr;
1267  if (pPreferredPageArea)
1268    pCurPageArea = pPreferredPageArea;
1269  else if (pFallbackPageArea)
1270    pCurPageArea = pFallbackPageArea;
1271
1272  if (!pCurPageArea)
1273    return false;
1274
1275  if (!bQuery) {
1276    CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1277    AddPageAreaLayoutItem(pNewRecord, pCurPageArea);
1278    if (!pTargetContentArea) {
1279      pTargetContentArea =
1280          pCurPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
1281    }
1282    AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
1283  }
1284  m_pCurPageArea = pCurPageArea;
1285  return true;
1286}
1287
1288bool CXFA_LayoutPageMgr::MatchPageAreaOddOrEven(CXFA_Node* pPageArea,
1289                                                bool bLastMatch) {
1290  if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated)
1291    return true;
1292
1293  XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
1294  pPageArea->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
1295  if (eOddOrEven != XFA_ATTRIBUTEENUM_Any) {
1296    int32_t iPageCount = GetPageCount();
1297    if (bLastMatch) {
1298      return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 1
1299                                                 : iPageCount % 2 == 0;
1300    }
1301    return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 0
1302                                               : iPageCount % 2 == 1;
1303  }
1304  return true;
1305}
1306
1307CXFA_Node* CXFA_LayoutPageMgr::GetNextAvailPageArea(
1308    CXFA_Node* pTargetPageArea,
1309    CXFA_Node* pTargetContentArea,
1310    bool bNewPage,
1311    bool bQuery) {
1312  if (!m_pCurPageArea) {
1313    FindPageAreaFromPageSet(m_pTemplatePageSetRoot, nullptr, pTargetPageArea,
1314                            pTargetContentArea, bNewPage, bQuery);
1315    ASSERT(m_pCurPageArea);
1316    return m_pCurPageArea;
1317  }
1318
1319  if (!pTargetPageArea || pTargetPageArea == m_pCurPageArea) {
1320    if (!bNewPage && GetNextContentArea(pTargetContentArea))
1321      return m_pCurPageArea;
1322
1323    if (IsPageSetRootOrderedOccurrence()) {
1324      int32_t iMax = -1;
1325      CXFA_Node* pOccurNode =
1326          m_pCurPageArea->GetFirstChildByClass(XFA_Element::Occur);
1327      if (pOccurNode)
1328        pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, false);
1329      if ((iMax < 0 || m_nCurPageCount < iMax)) {
1330        if (!bQuery) {
1331          CXFA_ContainerRecord* pNewRecord =
1332              CreateContainerRecord(m_pCurPageArea);
1333          AddPageAreaLayoutItem(pNewRecord, m_pCurPageArea);
1334          if (!pTargetContentArea) {
1335            pTargetContentArea =
1336                m_pCurPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
1337          }
1338          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
1339        }
1340        m_nCurPageCount++;
1341        return m_pCurPageArea;
1342      }
1343    }
1344  }
1345
1346  if (!bQuery && IsPageSetRootOrderedOccurrence())
1347    CreateMinPageRecord(m_pCurPageArea, false, true);
1348  if (FindPageAreaFromPageSet(m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent),
1349                              m_pCurPageArea, pTargetPageArea,
1350                              pTargetContentArea, bNewPage, bQuery)) {
1351    return m_pCurPageArea;
1352  }
1353
1354  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
1355  while (true) {
1356    if (FindPageAreaFromPageSet(pPageSet, nullptr, pTargetPageArea,
1357                                pTargetContentArea, bNewPage, bQuery)) {
1358      return m_pCurPageArea;
1359    }
1360    if (!bQuery && IsPageSetRootOrderedOccurrence())
1361      CreateMinPageSetRecord(pPageSet);
1362    if (FindPageAreaFromPageSet(nullptr, pPageSet, pTargetPageArea,
1363                                pTargetContentArea, bNewPage, bQuery)) {
1364      return m_pCurPageArea;
1365    }
1366    if (pPageSet == m_pTemplatePageSetRoot)
1367      break;
1368
1369    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
1370  }
1371  return nullptr;
1372}
1373
1374bool CXFA_LayoutPageMgr::GetNextContentArea(CXFA_Node* pContentArea) {
1375  CXFA_Node* pCurContentNode =
1376      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
1377  if (!pContentArea) {
1378    pContentArea =
1379        pCurContentNode->GetNextSameClassSibling(XFA_Element::ContentArea);
1380    if (!pContentArea)
1381      return false;
1382  } else {
1383    if (pContentArea->GetNodeItem(XFA_NODEITEM_Parent) != m_pCurPageArea)
1384      return false;
1385
1386    CXFA_ContainerLayoutItem* pContentAreaLayout = nullptr;
1387    if (!CheckContentAreaNotUsed(GetCurrentContainerRecord()->pCurPageArea,
1388                                 pContentArea, pContentAreaLayout)) {
1389      return false;
1390    }
1391    if (pContentAreaLayout) {
1392      if (pContentAreaLayout->m_pFormNode != pCurContentNode) {
1393        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1394        pNewRecord->pCurContentArea = pContentAreaLayout;
1395        return true;
1396      }
1397      return false;
1398    }
1399  }
1400
1401  CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1402  AddContentAreaLayoutItem(pNewRecord, pContentArea);
1403  return true;
1404}
1405
1406void CXFA_LayoutPageMgr::InitPageSetMap() {
1407  if (!IsPageSetRootOrderedOccurrence())
1408    return;
1409
1410  CXFA_NodeIterator sIterator(m_pTemplatePageSetRoot);
1411  for (CXFA_Node* pPageSetNode = sIterator.GetCurrent(); pPageSetNode;
1412       pPageSetNode = sIterator.MoveToNext()) {
1413    if (pPageSetNode->GetElementType() == XFA_Element::PageSet) {
1414      XFA_ATTRIBUTEENUM eRelation =
1415          pPageSetNode->GetEnum(XFA_ATTRIBUTE_Relation);
1416      if (eRelation == XFA_ATTRIBUTEENUM_OrderedOccurrence)
1417        m_pPageSetMap[pPageSetNode] = 0;
1418    }
1419  }
1420}
1421
1422int32_t CXFA_LayoutPageMgr::CreateMinPageRecord(CXFA_Node* pPageArea,
1423                                                bool bTargetPageArea,
1424                                                bool bCreateLast) {
1425  if (!pPageArea)
1426    return 0;
1427
1428  CXFA_Node* pOccurNode = pPageArea->GetFirstChildByClass(XFA_Element::Occur);
1429  int32_t iMin = 0;
1430  if ((pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, false)) ||
1431      bTargetPageArea) {
1432    CXFA_Node* pContentArea =
1433        pPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
1434    if (iMin < 1 && bTargetPageArea && !pContentArea)
1435      iMin = 1;
1436
1437    int32_t i = 0;
1438    if (bCreateLast)
1439      i = m_nCurPageCount;
1440
1441    for (; i < iMin; i++) {
1442      CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
1443      AddPageAreaLayoutItem(pNewRecord, pPageArea);
1444      AddContentAreaLayoutItem(pNewRecord, pContentArea);
1445    }
1446  }
1447  return iMin;
1448}
1449
1450void CXFA_LayoutPageMgr::CreateMinPageSetRecord(CXFA_Node* pPageSet,
1451                                                bool bCreateAll) {
1452  if (!pPageSet)
1453    return;
1454
1455  auto it = m_pPageSetMap.find(pPageSet);
1456  if (it == m_pPageSetMap.end())
1457    return;
1458
1459  int32_t iCurSetCount = it->second;
1460  if (bCreateAll)
1461    iCurSetCount = 0;
1462
1463  CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_Element::Occur);
1464  int32_t iMin = 0;
1465  if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, false)) {
1466    if (iCurSetCount < iMin) {
1467      for (int32_t i = 0; i < iMin - iCurSetCount; i++) {
1468        for (CXFA_Node* pCurrentPageNode =
1469                 pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
1470             pCurrentPageNode; pCurrentPageNode = pCurrentPageNode->GetNodeItem(
1471                                   XFA_NODEITEM_NextSibling)) {
1472          if (pCurrentPageNode->GetElementType() == XFA_Element::PageArea) {
1473            CreateMinPageRecord(pCurrentPageNode, false);
1474          } else if (pCurrentPageNode->GetElementType() ==
1475                     XFA_Element::PageSet) {
1476            CreateMinPageSetRecord(pCurrentPageNode, true);
1477          }
1478        }
1479      }
1480      m_pPageSetMap[pPageSet] = iMin;
1481    }
1482  }
1483}
1484
1485void CXFA_LayoutPageMgr::CreateNextMinRecord(CXFA_Node* pRecordNode) {
1486  if (!pRecordNode)
1487    return;
1488
1489  for (CXFA_Node* pCurrentNode =
1490           pRecordNode->GetNodeItem(XFA_NODEITEM_NextSibling);
1491       pCurrentNode;
1492       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1493    if (pCurrentNode->GetElementType() == XFA_Element::PageArea)
1494      CreateMinPageRecord(pCurrentNode, false);
1495    else if (pCurrentNode->GetElementType() == XFA_Element::PageSet)
1496      CreateMinPageSetRecord(pCurrentNode, true);
1497  }
1498}
1499
1500void CXFA_LayoutPageMgr::ProcessLastPageSet() {
1501  CreateMinPageRecord(m_pCurPageArea, false, true);
1502  CreateNextMinRecord(m_pCurPageArea);
1503  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
1504  while (true) {
1505    CreateMinPageSetRecord(pPageSet);
1506    if (pPageSet == m_pTemplatePageSetRoot)
1507      break;
1508
1509    CreateNextMinRecord(pPageSet);
1510    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
1511  }
1512}
1513
1514bool CXFA_LayoutPageMgr::GetNextAvailContentHeight(FX_FLOAT fChildHeight) {
1515  CXFA_Node* pCurContentNode =
1516      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
1517  if (!pCurContentNode)
1518    return false;
1519
1520  pCurContentNode =
1521      pCurContentNode->GetNextSameClassSibling(XFA_Element::ContentArea);
1522  if (pCurContentNode) {
1523    FX_FLOAT fNextContentHeight =
1524        pCurContentNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
1525    return fNextContentHeight > fChildHeight;
1526  }
1527
1528  CXFA_Node* pPageNode = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
1529  CXFA_Node* pOccurNode = pPageNode->GetFirstChildByClass(XFA_Element::Occur);
1530  int32_t iMax = 0;
1531  if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, false)) {
1532    if (m_nCurPageCount == iMax) {
1533      CXFA_Node* pSrcPage = m_pCurPageArea;
1534      int32_t nSrcPageCount = m_nCurPageCount;
1535      auto psSrcIter = GetTailPosition();
1536      CXFA_Node* pNextPage =
1537          GetNextAvailPageArea(nullptr, nullptr, false, true);
1538      m_pCurPageArea = pSrcPage;
1539      m_nCurPageCount = nSrcPageCount;
1540      CXFA_ContainerRecord* pPrevRecord = *psSrcIter++;
1541      while (psSrcIter != m_ProposedContainerRecords.end()) {
1542        auto psSaveIter = psSrcIter;
1543        CXFA_ContainerRecord* pInsertRecord = *psSrcIter++;
1544        RemoveLayoutRecord(pInsertRecord, pPrevRecord);
1545        delete pInsertRecord;
1546        m_ProposedContainerRecords.erase(psSaveIter);
1547      }
1548      if (pNextPage) {
1549        CXFA_Node* pContentArea =
1550            pNextPage->GetFirstChildByClass(XFA_Element::ContentArea);
1551        if (pContentArea) {
1552          FX_FLOAT fNextContentHeight =
1553              pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
1554          if (fNextContentHeight > fChildHeight)
1555            return true;
1556        }
1557      }
1558      return false;
1559    }
1560  }
1561
1562  CXFA_Node* pContentArea =
1563      pPageNode->GetFirstChildByClass(XFA_Element::ContentArea);
1564  FX_FLOAT fNextContentHeight =
1565      pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
1566  if (fNextContentHeight < XFA_LAYOUT_FLOAT_PERCISION)
1567    return true;
1568  if (fNextContentHeight > fChildHeight)
1569    return true;
1570  return false;
1571}
1572
1573void CXFA_LayoutPageMgr::ClearData() {
1574  if (!m_pTemplatePageSetRoot)
1575    return;
1576
1577  auto sPos = m_ProposedContainerRecords.begin();
1578  while (sPos != m_ProposedContainerRecords.end()) {
1579    CXFA_ContainerRecord* pRecord = *sPos++;
1580    delete pRecord;
1581  }
1582  m_ProposedContainerRecords.clear();
1583  m_CurrentContainerRecordIter = m_ProposedContainerRecords.end();
1584  m_pCurPageArea = nullptr;
1585  m_nCurPageCount = 0;
1586  m_bCreateOverFlowPage = false;
1587  m_pPageSetMap.clear();
1588}
1589
1590void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem) {
1591  CXFA_LayoutItem* pNextLayoutItem;
1592  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
1593  while (pCurLayoutItem) {
1594    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
1595    if (pCurLayoutItem->IsContentLayoutItem()) {
1596      if (pCurLayoutItem->m_pFormNode->HasRemovedChildren()) {
1597        CXFA_FFNotify* pNotify =
1598            m_pTemplatePageSetRoot->GetDocument()->GetNotify();
1599        CXFA_LayoutProcessor* pDocLayout =
1600            m_pTemplatePageSetRoot->GetDocument()->GetDocLayout();
1601        if (pCurLayoutItem->m_pFirstChild)
1602          SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
1603
1604        pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
1605        delete pCurLayoutItem;
1606        pCurLayoutItem = pNextLayoutItem;
1607        continue;
1608      }
1609
1610      if (pCurLayoutItem->m_pFormNode->IsLayoutGeneratedNode()) {
1611        CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
1612            sIterator(pCurLayoutItem->m_pFormNode);
1613        for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
1614             pNode = sIterator.MoveToNext()) {
1615          pNode->SetFlag(XFA_NodeFlag_UnusedNode, false);
1616        }
1617      }
1618    }
1619
1620    if (pCurLayoutItem->m_pFirstChild)
1621      SaveLayoutItem(pCurLayoutItem);
1622
1623    pCurLayoutItem->m_pParent = nullptr;
1624    pCurLayoutItem->m_pNextSibling = nullptr;
1625    pCurLayoutItem->m_pFirstChild = nullptr;
1626    if (!pCurLayoutItem->IsContentLayoutItem() &&
1627        pCurLayoutItem->m_pFormNode->GetElementType() !=
1628            XFA_Element::PageArea) {
1629      delete pCurLayoutItem;
1630    }
1631    pCurLayoutItem = pNextLayoutItem;
1632  }
1633}
1634
1635CXFA_Node* CXFA_LayoutPageMgr::QueryOverflow(
1636    CXFA_Node* pFormNode,
1637    CXFA_LayoutContext* pLayoutContext) {
1638  for (CXFA_Node* pCurNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1639       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
1640    if (pCurNode->GetElementType() == XFA_Element::Break) {
1641      CFX_WideStringC wsOverflowLeader;
1642      CFX_WideStringC wsOverflowTarget;
1643      CFX_WideStringC wsOverflowTrailer;
1644      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
1645      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
1646      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
1647      if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() ||
1648          !wsOverflowTarget.IsEmpty()) {
1649        return pCurNode;
1650      }
1651      return nullptr;
1652    }
1653    if (pCurNode->GetElementType() == XFA_Element::Overflow)
1654      return pCurNode;
1655  }
1656  return nullptr;
1657}
1658
1659void CXFA_LayoutPageMgr::MergePageSetContents() {
1660  CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
1661  CXFA_FFNotify* pNotify = pDocument->GetNotify();
1662  CXFA_LayoutProcessor* pDocLayout = pDocument->GetDocLayout();
1663  CXFA_ContainerLayoutItem* pRootLayout = GetRootLayoutItem();
1664  {
1665    for (int32_t iIndex = 0; iIndex < pDocument->m_pPendingPageSet.GetSize();
1666         iIndex++) {
1667      CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
1668          sIterator(pDocument->m_pPendingPageSet.GetAt(iIndex));
1669      for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
1670           pNode = sIterator.MoveToNext()) {
1671        if (pNode->IsContainerNode()) {
1672          CXFA_Node* pBindNode = pNode->GetBindData();
1673          if (pBindNode) {
1674            pBindNode->RemoveBindItem(pNode);
1675            pNode->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
1676          }
1677        }
1678        pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
1679      }
1680    }
1681  }
1682
1683  int32_t iIndex = 0;
1684  for (; pRootLayout; pRootLayout = static_cast<CXFA_ContainerLayoutItem*>(
1685                          pRootLayout->m_pNextSibling)) {
1686    CXFA_Node* pPendingPageSet = nullptr;
1687    CXFA_NodeIteratorTemplate<
1688        CXFA_ContainerLayoutItem,
1689        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
1690        iterator(pRootLayout);
1691    CXFA_ContainerLayoutItem* pRootPageSetContainerItem = iterator.GetCurrent();
1692    ASSERT(pRootPageSetContainerItem->m_pFormNode->GetElementType() ==
1693           XFA_Element::PageSet);
1694    if (iIndex < pDocument->m_pPendingPageSet.GetSize()) {
1695      pPendingPageSet = pDocument->m_pPendingPageSet.GetAt(iIndex);
1696      iIndex++;
1697    }
1698    if (!pPendingPageSet) {
1699      if (pRootPageSetContainerItem->m_pFormNode->GetPacketID() ==
1700          XFA_XDPPACKET_Template) {
1701        pPendingPageSet =
1702            pRootPageSetContainerItem->m_pFormNode->CloneTemplateToForm(false);
1703      } else {
1704        pPendingPageSet = pRootPageSetContainerItem->m_pFormNode;
1705      }
1706    }
1707    if (pRootPageSetContainerItem->m_pFormNode->GetUserData(
1708            XFA_LAYOUTITEMKEY) == pRootPageSetContainerItem) {
1709      pRootPageSetContainerItem->m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY,
1710                                                          nullptr);
1711    }
1712    pRootPageSetContainerItem->m_pFormNode = pPendingPageSet;
1713    pPendingPageSet->ClearFlag(XFA_NodeFlag_UnusedNode);
1714    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.MoveToNext();
1715         pContainerItem; pContainerItem = iterator.MoveToNext()) {
1716      CXFA_Node* pNode = pContainerItem->m_pFormNode;
1717      if (pNode->GetPacketID() != XFA_XDPPACKET_Template)
1718        continue;
1719
1720      switch (pNode->GetElementType()) {
1721        case XFA_Element::PageSet: {
1722          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
1723          pContainerItem->m_pFormNode = XFA_NodeMerge_CloneOrMergeContainer(
1724              pDocument, pParentNode, pContainerItem->m_pFormNode, true,
1725              nullptr);
1726          break;
1727        }
1728        case XFA_Element::PageArea: {
1729          CXFA_ContainerLayoutItem* pFormLayout = pContainerItem;
1730          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
1731          bool bIsExistForm = true;
1732          for (int32_t iLevel = 0; iLevel < 3; iLevel++) {
1733            pFormLayout = static_cast<CXFA_ContainerLayoutItem*>(
1734                pFormLayout->m_pFirstChild);
1735            if (iLevel == 2) {
1736              while (pFormLayout &&
1737                     !XFA_ItemLayoutProcessor_IsTakingSpace(
1738                         pFormLayout->m_pFormNode)) {
1739                pFormLayout = static_cast<CXFA_ContainerLayoutItem*>(
1740                    pFormLayout->m_pNextSibling);
1741              }
1742            }
1743            if (!pFormLayout) {
1744              bIsExistForm = false;
1745              break;
1746            }
1747          }
1748          if (bIsExistForm) {
1749            CXFA_Node* pNewSubform = pFormLayout->m_pFormNode;
1750            if (pContainerItem->m_pOldSubform &&
1751                pContainerItem->m_pOldSubform != pNewSubform) {
1752              CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
1753                  pDocument, pContainerItem->m_pFormNode->GetElementType(),
1754                  pContainerItem->m_pFormNode->GetNameHash(), pParentNode);
1755              CXFA_ContainerIterator sIterator(pExistingNode);
1756              for (CXFA_Node* pIter = sIterator.GetCurrent(); pIter;
1757                   pIter = sIterator.MoveToNext()) {
1758                if (pIter->GetElementType() != XFA_Element::ContentArea) {
1759                  CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
1760                      pIter->GetUserData(XFA_LAYOUTITEMKEY));
1761                  if (pLayoutItem) {
1762                    pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
1763                    delete pLayoutItem;
1764                  }
1765                }
1766              }
1767              if (pExistingNode) {
1768                pParentNode->RemoveChild(pExistingNode);
1769              }
1770            }
1771            pContainerItem->m_pOldSubform = pNewSubform;
1772          }
1773          pContainerItem->m_pFormNode = pDocument->DataMerge_CopyContainer(
1774              pContainerItem->m_pFormNode, pParentNode,
1775              ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record)), true, true,
1776              true);
1777          break;
1778        }
1779        case XFA_Element::ContentArea: {
1780          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
1781          for (CXFA_Node* pChildNode =
1782                   pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1783               pChildNode;
1784               pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1785            if (pChildNode->GetTemplateNode() != pContainerItem->m_pFormNode) {
1786              continue;
1787            }
1788            pContainerItem->m_pFormNode = pChildNode;
1789            break;
1790          }
1791          break;
1792        }
1793        default:
1794          break;
1795      }
1796    }
1797    if (!pPendingPageSet->GetNodeItem(XFA_NODEITEM_Parent)) {
1798      CXFA_Node* pFormToplevelSubform =
1799          pDocument->GetXFAObject(XFA_HASHCODE_Form)
1800              ->AsNode()
1801              ->GetFirstChildByClass(XFA_Element::Subform);
1802      pFormToplevelSubform->InsertChild(pPendingPageSet);
1803    }
1804    pDocument->DataMerge_UpdateBindingRelations(pPendingPageSet);
1805    pPendingPageSet->SetFlag(XFA_NodeFlag_Initialized, true);
1806  }
1807
1808  CXFA_Node* pPageSet = GetRootLayoutItem()->m_pFormNode;
1809  while (pPageSet) {
1810    CXFA_Node* pNextPageSet =
1811        pPageSet->GetNextSameClassSibling(XFA_Element::PageSet);
1812    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
1813        sIterator(pPageSet);
1814    CXFA_Node* pNode = sIterator.GetCurrent();
1815    while (pNode) {
1816      if (pNode->IsUnusedNode()) {
1817        if (pNode->IsContainerNode()) {
1818          XFA_Element eType = pNode->GetElementType();
1819          if (eType == XFA_Element::PageArea || eType == XFA_Element::PageSet) {
1820            CXFA_ContainerIterator iteChild(pNode);
1821            CXFA_Node* pChildNode = iteChild.MoveToNext();
1822            for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
1823              CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
1824                  pChildNode->GetUserData(XFA_LAYOUTITEMKEY));
1825              if (pLayoutItem) {
1826                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
1827                delete pLayoutItem;
1828              }
1829            }
1830          } else if (eType != XFA_Element::ContentArea) {
1831            CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
1832                pNode->GetUserData(XFA_LAYOUTITEMKEY));
1833            if (pLayoutItem) {
1834              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
1835              delete pLayoutItem;
1836            }
1837          }
1838          CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
1839          pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
1840          pNode = pNext;
1841        } else {
1842          pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
1843          pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1844          pNode = sIterator.MoveToNext();
1845        }
1846      } else {
1847        pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1848        pNode = sIterator.MoveToNext();
1849      }
1850    }
1851    pPageSet = pNextPageSet;
1852  }
1853}
1854
1855void CXFA_LayoutPageMgr::LayoutPageSetContents() {
1856  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
1857  for (; pRootLayoutItem;
1858       pRootLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
1859           pRootLayoutItem->m_pNextSibling)) {
1860    CXFA_NodeIteratorTemplate<
1861        CXFA_ContainerLayoutItem,
1862        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
1863        iterator(pRootLayoutItem);
1864    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.GetCurrent();
1865         pContainerItem; pContainerItem = iterator.MoveToNext()) {
1866      CXFA_Node* pNode = pContainerItem->m_pFormNode;
1867      switch (pNode->GetElementType()) {
1868        case XFA_Element::PageArea:
1869          m_pLayoutProcessor->GetRootRootItemLayoutProcessor()
1870              ->DoLayoutPageArea(pContainerItem);
1871          break;
1872        default:
1873          break;
1874      }
1875    }
1876  }
1877}
1878
1879void CXFA_LayoutPageMgr::SyncLayoutData() {
1880  MergePageSetContents();
1881  LayoutPageSetContents();
1882  CXFA_FFNotify* pNotify = m_pTemplatePageSetRoot->GetDocument()->GetNotify();
1883  int32_t nPageIdx = -1;
1884  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
1885  for (; pRootLayoutItem;
1886       pRootLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
1887           pRootLayoutItem->m_pNextSibling)) {
1888    CXFA_NodeIteratorTemplate<
1889        CXFA_ContainerLayoutItem,
1890        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
1891        iteratorParent(pRootLayoutItem);
1892    for (CXFA_ContainerLayoutItem* pContainerItem = iteratorParent.GetCurrent();
1893         pContainerItem; pContainerItem = iteratorParent.MoveToNext()) {
1894      switch (pContainerItem->m_pFormNode->GetElementType()) {
1895        case XFA_Element::PageArea: {
1896          nPageIdx++;
1897          uint32_t dwRelevant =
1898              XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable;
1899          CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
1900                                    CXFA_TraverseStrategy_LayoutItem>
1901              iterator(pContainerItem);
1902          CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent();
1903          while (pChildLayoutItem) {
1904            CXFA_ContentLayoutItem* pContentItem =
1905                pChildLayoutItem->AsContentLayoutItem();
1906            if (!pContentItem) {
1907              pChildLayoutItem = iterator.MoveToNext();
1908              continue;
1909            }
1910            bool bVisible =
1911                (pContentItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence) ==
1912                 XFA_ATTRIBUTEENUM_Visible);
1913            uint32_t dwRelevantChild =
1914                GetRelevant(pContentItem->m_pFormNode, dwRelevant);
1915            SyncContainer(pNotify, m_pLayoutProcessor, pContentItem,
1916                          dwRelevantChild, bVisible, nPageIdx);
1917            pChildLayoutItem = iterator.SkipChildrenAndMoveToNext();
1918          }
1919          break;
1920        }
1921        default:
1922          break;
1923      }
1924    }
1925  }
1926
1927  int32_t nPage = m_PageArray.GetSize();
1928  for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) {
1929    CXFA_ContainerLayoutItem* pPage = m_PageArray[i];
1930    m_PageArray.RemoveAt(i);
1931    pNotify->OnPageEvent(pPage, XFA_PAGEVIEWEVENT_PostRemoved);
1932    delete pPage;
1933  }
1934  ClearData();
1935}
1936
1937void XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItem* pLayoutItem) {
1938  CXFA_LayoutItem *pNext, *pNode = pLayoutItem->m_pFirstChild;
1939  while (pNode) {
1940    pNext = pNode->m_pNextSibling;
1941    pNode->m_pParent = nullptr;
1942    XFA_ReleaseLayoutItem_NoPageArea(pNode);
1943    pNode = pNext;
1944  }
1945  if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::PageArea)
1946    delete pLayoutItem;
1947}
1948
1949void CXFA_LayoutPageMgr::PrepareLayout() {
1950  m_pPageSetCurRoot = nullptr;
1951  m_ePageSetMode = XFA_ATTRIBUTEENUM_OrderedOccurrence;
1952  m_nAvailPages = 0;
1953  ClearData();
1954  if (!m_pPageSetLayoutItemRoot)
1955    return;
1956
1957  CXFA_ContainerLayoutItem* pRootLayoutItem = m_pPageSetLayoutItemRoot;
1958  if (pRootLayoutItem &&
1959      pRootLayoutItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Form) {
1960    CXFA_Node* pPageSetFormNode = pRootLayoutItem->m_pFormNode;
1961    pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.RemoveAll();
1962    if (pPageSetFormNode->HasRemovedChildren()) {
1963      XFA_ReleaseLayoutItem(pRootLayoutItem);
1964      m_pPageSetLayoutItemRoot = nullptr;
1965      pRootLayoutItem = nullptr;
1966      pPageSetFormNode = nullptr;
1967      m_PageArray.RemoveAll();
1968    }
1969    while (pPageSetFormNode) {
1970      CXFA_Node* pNextPageSet =
1971          pPageSetFormNode->GetNextSameClassSibling(XFA_Element::PageSet);
1972      pPageSetFormNode->GetNodeItem(XFA_NODEITEM_Parent)
1973          ->RemoveChild(pPageSetFormNode, false);
1974      pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.Add(
1975          pPageSetFormNode);
1976      pPageSetFormNode = pNextPageSet;
1977    }
1978  }
1979  pRootLayoutItem = m_pPageSetLayoutItemRoot;
1980  CXFA_ContainerLayoutItem* pNextLayout = nullptr;
1981  for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
1982    pNextLayout =
1983        static_cast<CXFA_ContainerLayoutItem*>(pRootLayoutItem->m_pNextSibling);
1984    SaveLayoutItem(pRootLayoutItem);
1985    delete pRootLayoutItem;
1986  }
1987  m_pPageSetLayoutItemRoot = nullptr;
1988}
1989