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