cxfa_layoutpagemgr.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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