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 <algorithm>
8 
9 #include "xfa/src/foxitlib.h"
10 #include "xfa/src/fxfa/src/common/xfa_utils.h"
11 #include "xfa/src/fxfa/src/common/xfa_object.h"
12 #include "xfa/src/fxfa/src/common/xfa_document.h"
13 #include "xfa/src/fxfa/src/common/xfa_parser.h"
14 #include "xfa/src/fxfa/src/common/xfa_script.h"
15 #include "xfa/src/fxfa/src/common/xfa_docdata.h"
16 #include "xfa/src/fxfa/src/common/xfa_doclayout.h"
17 #include "xfa/src/fxfa/src/common/xfa_localemgr.h"
18 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
19 #include "xfa_document_layout_imp.h"
20 #include "xfa_layout_itemlayout.h"
21 #include "xfa_layout_pagemgr_new.h"
22 #include "xfa_layout_appadapter.h"
CXFA_ItemLayoutProcessor(CXFA_Node * pNode,CXFA_LayoutPageMgr * pPageMgr)23 CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode,
24                                                    CXFA_LayoutPageMgr* pPageMgr)
25     : m_bKeepBreakFinish(FALSE),
26       m_bIsProcessKeep(FALSE),
27       m_pKeepHeadNode(nullptr),
28       m_pKeepTailNode(nullptr),
29       m_pFormNode(pNode),
30       m_pLayoutItem(nullptr),
31 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
32       m_pOldLayoutItem(nullptr),
33 #else
34       m_pPageMgrCreateItem(nullptr),
35 #endif
36       m_pCurChildNode(XFA_LAYOUT_INVALIDNODE),
37       m_pCurChildPreprocessor(nullptr),
38       m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None),
39       m_fUsedSize(0),
40       m_pPageMgr(pPageMgr),
41       m_bBreakPending(TRUE),
42       m_fLastRowWidth(0),
43       m_fLastRowY(0),
44       m_fWidthLimite(0),
45       m_bUseInheriated(FALSE),
46       m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done),
47       m_bHasAvailHeight(TRUE) {
48   FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() ||
49                                m_pFormNode->GetClassID() == XFA_ELEMENT_Form));
50 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
51   m_pOldLayoutItem =
52       (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
53 #endif
54 }
CreateContentLayoutItem(CXFA_Node * pFormNode)55 CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(
56     CXFA_Node* pFormNode) {
57   if (!pFormNode) {
58     return NULL;
59   }
60   CXFA_ContentLayoutItem* pLayoutItem = NULL;
61 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
62   if (m_pOldLayoutItem) {
63     pLayoutItem = m_pOldLayoutItem;
64     m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;
65     return pLayoutItem;
66   }
67   pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument()
68                     ->GetParser()
69                     ->GetNotify()
70                     ->OnCreateLayoutItem(pFormNode);
71 #else
72   pLayoutItem =
73       (CXFA_ContentLayoutItem*)m_pPageMgrCreateItem->FindOrCreateLayoutItem(
74           pFormNode);
75 #endif
76   CXFA_ContentLayoutItem* pPrevLayoutItem =
77       (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
78   if (pPrevLayoutItem) {
79     while (pPrevLayoutItem->m_pNext) {
80       pPrevLayoutItem = pPrevLayoutItem->m_pNext;
81     }
82     pPrevLayoutItem->m_pNext = pLayoutItem;
83     pLayoutItem->m_pPrev = pPrevLayoutItem;
84   } else {
85     pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem);
86   }
87   return pLayoutItem;
88 }
FindLayoutItemSplitPos(CXFA_ContentLayoutItem * pLayoutItem,FX_FLOAT fCurVerticalOffset,FX_FLOAT & fProposedSplitPos,FX_BOOL & bAppChange,FX_BOOL bCalculateMargin)89 FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos(
90     CXFA_ContentLayoutItem* pLayoutItem,
91     FX_FLOAT fCurVerticalOffset,
92     FX_FLOAT& fProposedSplitPos,
93     FX_BOOL& bAppChange,
94     FX_BOOL bCalculateMargin) {
95   CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;
96   if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION &&
97       fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y -
98                                XFA_LAYOUT_FLOAT_PERCISION) {
99     switch (pFormNode->GetIntact()) {
100       case XFA_ATTRIBUTEENUM_None: {
101         FX_BOOL bAnyChanged = FALSE;
102         CXFA_Document* pDocument = pFormNode->GetDocument();
103         IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
104         FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
105         CXFA_Node* pMarginNode =
106             pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
107         if (pMarginNode && bCalculateMargin) {
108           fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
109                               .ToUnit(XFA_UNIT_Pt);
110           fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset)
111                                  .ToUnit(XFA_UNIT_Pt);
112         }
113         FX_BOOL bChanged = TRUE;
114         while (bChanged) {
115           bChanged = FALSE;
116           {
117             FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset;
118             if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(),
119                                       fRelSplitPos)) {
120               bAnyChanged = TRUE;
121               bChanged = TRUE;
122               fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;
123               bAppChange = TRUE;
124               if (fProposedSplitPos <=
125                   fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
126                 return TRUE;
127               }
128             }
129           }
130           FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin;
131           for (CXFA_ContentLayoutItem* pChildItem =
132                    (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
133                pChildItem;
134                pChildItem =
135                    (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
136             FX_FLOAT fChildOffset =
137                 fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
138             FX_BOOL bAppChange = FALSE;
139             if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos,
140                                        bAppChange, bCalculateMargin)) {
141               if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION &&
142                   bAppChange) {
143                 fProposedSplitPos = fRelSplitPos - fCurTopMargin;
144               } else {
145                 fProposedSplitPos = fRelSplitPos + fCurBottomMargin;
146               }
147               bAnyChanged = TRUE;
148               bChanged = TRUE;
149               if (fProposedSplitPos <=
150                   fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
151                 return TRUE;
152               }
153               if (bAnyChanged) {
154                 break;
155               }
156             }
157           }
158         }
159         return bAnyChanged;
160       } break;
161       case XFA_ATTRIBUTEENUM_ContentArea:
162       case XFA_ATTRIBUTEENUM_PageArea: {
163         fProposedSplitPos = fCurVerticalOffset;
164         return TRUE;
165       }
166       default:
167         return FALSE;
168     }
169   }
170   return FALSE;
171 }
XFA_ItemLayoutProcessor_GetLayout(CXFA_Node * pFormNode,FX_BOOL & bRootForceTb)172 static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(
173     CXFA_Node* pFormNode,
174     FX_BOOL& bRootForceTb) {
175   bRootForceTb = FALSE;
176   XFA_ATTRIBUTEENUM eLayoutMode;
177   if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) {
178     return eLayoutMode;
179   }
180   CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
181   if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) {
182     bRootForceTb = TRUE;
183     return XFA_ATTRIBUTEENUM_Tb;
184   }
185   return XFA_ATTRIBUTEENUM_Position;
186 }
XFA_ExistContainerKeep(CXFA_Node * pCurNode,FX_BOOL bPreFind)187 static FX_BOOL XFA_ExistContainerKeep(CXFA_Node* pCurNode, FX_BOOL bPreFind) {
188   if (pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) {
189     return FALSE;
190   }
191   XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling;
192   if (!bPreFind) {
193     eItemType = XFA_NODEITEM_NextSibling;
194   }
195   CXFA_Node* pPreContainer =
196       pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode);
197   if (pPreContainer == NULL) {
198     return FALSE;
199   }
200   CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep);
201   if (pKeep) {
202     XFA_ATTRIBUTEENUM ePrevious;
203     XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous;
204     if (!bPreFind) {
205       eKeepType = XFA_ATTRIBUTE_Next;
206     }
207     if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) {
208       if (ePrevious == XFA_ATTRIBUTEENUM_ContentArea ||
209           ePrevious == XFA_ATTRIBUTEENUM_PageArea) {
210         return TRUE;
211       }
212     }
213   }
214   pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep);
215   if (!pKeep) {
216     return FALSE;
217   }
218   XFA_ATTRIBUTEENUM eNext;
219   XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next;
220   if (!bPreFind) {
221     eKeepType = XFA_ATTRIBUTE_Previous;
222   }
223   if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) {
224     return FALSE;
225   }
226   if (eNext == XFA_ATTRIBUTEENUM_ContentArea ||
227       eNext == XFA_ATTRIBUTEENUM_PageArea) {
228     return TRUE;
229   }
230   return FALSE;
231 }
FindSplitPos(FX_FLOAT fProposedSplitPos)232 FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos) {
233   ASSERT(m_pLayoutItem);
234   XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
235   FX_BOOL bCalculateMargin = TRUE;
236   if (eLayout == XFA_ATTRIBUTEENUM_Position) {
237     bCalculateMargin = FALSE;
238   }
239   while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
240     FX_BOOL bAppChange = FALSE;
241     if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange,
242                                 bCalculateMargin)) {
243       break;
244     }
245   }
246   return fProposedSplitPos;
247 }
SplitLayoutItem(CXFA_ContentLayoutItem * pLayoutItem,CXFA_ContentLayoutItem * pSecondParent,FX_FLOAT fSplitPos)248 void CXFA_ItemLayoutProcessor::SplitLayoutItem(
249     CXFA_ContentLayoutItem* pLayoutItem,
250     CXFA_ContentLayoutItem* pSecondParent,
251     FX_FLOAT fSplitPos) {
252   FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
253   XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
254   FX_BOOL bCalculateMargin = TRUE;
255   if (eLayout == XFA_ATTRIBUTEENUM_Position) {
256     bCalculateMargin = FALSE;
257   }
258   CXFA_Node* pMarginNode =
259       pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
260   if (pMarginNode && bCalculateMargin) {
261     fCurTopMargin =
262         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
263     fCurBottomMargin =
264         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
265   }
266   CXFA_ContentLayoutItem* pSecondLayoutItem = NULL;
267   if (m_pCurChildPreprocessor &&
268       m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) {
269     pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
270         pLayoutItem->m_pFormNode);
271   } else {
272     pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode);
273   }
274   pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x;
275   pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x;
276   pSecondLayoutItem->m_sPos.y = 0;
277   pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos;
278   pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y;
279   if (pLayoutItem->m_pFirstChild) {
280     pSecondLayoutItem->m_sSize.y += fCurTopMargin;
281   }
282   if (pSecondParent) {
283     pSecondParent->AddChild(pSecondLayoutItem);
284     if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {
285       pSecondParent->m_sSize.y += fCurTopMargin;
286       CXFA_ContentLayoutItem* pParentItem =
287           (CXFA_ContentLayoutItem*)pSecondParent->m_pParent;
288       while (pParentItem) {
289         pParentItem->m_sSize.y += fCurTopMargin;
290         pParentItem = (CXFA_ContentLayoutItem*)pParentItem->m_pParent;
291       }
292     }
293   } else {
294     pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent;
295     pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling;
296     pLayoutItem->m_pNextSibling = pSecondLayoutItem;
297   }
298   CXFA_ContentLayoutItem* pChildren =
299       (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
300   pLayoutItem->m_pFirstChild = NULL;
301   FX_FLOAT lHeightForKeep = 0;
302   CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
303   FX_FLOAT fAddMarginHeight = 0;
304   for (CXFA_ContentLayoutItem* pChildItem = pChildren, * pChildNext = NULL;
305        pChildItem; pChildItem = pChildNext) {
306     pChildNext = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling;
307     pChildItem->m_pNextSibling = NULL;
308     if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
309                          XFA_LAYOUT_FLOAT_PERCISION) {
310       if (!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) {
311         pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
312         pChildItem->m_sPos.y += lHeightForKeep;
313         pChildItem->m_sPos.y += fAddMarginHeight;
314         pSecondLayoutItem->AddChild(pChildItem);
315       } else {
316         if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {
317           for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize();
318                iIndex++) {
319             CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex];
320             pLayoutItem->RemoveChild(pPreItem);
321             pPreItem->m_sPos.y -= fSplitPos;
322             if (pPreItem->m_sPos.y < 0) {
323               pPreItem->m_sPos.y = 0;
324             }
325             if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) {
326               pPreItem->m_sPos.y = lHeightForKeep;
327               lHeightForKeep += pPreItem->m_sSize.y;
328               pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y;
329               if (pSecondParent) {
330                 pSecondParent->m_sSize.y += pPreItem->m_sSize.y;
331               }
332             }
333             pSecondLayoutItem->AddChild(pPreItem);
334           }
335         }
336         pChildItem->m_sPos.y -= fSplitPos;
337         pChildItem->m_sPos.y += lHeightForKeep;
338         pChildItem->m_sPos.y += fAddMarginHeight;
339         pSecondLayoutItem->AddChild(pChildItem);
340       }
341     } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >=
342                fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y +
343                    pChildItem->m_sSize.y) {
344       pLayoutItem->AddChild(pChildItem);
345       if (XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) {
346         keepLayoutItems.Add(pChildItem);
347       } else {
348         keepLayoutItems.RemoveAll();
349       }
350     } else {
351       FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y;
352       SplitLayoutItem(
353           pChildItem, pSecondLayoutItem,
354           fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
355       fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight;
356       pLayoutItem->AddChild(pChildItem);
357     }
358   }
359 }
SplitLayoutItem(FX_FLOAT fSplitPos)360 void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) {
361   ASSERT(m_pLayoutItem);
362   SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos);
363   return;
364 }
365 
GetPage() const366 IXFA_LayoutPage* CXFA_LayoutItem::GetPage() const {
367   for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode;
368        pCurNode = pCurNode->m_pParent) {
369     if (pCurNode->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea)
370       return static_cast<CXFA_ContainerLayoutItem*>(pCurNode);
371   }
372   return nullptr;
373 }
374 
GetFormNode() const375 CXFA_Node* CXFA_LayoutItem::GetFormNode() const {
376   return m_pFormNode;
377 }
378 
GetRect(CFX_RectF & rtLayout,FX_BOOL bRelative) const379 void CXFA_LayoutItem::GetRect(CFX_RectF& rtLayout, FX_BOOL bRelative) const {
380   ASSERT(m_bIsContentLayoutItem);
381   const CXFA_ContentLayoutItem* pThis =
382       static_cast<const CXFA_ContentLayoutItem*>(this);
383   CFX_PointF sPos = pThis->m_sPos;
384   CFX_SizeF sSize = pThis->m_sSize;
385   if (!bRelative) {
386     for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem;
387          pLayoutItem = pLayoutItem->m_pParent) {
388       if (CXFA_ContentLayoutItem* pContent =
389               pLayoutItem->AsContentLayoutItem()) {
390         sPos += pContent->m_sPos;
391         if (CXFA_Node* pMarginNode =
392                 pLayoutItem->m_pFormNode->GetFirstChildByClass(
393                     XFA_ELEMENT_Margin)) {
394           sPos.Add(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset)
395                        .ToUnit(XFA_UNIT_Pt),
396                    pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
397                        .ToUnit(XFA_UNIT_Pt));
398         }
399       } else {
400         if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
401           sPos.Add(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X)
402                        .ToUnit(XFA_UNIT_Pt),
403                    pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y)
404                        .ToUnit(XFA_UNIT_Pt));
405           break;
406         } else if (pLayoutItem->m_pFormNode->GetClassID() ==
407                    XFA_ELEMENT_PageArea) {
408           break;
409         }
410       }
411     }
412   }
413   rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y);
414 }
415 
GetParent() const416 CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const {
417   return m_pParent;
418 }
419 
GetFirst() const420 const CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const {
421   ASSERT(m_bIsContentLayoutItem);
422   const CXFA_ContentLayoutItem* pCurNode =
423       static_cast<const CXFA_ContentLayoutItem*>(this);
424   while (pCurNode->m_pPrev) {
425     pCurNode = pCurNode->m_pPrev;
426   }
427   return pCurNode;
428 }
429 
GetFirst()430 CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() {
431   ASSERT(m_bIsContentLayoutItem);
432   CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
433   while (pCurNode->m_pPrev) {
434     pCurNode = pCurNode->m_pPrev;
435   }
436   return pCurNode;
437 }
438 
GetLast()439 CXFA_LayoutItem* CXFA_LayoutItem::GetLast() {
440   ASSERT(m_bIsContentLayoutItem);
441   CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
442   while (pCurNode->m_pNext) {
443     pCurNode = pCurNode->m_pNext;
444   }
445   return pCurNode;
446 }
447 
GetLast() const448 const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const {
449   ASSERT(m_bIsContentLayoutItem);
450   const CXFA_ContentLayoutItem* pCurNode =
451       static_cast<const CXFA_ContentLayoutItem*>(this);
452   while (pCurNode->m_pNext) {
453     pCurNode = pCurNode->m_pNext;
454   }
455   return pCurNode;
456 }
457 
GetPrev() const458 CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const {
459   ASSERT(m_bIsContentLayoutItem);
460   return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev;
461 }
462 
GetNext() const463 CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const {
464   ASSERT(m_bIsContentLayoutItem);
465   return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext;
466 }
467 
GetIndex() const468 int32_t CXFA_LayoutItem::GetIndex() const {
469   ASSERT(m_bIsContentLayoutItem);
470   int32_t iIndex = 0;
471   const CXFA_ContentLayoutItem* pCurNode =
472       static_cast<const CXFA_ContentLayoutItem*>(this);
473   while (pCurNode->m_pPrev) {
474     pCurNode = pCurNode->m_pPrev;
475     ++iIndex;
476   }
477   return iIndex;
478 }
479 
GetCount() const480 int32_t CXFA_LayoutItem::GetCount() const {
481   ASSERT(m_bIsContentLayoutItem);
482   int32_t iCount = GetIndex() + 1;
483   const CXFA_ContentLayoutItem* pCurNode =
484       static_cast<const CXFA_ContentLayoutItem*>(this);
485   while (pCurNode->m_pNext) {
486     pCurNode = pCurNode->m_pNext;
487     iCount++;
488   }
489   return iCount;
490 }
491 
AddChild(CXFA_LayoutItem * pChildItem)492 void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) {
493   if (pChildItem->m_pParent) {
494     pChildItem->m_pParent->RemoveChild(pChildItem);
495   }
496   pChildItem->m_pParent = this;
497   if (m_pFirstChild == NULL) {
498     m_pFirstChild = pChildItem;
499   } else {
500     CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
501     while (pExistingChildItem->m_pNextSibling) {
502       pExistingChildItem = pExistingChildItem->m_pNextSibling;
503     }
504     pExistingChildItem->m_pNextSibling = pChildItem;
505   }
506 }
AddHeadChild(CXFA_LayoutItem * pChildItem)507 void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) {
508   if (pChildItem->m_pParent) {
509     pChildItem->m_pParent->RemoveChild(pChildItem);
510   }
511   pChildItem->m_pParent = this;
512   if (m_pFirstChild == NULL) {
513     m_pFirstChild = pChildItem;
514   } else {
515     CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
516     m_pFirstChild = pChildItem;
517     m_pFirstChild->m_pNextSibling = pExistingChildItem;
518   }
519 }
InsertChild(CXFA_LayoutItem * pBeforeItem,CXFA_LayoutItem * pChildItem)520 void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem,
521                                   CXFA_LayoutItem* pChildItem) {
522   if (pBeforeItem->m_pParent != this) {
523     return;
524   }
525   if (pChildItem->m_pParent) {
526     pChildItem->m_pParent = NULL;
527   }
528   pChildItem->m_pParent = this;
529   CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling;
530   pBeforeItem->m_pNextSibling = pChildItem;
531   pChildItem->m_pNextSibling = pExistingChildItem;
532 }
RemoveChild(CXFA_LayoutItem * pChildItem)533 void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) {
534   if (pChildItem->m_pParent != this) {
535     return;
536   }
537   if (m_pFirstChild == pChildItem) {
538     m_pFirstChild = pChildItem->m_pNextSibling;
539   } else {
540     CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
541     while (pExistingChildItem &&
542            pExistingChildItem->m_pNextSibling != pChildItem) {
543       pExistingChildItem = pExistingChildItem->m_pNextSibling;
544     }
545     if (pExistingChildItem) {
546       pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling;
547     }
548   }
549   pChildItem->m_pNextSibling = NULL;
550   pChildItem->m_pParent = NULL;
551 }
ExtractLayoutItem()552 CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() {
553   CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
554   if (pLayoutItem) {
555     m_pLayoutItem = (CXFA_ContentLayoutItem*)pLayoutItem->m_pNextSibling;
556     pLayoutItem->m_pNextSibling = NULL;
557   }
558 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
559   if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
560       ToContentLayoutItem(m_pOldLayoutItem)) {
561     if (m_pOldLayoutItem->m_pPrev) {
562       m_pOldLayoutItem->m_pPrev->m_pNext = NULL;
563     }
564     IXFA_Notify* pNotify =
565         m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();
566     IXFA_DocLayout* pDocLayout =
567         m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
568     CXFA_ContentLayoutItem* pOldLayoutItem = m_pOldLayoutItem;
569     while (pOldLayoutItem) {
570       CXFA_ContentLayoutItem* pNextOldLayoutItem = pOldLayoutItem->m_pNext;
571       pNotify->OnLayoutEvent(pDocLayout, pOldLayoutItem,
572                              XFA_LAYOUTEVENT_ItemRemoving);
573       delete pOldLayoutItem;
574       pOldLayoutItem = pNextOldLayoutItem;
575     }
576     m_pOldLayoutItem = NULL;
577   }
578 #endif
579   return pLayoutItem;
580 }
XFA_ItemLayoutProcessor_FindBreakNode(CXFA_Node * pContainerNode,CXFA_Node * & pCurActionNode,XFA_ItemLayoutProcessorStages & nCurStage,FX_BOOL bBreakBefore)581 static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode(
582     CXFA_Node* pContainerNode,
583     CXFA_Node*& pCurActionNode,
584     XFA_ItemLayoutProcessorStages& nCurStage,
585     FX_BOOL bBreakBefore) {
586   FX_BOOL bFindRs = FALSE;
587   for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
588        pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
589     XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before;
590     if (!bBreakBefore) {
591       eAttributeType = XFA_ATTRIBUTE_After;
592     }
593     switch (pBreakNode->GetClassID()) {
594       case XFA_ELEMENT_BreakBefore: {
595         if (bBreakBefore) {
596           pCurActionNode = pBreakNode;
597           nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
598           bFindRs = TRUE;
599         }
600       } break;
601       case XFA_ELEMENT_BreakAfter: {
602         if (!bBreakBefore) {
603           pCurActionNode = pBreakNode;
604           nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
605           bFindRs = TRUE;
606         }
607       } break;
608       case XFA_ELEMENT_Break:
609         if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) {
610           pCurActionNode = pBreakNode;
611           nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
612           if (!bBreakBefore) {
613             nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
614           }
615           bFindRs = TRUE;
616           break;
617         }
618       default:
619         break;
620     }
621     if (bFindRs) {
622       break;
623     }
624   }
625   return bFindRs;
626 }
627 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
XFA_DeleteLayoutGeneratedNode(CXFA_Node * pGenerateNode)628 static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
629   IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify();
630   IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout();
631   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
632       pGenerateNode);
633   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
634        pNode = sIterator.MoveToNext()) {
635     CXFA_ContentLayoutItem* pCurLayoutItem =
636         (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
637     CXFA_ContentLayoutItem* pNextLayoutItem = NULL;
638     while (pCurLayoutItem) {
639       pNextLayoutItem = pCurLayoutItem->m_pNext;
640       pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem,
641                              XFA_LAYOUTEVENT_ItemRemoving);
642       delete pCurLayoutItem;
643       pCurLayoutItem = pNextLayoutItem;
644     }
645   }
646   pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode);
647 }
648 #endif
XFA_ItemLayoutProcessor_GotoNextContainerNode(CXFA_Node * & pCurActionNode,XFA_ItemLayoutProcessorStages & nCurStage,CXFA_Node * pParentContainer,FX_BOOL bUsePageBreak)649 void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode(
650     CXFA_Node*& pCurActionNode,
651     XFA_ItemLayoutProcessorStages& nCurStage,
652     CXFA_Node* pParentContainer,
653     FX_BOOL bUsePageBreak) {
654   CXFA_Node* pEntireContainer = pParentContainer;
655   CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;
656   switch (nCurStage) {
657     case XFA_ItemLayoutProcessorStages_BreakBefore:
658     case XFA_ItemLayoutProcessorStages_BreakAfter: {
659       pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent);
660     } break;
661     case XFA_ItemLayoutProcessorStages_Keep:
662     case XFA_ItemLayoutProcessorStages_Container:
663       pChildContainer = pCurActionNode;
664       break;
665     default:
666       pChildContainer = XFA_LAYOUT_INVALIDNODE;
667       break;
668   }
669   switch (nCurStage) {
670     case XFA_ItemLayoutProcessorStages_Keep: {
671       CXFA_Node* pBreakAfterNode =
672           pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
673       if (!m_bKeepBreakFinish &&
674           XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
675                                                 nCurStage, FALSE)) {
676         return;
677       }
678       goto CheckNextChildContainer;
679     }
680     case XFA_ItemLayoutProcessorStages_None: {
681       pCurActionNode = XFA_LAYOUT_INVALIDNODE;
682       case XFA_ItemLayoutProcessorStages_BookendLeader:
683         for (CXFA_Node* pBookendNode =
684                  pCurActionNode == XFA_LAYOUT_INVALIDNODE
685                      ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
686                      : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
687              pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
688                                XFA_NODEITEM_NextSibling)) {
689           switch (pBookendNode->GetClassID()) {
690             case XFA_ELEMENT_Bookend:
691             case XFA_ELEMENT_Break:
692               pCurActionNode = pBookendNode;
693               nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader;
694               return;
695             default:
696               break;
697           }
698         }
699     }
700       {
701         pCurActionNode = XFA_LAYOUT_INVALIDNODE;
702         case XFA_ItemLayoutProcessorStages_BreakBefore:
703           if (pCurActionNode != XFA_LAYOUT_INVALIDNODE) {
704             CXFA_Node* pBreakBeforeNode =
705                 pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
706             if (!m_bKeepBreakFinish &&
707                 XFA_ItemLayoutProcessor_FindBreakNode(
708                     pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) {
709               return;
710             }
711             if (m_bIsProcessKeep) {
712               if (ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage,
713                                                  pChildContainer)) {
714                 return;
715               }
716               goto CheckNextChildContainer;
717             }
718             pCurActionNode = pChildContainer;
719             nCurStage = XFA_ItemLayoutProcessorStages_Container;
720             return;
721           }
722           goto CheckNextChildContainer;
723       }
724     case XFA_ItemLayoutProcessorStages_Container: {
725       pCurActionNode = XFA_LAYOUT_INVALIDNODE;
726       case XFA_ItemLayoutProcessorStages_BreakAfter: {
727         if (pCurActionNode == XFA_LAYOUT_INVALIDNODE) {
728           CXFA_Node* pBreakAfterNode =
729               pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
730           if (!m_bKeepBreakFinish &&
731               XFA_ItemLayoutProcessor_FindBreakNode(
732                   pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
733             return;
734           }
735         } else {
736           CXFA_Node* pBreakAfterNode =
737               pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
738           if (XFA_ItemLayoutProcessor_FindBreakNode(
739                   pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
740             return;
741           }
742         }
743         goto CheckNextChildContainer;
744       }
745     }
746     CheckNextChildContainer : {
747       CXFA_Node* pNextChildContainer =
748           pChildContainer == XFA_LAYOUT_INVALIDNODE
749               ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild,
750                                               XFA_OBJECTTYPE_ContainerNode)
751               : pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
752                                              XFA_OBJECTTYPE_ContainerNode);
753       while (pNextChildContainer &&
754              pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {
755         CXFA_Node* pSaveNode = pNextChildContainer;
756         pNextChildContainer = pNextChildContainer->GetNodeItem(
757             XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
758 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_
759         if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
760           XFA_DeleteLayoutGeneratedNode(pSaveNode);
761         }
762 #endif
763       }
764       if (!pNextChildContainer) {
765         goto NoMoreChildContainer;
766       }
767       FX_BOOL bLastKeep = FALSE;
768       if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage,
769                                        pNextChildContainer, bLastKeep)) {
770         return;
771       }
772       if (!m_bKeepBreakFinish && !bLastKeep &&
773           XFA_ItemLayoutProcessor_FindBreakNode(
774               pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
775               pCurActionNode, nCurStage, TRUE)) {
776         return;
777       }
778       pCurActionNode = pNextChildContainer;
779       if (m_bIsProcessKeep) {
780         nCurStage = XFA_ItemLayoutProcessorStages_Keep;
781       } else {
782         nCurStage = XFA_ItemLayoutProcessorStages_Container;
783       }
784       return;
785     }
786     NoMoreChildContainer : {
787       pCurActionNode = XFA_LAYOUT_INVALIDNODE;
788       case XFA_ItemLayoutProcessorStages_BookendTrailer:
789         for (CXFA_Node* pBookendNode =
790                  pCurActionNode == XFA_LAYOUT_INVALIDNODE
791                      ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
792                      : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
793              pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
794                                XFA_NODEITEM_NextSibling)) {
795           switch (pBookendNode->GetClassID()) {
796             case XFA_ELEMENT_Bookend:
797             case XFA_ELEMENT_Break:
798               pCurActionNode = pBookendNode;
799               nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer;
800               return;
801             default:
802               break;
803           }
804         }
805     }
806     default:
807       pCurActionNode = NULL;
808       nCurStage = XFA_ItemLayoutProcessorStages_Done;
809   }
810 }
ProcessKeepNodesForCheckNext(CXFA_Node * & pCurActionNode,XFA_ItemLayoutProcessorStages & nCurStage,CXFA_Node * & pNextContainer,FX_BOOL & bLastKeepNode)811 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(
812     CXFA_Node*& pCurActionNode,
813     XFA_ItemLayoutProcessorStages& nCurStage,
814     CXFA_Node*& pNextContainer,
815     FX_BOOL& bLastKeepNode) {
816   FX_BOOL bCanSplite = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None;
817   FX_BOOL bNextKeep = FALSE;
818   if (XFA_ExistContainerKeep(pNextContainer, FALSE)) {
819     bNextKeep = TRUE;
820   }
821   if (bNextKeep && !bCanSplite) {
822     if (!m_bIsProcessKeep && !m_bKeepBreakFinish) {
823       m_pKeepHeadNode = pNextContainer;
824       m_bIsProcessKeep = TRUE;
825     }
826   } else {
827     if (m_bIsProcessKeep && m_pKeepHeadNode != NULL) {
828       m_pKeepTailNode = pNextContainer;
829       if (!m_bKeepBreakFinish &&
830           XFA_ItemLayoutProcessor_FindBreakNode(
831               pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
832               pCurActionNode, nCurStage, TRUE)) {
833         return TRUE;
834       } else {
835         pNextContainer = m_pKeepHeadNode;
836         m_bKeepBreakFinish = TRUE;
837         m_pKeepHeadNode = NULL;
838         m_pKeepTailNode = NULL;
839         m_bIsProcessKeep = FALSE;
840       }
841     } else {
842       if (m_bKeepBreakFinish) {
843         bLastKeepNode = TRUE;
844       }
845       m_bKeepBreakFinish = FALSE;
846     }
847   }
848   return FALSE;
849 }
ProcessKeepNodesForBreakBefore(CXFA_Node * & pCurActionNode,XFA_ItemLayoutProcessorStages & nCurStage,CXFA_Node * pContainerNode)850 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore(
851     CXFA_Node*& pCurActionNode,
852     XFA_ItemLayoutProcessorStages& nCurStage,
853     CXFA_Node* pContainerNode) {
854   if (m_pKeepTailNode == pContainerNode) {
855     pCurActionNode = m_pKeepHeadNode;
856     m_bKeepBreakFinish = TRUE;
857     m_pKeepHeadNode = NULL;
858     m_pKeepTailNode = NULL;
859     m_bIsProcessKeep = FALSE;
860     nCurStage = XFA_ItemLayoutProcessorStages_Container;
861     return TRUE;
862   }
863   CXFA_Node* pBreakAfterNode =
864       pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild);
865   if (XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
866                                             nCurStage, FALSE)) {
867     return TRUE;
868   }
869   return FALSE;
870 }
XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node * pNode)871 FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) {
872   XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
873   return ePresence == XFA_ATTRIBUTEENUM_Visible ||
874          ePresence == XFA_ATTRIBUTEENUM_Invisible;
875 }
XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(CXFA_Node * pFormNode,FX_FLOAT & fContainerWidth,FX_FLOAT & fContainerHeight,FX_BOOL & bContainerWidthAutoSize,FX_BOOL & bContainerHeightAutoSize)876 static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
877     CXFA_Node* pFormNode,
878     FX_FLOAT& fContainerWidth,
879     FX_FLOAT& fContainerHeight,
880     FX_BOOL& bContainerWidthAutoSize,
881     FX_BOOL& bContainerHeightAutoSize) {
882   fContainerWidth = 0;
883   fContainerHeight = 0;
884   bContainerWidthAutoSize = TRUE;
885   bContainerHeightAutoSize = TRUE;
886   XFA_ELEMENT eClassID = pFormNode->GetClassID();
887   CXFA_Measurement mTmpValue;
888   if (bContainerWidthAutoSize &&
889       (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
890       pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) &&
891       mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
892     fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
893     bContainerWidthAutoSize = FALSE;
894   }
895   if (bContainerHeightAutoSize &&
896       (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
897       pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) &&
898       mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
899     fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
900     bContainerHeightAutoSize = FALSE;
901   }
902   if (bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform &&
903       pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) &&
904       mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
905     fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
906     bContainerWidthAutoSize = FALSE;
907   }
908   if (bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform &&
909       pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) &&
910       mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
911     fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
912     bContainerHeightAutoSize = FALSE;
913   }
914 }
915 static inline void
XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(CXFA_Node * pFormNode,FX_BOOL bContainerWidthAutoSize,FX_FLOAT fContentCalculatedWidth,FX_FLOAT & fContainerWidth,FX_BOOL bContainerHeightAutoSize,FX_FLOAT fContentCalculatedHeight,FX_FLOAT & fContainerHeight)916 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
917     CXFA_Node* pFormNode,
918     FX_BOOL bContainerWidthAutoSize,
919     FX_FLOAT fContentCalculatedWidth,
920     FX_FLOAT& fContainerWidth,
921     FX_BOOL bContainerHeightAutoSize,
922     FX_FLOAT fContentCalculatedHeight,
923     FX_FLOAT& fContainerHeight) {
924   CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
925   CXFA_Measurement mTmpValue;
926   if (bContainerWidthAutoSize) {
927     fContainerWidth = fContentCalculatedWidth;
928     if (pMarginNode) {
929       if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) {
930         fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
931       }
932       if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) {
933         fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
934       }
935     }
936   }
937   if (bContainerHeightAutoSize) {
938     fContainerHeight = fContentCalculatedHeight;
939     if (pMarginNode) {
940       if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) {
941         fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
942       }
943       if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue,
944                                   FALSE)) {
945         fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
946       }
947     }
948   }
949 }
CalculatePositionedContainerPos(CXFA_Node * pNode,FX_FLOAT fWidth,FX_FLOAT fHeight,FX_FLOAT & fAbsoluteX,FX_FLOAT & fAbsoluteY)950 void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(
951     CXFA_Node* pNode,
952     FX_FLOAT fWidth,
953     FX_FLOAT fHeight,
954     FX_FLOAT& fAbsoluteX,
955     FX_FLOAT& fAbsoluteY) {
956   XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
957   int32_t nAnchorType = 0;
958   switch (eAnchorType) {
959     case XFA_ATTRIBUTEENUM_TopLeft:
960       nAnchorType = 0;
961       break;
962     case XFA_ATTRIBUTEENUM_TopCenter:
963       nAnchorType = 1;
964       break;
965     case XFA_ATTRIBUTEENUM_TopRight:
966       nAnchorType = 2;
967       break;
968     case XFA_ATTRIBUTEENUM_MiddleLeft:
969       nAnchorType = 3;
970       break;
971     case XFA_ATTRIBUTEENUM_MiddleCenter:
972       nAnchorType = 4;
973       break;
974     case XFA_ATTRIBUTEENUM_MiddleRight:
975       nAnchorType = 5;
976       break;
977     case XFA_ATTRIBUTEENUM_BottomLeft:
978       nAnchorType = 6;
979       break;
980     case XFA_ATTRIBUTEENUM_BottomCenter:
981       nAnchorType = 7;
982       break;
983     case XFA_ATTRIBUTEENUM_BottomRight:
984       nAnchorType = 8;
985       break;
986     default:
987       break;
988   }
989   static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8},
990                                          {6, 3, 0, 7, 4, 1, 8, 5, 2},
991                                          {8, 7, 6, 5, 4, 3, 2, 1, 0},
992                                          {2, 5, 8, 1, 4, 7, 0, 3, 6}};
993 
994   FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
995   FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
996   int32_t nRotate =
997       FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
998   nRotate = XFA_MapRotation(nRotate) / 90;
999   int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];
1000   fAbsoluteX = fAnchorX;
1001   fAbsoluteY = fAnchorY;
1002   switch (nAbsoluteAnchorType / 3) {
1003     case 1:
1004       fAbsoluteY -= fHeight / 2;
1005       break;
1006     case 2:
1007       fAbsoluteY -= fHeight;
1008       break;
1009     default:
1010       break;
1011   }
1012   switch (nAbsoluteAnchorType % 3) {
1013     case 1:
1014       fAbsoluteX -= fWidth / 2;
1015       break;
1016     case 2:
1017       fAbsoluteX -= fWidth;
1018       break;
1019     default:
1020       break;
1021   }
1022 }
IncrementRelayoutNode(CXFA_LayoutProcessor * pLayoutProcessor,CXFA_Node * pNode,CXFA_Node * pParentNode)1023 FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(
1024     CXFA_LayoutProcessor* pLayoutProcessor,
1025     CXFA_Node* pNode,
1026     CXFA_Node* pParentNode) {
1027   return FALSE;
1028 }
DoLayoutPageArea(CXFA_ContainerLayoutItem * pPageAreaLayoutItem)1029 void CXFA_ItemLayoutProcessor::DoLayoutPageArea(
1030     CXFA_ContainerLayoutItem* pPageAreaLayoutItem) {
1031   CXFA_Node* pFormNode = pPageAreaLayoutItem->m_pFormNode;
1032   CXFA_Node* pCurChildNode = XFA_LAYOUT_INVALIDNODE;
1033   XFA_ItemLayoutProcessorStages nCurChildNodeStage =
1034       XFA_ItemLayoutProcessorStages_None;
1035   CXFA_LayoutItem* pBeforeItem = NULL;
1036   for (XFA_ItemLayoutProcessor_GotoNextContainerNode(
1037            pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);
1038        pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
1039            pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {
1040     if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
1041       continue;
1042     }
1043     if (pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
1044       continue;
1045     }
1046     CXFA_ItemLayoutProcessor* pProcessor =
1047         new CXFA_ItemLayoutProcessor(pCurChildNode, NULL);
1048 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
1049     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
1050 #endif
1051     pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
1052     if (!pProcessor->HasLayoutItem()) {
1053       delete pProcessor;
1054       continue;
1055     }
1056     FX_FLOAT fWidth, fHeight;
1057     pProcessor->GetCurrentComponentSize(fWidth, fHeight);
1058     FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
1059     CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX,
1060                                     fAbsoluteY);
1061     pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
1062     CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
1063     if (pBeforeItem == NULL) {
1064       pPageAreaLayoutItem->AddHeadChild(pProcessItem);
1065     } else {
1066       pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);
1067     }
1068     pBeforeItem = pProcessItem;
1069     delete pProcessor;
1070   }
1071   pBeforeItem = NULL;
1072   CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;
1073   while (pLayoutItem) {
1074     if (!pLayoutItem->IsContentLayoutItem() ||
1075         pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {
1076       pLayoutItem = pLayoutItem->m_pNextSibling;
1077       continue;
1078     }
1079     if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {
1080       CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling;
1081       pPageAreaLayoutItem->RemoveChild(pLayoutItem);
1082       if (pBeforeItem == NULL) {
1083         pPageAreaLayoutItem->AddHeadChild(pLayoutItem);
1084       } else {
1085         pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);
1086       }
1087       pBeforeItem = pLayoutItem;
1088       pLayoutItem = pNextLayoutItem;
1089     }
1090   }
1091 }
DoLayoutPositionedContainer(CXFA_LayoutContext * pContext)1092 void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(
1093     CXFA_LayoutContext* pContext) {
1094   if (m_pLayoutItem != NULL) {
1095     return;
1096   }
1097   m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
1098   FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) !=
1099                        XFA_ATTRIBUTEENUM_Position);
1100   FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
1101   FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
1102   XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
1103       m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
1104       bContainerHeightAutoSize);
1105   FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
1106   FX_FLOAT fHiddenContentCalculatedWidth = 0,
1107            fHiddenContentCalculatedHeight = 0;
1108   if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
1109     XFA_ItemLayoutProcessor_GotoNextContainerNode(
1110         m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
1111   }
1112   int32_t iColIndex = 0;
1113   for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
1114            m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
1115     if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
1116       continue;
1117     }
1118     if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
1119       continue;
1120     }
1121     CXFA_ItemLayoutProcessor* pProcessor =
1122         new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
1123 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
1124     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
1125 #endif
1126     if (pContext && pContext->m_prgSpecifiedColumnWidths) {
1127       int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
1128       if (iColSpan <=
1129           pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {
1130         pContext->m_fCurColumnWidth = 0;
1131         pContext->m_bCurColumnWidthAvaiable = TRUE;
1132         if (iColSpan == -1) {
1133           iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();
1134         }
1135         for (int32_t i = 0; i < iColSpan; i++) {
1136           pContext->m_fCurColumnWidth +=
1137               pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);
1138         }
1139         if (pContext->m_fCurColumnWidth == 0) {
1140           pContext->m_bCurColumnWidthAvaiable = FALSE;
1141         }
1142         iColIndex += iColSpan;
1143       }
1144     }
1145     pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
1146                          pContext);
1147     if (!pProcessor->HasLayoutItem()) {
1148       delete pProcessor;
1149       continue;
1150     }
1151     FX_FLOAT fWidth, fHeight;
1152     pProcessor->GetCurrentComponentSize(fWidth, fHeight);
1153     FX_BOOL bChangeParentSize = FALSE;
1154     if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
1155       bChangeParentSize = TRUE;
1156     }
1157     FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
1158     if (!bIgnoreXY) {
1159       CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight,
1160                                       fAbsoluteX, fAbsoluteY);
1161     }
1162     pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
1163     if (bContainerWidthAutoSize) {
1164       FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;
1165       if (bChangeParentSize) {
1166         if (fContentCalculatedWidth < fChildSuppliedWidth) {
1167           fContentCalculatedWidth = fChildSuppliedWidth;
1168         }
1169       } else {
1170         if (fHiddenContentCalculatedWidth < fChildSuppliedWidth &&
1171             m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
1172           fHiddenContentCalculatedWidth = fChildSuppliedWidth;
1173         }
1174       }
1175     }
1176     if (bContainerHeightAutoSize) {
1177       FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;
1178       if (bChangeParentSize) {
1179         if (fContentCalculatedHeight < fChildSuppliedHeight) {
1180           fContentCalculatedHeight = fChildSuppliedHeight;
1181         }
1182       } else {
1183         if (fHiddenContentCalculatedHeight < fChildSuppliedHeight &&
1184             m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
1185           fHiddenContentCalculatedHeight = fChildSuppliedHeight;
1186         }
1187       }
1188     }
1189     m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
1190     delete pProcessor;
1191   }
1192   XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();
1193   if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {
1194     fContentCalculatedWidth = fHiddenContentCalculatedWidth;
1195   }
1196   if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {
1197     fContentCalculatedHeight = fHiddenContentCalculatedHeight;
1198   }
1199   XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
1200       m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
1201       fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
1202       fContainerHeight);
1203   SetCurrentComponentSize(fContainerWidth, fContainerHeight);
1204 }
XFA_ItemLayoutProcessor_UpdateWidgetSize(CXFA_ContentLayoutItem * pLayoutItem,FX_FLOAT & fWidth,FX_FLOAT & fHeight)1205 static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(
1206     CXFA_ContentLayoutItem* pLayoutItem,
1207     FX_FLOAT& fWidth,
1208     FX_FLOAT& fHeight) {
1209   CXFA_Node* pNode = pLayoutItem->m_pFormNode;
1210   ASSERT(pNode);
1211   XFA_ELEMENT eClassID = pNode->GetClassID();
1212   switch (eClassID) {
1213     case XFA_ELEMENT_Subform:
1214     case XFA_ELEMENT_Area:
1215     case XFA_ELEMENT_ExclGroup:
1216     case XFA_ELEMENT_SubformSet: {
1217       if (fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {
1218         fWidth = pLayoutItem->m_sSize.x;
1219       }
1220       if (fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {
1221         fHeight = pLayoutItem->m_sSize.y;
1222       }
1223       break;
1224     }
1225     case XFA_ELEMENT_Draw:
1226     case XFA_ELEMENT_Field: {
1227       pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(
1228           pNode, fWidth, fHeight);
1229       break;
1230     }
1231     default:
1232       ASSERT(FALSE);
1233   }
1234 }
XFA_ItemLayoutProcessor_RelocateTableRowCells(CXFA_ContentLayoutItem * pLayoutRow,const CFX_ArrayTemplate<FX_FLOAT> & rgSpecifiedColumnWidths,XFA_ATTRIBUTEENUM eLayout)1235 static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(
1236     CXFA_ContentLayoutItem* pLayoutRow,
1237     const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths,
1238     XFA_ATTRIBUTEENUM eLayout) {
1239   FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
1240   FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
1241   XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
1242       pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight,
1243       bContainerWidthAutoSize, bContainerHeightAutoSize);
1244   CXFA_Node* pMarginNode =
1245       pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
1246   FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
1247   if (pMarginNode) {
1248     fLeftInset =
1249         pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
1250     fTopInset =
1251         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
1252     fRightInset =
1253         pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
1254     fBottomInset =
1255         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
1256   }
1257   FX_FLOAT fContentWidthLimit =
1258       bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
1259                               : fContainerWidth - fLeftInset - fRightInset;
1260   FX_FLOAT fContentCurrentHeight =
1261       pLayoutRow->m_sSize.y - fTopInset - fBottomInset;
1262   FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
1263   FX_FLOAT fCurrentColX = 0;
1264   int32_t nCurrentColIdx = 0;
1265   FX_BOOL bMetWholeRowCell = FALSE;
1266   for (CXFA_ContentLayoutItem* pLayoutChild =
1267            (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
1268        pLayoutChild;
1269        pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
1270     int32_t nOriginalColSpan =
1271         pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
1272     int32_t nColSpan = nOriginalColSpan;
1273     FX_FLOAT fColSpanWidth = 0;
1274     if (nColSpan == -1 ||
1275         nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {
1276       nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;
1277     }
1278     for (int32_t i = 0; i < nColSpan; i++) {
1279       fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];
1280     }
1281     if (nColSpan != nOriginalColSpan) {
1282       fColSpanWidth = bMetWholeRowCell ? 0 : std::max(fColSpanWidth,
1283                                                       pLayoutChild->m_sSize.y);
1284     }
1285     if (nOriginalColSpan == -1) {
1286       bMetWholeRowCell = TRUE;
1287     }
1288     pLayoutChild->m_sPos.Set(fCurrentColX, 0);
1289     pLayoutChild->m_sSize.x = fColSpanWidth;
1290     if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
1291       fCurrentColX += fColSpanWidth;
1292       nCurrentColIdx += nColSpan;
1293       FX_FLOAT fNewHeight =
1294           bContainerHeightAutoSize ? -1 : fContentCurrentHeight;
1295       XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth,
1296                                                fNewHeight);
1297       pLayoutChild->m_sSize.y = fNewHeight;
1298       if (bContainerHeightAutoSize) {
1299         FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;
1300         if (fContentCalculatedHeight < fChildSuppliedHeight) {
1301           fContentCalculatedHeight = fChildSuppliedHeight;
1302         }
1303       }
1304     }
1305   }
1306   if (bContainerHeightAutoSize) {
1307     for (CXFA_ContentLayoutItem* pLayoutChild =
1308              (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
1309          pLayoutChild;
1310          pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
1311       XFA_ItemLayoutProcessor_UpdateWidgetSize(
1312           pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);
1313       FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;
1314       pLayoutChild->m_sSize.y = fContentCalculatedHeight;
1315       CXFA_Node* pParaNode =
1316           pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);
1317       if (pParaNode && pLayoutChild->m_pFirstChild) {
1318         FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;
1319         XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);
1320         switch (eVType) {
1321           case XFA_ATTRIBUTEENUM_Middle:
1322             fOffHeight = fOffHeight / 2;
1323             break;
1324           case XFA_ATTRIBUTEENUM_Bottom:
1325             break;
1326           case XFA_ATTRIBUTEENUM_Top:
1327           default:
1328             fOffHeight = 0;
1329             break;
1330         }
1331         if (fOffHeight > 0) {
1332           for (CXFA_ContentLayoutItem* pInnerLayoutChild =
1333                    (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild;
1334                pInnerLayoutChild;
1335                pInnerLayoutChild =
1336                    (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) {
1337             pInnerLayoutChild->m_sPos.y += fOffHeight;
1338           }
1339         }
1340       }
1341     }
1342   }
1343   if (bContainerWidthAutoSize) {
1344     FX_FLOAT fChildSuppliedWidth = fCurrentColX;
1345     if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
1346         fContentWidthLimit > fChildSuppliedWidth) {
1347       fChildSuppliedWidth = fContentWidthLimit;
1348     }
1349     if (fContentCalculatedWidth < fChildSuppliedWidth) {
1350       fContentCalculatedWidth = fChildSuppliedWidth;
1351     }
1352   } else {
1353     fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;
1354   }
1355   if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) ==
1356       XFA_ATTRIBUTEENUM_Rl_row) {
1357     for (CXFA_ContentLayoutItem* pLayoutChild =
1358              (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
1359          pLayoutChild;
1360          pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
1361       pLayoutChild->m_sPos.x = fContentCalculatedWidth -
1362                                pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;
1363     }
1364   }
1365   XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
1366       pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
1367       fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
1368       fContainerHeight);
1369   pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight);
1370 }
DoLayoutTableContainer(CXFA_Node * pLayoutNode)1371 void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) {
1372   if (m_pLayoutItem != NULL) {
1373     return;
1374   }
1375   if (pLayoutNode == NULL) {
1376     pLayoutNode = m_pFormNode;
1377   }
1378   ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
1379   m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
1380   FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
1381   FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
1382   XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
1383       m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
1384       bContainerHeightAutoSize);
1385   FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
1386   CXFA_Node* pMarginNode =
1387       m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
1388   FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
1389   if (pMarginNode) {
1390     fLeftInset =
1391         pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
1392     fTopInset =
1393         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
1394     fRightInset =
1395         pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
1396     fBottomInset =
1397         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
1398   }
1399   FX_FLOAT fContentWidthLimit =
1400       bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
1401                               : fContainerWidth - fLeftInset - fRightInset;
1402   CFX_WideStringC wsColumnWidths;
1403   if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {
1404     CFX_WideStringArray widths;
1405     if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(),
1406                            L' ', widths) > 0) {
1407       int32_t iCols = widths.GetSize();
1408       CFX_WideString wsWidth;
1409       for (int32_t i = 0; i < iCols; i++) {
1410         wsWidth = widths[i];
1411         wsWidth.TrimLeft(L' ');
1412         if (!wsWidth.IsEmpty()) {
1413           CXFA_Measurement measure(wsWidth);
1414           m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));
1415         }
1416       }
1417     }
1418   }
1419   int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();
1420   CXFA_LayoutContext layoutContext;
1421   layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
1422   CXFA_LayoutContext* pLayoutContext =
1423       iSpecifiedColumnCount > 0 ? &layoutContext : NULL;
1424   if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
1425     XFA_ItemLayoutProcessor_GotoNextContainerNode(
1426         m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
1427   }
1428   for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
1429            m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
1430     layoutContext.m_bCurColumnWidthAvaiable = FALSE;
1431     layoutContext.m_fCurColumnWidth = 0;
1432     if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
1433       continue;
1434     }
1435     CXFA_ItemLayoutProcessor* pProcessor =
1436         new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
1437 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
1438     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
1439 #endif
1440     pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
1441                          pLayoutContext);
1442     if (!pProcessor->HasLayoutItem()) {
1443       delete pProcessor;
1444       continue;
1445     }
1446     m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
1447     delete pProcessor;
1448   }
1449   int32_t iRowCount = 0, iColCount = 0;
1450   {
1451     CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgRowItems;
1452     CFX_ArrayTemplate<int32_t> rgRowItemsSpan;
1453     CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;
1454     for (CXFA_ContentLayoutItem* pLayoutChild =
1455              (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
1456          pLayoutChild;
1457          pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
1458       if (pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {
1459         continue;
1460       }
1461       if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
1462         continue;
1463       }
1464       XFA_ATTRIBUTEENUM eLayout =
1465           pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
1466       if (eLayout != XFA_ATTRIBUTEENUM_Row &&
1467           eLayout != XFA_ATTRIBUTEENUM_Rl_row) {
1468         continue;
1469       }
1470       if (CXFA_ContentLayoutItem* pRowLayoutCell =
1471               (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild) {
1472         rgRowItems.Add(pRowLayoutCell);
1473         int32_t iColSpan =
1474             pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
1475         rgRowItemsSpan.Add(iColSpan);
1476         rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);
1477       }
1478     }
1479     iRowCount = rgRowItems.GetSize();
1480     iColCount = 0;
1481     FX_BOOL bMoreColumns = TRUE;
1482     while (bMoreColumns) {
1483       bMoreColumns = FALSE;
1484       FX_BOOL bAutoCol = FALSE;
1485       for (int32_t i = 0; i < iRowCount; i++) {
1486         while (rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 ||
1487                                          !XFA_ItemLayoutProcessor_IsTakingSpace(
1488                                              rgRowItems[i]->m_pFormNode))) {
1489           CXFA_ContentLayoutItem* pNewCell =
1490               (CXFA_ContentLayoutItem*)rgRowItems[i]->m_pNextSibling;
1491           if (rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(
1492                                            rgRowItems[i]->m_pFormNode)) {
1493             pNewCell = NULL;
1494           }
1495           rgRowItems[i] = pNewCell;
1496           rgRowItemsSpan[i] =
1497               pNewCell
1498                   ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan)
1499                   : 0;
1500           rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;
1501         }
1502         CXFA_ContentLayoutItem* pCell = rgRowItems[i];
1503         if (!pCell) {
1504           continue;
1505         }
1506         bMoreColumns = TRUE;
1507         if (rgRowItemsSpan[i] == 1) {
1508           if (iColCount >= iSpecifiedColumnCount) {
1509             for (int32_t j = 0, c = iColCount + 1 -
1510                                     m_rgSpecifiedColumnWidths.GetSize();
1511                  j < c; j++) {
1512               m_rgSpecifiedColumnWidths.Add(0);
1513             }
1514           }
1515           if (m_rgSpecifiedColumnWidths[iColCount] <
1516               XFA_LAYOUT_FLOAT_PERCISION) {
1517             bAutoCol = TRUE;
1518           }
1519           if (bAutoCol &&
1520               m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {
1521             m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];
1522           }
1523         }
1524       }
1525       if (bMoreColumns) {
1526         FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];
1527         for (int32_t i = 0; i < iRowCount; i++) {
1528           if (!rgRowItems[i]) {
1529             continue;
1530           }
1531           rgRowItemsSpan[i]--;
1532           rgRowItemsWidth[i] -= fFinalColumnWidth;
1533         }
1534         iColCount++;
1535       }
1536     }
1537   }
1538   FX_FLOAT fCurrentRowY = 0;
1539   for (CXFA_ContentLayoutItem* pLayoutChild =
1540            (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
1541        pLayoutChild;
1542        pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
1543     if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
1544       continue;
1545     }
1546     if (pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {
1547       XFA_ATTRIBUTEENUM eSubformLayout =
1548           pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
1549       if (eSubformLayout == XFA_ATTRIBUTEENUM_Row ||
1550           eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {
1551         XFA_ItemLayoutProcessor_RelocateTableRowCells(
1552             pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);
1553       }
1554     }
1555     pLayoutChild->m_sPos.y = fCurrentRowY;
1556     if (bContainerWidthAutoSize) {
1557       pLayoutChild->m_sPos.x = 0;
1558     } else {
1559       switch (pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
1560         case XFA_ATTRIBUTEENUM_Left:
1561         default:
1562           pLayoutChild->m_sPos.x = 0;
1563           break;
1564         case XFA_ATTRIBUTEENUM_Center:
1565           pLayoutChild->m_sPos.x =
1566               (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2;
1567           break;
1568         case XFA_ATTRIBUTEENUM_Right:
1569           pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;
1570           break;
1571       }
1572     }
1573     if (bContainerWidthAutoSize) {
1574       FX_FLOAT fChildSuppliedWidth =
1575           pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;
1576       if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
1577           fContentWidthLimit > fChildSuppliedWidth) {
1578         fChildSuppliedWidth = fContentWidthLimit;
1579       }
1580       if (fContentCalculatedWidth < fChildSuppliedWidth) {
1581         fContentCalculatedWidth = fChildSuppliedWidth;
1582       }
1583     }
1584     fCurrentRowY += pLayoutChild->m_sSize.y;
1585   }
1586   if (bContainerHeightAutoSize) {
1587     FX_FLOAT fChildSuppliedHeight = fCurrentRowY;
1588     if (fContentCalculatedHeight < fChildSuppliedHeight) {
1589       fContentCalculatedHeight = fChildSuppliedHeight;
1590     }
1591   }
1592   XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
1593       m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
1594       fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
1595       fContainerHeight);
1596   SetCurrentComponentSize(fContainerWidth, fContainerHeight);
1597 }
XFA_ItemLayoutProcessor_HAlignEnumToInt(XFA_ATTRIBUTEENUM eHAlign)1598 static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt(
1599     XFA_ATTRIBUTEENUM eHAlign) {
1600   switch (eHAlign) {
1601     case XFA_ATTRIBUTEENUM_Center:
1602       return 1;
1603     case XFA_ATTRIBUTEENUM_Right:
1604       return 2;
1605     case XFA_ATTRIBUTEENUM_Left:
1606     default:
1607       return 0;
1608   }
1609 }
XFA_ItemLayoutProcessor_UpdatePendedItemLayout(CXFA_ItemLayoutProcessor * pProcessor,CXFA_ContentLayoutItem * pLayoutItem)1610 static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout(
1611     CXFA_ItemLayoutProcessor* pProcessor,
1612     CXFA_ContentLayoutItem* pLayoutItem) {
1613   XFA_ATTRIBUTEENUM eLayout =
1614       pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
1615   switch (eLayout) {
1616     case XFA_ATTRIBUTEENUM_Row:
1617     case XFA_ATTRIBUTEENUM_Rl_row:
1618       XFA_ItemLayoutProcessor_RelocateTableRowCells(
1619           pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);
1620       break;
1621     default:
1622       break;
1623   }
1624 }
IsAddNewRowForTrailer(CXFA_ContentLayoutItem * pTrailerItem)1625 FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(
1626     CXFA_ContentLayoutItem* pTrailerItem) {
1627   if (!pTrailerItem) {
1628     return FALSE;
1629   }
1630   FX_FLOAT fWidth = pTrailerItem->m_sSize.x;
1631   XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
1632   if (eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {
1633     return FALSE;
1634   }
1635   return TRUE;
1636 }
XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor * pProcessor,FX_FLOAT fSplitPos,CXFA_ContentLayoutItem * pTrailerLayoutItem,FX_BOOL bUseInherited=FALSE)1637 static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
1638     CXFA_ItemLayoutProcessor* pProcessor,
1639     FX_FLOAT fSplitPos,
1640     CXFA_ContentLayoutItem* pTrailerLayoutItem,
1641     FX_BOOL bUseInherited = FALSE) {
1642   if (!pTrailerLayoutItem) {
1643     return;
1644   }
1645   FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;
1646   if (bUseInherited) {
1647     FX_FLOAT fNewSplitPos = 0;
1648     if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
1649       fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
1650     }
1651     if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
1652       pProcessor->SplitLayoutItem(fNewSplitPos);
1653     }
1654     return;
1655   }
1656   XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor,
1657                                                  pTrailerLayoutItem);
1658   CXFA_Node* pMarginNode =
1659       pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
1660   FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
1661   if (pMarginNode) {
1662     fLeftInset =
1663         pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
1664     fTopInset =
1665         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
1666     fRightInset =
1667         pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
1668     fBottomInset =
1669         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
1670   }
1671   if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {
1672     pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;
1673     pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;
1674     pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;
1675     pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
1676     return;
1677   }
1678   FX_FLOAT fNewSplitPos = 0;
1679   if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
1680     fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
1681   }
1682   if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
1683     pProcessor->SplitLayoutItem(fNewSplitPos);
1684     pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;
1685   } else {
1686     pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;
1687   }
1688   switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
1689     case XFA_ATTRIBUTEENUM_Left:
1690     default:
1691       pTrailerLayoutItem->m_sPos.x = fLeftInset;
1692       break;
1693     case XFA_ATTRIBUTEENUM_Right:
1694       pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
1695                                      fRightInset -
1696                                      pTrailerLayoutItem->m_sSize.x;
1697       break;
1698     case XFA_ATTRIBUTEENUM_Center:
1699       pTrailerLayoutItem->m_sPos.x =
1700           (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
1701            pTrailerLayoutItem->m_sSize.x) /
1702           2;
1703       break;
1704   }
1705   pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
1706   pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
1707 };
XFA_ItemLayoutProcessor_AddLeaderAfterSplit(CXFA_ItemLayoutProcessor * pProcessor,CXFA_ContentLayoutItem * pLeaderLayoutItem)1708 static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(
1709     CXFA_ItemLayoutProcessor* pProcessor,
1710     CXFA_ContentLayoutItem* pLeaderLayoutItem) {
1711   XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);
1712   CXFA_Node* pMarginNode =
1713       pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
1714   FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
1715   if (pMarginNode) {
1716     fLeftInset =
1717         pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
1718     fTopInset =
1719         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
1720     fRightInset =
1721         pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
1722     fBottomInset =
1723         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
1724   }
1725   FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;
1726   for (CXFA_ContentLayoutItem* pChildItem =
1727            (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild;
1728        pChildItem;
1729        pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
1730     pChildItem->m_sPos.y += fHeight;
1731   }
1732   pLeaderLayoutItem->m_sPos.y = 0;
1733   switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
1734     case XFA_ATTRIBUTEENUM_Left:
1735     default:
1736       pLeaderLayoutItem->m_sPos.x = fLeftInset;
1737       break;
1738     case XFA_ATTRIBUTEENUM_Right:
1739       pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
1740                                     fRightInset - pLeaderLayoutItem->m_sSize.x;
1741       break;
1742     case XFA_ATTRIBUTEENUM_Center:
1743       pLeaderLayoutItem->m_sPos.x =
1744           (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
1745            pLeaderLayoutItem->m_sSize.x) /
1746           2;
1747       break;
1748   }
1749   pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
1750   pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);
1751 };
XFA_ItemLayoutProcessor_AddPendingNode(CXFA_ItemLayoutProcessor * pProcessor,CXFA_Node * pPendingNode,FX_BOOL bBreakPending)1752 static void XFA_ItemLayoutProcessor_AddPendingNode(
1753     CXFA_ItemLayoutProcessor* pProcessor,
1754     CXFA_Node* pPendingNode,
1755     FX_BOOL bBreakPending) {
1756   pProcessor->m_rgPendingNodes.AddTail(pPendingNode);
1757   pProcessor->m_bBreakPending = bBreakPending;
1758 }
XFA_ItemLayoutProcessor_InsertPendingItems(CXFA_ItemLayoutProcessor * pProcessor,CXFA_Node * pCurChildNode)1759 static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(
1760     CXFA_ItemLayoutProcessor* pProcessor,
1761     CXFA_Node* pCurChildNode) {
1762   FX_FLOAT fTotalHeight = 0;
1763   if (pProcessor->m_rgPendingNodes.GetCount() < 1) {
1764     return fTotalHeight;
1765   }
1766   if (pProcessor->m_pLayoutItem == NULL) {
1767     pProcessor->m_pLayoutItem =
1768         pProcessor->CreateContentLayoutItem(pCurChildNode);
1769     pProcessor->m_pLayoutItem->m_sSize.Set(0, 0);
1770   }
1771   while (pProcessor->m_rgPendingNodes.GetCount() > 0) {
1772     FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition();
1773     CXFA_Node* pPendingNode =
1774         (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos);
1775     pProcessor->m_rgPendingNodes.RemoveAt(pos);
1776     CXFA_ContentLayoutItem* pPendingLayoutItem = NULL;
1777     CXFA_ItemLayoutProcessor* pPendingProcessor =
1778         new CXFA_ItemLayoutProcessor(pPendingNode, NULL);
1779 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
1780     pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;
1781 #endif
1782     pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
1783     pPendingLayoutItem = pPendingProcessor->HasLayoutItem()
1784                              ? pPendingProcessor->ExtractLayoutItem()
1785                              : NULL;
1786     delete pPendingProcessor;
1787     if (pPendingLayoutItem) {
1788       XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor,
1789                                                   pPendingLayoutItem);
1790       if (pProcessor->m_bBreakPending) {
1791         fTotalHeight += pPendingLayoutItem->m_sSize.y;
1792       }
1793     }
1794   }
1795   return fTotalHeight;
1796 }
InsertKeepLayoutItems()1797 FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() {
1798   FX_FLOAT fTotalHeight = 0;
1799   if (m_arrayKeepItems.GetSize()) {
1800     if (m_pLayoutItem == NULL) {
1801       m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
1802       m_pLayoutItem->m_sSize.Set(0, 0);
1803     }
1804     for (int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0;
1805          iIndex--) {
1806       XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this,
1807                                                   m_arrayKeepItems[iIndex]);
1808       fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;
1809     }
1810     m_arrayKeepItems.RemoveAll();
1811   }
1812   return fTotalHeight;
1813 }
ProcessKeepForSplite(CXFA_ItemLayoutProcessor * pParentProcessor,CXFA_ItemLayoutProcessor * pChildProcessor,XFA_ItemLayoutProcessorResult eRetValue,CFX_ArrayTemplate<CXFA_ContentLayoutItem * > & rgCurLineLayoutItem,FX_FLOAT & fContentCurRowAvailWidth,FX_FLOAT & fContentCurRowHeight,FX_FLOAT & fContentCurRowY,FX_BOOL & bAddedItemInRow,FX_BOOL & bForceEndPage,XFA_ItemLayoutProcessorResult & result)1814 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(
1815     CXFA_ItemLayoutProcessor* pParentProcessor,
1816     CXFA_ItemLayoutProcessor* pChildProcessor,
1817     XFA_ItemLayoutProcessorResult eRetValue,
1818     CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem,
1819     FX_FLOAT& fContentCurRowAvailWidth,
1820     FX_FLOAT& fContentCurRowHeight,
1821     FX_FLOAT& fContentCurRowY,
1822     FX_BOOL& bAddedItemInRow,
1823     FX_BOOL& bForceEndPage,
1824     XFA_ItemLayoutProcessorResult& result) {
1825   if (pParentProcessor == NULL || pChildProcessor == NULL) {
1826     return FALSE;
1827   }
1828   if (pParentProcessor->m_pCurChildNode->GetIntact() !=
1829           XFA_ATTRIBUTEENUM_None ||
1830       !pChildProcessor->m_bHasAvailHeight) {
1831     if (XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {
1832       FX_FLOAT fChildWidth, fChildHeight;
1833       pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
1834       CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
1835       if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem,
1836                                              fChildHeight, keepLayoutItems)) {
1837         m_arrayKeepItems.RemoveAll();
1838         for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {
1839           CXFA_ContentLayoutItem* pItem = keepLayoutItems.GetAt(iIndex);
1840           pParentProcessor->m_pLayoutItem->RemoveChild(pItem);
1841           fContentCurRowY -= pItem->m_sSize.y;
1842           m_arrayKeepItems.Add(pItem);
1843         }
1844         bAddedItemInRow = TRUE;
1845         bForceEndPage = TRUE;
1846         result = XFA_ItemLayoutProcessorResult_PageFullBreak;
1847         return TRUE;
1848       }
1849       rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());
1850       bAddedItemInRow = TRUE;
1851       fContentCurRowAvailWidth -= fChildWidth;
1852       if (fContentCurRowHeight < fChildHeight) {
1853         fContentCurRowHeight = fChildHeight;
1854       }
1855       result = eRetValue;
1856       return TRUE;
1857     }
1858   }
1859   return FALSE;
1860 }
JudgePutNextPage(CXFA_ContentLayoutItem * pParentLayoutItem,FX_FLOAT fChildHeight,CFX_ArrayTemplate<CXFA_ContentLayoutItem * > & pKeepItems)1861 FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(
1862     CXFA_ContentLayoutItem* pParentLayoutItem,
1863     FX_FLOAT fChildHeight,
1864     CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems) {
1865   if (pParentLayoutItem == NULL) {
1866     return FALSE;
1867   }
1868   FX_FLOAT fItemsHeight = 0;
1869   for (CXFA_ContentLayoutItem* pChildLayoutItem =
1870            (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild;
1871        pChildLayoutItem;
1872        pChildLayoutItem =
1873            (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) {
1874     if (XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {
1875       pKeepItems.Add(pChildLayoutItem);
1876       fItemsHeight += pChildLayoutItem->m_sSize.y;
1877     } else {
1878       pKeepItems.RemoveAll();
1879       fItemsHeight = 0;
1880     }
1881   }
1882   fItemsHeight += fChildHeight;
1883   if (m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {
1884     return TRUE;
1885   }
1886   return FALSE;
1887 }
ProcessUnUseBinds(CXFA_Node * pFormNode)1888 void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
1889   if (!pFormNode) {
1890     return;
1891   }
1892   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
1893       pFormNode);
1894   for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
1895        pNode = sIterator.MoveToNext()) {
1896     if (pNode->IsContainerNode()) {
1897       CXFA_Node* pBindNode = pNode->GetBindData();
1898       if (pBindNode) {
1899         pBindNode->RemoveBindItem(pNode);
1900         pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
1901       }
1902     }
1903     pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
1904   }
1905 }
ProcessUnUseOverFlow(CXFA_Node * pLeaderNode,CXFA_Node * pTrailerNode,CXFA_ContentLayoutItem * pTrailerItem,CXFA_Node * pFormNode)1906 void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(
1907     CXFA_Node* pLeaderNode,
1908     CXFA_Node* pTrailerNode,
1909     CXFA_ContentLayoutItem* pTrailerItem,
1910     CXFA_Node* pFormNode) {
1911   ProcessUnUseBinds(pLeaderNode);
1912   ProcessUnUseBinds(pTrailerNode);
1913   if (pFormNode == NULL) {
1914     return;
1915   }
1916   if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow ||
1917       pFormNode->GetClassID() == XFA_ELEMENT_Break) {
1918     pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
1919   }
1920   if (pLeaderNode && pFormNode) {
1921     pFormNode->RemoveChild(pLeaderNode);
1922   }
1923   if (pTrailerNode && pFormNode) {
1924     pFormNode->RemoveChild(pTrailerNode);
1925   }
1926   if (pTrailerItem) {
1927     XFA_ReleaseLayoutItem(pTrailerItem);
1928   }
1929 }
XFA_ItemLayoutProcessor_InsertFlowedItem(CXFA_ItemLayoutProcessor * pThis,CXFA_ItemLayoutProcessor * & pProcessor,FX_BOOL bContainerWidthAutoSize,FX_BOOL bContainerHeightAutoSize,FX_FLOAT fContainerHeight,XFA_ATTRIBUTEENUM eFlowStrategy,uint8_t & uCurHAlignState,CFX_ArrayTemplate<CXFA_ContentLayoutItem * > (& rgCurLineLayoutItems)[3],FX_BOOL bUseBreakControl,FX_FLOAT fAvailHeight,FX_FLOAT fRealHeight,FX_FLOAT & fContentCurRowY,FX_FLOAT & fContentWidthLimit,FX_FLOAT & fContentCurRowAvailWidth,FX_FLOAT & fContentCurRowHeight,FX_BOOL & bAddedItemInRow,FX_BOOL & bForceEndPage,CXFA_LayoutContext * pLayoutContext=NULL,FX_BOOL bNewRow=FALSE)1930 static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(
1931     CXFA_ItemLayoutProcessor* pThis,
1932     CXFA_ItemLayoutProcessor*& pProcessor,
1933     FX_BOOL bContainerWidthAutoSize,
1934     FX_BOOL bContainerHeightAutoSize,
1935     FX_FLOAT fContainerHeight,
1936     XFA_ATTRIBUTEENUM eFlowStrategy,
1937     uint8_t& uCurHAlignState,
1938     CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
1939     FX_BOOL bUseBreakControl,
1940     FX_FLOAT fAvailHeight,
1941     FX_FLOAT fRealHeight,
1942     FX_FLOAT& fContentCurRowY,
1943     FX_FLOAT& fContentWidthLimit,
1944     FX_FLOAT& fContentCurRowAvailWidth,
1945     FX_FLOAT& fContentCurRowHeight,
1946     FX_BOOL& bAddedItemInRow,
1947     FX_BOOL& bForceEndPage,
1948     CXFA_LayoutContext* pLayoutContext = NULL,
1949     FX_BOOL bNewRow = FALSE) {
1950   FX_BOOL bTakeSpace =
1951       XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);
1952   uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
1953       pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));
1954   if (bContainerWidthAutoSize) {
1955     uHAlign = 0;
1956   }
1957   if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) ||
1958       (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {
1959     return XFA_ItemLayoutProcessorResult_RowFullBreak;
1960   }
1961   uCurHAlignState = uHAlign;
1962   FX_BOOL bIsOwnSplite =
1963       pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;
1964   FX_BOOL bUseRealHeight =
1965       bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite &&
1966       pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() ==
1967           XFA_ATTRIBUTEENUM_None;
1968   FX_BOOL bIsTransHeight = bTakeSpace;
1969   if (bIsTransHeight && !bIsOwnSplite) {
1970     FX_BOOL bRootForceTb = FALSE;
1971     XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(
1972         pProcessor->m_pFormNode, bRootForceTb);
1973     if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb ||
1974         eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {
1975       bIsTransHeight = FALSE;
1976     }
1977   }
1978   FX_BOOL bUseInherited = FALSE;
1979   CXFA_LayoutContext layoutContext;
1980   if (pThis->m_pPageMgr) {
1981     CXFA_Node* pOverflowNode =
1982         pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);
1983     if (pOverflowNode) {
1984       layoutContext.m_pOverflowNode = pOverflowNode;
1985       layoutContext.m_pOverflowProcessor = pThis;
1986       pLayoutContext = &layoutContext;
1987     }
1988   }
1989   XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;
1990   if (!bNewRow ||
1991       pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {
1992     eRetValue = pProcessor->DoLayout(
1993         bTakeSpace ? bUseBreakControl : FALSE,
1994         bUseRealHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
1995         bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
1996         pLayoutContext);
1997     pProcessor->m_ePreProcessRs = eRetValue;
1998   } else {
1999     eRetValue = pProcessor->m_ePreProcessRs;
2000     pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;
2001   }
2002   if (pProcessor->HasLayoutItem() == FALSE) {
2003     return eRetValue;
2004   }
2005   FX_FLOAT fChildWidth, fChildHeight;
2006   pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
2007   if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {
2008     fRealHeight = XFA_LAYOUT_FLOAT_MAX;
2009     fAvailHeight = XFA_LAYOUT_FLOAT_MAX;
2010   }
2011   if (!bTakeSpace ||
2012       (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) ||
2013       (fContentWidthLimit - fContentCurRowAvailWidth <=
2014        XFA_LAYOUT_FLOAT_PERCISION)) {
2015     CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL,
2016               *pFormNode = NULL;
2017     CXFA_ContentLayoutItem* pTrailerLayoutItem = NULL;
2018     FX_BOOL bIsAddTrailerHeight = FALSE;
2019     if (pThis->m_pPageMgr &&
2020         pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
2021       pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);
2022       if (pFormNode == NULL && pLayoutContext &&
2023           pLayoutContext->m_pOverflowProcessor) {
2024         pFormNode = pLayoutContext->m_pOverflowNode;
2025         bUseInherited = TRUE;
2026       }
2027       if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
2028                                              pOverflowTrailerNode, FALSE,
2029                                              FALSE)) {
2030         if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
2031           if (pOverflowTrailerNode) {
2032             CXFA_ItemLayoutProcessor* pOverflowLeaderProcessor =
2033                 new CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);
2034 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2035             pOverflowLeaderProcessor->m_pPageMgrCreateItem =
2036                 pProcessor->m_pPageMgrCreateItem;
2037 #endif
2038             pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
2039             pTrailerLayoutItem =
2040                 pOverflowLeaderProcessor->HasLayoutItem()
2041                     ? pOverflowLeaderProcessor->ExtractLayoutItem()
2042                     : NULL;
2043             delete pOverflowLeaderProcessor;
2044           }
2045           if (bUseInherited) {
2046             bIsAddTrailerHeight =
2047                 pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);
2048           } else {
2049             bIsAddTrailerHeight =
2050                 pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
2051           }
2052           if (bIsAddTrailerHeight) {
2053             FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;
2054             fChildHeight += fTrailerHeight;
2055             bIsAddTrailerHeight = TRUE;
2056           }
2057         }
2058       }
2059     }
2060     if (!bTakeSpace ||
2061         fContentCurRowY + fChildHeight <=
2062             fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||
2063         (!bContainerHeightAutoSize &&
2064          pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >=
2065              fContainerHeight)) {
2066       if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {
2067         if (pProcessor->m_bUseInheriated) {
2068           if (pTrailerLayoutItem) {
2069             XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
2070                 pProcessor, fChildHeight, pTrailerLayoutItem);
2071           }
2072           if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
2073             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
2074                                                    pOverflowLeaderNode, FALSE);
2075           }
2076           pProcessor->m_bUseInheriated = FALSE;
2077         } else {
2078           if (bIsAddTrailerHeight) {
2079             fChildHeight -= pTrailerLayoutItem->m_sSize.y;
2080           }
2081           pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2082                                            pOverflowTrailerNode,
2083                                            pTrailerLayoutItem, pFormNode);
2084         }
2085         CXFA_ContentLayoutItem* pChildLayoutItem =
2086             pProcessor->ExtractLayoutItem();
2087         if (XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) &&
2088             pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
2089           pThis->m_arrayKeepItems.Add(pChildLayoutItem);
2090         } else {
2091           pThis->m_arrayKeepItems.RemoveAll();
2092         }
2093         rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);
2094         bAddedItemInRow = TRUE;
2095         if (bTakeSpace) {
2096           fContentCurRowAvailWidth -= fChildWidth;
2097           if (fContentCurRowHeight < fChildHeight) {
2098             fContentCurRowHeight = fChildHeight;
2099           }
2100         }
2101         return XFA_ItemLayoutProcessorResult_Done;
2102       } else {
2103         if (eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {
2104           if (pProcessor->m_bUseInheriated) {
2105             if (pTrailerLayoutItem) {
2106               XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
2107                   pProcessor, fChildHeight, pTrailerLayoutItem);
2108             }
2109             if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
2110               XFA_ItemLayoutProcessor_AddPendingNode(
2111                   pProcessor, pOverflowLeaderNode, FALSE);
2112             }
2113             pProcessor->m_bUseInheriated = FALSE;
2114           } else {
2115             if (bIsAddTrailerHeight) {
2116               fChildHeight -= pTrailerLayoutItem->m_sSize.y;
2117             }
2118             pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2119                                              pOverflowTrailerNode,
2120                                              pTrailerLayoutItem, pFormNode);
2121           }
2122         }
2123         rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
2124         bAddedItemInRow = TRUE;
2125         fContentCurRowAvailWidth -= fChildWidth;
2126         if (fContentCurRowHeight < fChildHeight) {
2127           fContentCurRowHeight = fChildHeight;
2128         }
2129         return eRetValue;
2130       }
2131     } else {
2132       XFA_ItemLayoutProcessorResult eResult;
2133       if (pThis->ProcessKeepForSplite(
2134               pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],
2135               fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY,
2136               bAddedItemInRow, bForceEndPage, eResult)) {
2137         return eResult;
2138       }
2139       bForceEndPage = TRUE;
2140       FX_FLOAT fSplitPos =
2141           pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);
2142       if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
2143         XFA_ATTRIBUTEENUM eLayout =
2144             pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
2145         if (eLayout == XFA_ATTRIBUTEENUM_Tb &&
2146             eRetValue == XFA_ItemLayoutProcessorResult_Done) {
2147           pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2148                                            pOverflowTrailerNode,
2149                                            pTrailerLayoutItem, pFormNode);
2150           rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
2151           bAddedItemInRow = TRUE;
2152           if (bTakeSpace) {
2153             fContentCurRowAvailWidth -= fChildWidth;
2154             if (fContentCurRowHeight < fChildHeight) {
2155               fContentCurRowHeight = fChildHeight;
2156             }
2157           }
2158           return XFA_ItemLayoutProcessorResult_PageFullBreak;
2159         }
2160         CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
2161         if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated &&
2162             eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {
2163           pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
2164                                              pTempTrailerNode, FALSE, TRUE);
2165         }
2166         if (pTrailerLayoutItem && bIsAddTrailerHeight) {
2167           XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
2168               pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);
2169         } else {
2170           pProcessor->SplitLayoutItem(fSplitPos);
2171         }
2172         if (bUseInherited) {
2173           pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2174                                            pOverflowTrailerNode,
2175                                            pTrailerLayoutItem, pFormNode);
2176           pThis->m_bUseInheriated = TRUE;
2177         } else {
2178           if (pProcessor->m_pLayoutItem->m_pFirstChild &&
2179               pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling ==
2180                   NULL &&
2181               pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(
2182                   XFA_NODEFLAG_LayoutGeneratedNode)) {
2183             pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2184                                              pOverflowTrailerNode,
2185                                              pTrailerLayoutItem, pFormNode);
2186           } else {
2187             if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
2188               XFA_ItemLayoutProcessor_AddPendingNode(
2189                   pProcessor, pOverflowLeaderNode, FALSE);
2190             }
2191           }
2192         }
2193         if (pProcessor->m_pLayoutItem->m_pNextSibling) {
2194           pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
2195           rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
2196           bAddedItemInRow = TRUE;
2197           if (bTakeSpace) {
2198             fContentCurRowAvailWidth -= fChildWidth;
2199             if (fContentCurRowHeight < fChildHeight) {
2200               fContentCurRowHeight = fChildHeight;
2201             }
2202           }
2203         }
2204         return XFA_ItemLayoutProcessorResult_PageFullBreak;
2205       } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {
2206         pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
2207         if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {
2208           CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
2209           if (pThis->m_pPageMgr) {
2210             if (pFormNode == NULL && pLayoutContext != NULL) {
2211               pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
2212             }
2213             pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
2214                                                pTempTrailerNode, FALSE, TRUE);
2215           }
2216           if (bUseInherited) {
2217             pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2218                                              pOverflowTrailerNode,
2219                                              pTrailerLayoutItem, pFormNode);
2220             pThis->m_bUseInheriated = TRUE;
2221           }
2222           return XFA_ItemLayoutProcessorResult_PageFullBreak;
2223         }
2224         rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
2225         bAddedItemInRow = TRUE;
2226         if (bTakeSpace) {
2227           fContentCurRowAvailWidth -= fChildWidth;
2228           if (fContentCurRowHeight < fChildHeight) {
2229             fContentCurRowHeight = fChildHeight;
2230           }
2231         }
2232         if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
2233           bForceEndPage = FALSE;
2234         }
2235         return eRetValue;
2236       } else {
2237         XFA_ATTRIBUTEENUM eLayout =
2238             pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
2239         if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None &&
2240             eLayout == XFA_ATTRIBUTEENUM_Tb) {
2241           if (pThis->m_pPageMgr) {
2242             pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
2243                                                pOverflowTrailerNode, FALSE,
2244                                                TRUE);
2245           }
2246           if (pTrailerLayoutItem) {
2247             XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos,
2248                                                           pTrailerLayoutItem);
2249           }
2250           if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
2251             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
2252                                                    pOverflowLeaderNode, FALSE);
2253           }
2254         } else {
2255           if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
2256             if (pFormNode == NULL && pLayoutContext != NULL) {
2257               pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
2258             }
2259             if (pThis->m_pPageMgr) {
2260               pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
2261                                                  pOverflowTrailerNode, FALSE,
2262                                                  TRUE);
2263             }
2264             if (bUseInherited) {
2265               pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
2266                                                pOverflowTrailerNode,
2267                                                pTrailerLayoutItem, pFormNode);
2268               pThis->m_bUseInheriated = TRUE;
2269             }
2270           }
2271         }
2272         return XFA_ItemLayoutProcessorResult_PageFullBreak;
2273       }
2274     }
2275   } else {
2276     return XFA_ItemLayoutProcessorResult_RowFullBreak;
2277   }
2278   return XFA_ItemLayoutProcessorResult_Done;
2279 }
DoLayoutFlowedContainer(FX_BOOL bUseBreakControl,XFA_ATTRIBUTEENUM eFlowStrategy,FX_FLOAT fHeightLimit,FX_FLOAT fRealHeight,CXFA_LayoutContext * pContext,FX_BOOL bRootForceTb)2280 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(
2281     FX_BOOL bUseBreakControl,
2282     XFA_ATTRIBUTEENUM eFlowStrategy,
2283     FX_FLOAT fHeightLimit,
2284     FX_FLOAT fRealHeight,
2285     CXFA_LayoutContext* pContext,
2286     FX_BOOL bRootForceTb) {
2287   m_bHasAvailHeight = TRUE;
2288   FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
2289   FX_BOOL bBreakDone = FALSE;
2290   FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
2291   FX_BOOL bForceEndPage = FALSE;
2292   FX_BOOL bIsManualBreak = FALSE;
2293   if (m_pCurChildPreprocessor) {
2294     m_pCurChildPreprocessor->m_ePreProcessRs =
2295         XFA_ItemLayoutProcessorResult_Done;
2296   }
2297   XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
2298       m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
2299       bContainerHeightAutoSize);
2300   if (pContext && pContext->m_bCurColumnWidthAvaiable) {
2301     bContainerWidthAutoSize = FALSE;
2302     fContainerWidth = pContext->m_fCurColumnWidth;
2303   }
2304   if (!bContainerHeightAutoSize) {
2305     fContainerHeight -= m_fUsedSize;
2306   }
2307   if (!bContainerHeightAutoSize) {
2308     CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
2309     FX_BOOL bFocrTb = FALSE;
2310     if (pParentNode &&
2311         XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) ==
2312             XFA_ATTRIBUTEENUM_Row) {
2313       CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(
2314           XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
2315       if (pChildContainer &&
2316           pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
2317                                        XFA_OBJECTTYPE_ContainerNode)) {
2318         fContainerHeight = 0;
2319         bContainerHeightAutoSize = TRUE;
2320       }
2321     }
2322   }
2323   CXFA_Node* pMarginNode =
2324       m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
2325   FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
2326   if (pMarginNode) {
2327     fLeftInset =
2328         pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
2329     fTopInset =
2330         pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
2331     fRightInset =
2332         pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
2333     fBottomInset =
2334         pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
2335   }
2336   FX_FLOAT fContentWidthLimit =
2337       bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
2338                               : fContainerWidth - fLeftInset - fRightInset;
2339   FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
2340   FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;
2341   if (fAvailHeight < 0) {
2342     m_bHasAvailHeight = FALSE;
2343   }
2344   fRealHeight = fRealHeight - fTopInset - fBottomInset;
2345   FX_FLOAT fContentCurRowY = 0;
2346   CXFA_ContentLayoutItem* pLayoutChild = NULL;
2347   if (m_pLayoutItem != NULL) {
2348     if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done &&
2349         eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {
2350       pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
2351       for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
2352            pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
2353         if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {
2354           pLayoutChild = pLayoutNext;
2355         }
2356       }
2357     }
2358     for (CXFA_ContentLayoutItem* pLayoutTempChild =
2359              (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
2360          pLayoutTempChild != pLayoutChild;
2361          pLayoutTempChild =
2362              (CXFA_ContentLayoutItem*)pLayoutTempChild->m_pNextSibling) {
2363       if (XFA_ItemLayoutProcessor_IsTakingSpace(
2364               pLayoutTempChild->m_pFormNode)) {
2365         FX_FLOAT fChildContentWidth =
2366             pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;
2367         FX_FLOAT fChildContentHeight =
2368             pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;
2369         if (fContentCalculatedWidth < fChildContentWidth) {
2370           fContentCalculatedWidth = fChildContentWidth;
2371         }
2372         if (fContentCalculatedHeight < fChildContentHeight) {
2373           fContentCalculatedHeight = fChildContentHeight;
2374         }
2375       }
2376     }
2377     if (pLayoutChild) {
2378       fContentCurRowY = pLayoutChild->m_sPos.y;
2379     } else {
2380       fContentCurRowY = fContentCalculatedHeight;
2381     }
2382   }
2383   fContentCurRowY += InsertKeepLayoutItems();
2384   if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {
2385     XFA_ItemLayoutProcessor_GotoNextContainerNode(
2386         m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
2387   }
2388   fContentCurRowY +=
2389       XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
2390   if (m_pCurChildPreprocessor &&
2391       m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {
2392     if (XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {
2393       m_pKeepHeadNode = m_pCurChildNode;
2394       m_bIsProcessKeep = TRUE;
2395       m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;
2396     }
2397   }
2398   while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {
2399     FX_FLOAT fContentCurRowHeight = 0;
2400     FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;
2401     m_fWidthLimite = fContentCurRowAvailWidth;
2402     CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3];
2403     uint8_t uCurHAlignState =
2404         (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);
2405     if (pLayoutChild) {
2406       for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
2407            pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
2408         if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor &&
2409             m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {
2410           pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;
2411           m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
2412           break;
2413         }
2414         uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
2415             pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));
2416         rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);
2417         if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {
2418           if (uHAlign > uCurHAlignState) {
2419             uCurHAlignState = uHAlign;
2420           }
2421         } else if (uHAlign < uCurHAlignState) {
2422           uCurHAlignState = uHAlign;
2423         }
2424         if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {
2425           if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {
2426             fContentCurRowHeight = pLayoutNext->m_sSize.y;
2427           }
2428           fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;
2429         }
2430       }
2431       if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild ==
2432           pLayoutChild) {
2433         m_pLayoutItem->m_pFirstChild = NULL;
2434       } else {
2435         CXFA_ContentLayoutItem* pLayoutNext =
2436             (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
2437         for (; pLayoutNext;
2438              pLayoutNext =
2439                  (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
2440           if ((CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling ==
2441               pLayoutChild) {
2442             pLayoutNext->m_pNextSibling = NULL;
2443             break;
2444           }
2445         }
2446       }
2447       CXFA_ContentLayoutItem* pLayoutNextTemp =
2448           (CXFA_ContentLayoutItem*)pLayoutChild;
2449       while (pLayoutNextTemp) {
2450         pLayoutNextTemp->m_pParent = NULL;
2451         CXFA_ContentLayoutItem* pSaveLayoutNext =
2452             (CXFA_ContentLayoutItem*)pLayoutNextTemp->m_pNextSibling;
2453         pLayoutNextTemp->m_pNextSibling = NULL;
2454         pLayoutNextTemp = pSaveLayoutNext;
2455       }
2456       pLayoutChild = NULL;
2457     }
2458     while (m_pCurChildNode) {
2459       CXFA_ItemLayoutProcessor* pProcessor = NULL;
2460       FX_BOOL bAddedItemInRow = FALSE;
2461       fContentCurRowY +=
2462           XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
2463       switch (m_nCurChildNodeStage) {
2464         case XFA_ItemLayoutProcessorStages_Keep:
2465         case XFA_ItemLayoutProcessorStages_None:
2466           break;
2467         case XFA_ItemLayoutProcessorStages_BreakBefore: {
2468           for (int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize();
2469                iIndex++) {
2470             CXFA_ContentLayoutItem* pItem = m_arrayKeepItems.GetAt(iIndex);
2471             m_pLayoutItem->RemoveChild(pItem);
2472             fContentCalculatedHeight -= pItem->m_sSize.y;
2473           }
2474           CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
2475           FX_BOOL bCreatePage = FALSE;
2476           if (bUseBreakControl && m_pPageMgr &&
2477               m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE,
2478                                                     pLeaderNode, pTrailerNode,
2479                                                     bCreatePage) &&
2480               m_pFormNode->GetClassID() != XFA_ELEMENT_Form && bCreatePage) {
2481             if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
2482               XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
2483             }
2484             if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
2485               if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() ==
2486                       XFA_ELEMENT_Form &&
2487                   m_pLayoutItem == NULL) {
2488                 XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode,
2489                                                        TRUE);
2490               } else {
2491                 CXFA_ItemLayoutProcessor* pProcessor =
2492                     new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
2493 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2494                 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2495 #endif
2496                 XFA_ItemLayoutProcessor_InsertFlowedItem(
2497                     this, pProcessor, bContainerWidthAutoSize,
2498                     bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2499                     uCurHAlignState, rgCurLineLayoutItems, FALSE,
2500                     XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
2501                     fContentWidthLimit, fContentCurRowAvailWidth,
2502                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2503                     pContext);
2504                 delete pProcessor;
2505                 pProcessor = NULL;
2506               }
2507             }
2508             XFA_ItemLayoutProcessor_GotoNextContainerNode(
2509                 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
2510             bForceEndPage = TRUE;
2511             bIsManualBreak = TRUE;
2512             goto SuspendAndCreateNewRow;
2513           }
2514         } break;
2515         case XFA_ItemLayoutProcessorStages_BreakAfter: {
2516           XFA_ItemLayoutProcessorResult eResult;
2517           CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
2518           FX_BOOL bCreatePage = FALSE;
2519           if (bUseBreakControl && m_pPageMgr &&
2520               m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE,
2521                                                     pLeaderNode, pTrailerNode,
2522                                                     bCreatePage) &&
2523               m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {
2524             if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
2525               CXFA_ItemLayoutProcessor* pProcessor =
2526                   new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
2527 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2528               pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2529 #endif
2530               eResult = XFA_ItemLayoutProcessor_InsertFlowedItem(
2531                   this, pProcessor, bContainerWidthAutoSize,
2532                   bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2533                   uCurHAlignState, rgCurLineLayoutItems, FALSE,
2534                   XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
2535                   fContentWidthLimit, fContentCurRowAvailWidth,
2536                   fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2537                   pContext);
2538               delete pProcessor;
2539               pProcessor = NULL;
2540             }
2541             if (!bCreatePage) {
2542               if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
2543                 CalculateRowChildPosition(
2544                     rgCurLineLayoutItems, eFlowStrategy,
2545                     bContainerHeightAutoSize, bContainerWidthAutoSize,
2546                     fContentCalculatedWidth, fContentCalculatedHeight,
2547                     fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);
2548                 rgCurLineLayoutItems->RemoveAll();
2549                 CXFA_ItemLayoutProcessor* pProcessor =
2550                     new CXFA_ItemLayoutProcessor(pLeaderNode, NULL);
2551 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2552                 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2553 #endif
2554                 XFA_ItemLayoutProcessor_InsertFlowedItem(
2555                     this, pProcessor, bContainerWidthAutoSize,
2556                     bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2557                     uCurHAlignState, rgCurLineLayoutItems, FALSE,
2558                     XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
2559                     fContentWidthLimit, fContentCurRowAvailWidth,
2560                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2561                     pContext);
2562                 delete pProcessor;
2563                 pProcessor = NULL;
2564               }
2565             } else {
2566               if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
2567                 XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
2568               }
2569             }
2570             XFA_ItemLayoutProcessor_GotoNextContainerNode(
2571                 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
2572             if (bCreatePage) {
2573               bForceEndPage = TRUE;
2574               bIsManualBreak = TRUE;
2575               if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {
2576                 bBreakDone = TRUE;
2577               }
2578             }
2579             goto SuspendAndCreateNewRow;
2580           }
2581         } break;
2582         case XFA_ItemLayoutProcessorStages_BookendLeader: {
2583           CXFA_Node* pLeaderNode = NULL;
2584           if (m_pCurChildPreprocessor) {
2585             pProcessor = m_pCurChildPreprocessor;
2586             m_pCurChildPreprocessor = NULL;
2587           } else if (m_pPageMgr &&
2588                      m_pPageMgr->ProcessBookendLeaderOrTrailer(
2589                          m_pCurChildNode, TRUE, pLeaderNode)) {
2590             pProcessor = new CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);
2591 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2592             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2593 #endif
2594           }
2595           if (pProcessor) {
2596             if (XFA_ItemLayoutProcessor_InsertFlowedItem(
2597                     this, pProcessor, bContainerWidthAutoSize,
2598                     bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2599                     uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
2600                     fAvailHeight, fRealHeight, fContentCurRowY,
2601                     fContentWidthLimit, fContentCurRowAvailWidth,
2602                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2603                     pContext) != XFA_ItemLayoutProcessorResult_Done) {
2604               goto SuspendAndCreateNewRow;
2605             } else {
2606               delete pProcessor;
2607               pProcessor = NULL;
2608             }
2609           }
2610         } break;
2611         case XFA_ItemLayoutProcessorStages_BookendTrailer: {
2612           CXFA_Node* pTrailerNode = NULL;
2613           if (m_pCurChildPreprocessor) {
2614             pProcessor = m_pCurChildPreprocessor;
2615             m_pCurChildPreprocessor = NULL;
2616           } else if (m_pPageMgr &&
2617                      m_pPageMgr->ProcessBookendLeaderOrTrailer(
2618                          m_pCurChildNode, FALSE, pTrailerNode)) {
2619             pProcessor = new CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);
2620 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2621             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2622 #endif
2623           }
2624           if (pProcessor) {
2625             if (XFA_ItemLayoutProcessor_InsertFlowedItem(
2626                     this, pProcessor, bContainerWidthAutoSize,
2627                     bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2628                     uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
2629                     fAvailHeight, fRealHeight, fContentCurRowY,
2630                     fContentWidthLimit, fContentCurRowAvailWidth,
2631                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2632                     pContext) != XFA_ItemLayoutProcessorResult_Done) {
2633               goto SuspendAndCreateNewRow;
2634             } else {
2635               delete pProcessor;
2636               pProcessor = NULL;
2637             }
2638           }
2639         } break;
2640         case XFA_ItemLayoutProcessorStages_Container:
2641           ASSERT(m_pCurChildNode->IsContainerNode());
2642           if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
2643             break;
2644           }
2645           if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION &&
2646               XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
2647             bForceEndPage = TRUE;
2648             goto SuspendAndCreateNewRow;
2649           }
2650           if (m_pCurChildNode->IsContainerNode()) {
2651             FX_BOOL bNewRow = FALSE;
2652             if (m_pCurChildPreprocessor) {
2653               pProcessor = m_pCurChildPreprocessor;
2654               m_pCurChildPreprocessor = NULL;
2655               bNewRow = TRUE;
2656             } else {
2657               pProcessor =
2658                   new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
2659 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_
2660               pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
2661 #endif
2662             }
2663             XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor,
2664                                                        m_pCurChildNode);
2665             XFA_ItemLayoutProcessorResult rs =
2666                 XFA_ItemLayoutProcessor_InsertFlowedItem(
2667                     this, pProcessor, bContainerWidthAutoSize,
2668                     bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
2669                     uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
2670                     fAvailHeight, fRealHeight, fContentCurRowY,
2671                     fContentWidthLimit, fContentCurRowAvailWidth,
2672                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
2673                     pContext, bNewRow);
2674             switch (rs) {
2675               case XFA_ItemLayoutProcessorResult_ManualBreak:
2676                 bIsManualBreak = TRUE;
2677               case XFA_ItemLayoutProcessorResult_PageFullBreak:
2678                 bForceEndPage = TRUE;
2679               case XFA_ItemLayoutProcessorResult_RowFullBreak:
2680                 goto SuspendAndCreateNewRow;
2681               case XFA_ItemLayoutProcessorResult_Done:
2682               default:
2683                 fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(
2684                     pProcessor, m_pCurChildNode);
2685                 delete pProcessor;
2686                 pProcessor = NULL;
2687             }
2688           }
2689           break;
2690         case XFA_ItemLayoutProcessorStages_Done:
2691           break;
2692         default:
2693           break;
2694       }
2695       XFA_ItemLayoutProcessor_GotoNextContainerNode(
2696           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
2697       if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {
2698         break;
2699       } else {
2700         continue;
2701       }
2702     SuspendAndCreateNewRow:
2703       if (pProcessor) {
2704         m_pCurChildPreprocessor = pProcessor;
2705       }
2706       break;
2707     }
2708     CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy,
2709                               bContainerHeightAutoSize, bContainerWidthAutoSize,
2710                               fContentCalculatedWidth, fContentCalculatedHeight,
2711                               fContentCurRowY, fContentCurRowHeight,
2712                               fContentWidthLimit, bRootForceTb);
2713     m_fWidthLimite = fContentCurRowAvailWidth;
2714     if (bForceEndPage) {
2715       break;
2716     }
2717   }
2718   FX_BOOL bRetValue =
2719       (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
2720        m_rgPendingNodes.GetCount() == 0);
2721   if (bBreakDone) {
2722     bRetValue = FALSE;
2723   }
2724   XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
2725       m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
2726       fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
2727       fContainerHeight);
2728   if (fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem ||
2729       bRetValue) {
2730     if (m_pLayoutItem == NULL) {
2731       m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
2732     }
2733     if (fContainerHeight < 0) {
2734       fContainerHeight = 0;
2735     }
2736     SetCurrentComponentSize(fContainerWidth, fContainerHeight);
2737     if (bForceEndPage) {
2738       m_fUsedSize = 0;
2739     } else {
2740       m_fUsedSize += m_pLayoutItem->m_sSize.y;
2741     }
2742   }
2743   return bRetValue
2744              ? XFA_ItemLayoutProcessorResult_Done
2745              : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak
2746                                : XFA_ItemLayoutProcessorResult_PageFullBreak);
2747 }
CalculateRowChildPosition(CFX_ArrayTemplate<CXFA_ContentLayoutItem * > (& rgCurLineLayoutItems)[3],XFA_ATTRIBUTEENUM eFlowStrategy,FX_BOOL bContainerHeightAutoSize,FX_BOOL bContainerWidthAutoSize,FX_FLOAT & fContentCalculatedWidth,FX_FLOAT & fContentCalculatedHeight,FX_FLOAT & fContentCurRowY,FX_FLOAT fContentCurRowHeight,FX_FLOAT fContentWidthLimit,FX_BOOL bRootForceTb)2748 FX_BOOL CXFA_ItemLayoutProcessor::CalculateRowChildPosition(
2749     CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
2750     XFA_ATTRIBUTEENUM eFlowStrategy,
2751     FX_BOOL bContainerHeightAutoSize,
2752     FX_BOOL bContainerWidthAutoSize,
2753     FX_FLOAT& fContentCalculatedWidth,
2754     FX_FLOAT& fContentCalculatedHeight,
2755     FX_FLOAT& fContentCurRowY,
2756     FX_FLOAT fContentCurRowHeight,
2757     FX_FLOAT fContentWidthLimit,
2758     FX_BOOL bRootForceTb) {
2759   int32_t nGroupLengths[3] = {0, 0, 0};
2760   FX_FLOAT fGroupWidths[3] = {0, 0, 0};
2761   int32_t nTotalLength = 0;
2762   for (int32_t i = 0; i < 3; i++) {
2763     nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();
2764     for (int32_t c = nGroupLengths[i], j = 0; j < c; j++) {
2765       nTotalLength++;
2766       if (XFA_ItemLayoutProcessor_IsTakingSpace(
2767               rgCurLineLayoutItems[i][j]->m_pFormNode)) {
2768         fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;
2769       }
2770     }
2771   }
2772   if (!nTotalLength) {
2773     if (bContainerHeightAutoSize) {
2774       FX_FLOAT fNewHeight = fContentCurRowY;
2775       if (fContentCalculatedHeight > fNewHeight) {
2776         fContentCalculatedHeight = fNewHeight;
2777       }
2778     }
2779     return FALSE;
2780   }
2781   if (m_pLayoutItem == NULL) {
2782     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
2783   }
2784   if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {
2785     FX_FLOAT fCurPos;
2786     fCurPos = 0;
2787     for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
2788       if (bRootForceTb) {
2789         FX_FLOAT fAbsoluteX, fAbsoluteY;
2790         CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode,
2791                                         rgCurLineLayoutItems[0][j]->m_sSize.x,
2792                                         rgCurLineLayoutItems[0][j]->m_sSize.y,
2793                                         fAbsoluteX, fAbsoluteY);
2794         rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
2795       } else {
2796         rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2797         if (XFA_ItemLayoutProcessor_IsTakingSpace(
2798                 rgCurLineLayoutItems[0][j]->m_pFormNode)) {
2799           fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;
2800         }
2801       }
2802       m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
2803       m_fLastRowWidth = fCurPos;
2804     }
2805     fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] -
2806                fGroupWidths[2]) /
2807               2;
2808     for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
2809       if (bRootForceTb) {
2810         FX_FLOAT fAbsoluteX, fAbsoluteY;
2811         CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode,
2812                                         rgCurLineLayoutItems[1][j]->m_sSize.x,
2813                                         rgCurLineLayoutItems[1][j]->m_sSize.y,
2814                                         fAbsoluteX, fAbsoluteY);
2815         rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
2816       } else {
2817         rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2818         if (XFA_ItemLayoutProcessor_IsTakingSpace(
2819                 rgCurLineLayoutItems[1][j]->m_pFormNode)) {
2820           fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;
2821         }
2822       }
2823       m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
2824       m_fLastRowWidth = fCurPos;
2825     }
2826     fCurPos = fContentWidthLimit - fGroupWidths[2];
2827     for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
2828       if (bRootForceTb) {
2829         FX_FLOAT fAbsoluteX, fAbsoluteY;
2830         CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode,
2831                                         rgCurLineLayoutItems[2][j]->m_sSize.x,
2832                                         rgCurLineLayoutItems[2][j]->m_sSize.y,
2833                                         fAbsoluteX, fAbsoluteY);
2834         rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
2835       } else {
2836         rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2837         if (XFA_ItemLayoutProcessor_IsTakingSpace(
2838                 rgCurLineLayoutItems[2][j]->m_pFormNode)) {
2839           fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;
2840         }
2841       }
2842       m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
2843       m_fLastRowWidth = fCurPos;
2844     }
2845   } else {
2846     FX_FLOAT fCurPos;
2847     fCurPos = fGroupWidths[0];
2848     for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
2849       if (XFA_ItemLayoutProcessor_IsTakingSpace(
2850               rgCurLineLayoutItems[0][j]->m_pFormNode)) {
2851         fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;
2852       }
2853       rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2854       m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
2855       m_fLastRowWidth = fCurPos;
2856     }
2857     fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] -
2858                fGroupWidths[2]) /
2859               2;
2860     for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
2861       if (XFA_ItemLayoutProcessor_IsTakingSpace(
2862               rgCurLineLayoutItems[1][j]->m_pFormNode)) {
2863         fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;
2864       }
2865       rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2866       m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
2867       m_fLastRowWidth = fCurPos;
2868     }
2869     fCurPos = fContentWidthLimit;
2870     for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
2871       if (XFA_ItemLayoutProcessor_IsTakingSpace(
2872               rgCurLineLayoutItems[2][j]->m_pFormNode)) {
2873         fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;
2874       }
2875       rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
2876       m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
2877       m_fLastRowWidth = fCurPos;
2878     }
2879   }
2880   m_fLastRowY = fContentCurRowY;
2881   fContentCurRowY += fContentCurRowHeight;
2882   if (bContainerWidthAutoSize) {
2883     FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];
2884     if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
2885         fContentWidthLimit > fChildSuppliedWidth) {
2886       fChildSuppliedWidth = fContentWidthLimit;
2887     }
2888     if (fContentCalculatedWidth < fChildSuppliedWidth) {
2889       fContentCalculatedWidth = fChildSuppliedWidth;
2890     }
2891   }
2892   if (bContainerHeightAutoSize) {
2893     FX_FLOAT fChildSuppliedHeight = fContentCurRowY;
2894     if (fContentCalculatedHeight < fChildSuppliedHeight) {
2895       fContentCalculatedHeight = fChildSuppliedHeight;
2896     }
2897   }
2898   return TRUE;
2899 }
GetSubformSetParent(CXFA_Node * pSubformSet)2900 CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(
2901     CXFA_Node* pSubformSet) {
2902   if (pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {
2903     CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);
2904     while (pParent) {
2905       if (pParent->GetClassID() != XFA_ELEMENT_SubformSet) {
2906         return pParent;
2907       }
2908       pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
2909     }
2910   }
2911   return pSubformSet;
2912 }
DoLayoutField()2913 void CXFA_ItemLayoutProcessor::DoLayoutField() {
2914   if (m_pLayoutItem != NULL) {
2915     return;
2916   }
2917   ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
2918   m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
2919   if (!m_pLayoutItem) {
2920     return;
2921   }
2922   CXFA_Document* pDocument = m_pFormNode->GetDocument();
2923   IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
2924   FX_FLOAT fHeight = -1;
2925   FX_FLOAT fWidth = -1;
2926   pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);
2927   int32_t nRotate =
2928       FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
2929   nRotate = XFA_MapRotation(nRotate);
2930   if (nRotate == 90 || nRotate == 270) {
2931     FX_FLOAT fTmp = fWidth;
2932     fWidth = fHeight;
2933     fHeight = fTmp;
2934   }
2935   SetCurrentComponentSize(fWidth, fHeight);
2936 }
DoLayout(FX_BOOL bUseBreakControl,FX_FLOAT fHeightLimit,FX_FLOAT fRealHeight,CXFA_LayoutContext * pContext)2937 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(
2938     FX_BOOL bUseBreakControl,
2939     FX_FLOAT fHeightLimit,
2940     FX_FLOAT fRealHeight,
2941     CXFA_LayoutContext* pContext) {
2942   XFA_ELEMENT eClassID = m_pFormNode->GetClassID();
2943   switch (eClassID) {
2944     case XFA_ELEMENT_Subform:
2945     case XFA_ELEMENT_Area:
2946     case XFA_ELEMENT_ExclGroup:
2947     case XFA_ELEMENT_SubformSet: {
2948       FX_BOOL bRootForceTb = FALSE;
2949       CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);
2950       XFA_ATTRIBUTEENUM eLayoutStrategy =
2951           XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);
2952       switch (eLayoutStrategy) {
2953         case XFA_ATTRIBUTEENUM_Tb:
2954         case XFA_ATTRIBUTEENUM_Lr_tb:
2955         case XFA_ATTRIBUTEENUM_Rl_tb:
2956           return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy,
2957                                          fHeightLimit, fRealHeight, pContext,
2958                                          bRootForceTb);
2959         case XFA_ATTRIBUTEENUM_Position:
2960         case XFA_ATTRIBUTEENUM_Row:
2961         case XFA_ATTRIBUTEENUM_Rl_row:
2962         default:
2963           DoLayoutPositionedContainer(pContext);
2964           m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
2965           return XFA_ItemLayoutProcessorResult_Done;
2966         case XFA_ATTRIBUTEENUM_Table:
2967           DoLayoutTableContainer(pLayoutNode);
2968           m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
2969           return XFA_ItemLayoutProcessorResult_Done;
2970       }
2971     }
2972     case XFA_ELEMENT_Draw:
2973     case XFA_ELEMENT_Field:
2974       DoLayoutField();
2975       m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
2976       return XFA_ItemLayoutProcessorResult_Done;
2977     case XFA_ELEMENT_ContentArea:
2978       return XFA_ItemLayoutProcessorResult_Done;
2979     default:
2980       return XFA_ItemLayoutProcessorResult_Done;
2981   }
2982 }
GetCurrentComponentPos(FX_FLOAT & fAbsoluteX,FX_FLOAT & fAbsoluteY)2983 void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX,
2984                                                       FX_FLOAT& fAbsoluteY) {
2985   ASSERT(m_pLayoutItem);
2986   fAbsoluteX = m_pLayoutItem->m_sPos.x;
2987   fAbsoluteY = m_pLayoutItem->m_sPos.y;
2988 }
GetCurrentComponentSize(FX_FLOAT & fWidth,FX_FLOAT & fHeight)2989 void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth,
2990                                                        FX_FLOAT& fHeight) {
2991   ASSERT(m_pLayoutItem);
2992   fWidth = m_pLayoutItem->m_sSize.x;
2993   fHeight = m_pLayoutItem->m_sSize.y;
2994 }
SetCurrentComponentPos(FX_FLOAT fAbsoluteX,FX_FLOAT fAbsoluteY)2995 void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX,
2996                                                       FX_FLOAT fAbsoluteY) {
2997   ASSERT(m_pLayoutItem);
2998   m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY);
2999 }
SetCurrentComponentSize(FX_FLOAT fWidth,FX_FLOAT fHeight)3000 void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth,
3001                                                        FX_FLOAT fHeight) {
3002   ASSERT(m_pLayoutItem);
3003   m_pLayoutItem->m_sSize.Set(fWidth, fHeight);
3004 }
JudgeLeaderOrTrailerForOccur(CXFA_Node * pFormNode)3005 FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(
3006     CXFA_Node* pFormNode) {
3007   if (pFormNode == NULL) {
3008     return FALSE;
3009   }
3010   CXFA_Node* pTemplate = pFormNode->GetTemplateNode();
3011   if (!pTemplate) {
3012     pTemplate = pFormNode;
3013   }
3014   CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur);
3015   int32_t iMax = NodeOccur.GetMax();
3016   if (iMax > -1) {
3017     int32_t iCount =
3018         (int32_t)(uintptr_t)m_PendingNodesCount.GetValueAt(pTemplate);
3019     if (iCount >= iMax) {
3020       return FALSE;
3021     }
3022     iCount++;
3023     m_PendingNodesCount.SetAt(pTemplate, (void*)(uintptr_t)(iCount));
3024     return TRUE;
3025   }
3026   return TRUE;
3027 }
3028