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
25 namespace {
26
27 class PageSetContainerLayoutItem {
28 public:
GetFirstChild(CXFA_ContainerLayoutItem * pLayoutItem)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
GetNextSibling(CXFA_ContainerLayoutItem * pLayoutItem)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
GetParent(CXFA_ContainerLayoutItem * pLayoutItem)56 static CXFA_ContainerLayoutItem* GetParent(
57 CXFA_ContainerLayoutItem* pLayoutItem) {
58 return static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
59 }
60 };
61
GetRelevant(CXFA_Node * pFormItem,uint32_t dwParentRelvant)62 uint32_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
SyncContainer(CXFA_FFNotify * pNotify,CXFA_LayoutProcessor * pDocLayout,CXFA_LayoutItem * pContainerItem,uint32_t dwRelevant,bool bVisible,int32_t nPageIndex)84 void 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
ReorderLayoutItemToTail(CXFA_ContainerLayoutItem * pLayoutItem)114 void 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
RemoveLayoutItem(CXFA_ContainerLayoutItem * pLayoutItem)124 void 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
ResolveBreakTarget(CXFA_Node * pPageSetRoot,bool bNewExprStyle,CFX_WideStringC & wsTargetExpr)133 CXFA_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
SetLayoutGeneratedNodeFlag(CXFA_Node * pNode)183 void SetLayoutGeneratedNodeFlag(CXFA_Node* pNode) {
184 pNode->SetFlag(XFA_NodeFlag_LayoutGeneratedNode, false);
185 pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
186 }
187
CheckContentAreaNotUsed(CXFA_ContainerLayoutItem * pPageAreaLayoutItem,CXFA_Node * pContentArea,CXFA_ContainerLayoutItem * & pContentAreaLayoutItem)188 bool 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
SyncRemoveLayoutItem(CXFA_LayoutItem * pParentLayoutItem,CXFA_FFNotify * pNotify,CXFA_LayoutProcessor * pDocLayout)208 void 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
226 class CXFA_ContainerRecord {
227 public:
CXFA_ContainerRecord(CXFA_ContainerLayoutItem * pPageSet=nullptr,CXFA_ContainerLayoutItem * pPageArea=nullptr,CXFA_ContainerLayoutItem * pContentArea=nullptr)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
CXFA_LayoutPageMgr(CXFA_LayoutProcessor * pLayoutProcessor)240 CXFA_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
~CXFA_LayoutPageMgr()252 CXFA_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
InitLayoutPage(CXFA_Node * pFormNode)262 bool 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
PrepareFirstPage(CXFA_Node * pRootSubform)348 bool 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
AppendNewPage(bool bFirstTemPage)386 bool 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
RemoveLayoutRecord(CXFA_ContainerRecord * pNewRecord,CXFA_ContainerRecord * pPrevRecord)402 void 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
ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord * pNewRecord,CXFA_ContainerRecord * pPrevRecord)420 void 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
SubmitContentItem(CXFA_ContentLayoutItem * pContentLayoutItem,XFA_ItemLayoutProcessorResult eStatus)439 void 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
GetAvailHeight()457 FX_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
XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node * pTestScript)472 bool 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
CreateContainerRecord(CXFA_Node * pPageNode,bool bCreateNew)482 CXFA_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
AddPageAreaLayoutItem(CXFA_ContainerRecord * pNewRecord,CXFA_Node * pNewPageArea)552 void 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
AddContentAreaLayoutItem(CXFA_ContainerRecord * pNewRecord,CXFA_Node * pContentArea)575 void 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
FinishPaginatedPageSets()589 void 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
GetPageCount() const725 int32_t CXFA_LayoutPageMgr::GetPageCount() const {
726 return m_PageArray.GetSize();
727 }
728
GetPage(int32_t index) const729 CXFA_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
GetPageIndex(const CXFA_ContainerLayoutItem * pPage) const735 int32_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
RunBreak(XFA_Element eBreakType,XFA_ATTRIBUTEENUM eTargetType,CXFA_Node * pTarget,bool bStartNew)741 bool 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
ExecuteBreakBeforeOrAfter(CXFA_Node * pCurNode,bool bBefore,CXFA_Node * & pBreakLeaderTemplate,CXFA_Node * & pBreakTrailerTemplate)789 bool 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
ProcessBreakBeforeOrAfter(CXFA_Node * pBreakNode,bool bBefore,CXFA_Node * & pBreakLeaderNode,CXFA_Node * & pBreakTrailerNode,bool & bCreatePage)860 bool 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
ProcessBookendLeaderOrTrailer(CXFA_Node * pBookendNode,bool bLeader,CXFA_Node * & pBookendAppendNode)900 bool 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
BreakOverflow(CXFA_Node * pOverflowNode,CXFA_Node * & pLeaderTemplate,CXFA_Node * & pTrailerTemplate,bool bCreatePage)924 CXFA_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
ProcessOverflow(CXFA_Node * pFormNode,CXFA_Node * & pLeaderNode,CXFA_Node * & pTrailerNode,bool bDataMerge,bool bCreatePage)1007 bool 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
ResolveBookendLeaderOrTrailer(CXFA_Node * pBookendNode,bool bLeader,CXFA_Node * & pBookendAppendTemplate)1060 bool 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
FindPageAreaFromPageSet(CXFA_Node * pPageSet,CXFA_Node * pStartChild,CXFA_Node * pTargetPageArea,CXFA_Node * pTargetContentArea,bool bNewPage,bool bQuery)1090 bool 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
FindPageAreaFromPageSet_Ordered(CXFA_Node * pPageSet,CXFA_Node * pStartChild,CXFA_Node * pTargetPageArea,CXFA_Node * pTargetContentArea,bool bNewPage,bool bQuery)1113 bool 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
FindPageAreaFromPageSet_SimplexDuplex(CXFA_Node * pPageSet,CXFA_Node * pStartChild,CXFA_Node * pTargetPageArea,CXFA_Node * pTargetContentArea,bool bNewPage,bool bQuery,XFA_ATTRIBUTEENUM ePreferredPosition)1180 bool 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
MatchPageAreaOddOrEven(CXFA_Node * pPageArea,bool bLastMatch)1288 bool 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
GetNextAvailPageArea(CXFA_Node * pTargetPageArea,CXFA_Node * pTargetContentArea,bool bNewPage,bool bQuery)1307 CXFA_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
GetNextContentArea(CXFA_Node * pContentArea)1374 bool 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
InitPageSetMap()1406 void 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
CreateMinPageRecord(CXFA_Node * pPageArea,bool bTargetPageArea,bool bCreateLast)1422 int32_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
CreateMinPageSetRecord(CXFA_Node * pPageSet,bool bCreateAll)1450 void 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
CreateNextMinRecord(CXFA_Node * pRecordNode)1485 void 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
ProcessLastPageSet()1500 void 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
GetNextAvailContentHeight(FX_FLOAT fChildHeight)1514 bool 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
ClearData()1573 void 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
SaveLayoutItem(CXFA_LayoutItem * pParentLayoutItem)1590 void 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
QueryOverflow(CXFA_Node * pFormNode,CXFA_LayoutContext * pLayoutContext)1635 CXFA_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
MergePageSetContents()1659 void 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
LayoutPageSetContents()1855 void 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
SyncLayoutData()1879 void 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
XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItem * pLayoutItem)1937 void 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
PrepareLayout()1949 void 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