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