Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fxfa / src / parser / xfa_layout_itemlayout.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_utils.h"\r
9 #include "../common/xfa_object.h"\r
10 #include "../common/xfa_document.h"\r
11 #include "../common/xfa_parser.h"\r
12 #include "../common/xfa_script.h"\r
13 #include "../common/xfa_docdata.h"\r
14 #include "../common/xfa_doclayout.h"\r
15 #include "../common/xfa_debug.h"\r
16 #include "../common/xfa_localemgr.h"\r
17 #include "../common/xfa_fm2jsapi.h"\r
18 #include "xfa_debug_parser.h"\r
19 #include "xfa_document_layout_imp.h"\r
20 #include "xfa_layout_itemlayout.h"\r
21 #include "xfa_layout_pagemgr_new.h"\r
22 #include "xfa_layout_appadapter.h"\r
23 CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node *pNode, CXFA_LayoutPageMgr* pPageMgr)\r
24     : m_pFormNode(pNode)\r
25     , m_pLayoutItem(NULL)\r
26     , m_pCurChildNode(XFA_LAYOUT_INVALIDNODE)\r
27     , m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None)\r
28     , m_pCurChildPreprocessor(NULL)\r
29     , m_fUsedSize(0)\r
30     , m_pPageMgr(pPageMgr)\r
31     , m_bHasAvailHeight(TRUE)\r
32 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
33     , m_pOldLayoutItem(NULL)\r
34 #else\r
35     , m_pPageMgrCreateItem(NULL)\r
36 #endif\r
37     , m_bKeepBreakFinish(FALSE)\r
38     , m_pKeepHeadNode(NULL)\r
39     , m_pKeepTailNode(NULL)\r
40     , m_bIsProcessKeep(FALSE)\r
41     , m_bBreakPending(TRUE)\r
42     , m_fLastRowWidth(0)\r
43     , m_fLastRowY(0)\r
44     , m_bUseInheriated(FALSE)\r
45     , m_fWidthLimite(0)\r
46     , m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done)\r
47 {\r
48     FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() || m_pFormNode->GetClassID() == XFA_ELEMENT_Form));\r
49 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
50     m_pOldLayoutItem = (CXFA_ContentLayoutItemImpl*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY);\r
51 #endif\r
52 }\r
53 CXFA_ContentLayoutItemImpl* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(CXFA_Node* pFormNode)\r
54 {\r
55     if(!pFormNode) {\r
56         return NULL;\r
57     }\r
58     CXFA_ContentLayoutItemImpl* pLayoutItem = NULL;\r
59 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
60     if (m_pOldLayoutItem) {\r
61         pLayoutItem = m_pOldLayoutItem;\r
62         m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;\r
63         return pLayoutItem;\r
64     }\r
65     pLayoutItem = (CXFA_ContentLayoutItemImpl*)pFormNode->GetDocument()->GetParser()->GetNotify()->OnCreateLayoutItem(pFormNode);\r
66 #else\r
67     pLayoutItem = (CXFA_ContentLayoutItemImpl*)m_pPageMgrCreateItem->FindOrCreateLayoutItem(pFormNode);\r
68 #endif\r
69     CXFA_ContentLayoutItemImpl* pPrevLayoutItem = (CXFA_ContentLayoutItemImpl*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY);\r
70     if(pPrevLayoutItem) {\r
71         while(pPrevLayoutItem->m_pNext) {\r
72             pPrevLayoutItem = pPrevLayoutItem->m_pNext;\r
73         }\r
74         pPrevLayoutItem->m_pNext = pLayoutItem;\r
75         pLayoutItem->m_pPrev = pPrevLayoutItem;\r
76     } else {\r
77         pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem);\r
78     }\r
79     return pLayoutItem;\r
80 }\r
81 FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT fCurVerticalOffset, FX_FLOAT& fProposedSplitPos, FX_BOOL& bAppChange, FX_BOOL bCalculateMargin )\r
82 {\r
83     CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;\r
84     if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION && fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y - XFA_LAYOUT_FLOAT_PERCISION) {\r
85         switch(pFormNode->GetIntact()) {\r
86             case XFA_ATTRIBUTEENUM_None: {\r
87                     FX_BOOL bAnyChanged = FALSE;\r
88                     CXFA_Document* pDocument = pFormNode->GetDocument();\r
89                     IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();\r
90                     FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;\r
91                     CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
92                     if(pMarginNode && bCalculateMargin) {\r
93                         fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
94                         fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
95                     }\r
96                     FX_BOOL bChanged = TRUE;\r
97                     while(bChanged) {\r
98                         bChanged = FALSE;\r
99                         {\r
100                             FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset;\r
101                             if(pNotify->FindSplitPos(pFormNode, ((CXFA_LayoutItem*)pLayoutItem)->GetIndex(), fRelSplitPos)) {\r
102                                 bAnyChanged = TRUE;\r
103                                 bChanged = TRUE;\r
104                                 fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;\r
105                                 bAppChange = TRUE;\r
106                                 if(fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {\r
107                                     return TRUE;\r
108                                 }\r
109                             }\r
110                         }\r
111                         FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin;\r
112                         for(CXFA_ContentLayoutItemImpl* pChildItem = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pFirstChild; pChildItem; pChildItem = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling) {\r
113                             FX_FLOAT fChildOffset = fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;\r
114                             FX_BOOL bAppChange = FALSE;\r
115                             if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos, bAppChange, bCalculateMargin)) {\r
116                                 if(fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION && bAppChange) {\r
117                                     fProposedSplitPos = fRelSplitPos - fCurTopMargin;\r
118                                 } else {\r
119                                     fProposedSplitPos = fRelSplitPos + fCurBottomMargin;\r
120                                 }\r
121                                 bAnyChanged = TRUE;\r
122                                 bChanged = TRUE;\r
123                                 if(fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {\r
124                                     return TRUE;\r
125                                 }\r
126                                 if(bAnyChanged) {\r
127                                     break;\r
128                                 }\r
129                             }\r
130                         }\r
131                     }\r
132                     return bAnyChanged;\r
133                 }\r
134                 break;\r
135             case XFA_ATTRIBUTEENUM_ContentArea:\r
136             case XFA_ATTRIBUTEENUM_PageArea: {\r
137                     fProposedSplitPos = fCurVerticalOffset;\r
138                     return TRUE;\r
139                 }\r
140             default:\r
141                 return FALSE;\r
142         }\r
143     }\r
144     return FALSE;\r
145 }\r
146 static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(CXFA_Node* pFormNode, FX_BOOL& bRootForceTb)\r
147 {\r
148     bRootForceTb = FALSE;\r
149     XFA_ATTRIBUTEENUM eLayoutMode;\r
150     if(pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) {\r
151         return eLayoutMode;\r
152     }\r
153     CXFA_Node *pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);\r
154     if(pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) {\r
155         bRootForceTb = TRUE;\r
156         return XFA_ATTRIBUTEENUM_Tb;\r
157     }\r
158     return XFA_ATTRIBUTEENUM_Position;\r
159 }\r
160 static FX_BOOL  XFA_ExistContainerKeep(CXFA_Node*  pCurNode, FX_BOOL bPreFind)\r
161 {\r
162     if(pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) {\r
163         return FALSE;\r
164     }\r
165     XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling;\r
166     if(!bPreFind) {\r
167         eItemType = XFA_NODEITEM_NextSibling;\r
168     }\r
169     CXFA_Node* pPreContainer = pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode);\r
170     if(pPreContainer == NULL) {\r
171         return FALSE;\r
172     }\r
173     CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep);\r
174     if (pKeep) {\r
175         XFA_ATTRIBUTEENUM ePrevious;\r
176         XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous;\r
177         if(!bPreFind) {\r
178             eKeepType = XFA_ATTRIBUTE_Next;\r
179         }\r
180         if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) {\r
181             if(ePrevious == XFA_ATTRIBUTEENUM_ContentArea || ePrevious == XFA_ATTRIBUTEENUM_PageArea) {\r
182                 return TRUE;\r
183             }\r
184         }\r
185     }\r
186     pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep);\r
187     if (!pKeep) {\r
188         return FALSE;\r
189     }\r
190     XFA_ATTRIBUTEENUM eNext;\r
191     XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next;\r
192     if(!bPreFind) {\r
193         eKeepType = XFA_ATTRIBUTE_Previous;\r
194     }\r
195     if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) {\r
196         return FALSE;\r
197     }\r
198     if(eNext == XFA_ATTRIBUTEENUM_ContentArea || eNext == XFA_ATTRIBUTEENUM_PageArea) {\r
199         return TRUE;\r
200     }\r
201     return FALSE;\r
202 }\r
203 FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos)\r
204 {\r
205     ASSERT(m_pLayoutItem);\r
206     XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
207     FX_BOOL bCalculateMargin = TRUE;\r
208     if(eLayout == XFA_ATTRIBUTEENUM_Position) {\r
209         bCalculateMargin = FALSE;\r
210     }\r
211     while(fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
212         FX_BOOL bAppChange = FALSE;\r
213         if(!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange, bCalculateMargin)) {\r
214             break;\r
215         }\r
216     }\r
217     return fProposedSplitPos;\r
218 }\r
219 void CXFA_ItemLayoutProcessor::SplitLayoutItem(CXFA_ContentLayoutItemImpl* pLayoutItem, CXFA_ContentLayoutItemImpl* pSecondParent, FX_FLOAT fSplitPos)\r
220 {\r
221     FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;\r
222     XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
223     FX_BOOL bCalculateMargin = TRUE;\r
224     if(eLayout == XFA_ATTRIBUTEENUM_Position) {\r
225         bCalculateMargin = FALSE;\r
226     }\r
227     CXFA_Node* pMarginNode = pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
228     if(pMarginNode && bCalculateMargin) {\r
229         fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
230         fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
231     }\r
232     CXFA_ContentLayoutItemImpl* pSecondLayoutItem = NULL;\r
233     if (m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) {\r
234         pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(pLayoutItem->m_pFormNode);\r
235     } else {\r
236         pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode);\r
237     }\r
238     pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x;\r
239     pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x;\r
240     pSecondLayoutItem->m_sPos.y = 0;\r
241     pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos;\r
242     pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y;\r
243     if(pLayoutItem->m_pFirstChild) {\r
244         pSecondLayoutItem->m_sSize.y += fCurTopMargin;\r
245     }\r
246     if (pSecondParent) {\r
247         pSecondParent->AddChild(pSecondLayoutItem);\r
248         if(fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {\r
249             pSecondParent->m_sSize.y += fCurTopMargin;\r
250             CXFA_ContentLayoutItemImpl* pParentItem = (CXFA_ContentLayoutItemImpl*)pSecondParent->m_pParent;\r
251             while(pParentItem) {\r
252                 pParentItem->m_sSize.y += fCurTopMargin;\r
253                 pParentItem = (CXFA_ContentLayoutItemImpl*)pParentItem->m_pParent;\r
254             }\r
255         }\r
256     } else {\r
257         pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent;\r
258         pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling;\r
259         pLayoutItem->m_pNextSibling = pSecondLayoutItem;\r
260     }\r
261     CXFA_ContentLayoutItemImpl *pChildren = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pFirstChild;\r
262     pLayoutItem->m_pFirstChild = NULL;\r
263     FX_FLOAT lHeightForKeep = 0;\r
264     CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> keepLayoutItems;\r
265     FX_FLOAT fAddMarginHeight = 0;\r
266     for(CXFA_ContentLayoutItemImpl *pChildItem = pChildren, *pChildNext = NULL; pChildItem; pChildItem = pChildNext) {\r
267         pChildNext = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling;\r
268         pChildItem->m_pNextSibling = NULL;\r
269         if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin + XFA_LAYOUT_FLOAT_PERCISION) {\r
270             if(!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) {\r
271                 pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;\r
272                 pChildItem->m_sPos.y += lHeightForKeep;\r
273                 pChildItem->m_sPos.y += fAddMarginHeight;\r
274                 pSecondLayoutItem->AddChild(pChildItem);\r
275             } else {\r
276                 if(lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {\r
277                     for(int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex ++) {\r
278                         CXFA_ContentLayoutItemImpl *pPreItem = keepLayoutItems[iIndex];\r
279                         pLayoutItem->RemoveChild(pPreItem);\r
280                         pPreItem->m_sPos.y -= fSplitPos;\r
281                         if(pPreItem->m_sPos.y < 0) {\r
282                             pPreItem->m_sPos.y = 0;\r
283                         }\r
284                         if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) {\r
285                             pPreItem->m_sPos.y = lHeightForKeep;\r
286                             lHeightForKeep += pPreItem->m_sSize.y;\r
287                             pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y;\r
288                             if(pSecondParent) {\r
289                                 pSecondParent->m_sSize.y += pPreItem->m_sSize.y;\r
290                             }\r
291                         }\r
292                         pSecondLayoutItem->AddChild(pPreItem);\r
293                     }\r
294                 }\r
295                 pChildItem->m_sPos.y -= fSplitPos;\r
296                 pChildItem->m_sPos.y += lHeightForKeep;\r
297                 pChildItem->m_sPos.y += fAddMarginHeight;\r
298                 pSecondLayoutItem->AddChild(pChildItem);\r
299             }\r
300         } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >= fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y + pChildItem->m_sSize.y) {\r
301             pLayoutItem->AddChild(pChildItem);\r
302             if(XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) {\r
303                 keepLayoutItems.Add(pChildItem);\r
304             } else {\r
305                 keepLayoutItems.RemoveAll();\r
306             }\r
307         } else {\r
308             FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y;\r
309             SplitLayoutItem(pChildItem, pSecondLayoutItem, fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);\r
310             fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight;\r
311             pLayoutItem->AddChild(pChildItem);\r
312         }\r
313     }\r
314 }\r
315 void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos)\r
316 {\r
317     ASSERT(m_pLayoutItem);\r
318     SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos);\r
319     return;\r
320 }\r
321 void CXFA_LayoutItemImpl::AddChild(CXFA_LayoutItemImpl *pChildItem)\r
322 {\r
323     if(pChildItem->m_pParent) {\r
324         pChildItem->m_pParent->RemoveChild(pChildItem);\r
325     }\r
326     pChildItem->m_pParent = this;\r
327     if(m_pFirstChild == NULL) {\r
328         m_pFirstChild = pChildItem;\r
329     } else {\r
330         CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;\r
331         while(pExistingChildItem->m_pNextSibling) {\r
332             pExistingChildItem = pExistingChildItem->m_pNextSibling;\r
333         }\r
334         pExistingChildItem->m_pNextSibling = pChildItem;\r
335     }\r
336 }\r
337 void CXFA_LayoutItemImpl::AddHeadChild(CXFA_LayoutItemImpl *pChildItem)\r
338 {\r
339     if(pChildItem->m_pParent) {\r
340         pChildItem->m_pParent->RemoveChild(pChildItem);\r
341     }\r
342     pChildItem->m_pParent = this;\r
343     if(m_pFirstChild == NULL) {\r
344         m_pFirstChild = pChildItem;\r
345     } else {\r
346         CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;\r
347         m_pFirstChild = pChildItem;\r
348         m_pFirstChild->m_pNextSibling = pExistingChildItem;\r
349     }\r
350 }\r
351 void CXFA_LayoutItemImpl::InsertChild(CXFA_LayoutItemImpl *pBeforeItem, CXFA_LayoutItemImpl *pChildItem)\r
352 {\r
353     if(pBeforeItem->m_pParent != this) {\r
354         return;\r
355     }\r
356     if(pChildItem->m_pParent) {\r
357         pChildItem->m_pParent = NULL;\r
358     }\r
359     pChildItem->m_pParent = this;\r
360     CXFA_LayoutItemImpl* pExistingChildItem = pBeforeItem->m_pNextSibling;\r
361     pBeforeItem->m_pNextSibling = pChildItem;\r
362     pChildItem->m_pNextSibling = pExistingChildItem;\r
363 }\r
364 void CXFA_LayoutItemImpl::RemoveChild(CXFA_LayoutItemImpl *pChildItem)\r
365 {\r
366     if(pChildItem->m_pParent != this) {\r
367         return;\r
368     }\r
369     if(m_pFirstChild == pChildItem) {\r
370         m_pFirstChild = pChildItem->m_pNextSibling;\r
371     } else {\r
372         CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;\r
373         while(pExistingChildItem && pExistingChildItem->m_pNextSibling != pChildItem) {\r
374             pExistingChildItem = pExistingChildItem->m_pNextSibling;\r
375         }\r
376         if(pExistingChildItem) {\r
377             pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling;\r
378         }\r
379     }\r
380     pChildItem->m_pNextSibling = NULL;\r
381     pChildItem->m_pParent = NULL;\r
382 }\r
383 CXFA_ContentLayoutItemImpl* CXFA_ItemLayoutProcessor::ExtractLayoutItem()\r
384 {\r
385     CXFA_ContentLayoutItemImpl* pLayoutItem = m_pLayoutItem;\r
386     if(pLayoutItem) {\r
387         m_pLayoutItem = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pNextSibling;\r
388         pLayoutItem->m_pNextSibling = NULL;\r
389     }\r
390 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
391     if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && m_pOldLayoutItem && m_pOldLayoutItem->IsContentLayoutItem()) {\r
392         if (m_pOldLayoutItem->m_pPrev) {\r
393             m_pOldLayoutItem->m_pPrev->m_pNext = NULL;\r
394         }\r
395         IXFA_Notify* pNotify = m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();\r
396         IXFA_DocLayout* pDocLayout = m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();\r
397         CXFA_ContentLayoutItemImpl* pOldLayoutItem = m_pOldLayoutItem;\r
398         while (pOldLayoutItem) {\r
399             CXFA_ContentLayoutItemImpl* pNextOldLayoutItem = pOldLayoutItem->m_pNext;\r
400             pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pOldLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);\r
401             delete pOldLayoutItem;\r
402             pOldLayoutItem = pNextOldLayoutItem;\r
403         }\r
404         m_pOldLayoutItem = NULL;\r
405     }\r
406 #endif\r
407     return pLayoutItem;\r
408 }\r
409 static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode(CXFA_Node* pContainerNode, CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, FX_BOOL bBreakBefore)\r
410 {\r
411     FX_BOOL bFindRs = FALSE;\r
412     for(CXFA_Node *pBreakNode = pContainerNode; pBreakNode; pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
413         XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before;\r
414         if(!bBreakBefore) {\r
415             eAttributeType = XFA_ATTRIBUTE_After;\r
416         }\r
417         switch(pBreakNode->GetClassID()) {\r
418             case XFA_ELEMENT_BreakBefore: {\r
419                     if(bBreakBefore) {\r
420                         pCurActionNode = pBreakNode;\r
421                         nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;\r
422                         bFindRs = TRUE;\r
423                     }\r
424                 }\r
425                 break;\r
426             case XFA_ELEMENT_BreakAfter: {\r
427                     if(!bBreakBefore) {\r
428                         pCurActionNode = pBreakNode;\r
429                         nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;\r
430                         bFindRs = TRUE;\r
431                     }\r
432                 }\r
433                 break;\r
434             case XFA_ELEMENT_Break:\r
435                 if(pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) {\r
436                     pCurActionNode = pBreakNode;\r
437                     nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;\r
438                     if(!bBreakBefore) {\r
439                         nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;\r
440                     }\r
441                     bFindRs = TRUE;\r
442                     break;\r
443                 }\r
444             default:\r
445                 break;\r
446         }\r
447         if(bFindRs) {\r
448             break;\r
449         }\r
450     }\r
451     return bFindRs;\r
452 }\r
453 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
454 static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode)\r
455 {\r
456     IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify();\r
457     IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout();\r
458     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pGenerateNode);\r
459     for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {\r
460         CXFA_ContentLayoutItemImpl* pCurLayoutItem = (CXFA_ContentLayoutItemImpl*)pNode->GetUserData(XFA_LAYOUTITEMKEY);\r
461         CXFA_ContentLayoutItemImpl* pNextLayoutItem = NULL;\r
462         while (pCurLayoutItem) {\r
463             pNextLayoutItem = pCurLayoutItem->m_pNext;\r
464             pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pCurLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);\r
465             delete pCurLayoutItem;\r
466             pCurLayoutItem = pNextLayoutItem;\r
467         }\r
468     }\r
469     pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode);\r
470 }\r
471 #endif\r
472 void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pParentContainer, FX_BOOL bUsePageBreak)\r
473 {\r
474     CXFA_Node *pEntireContainer = pParentContainer;\r
475     CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;\r
476     switch (nCurStage) {\r
477         case XFA_ItemLayoutProcessorStages_BreakBefore:\r
478         case XFA_ItemLayoutProcessorStages_BreakAfter: {\r
479                 pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent);\r
480             }\r
481             break;\r
482         case XFA_ItemLayoutProcessorStages_Keep:\r
483         case XFA_ItemLayoutProcessorStages_Container:\r
484             pChildContainer = pCurActionNode;\r
485             break;\r
486         default:\r
487             pChildContainer = XFA_LAYOUT_INVALIDNODE;\r
488             break;\r
489     }\r
490     switch(nCurStage) {\r
491         case XFA_ItemLayoutProcessorStages_Keep: {\r
492                 CXFA_Node *pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);\r
493                 if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {\r
494                     return;\r
495                 }\r
496                 goto CheckNextChildContainer;\r
497             }\r
498         case XFA_ItemLayoutProcessorStages_None: {\r
499                 pCurActionNode = XFA_LAYOUT_INVALIDNODE;\r
500             case XFA_ItemLayoutProcessorStages_BookendLeader:\r
501                 for(CXFA_Node *pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) :\r
502                                               pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
503                         pBookendNode; pBookendNode = pBookendNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
504                     switch(pBookendNode->GetClassID()) {\r
505                         case XFA_ELEMENT_Bookend:\r
506                         case XFA_ELEMENT_Break:\r
507                             pCurActionNode = pBookendNode;\r
508                             nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader;\r
509                             return;\r
510                         default:\r
511                             break;\r
512                     }\r
513                 }\r
514             }\r
515             {\r
516                 pCurActionNode = XFA_LAYOUT_INVALIDNODE;\r
517             case XFA_ItemLayoutProcessorStages_BreakBefore:\r
518                 if(pCurActionNode != XFA_LAYOUT_INVALIDNODE) {\r
519                     CXFA_Node *pBreakBeforeNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
520                     if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) {\r
521                         return;\r
522                     }\r
523                     if(m_bIsProcessKeep) {\r
524                         if(ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage, pChildContainer)) {\r
525                             return;\r
526                         }\r
527                         goto CheckNextChildContainer;\r
528                     }\r
529                     pCurActionNode = pChildContainer;\r
530                     nCurStage = XFA_ItemLayoutProcessorStages_Container;\r
531                     return;\r
532                 }\r
533                 goto CheckNextChildContainer;\r
534             }\r
535         case XFA_ItemLayoutProcessorStages_Container: {\r
536                 pCurActionNode = XFA_LAYOUT_INVALIDNODE;\r
537             case XFA_ItemLayoutProcessorStages_BreakAfter: {\r
538                     if(pCurActionNode == XFA_LAYOUT_INVALIDNODE) {\r
539                         CXFA_Node *pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);\r
540                         if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {\r
541                             return;\r
542                         }\r
543                     } else {\r
544                         CXFA_Node *pBreakAfterNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
545                         if(XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {\r
546                             return;\r
547                         }\r
548                     }\r
549                     goto CheckNextChildContainer;\r
550                 }\r
551             }\r
552 CheckNextChildContainer: {\r
553                 CXFA_Node *pNextChildContainer = pChildContainer == XFA_LAYOUT_INVALIDNODE ?\r
554                                                  pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode) :\r
555                                                  pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);\r
556                 while(pNextChildContainer && pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {\r
557                     CXFA_Node* pSaveNode = pNextChildContainer;\r
558                     pNextChildContainer = pNextChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);\r
559 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_\r
560                     if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {\r
561                         XFA_DeleteLayoutGeneratedNode(pSaveNode);\r
562                     }\r
563 #endif\r
564                 }\r
565                 if(!pNextChildContainer) {\r
566                     goto NoMoreChildContainer;\r
567                 }\r
568                 FX_BOOL bLastKeep = FALSE;\r
569                 if(ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage, pNextChildContainer, bLastKeep)) {\r
570                     return;\r
571                 }\r
572                 if(!m_bKeepBreakFinish && !bLastKeep && XFA_ItemLayoutProcessor_FindBreakNode(pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild), pCurActionNode, nCurStage, TRUE)) {\r
573                     return;\r
574                 }\r
575                 pCurActionNode = pNextChildContainer;\r
576                 if(m_bIsProcessKeep) {\r
577                     nCurStage = XFA_ItemLayoutProcessorStages_Keep;\r
578                 } else {\r
579                     nCurStage = XFA_ItemLayoutProcessorStages_Container;\r
580                 }\r
581                 return;\r
582             }\r
583 NoMoreChildContainer: {\r
584                 pCurActionNode = XFA_LAYOUT_INVALIDNODE;\r
585             case XFA_ItemLayoutProcessorStages_BookendTrailer:\r
586                 for(CXFA_Node *pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) :\r
587                                               pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
588                         pBookendNode; pBookendNode = pBookendNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
589                     switch(pBookendNode->GetClassID()) {\r
590                         case XFA_ELEMENT_Bookend:\r
591                         case XFA_ELEMENT_Break:\r
592                             pCurActionNode = pBookendNode;\r
593                             nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer;\r
594                             return;\r
595                         default:\r
596                             break;\r
597                     }\r
598                 }\r
599             }\r
600         default:\r
601             pCurActionNode = NULL;\r
602             nCurStage = XFA_ItemLayoutProcessorStages_Done;\r
603     }\r
604 }\r
605 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node*& pNextContainer, FX_BOOL& bLastKeepNode)\r
606 {\r
607     FX_BOOL bCanSplite = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None;\r
608     FX_BOOL bNextKeep = FALSE;\r
609     if(XFA_ExistContainerKeep(pNextContainer, FALSE)) {\r
610         bNextKeep = TRUE;\r
611     }\r
612     if(bNextKeep && !bCanSplite) {\r
613         if(!m_bIsProcessKeep && !m_bKeepBreakFinish) {\r
614             m_pKeepHeadNode = pNextContainer;\r
615             m_bIsProcessKeep = TRUE;\r
616         }\r
617     } else {\r
618         if(m_bIsProcessKeep && m_pKeepHeadNode != NULL) {\r
619             m_pKeepTailNode = pNextContainer;\r
620             if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild), pCurActionNode, nCurStage, TRUE)) {\r
621                 return TRUE;\r
622             } else {\r
623                 pNextContainer = m_pKeepHeadNode;\r
624                 m_bKeepBreakFinish = TRUE;\r
625                 m_pKeepHeadNode = NULL;\r
626                 m_pKeepTailNode = NULL;\r
627                 m_bIsProcessKeep = FALSE;\r
628             }\r
629         } else {\r
630             if(m_bKeepBreakFinish) {\r
631                 bLastKeepNode = TRUE;\r
632             }\r
633             m_bKeepBreakFinish = FALSE;\r
634         }\r
635     }\r
636     return FALSE;\r
637 }\r
638 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pContainerNode)\r
639 {\r
640     if(m_pKeepTailNode == pContainerNode) {\r
641         pCurActionNode = m_pKeepHeadNode;\r
642         m_bKeepBreakFinish = TRUE;\r
643         m_pKeepHeadNode = NULL;\r
644         m_pKeepTailNode = NULL;\r
645         m_bIsProcessKeep = FALSE;\r
646         nCurStage = XFA_ItemLayoutProcessorStages_Container;\r
647         return TRUE;\r
648     }\r
649     CXFA_Node *pBreakAfterNode = pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild);\r
650     if(XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {\r
651         return TRUE;\r
652     }\r
653     return FALSE;\r
654 }\r
655 FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode)\r
656 {\r
657     XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence);\r
658     return ePresence == XFA_ATTRIBUTEENUM_Visible || ePresence == XFA_ATTRIBUTEENUM_Invisible;\r
659 }\r
660 static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(CXFA_Node* pFormNode, FX_FLOAT& fContainerWidth, FX_FLOAT& fContainerHeight, FX_BOOL& bContainerWidthAutoSize, FX_BOOL& bContainerHeightAutoSize)\r
661 {\r
662     fContainerWidth = 0;\r
663     fContainerHeight = 0;\r
664     bContainerWidthAutoSize = TRUE;\r
665     bContainerHeightAutoSize = TRUE;\r
666     XFA_ELEMENT eClassID = pFormNode->GetClassID();\r
667     CXFA_Measurement mTmpValue;\r
668     if(bContainerWidthAutoSize && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {\r
669         fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);\r
670         bContainerWidthAutoSize = FALSE;\r
671     }\r
672     if(bContainerHeightAutoSize && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {\r
673         fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);\r
674         bContainerHeightAutoSize = FALSE;\r
675     }\r
676     if(bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform && pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {\r
677         fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);\r
678         bContainerWidthAutoSize = FALSE;\r
679     }\r
680     if(bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform && pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {\r
681         fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);\r
682         bContainerHeightAutoSize = FALSE;\r
683     }\r
684 }\r
685 static inline void XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize\r
686 (CXFA_Node* pFormNode, FX_BOOL bContainerWidthAutoSize, FX_FLOAT fContentCalculatedWidth, FX_FLOAT& fContainerWidth, FX_BOOL bContainerHeightAutoSize, FX_FLOAT fContentCalculatedHeight, FX_FLOAT& fContainerHeight)\r
687 {\r
688     CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
689     CXFA_Measurement mTmpValue;\r
690     if(bContainerWidthAutoSize) {\r
691         fContainerWidth = fContentCalculatedWidth;\r
692         if(pMarginNode) {\r
693             if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) {\r
694                 fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);\r
695             }\r
696             if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) {\r
697                 fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);\r
698             }\r
699         }\r
700     }\r
701     if(bContainerHeightAutoSize) {\r
702         fContainerHeight = fContentCalculatedHeight;\r
703         if(pMarginNode) {\r
704             if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) {\r
705                 fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);\r
706             }\r
707             if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue, FALSE)) {\r
708                 fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);\r
709             }\r
710         }\r
711     }\r
712 }\r
713 void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)\r
714 {\r
715     XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);\r
716     int32_t nAnchorType = 0;\r
717     switch(eAnchorType) {\r
718         case XFA_ATTRIBUTEENUM_TopLeft:\r
719             nAnchorType = 0;\r
720             break;\r
721         case XFA_ATTRIBUTEENUM_TopCenter:\r
722             nAnchorType = 1;\r
723             break;\r
724         case XFA_ATTRIBUTEENUM_TopRight:\r
725             nAnchorType = 2;\r
726             break;\r
727         case XFA_ATTRIBUTEENUM_MiddleLeft:\r
728             nAnchorType = 3;\r
729             break;\r
730         case XFA_ATTRIBUTEENUM_MiddleCenter:\r
731             nAnchorType = 4;\r
732             break;\r
733         case XFA_ATTRIBUTEENUM_MiddleRight:\r
734             nAnchorType = 5;\r
735             break;\r
736         case XFA_ATTRIBUTEENUM_BottomLeft:\r
737             nAnchorType = 6;\r
738             break;\r
739         case XFA_ATTRIBUTEENUM_BottomCenter:\r
740             nAnchorType = 7;\r
741             break;\r
742         case XFA_ATTRIBUTEENUM_BottomRight:\r
743             nAnchorType = 8;\r
744             break;\r
745         default:\r
746             break;\r
747     }\r
748     static const uint8_t nNextPos[4][9] = { {0, 1, 2, 3, 4, 5, 6, 7, 8},\r
749                                              {6, 3, 0, 7, 4, 1, 8, 5, 2}, \r
750                                              {8, 7, 6, 5, 4, 3, 2, 1, 0},\r
751                                              {2, 5, 8, 1, 4, 7, 0, 3, 6} };\r
752 \r
753     FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);\r
754     FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);\r
755     int32_t nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
756     nRotate = XFA_MapRotation(nRotate) / 90;\r
757     int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];\r
758     fAbsoluteX = fAnchorX;\r
759     fAbsoluteY = fAnchorY;\r
760     switch(nAbsoluteAnchorType / 3) {\r
761         case 1:\r
762             fAbsoluteY -= fHeight / 2;\r
763             break;\r
764         case 2:\r
765             fAbsoluteY -= fHeight;\r
766             break;\r
767         default:\r
768             break;\r
769     }\r
770     switch(nAbsoluteAnchorType % 3) {\r
771         case 1:\r
772             fAbsoluteX -= fWidth / 2;\r
773             break;\r
774         case 2:\r
775             fAbsoluteX -= fWidth;\r
776             break;\r
777         default:\r
778             break;\r
779     }\r
780 }\r
781 static FX_BOOL XFA_ItemLayoutProcessor_FloatAlmostEqual(FX_FLOAT f1, FX_FLOAT f2)\r
782 {\r
783     return f1 >= f2 - XFA_LAYOUT_FLOAT_PERCISION && f1 <= f2 + XFA_LAYOUT_FLOAT_PERCISION;\r
784 }\r
785 static FX_BOOL XFA_ItemLayoutProcessor_FloatGreaterThan(FX_FLOAT f1, FX_FLOAT f2)\r
786 {\r
787     return f1 > f2 + XFA_LAYOUT_FLOAT_PERCISION;\r
788 }\r
789 static FX_BOOL XFA_ItemLayoutProcessor_FloatLessThan(FX_FLOAT f1, FX_FLOAT f2)\r
790 {\r
791     return f1 < f2 - XFA_LAYOUT_FLOAT_PERCISION;\r
792 }\r
793 FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node *pNode, CXFA_Node *pParentNode)\r
794 {\r
795     return FALSE;\r
796 }\r
797 void CXFA_ItemLayoutProcessor::DoLayoutPageArea(CXFA_ContainerLayoutItemImpl* pPageAreaLayoutItem)\r
798 {\r
799     CXFA_Node *pFormNode = pPageAreaLayoutItem->m_pFormNode;\r
800     CXFA_Node *pCurChildNode = XFA_LAYOUT_INVALIDNODE;\r
801     XFA_ItemLayoutProcessorStages nCurChildNodeStage = XFA_ItemLayoutProcessorStages_None;\r
802     CXFA_LayoutItemImpl* pBeforeItem = NULL;\r
803     for(XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);\r
804             pCurChildNode;\r
805             XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {\r
806         if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
807             continue;\r
808         }\r
809         if(pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
810             continue;\r
811         }\r
812         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pCurChildNode, NULL);\r
813 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
814         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
815 #endif\r
816         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
817         if(!pProcessor->HasLayoutItem()) {\r
818             delete pProcessor;\r
819             continue;\r
820         }\r
821         FX_FLOAT fWidth, fHeight;\r
822         pProcessor->GetCurrentComponentSize(fWidth, fHeight);\r
823         FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;\r
824         CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);\r
825         pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);\r
826         CXFA_LayoutItemImpl* pProcessItem = pProcessor->ExtractLayoutItem();\r
827         if(pBeforeItem == NULL) {\r
828             pPageAreaLayoutItem->AddHeadChild(pProcessItem);\r
829         } else {\r
830             pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);\r
831         }\r
832         pBeforeItem = pProcessItem;\r
833         delete pProcessor;\r
834     }\r
835     pBeforeItem = NULL;\r
836     CXFA_LayoutItemImpl* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;\r
837     while (pLayoutItem) {\r
838         if (!pLayoutItem->IsContentLayoutItem() || pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {\r
839             pLayoutItem = pLayoutItem->m_pNextSibling;\r
840             continue;\r
841         }\r
842         if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {\r
843             CXFA_LayoutItemImpl* pNextLayoutItem = pLayoutItem->m_pNextSibling;\r
844             pPageAreaLayoutItem->RemoveChild(pLayoutItem);\r
845             if (pBeforeItem == NULL) {\r
846                 pPageAreaLayoutItem->AddHeadChild(pLayoutItem);\r
847             } else {\r
848                 pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);\r
849             }\r
850             pBeforeItem = pLayoutItem;\r
851             pLayoutItem = pNextLayoutItem;\r
852         }\r
853     }\r
854 }\r
855 void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(CXFA_LayoutContext* pContext)\r
856 {\r
857     if(m_pLayoutItem != NULL) {\r
858         return;\r
859     }\r
860     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
861     FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) != XFA_ATTRIBUTEENUM_Position);\r
862     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
863     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
864     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
865     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
866     FX_FLOAT fHiddenContentCalculatedWidth = 0, fHiddenContentCalculatedHeight = 0;\r
867     if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {\r
868         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);\r
869     }\r
870     int32_t iColIndex = 0;\r
871     for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {\r
872         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
873             continue;\r
874         }\r
875         if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
876             continue;\r
877         }\r
878         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
879 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
880         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
881 #endif\r
882         if (pContext && pContext->m_prgSpecifiedColumnWidths) {\r
883             int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
884             if (iColSpan <= pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {\r
885                 pContext->m_fCurColumnWidth = 0;\r
886                 pContext->m_bCurColumnWidthAvaiable = TRUE;\r
887                 if(iColSpan == -1) {\r
888                     iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();\r
889                 }\r
890                 for (int32_t i = 0; i < iColSpan; i++) {\r
891                     pContext->m_fCurColumnWidth += pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);\r
892                 }\r
893                 if(pContext->m_fCurColumnWidth == 0) {\r
894                     pContext->m_bCurColumnWidthAvaiable = FALSE;\r
895                 }\r
896                 iColIndex += iColSpan;\r
897             }\r
898         }\r
899         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pContext);\r
900         if(!pProcessor->HasLayoutItem()) {\r
901             delete pProcessor;\r
902             continue;\r
903         }\r
904         FX_FLOAT fWidth, fHeight;\r
905         pProcessor->GetCurrentComponentSize(fWidth, fHeight);\r
906         FX_BOOL bChangeParentSize = FALSE;\r
907         if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {\r
908             bChangeParentSize = TRUE;\r
909         }\r
910         FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;\r
911         if(!bIgnoreXY) {\r
912             CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);\r
913         }\r
914         pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);\r
915         if(bContainerWidthAutoSize) {\r
916             FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;\r
917             if(bChangeParentSize) {\r
918                 if(fContentCalculatedWidth < fChildSuppliedWidth) {\r
919                     fContentCalculatedWidth = fChildSuppliedWidth;\r
920                 }\r
921             } else {\r
922                 if(fHiddenContentCalculatedWidth < fChildSuppliedWidth && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {\r
923                     fHiddenContentCalculatedWidth = fChildSuppliedWidth;\r
924                 }\r
925             }\r
926         }\r
927         if(bContainerHeightAutoSize) {\r
928             FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;\r
929             if(bChangeParentSize) {\r
930                 if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
931                     fContentCalculatedHeight = fChildSuppliedHeight;\r
932                 }\r
933             } else {\r
934                 if(fHiddenContentCalculatedHeight < fChildSuppliedHeight && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {\r
935                     fHiddenContentCalculatedHeight = fChildSuppliedHeight;\r
936                 }\r
937             }\r
938         }\r
939         m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());\r
940         delete pProcessor;\r
941     }\r
942     XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();\r
943     if(fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {\r
944         fContentCalculatedWidth = fHiddenContentCalculatedWidth;\r
945     }\r
946     if(fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {\r
947         fContentCalculatedHeight = fHiddenContentCalculatedHeight;\r
948     }\r
949     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
950     SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
951 }\r
952 static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT& fWidth, FX_FLOAT& fHeight)\r
953 {\r
954     CXFA_Node *pNode = pLayoutItem->m_pFormNode;\r
955     ASSERT(pNode);\r
956     XFA_ELEMENT eClassID = pNode->GetClassID();\r
957     switch(eClassID) {\r
958         case XFA_ELEMENT_Subform:\r
959         case XFA_ELEMENT_Area:\r
960         case XFA_ELEMENT_ExclGroup:\r
961         case XFA_ELEMENT_SubformSet: {\r
962                 if(fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {\r
963                     fWidth = pLayoutItem->m_sSize.x;\r
964                 }\r
965                 if(fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {\r
966                     fHeight = pLayoutItem->m_sSize.y;\r
967                 }\r
968                 break;\r
969             }\r
970         case XFA_ELEMENT_Draw:\r
971         case XFA_ELEMENT_Field: {\r
972                 pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(pNode, fWidth, fHeight);\r
973                 break;\r
974             }\r
975         default:\r
976             ASSERT(FALSE);\r
977     }\r
978 }\r
979 static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(CXFA_ContentLayoutItemImpl* pLayoutRow, const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, XFA_ATTRIBUTEENUM eLayout)\r
980 {\r
981     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
982     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
983     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
984     CXFA_Node* pMarginNode = pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
985     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
986     if(pMarginNode) {\r
987         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
988         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
989         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
990         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
991     }\r
992     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
993     FX_FLOAT fContentCurrentHeight = pLayoutRow->m_sSize.y - fTopInset - fBottomInset;\r
994     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
995     FX_FLOAT fCurrentColX = 0;\r
996     int32_t nCurrentColIdx = 0;\r
997     FX_BOOL  bMetWholeRowCell = FALSE;\r
998     for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
999         int32_t nOriginalColSpan = pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
1000         int32_t nColSpan = nOriginalColSpan;\r
1001         FX_FLOAT fColSpanWidth = 0;\r
1002         if(nColSpan == -1 || nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {\r
1003             nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;\r
1004         }\r
1005         for(int32_t i = 0; i < nColSpan; i ++) {\r
1006             fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];\r
1007         }\r
1008         if (nColSpan != nOriginalColSpan) {\r
1009             fColSpanWidth = bMetWholeRowCell ? 0 : FX_MAX(fColSpanWidth, pLayoutChild->m_sSize.y);\r
1010         }\r
1011         if(nOriginalColSpan == -1) {\r
1012             bMetWholeRowCell = TRUE;\r
1013         }\r
1014         pLayoutChild->m_sPos.Set(fCurrentColX, 0);\r
1015         pLayoutChild->m_sSize.x = fColSpanWidth;\r
1016         if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1017             fCurrentColX += fColSpanWidth;\r
1018             nCurrentColIdx += nColSpan;\r
1019             FX_FLOAT fNewHeight = bContainerHeightAutoSize ? -1 : fContentCurrentHeight;\r
1020             XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth, fNewHeight);\r
1021             pLayoutChild->m_sSize.y = fNewHeight;\r
1022             if(bContainerHeightAutoSize) {\r
1023                 FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;\r
1024                 if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
1025                     fContentCalculatedHeight = fChildSuppliedHeight;\r
1026                 }\r
1027             }\r
1028         }\r
1029     }\r
1030     if(bContainerHeightAutoSize) {\r
1031         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1032             XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);\r
1033             FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;\r
1034             pLayoutChild->m_sSize.y = fContentCalculatedHeight;\r
1035             CXFA_Node* pParaNode = pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);\r
1036             if(pParaNode && pLayoutChild->m_pFirstChild) {\r
1037                 FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;\r
1038                 XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);\r
1039                 switch(eVType) {\r
1040                     case XFA_ATTRIBUTEENUM_Middle:\r
1041                         fOffHeight = fOffHeight / 2;\r
1042                         break;\r
1043                     case XFA_ATTRIBUTEENUM_Bottom:\r
1044                         break;\r
1045                     case XFA_ATTRIBUTEENUM_Top:\r
1046                     default:\r
1047                         fOffHeight = 0;\r
1048                         break;\r
1049                 }\r
1050                 if(fOffHeight > 0) {\r
1051                     for(CXFA_ContentLayoutItemImpl* pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild; pInnerLayoutChild; pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pInnerLayoutChild->m_pNextSibling) {\r
1052                         pInnerLayoutChild->m_sPos.y += fOffHeight;\r
1053                     }\r
1054                 }\r
1055             }\r
1056         }\r
1057     }\r
1058     if(bContainerWidthAutoSize) {\r
1059         FX_FLOAT fChildSuppliedWidth = fCurrentColX;\r
1060         if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
1061             fChildSuppliedWidth = fContentWidthLimit;\r
1062         }\r
1063         if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
1064             fContentCalculatedWidth = fChildSuppliedWidth;\r
1065         }\r
1066     } else {\r
1067         fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;\r
1068     }\r
1069     if(pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == XFA_ATTRIBUTEENUM_Rl_row) {\r
1070         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1071             pLayoutChild->m_sPos.x = fContentCalculatedWidth - pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;\r
1072         }\r
1073     }\r
1074     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
1075     pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight);\r
1076 }\r
1077 void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode)\r
1078 {\r
1079     if(m_pLayoutItem != NULL) {\r
1080         return;\r
1081     }\r
1082     if(pLayoutNode == NULL) {\r
1083         pLayoutNode = m_pFormNode;\r
1084     }\r
1085     ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);\r
1086     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
1087     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
1088     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
1089     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
1090     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
1091     CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1092     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1093     if(pMarginNode) {\r
1094         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1095         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1096         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1097         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1098     }\r
1099     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
1100     CFX_WideStringC wsColumnWidths;\r
1101     if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {\r
1102         CFX_WideStringArray widths;\r
1103         if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(), L' ', widths) > 0) {\r
1104             int32_t iCols = widths.GetSize();\r
1105             CFX_WideString wsWidth;\r
1106             for (int32_t i = 0; i < iCols; i++) {\r
1107                 wsWidth = widths[i];\r
1108                 wsWidth.TrimLeft(L' ');\r
1109                 if (!wsWidth.IsEmpty()) {\r
1110                     CXFA_Measurement measure(wsWidth);\r
1111                     m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));\r
1112                 }\r
1113             }\r
1114         }\r
1115     }\r
1116     int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();\r
1117     CXFA_LayoutContext layoutContext;\r
1118     layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;\r
1119     CXFA_LayoutContext* pLayoutContext = iSpecifiedColumnCount > 0  ? &layoutContext : NULL;\r
1120     if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {\r
1121         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);\r
1122     }\r
1123     for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {\r
1124         layoutContext.m_bCurColumnWidthAvaiable = FALSE;\r
1125         layoutContext.m_fCurColumnWidth = 0;\r
1126         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
1127             continue;\r
1128         }\r
1129         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
1130 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1131         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1132 #endif\r
1133         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pLayoutContext);\r
1134         if(!pProcessor->HasLayoutItem()) {\r
1135             delete pProcessor;\r
1136             continue;\r
1137         }\r
1138         m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());\r
1139         delete pProcessor;\r
1140     }\r
1141     int32_t iRowCount = 0, iColCount = 0;\r
1142     {\r
1143         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgRowItems;\r
1144         CFX_ArrayTemplate<int32_t> rgRowItemsSpan;\r
1145         CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;\r
1146         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1147             if(pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {\r
1148                 continue;\r
1149             }\r
1150             if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1151                 continue;\r
1152             }\r
1153             XFA_ATTRIBUTEENUM eLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1154             if(eLayout != XFA_ATTRIBUTEENUM_Row && eLayout != XFA_ATTRIBUTEENUM_Rl_row) {\r
1155                 continue;\r
1156             }\r
1157             if (CXFA_ContentLayoutItemImpl* pRowLayoutCell = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild) {\r
1158                 rgRowItems.Add(pRowLayoutCell);\r
1159                 int32_t iColSpan = pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
1160                 rgRowItemsSpan.Add(iColSpan);\r
1161                 rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);\r
1162             }\r
1163         }\r
1164         iRowCount = rgRowItems.GetSize();\r
1165         iColCount = 0;\r
1166         FX_BOOL bMoreColumns = TRUE;\r
1167         while(bMoreColumns) {\r
1168             bMoreColumns = FALSE;\r
1169             FX_BOOL bAutoCol = FALSE;\r
1170             for(int32_t i = 0; i < iRowCount; i ++) {\r
1171                 while(rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 || !XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode))) {\r
1172                     CXFA_ContentLayoutItemImpl* pNewCell = (CXFA_ContentLayoutItemImpl*)rgRowItems[i]->m_pNextSibling;\r
1173                     if(rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode)) {\r
1174                         pNewCell = NULL;\r
1175                     }\r
1176                     rgRowItems[i] = pNewCell;\r
1177                     rgRowItemsSpan[i] = pNewCell ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan) : 0;\r
1178                     rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;\r
1179                 }\r
1180                 CXFA_ContentLayoutItemImpl* pCell = rgRowItems[i];\r
1181                 if(!pCell) {\r
1182                     continue;\r
1183                 }\r
1184                 bMoreColumns = TRUE;\r
1185                 if (rgRowItemsSpan[i] == 1) {\r
1186                     if (iColCount >= iSpecifiedColumnCount) {\r
1187                         for (int32_t j = 0, c = iColCount + 1 - m_rgSpecifiedColumnWidths.GetSize(); j < c; j ++) {\r
1188                             m_rgSpecifiedColumnWidths.Add(0);\r
1189                         }\r
1190                     }\r
1191                     if (m_rgSpecifiedColumnWidths[iColCount] < XFA_LAYOUT_FLOAT_PERCISION) {\r
1192                         bAutoCol = TRUE;\r
1193                     }\r
1194                     if (bAutoCol && m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {\r
1195                         m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];\r
1196                     }\r
1197                 }\r
1198             }\r
1199             if(bMoreColumns) {\r
1200                 FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];\r
1201                 for(int32_t i = 0; i < iRowCount; i ++) {\r
1202                     if(!rgRowItems[i]) {\r
1203                         continue;\r
1204                     }\r
1205                     rgRowItemsSpan[i]--;\r
1206                     rgRowItemsWidth[i] -= fFinalColumnWidth;\r
1207                 }\r
1208                 iColCount ++;\r
1209             }\r
1210         }\r
1211     }\r
1212     FX_FLOAT fCurrentRowY = 0;\r
1213     for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1214         if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1215             continue;\r
1216         }\r
1217         if(pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {\r
1218             XFA_ATTRIBUTEENUM eSubformLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1219             if(eSubformLayout == XFA_ATTRIBUTEENUM_Row || eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {\r
1220                 XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);\r
1221             }\r
1222         }\r
1223         pLayoutChild->m_sPos.y = fCurrentRowY;\r
1224         if(bContainerWidthAutoSize) {\r
1225             pLayoutChild->m_sPos.x = 0;\r
1226         } else {\r
1227             switch(pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1228                 case XFA_ATTRIBUTEENUM_Left:\r
1229                 default:\r
1230                     pLayoutChild->m_sPos.x = 0;\r
1231                     break;\r
1232                 case XFA_ATTRIBUTEENUM_Center:\r
1233                     pLayoutChild->m_sPos.x = (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2 ;\r
1234                     break;\r
1235                 case XFA_ATTRIBUTEENUM_Right:\r
1236                     pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;\r
1237                     break;\r
1238             }\r
1239         }\r
1240         if(bContainerWidthAutoSize) {\r
1241             FX_FLOAT fChildSuppliedWidth = pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;\r
1242             if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
1243                 fChildSuppliedWidth = fContentWidthLimit;\r
1244             }\r
1245             if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
1246                 fContentCalculatedWidth = fChildSuppliedWidth;\r
1247             }\r
1248         }\r
1249         fCurrentRowY += pLayoutChild->m_sSize.y;\r
1250     }\r
1251     if(bContainerHeightAutoSize) {\r
1252         FX_FLOAT fChildSuppliedHeight = fCurrentRowY;\r
1253         if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
1254             fContentCalculatedHeight = fChildSuppliedHeight;\r
1255         }\r
1256     }\r
1257     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
1258     SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
1259 }\r
1260 static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt(XFA_ATTRIBUTEENUM eHAlign)\r
1261 {\r
1262     switch(eHAlign) {\r
1263         case XFA_ATTRIBUTEENUM_Center:\r
1264             return 1;\r
1265         case XFA_ATTRIBUTEENUM_Right:\r
1266             return 2;\r
1267         case XFA_ATTRIBUTEENUM_Left:\r
1268         default:\r
1269             return 0;\r
1270     }\r
1271 }\r
1272 static void     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLayoutItem)\r
1273 {\r
1274     XFA_ATTRIBUTEENUM eLayout = pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1275     switch(eLayout) {\r
1276         case XFA_ATTRIBUTEENUM_Row:\r
1277         case XFA_ATTRIBUTEENUM_Rl_row:\r
1278             XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);\r
1279             break;\r
1280         default:\r
1281             break;\r
1282     }\r
1283 }\r
1284 FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(CXFA_ContentLayoutItemImpl* pTrailerItem)\r
1285 {\r
1286     if(!pTrailerItem) {\r
1287         return FALSE;\r
1288     }\r
1289     FX_FLOAT fWidth = pTrailerItem->m_sSize.x;\r
1290     XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1291     if(eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {\r
1292         return FALSE;\r
1293     }\r
1294     return TRUE;\r
1295 }\r
1296 static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor* pProcessor, FX_FLOAT fSplitPos, CXFA_ContentLayoutItemImpl* pTrailerLayoutItem, FX_BOOL bUseInherited = FALSE)\r
1297 {\r
1298     if(!pTrailerLayoutItem) {\r
1299         return;\r
1300     }\r
1301     FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;\r
1302     if(bUseInherited) {\r
1303         FX_FLOAT fNewSplitPos = 0;\r
1304         if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {\r
1305             fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);\r
1306         }\r
1307         if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1308             pProcessor->SplitLayoutItem(fNewSplitPos);\r
1309         }\r
1310         return;\r
1311     }\r
1312     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pTrailerLayoutItem);\r
1313     CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1314     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1315     if(pMarginNode) {\r
1316         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1317         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1318         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1319         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1320     }\r
1321     FX_FLOAT fWidth = pTrailerLayoutItem->m_sSize.x;\r
1322     XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1323     if(!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {\r
1324         pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;\r
1325         pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;\r
1326         pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;\r
1327         pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);\r
1328         return;\r
1329     }\r
1330     FX_FLOAT fNewSplitPos = 0;\r
1331     if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {\r
1332         fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);\r
1333     }\r
1334     if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1335         pProcessor->SplitLayoutItem(fNewSplitPos);\r
1336         pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;\r
1337     } else {\r
1338         pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;\r
1339     }\r
1340     switch(pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1341         case XFA_ATTRIBUTEENUM_Left:\r
1342         default:\r
1343             pTrailerLayoutItem->m_sPos.x = fLeftInset;\r
1344             break;\r
1345         case XFA_ATTRIBUTEENUM_Right:\r
1346             pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pTrailerLayoutItem->m_sSize.x;\r
1347             break;\r
1348         case XFA_ATTRIBUTEENUM_Center:\r
1349             pTrailerLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pTrailerLayoutItem->m_sSize.x) / 2;\r
1350             break;\r
1351     }\r
1352     pProcessor->m_pLayoutItem->m_sSize.y += fHeight;\r
1353     pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);\r
1354 };\r
1355 static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLeaderLayoutItem)\r
1356 {\r
1357     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);\r
1358     CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1359     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1360     if(pMarginNode) {\r
1361         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1362         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1363         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1364         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1365     }\r
1366     FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;\r
1367     for (CXFA_ContentLayoutItemImpl* pChildItem = (CXFA_ContentLayoutItemImpl*)pProcessor->m_pLayoutItem->m_pFirstChild; pChildItem; pChildItem = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling) {\r
1368         pChildItem->m_sPos.y += fHeight;\r
1369     }\r
1370     pLeaderLayoutItem->m_sPos.y = 0;\r
1371     switch(pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1372         case XFA_ATTRIBUTEENUM_Left:\r
1373         default:\r
1374             pLeaderLayoutItem->m_sPos.x = fLeftInset;\r
1375             break;\r
1376         case XFA_ATTRIBUTEENUM_Right:\r
1377             pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pLeaderLayoutItem->m_sSize.x;\r
1378             break;\r
1379         case XFA_ATTRIBUTEENUM_Center:\r
1380             pLeaderLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pLeaderLayoutItem->m_sSize.x) / 2;\r
1381             break;\r
1382     }\r
1383     pProcessor->m_pLayoutItem->m_sSize.y += fHeight;\r
1384     pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);\r
1385 };\r
1386 static void XFA_ItemLayoutProcessor_AddPendingNode(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pPendingNode, FX_BOOL bBreakPending)\r
1387 {\r
1388     pProcessor->m_rgPendingNodes.AddTail(pPendingNode);\r
1389     pProcessor->m_bBreakPending = bBreakPending;\r
1390 }\r
1391 static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pCurChildNode)\r
1392 {\r
1393     FX_FLOAT fTotalHeight = 0;\r
1394     if(pProcessor->m_rgPendingNodes.GetCount() < 1) {\r
1395         return fTotalHeight;\r
1396     }\r
1397     if(pProcessor->m_pLayoutItem == NULL) {\r
1398         pProcessor->m_pLayoutItem = pProcessor->CreateContentLayoutItem(pCurChildNode);\r
1399         pProcessor->m_pLayoutItem->m_sSize.Set(0, 0);\r
1400     }\r
1401     while(pProcessor->m_rgPendingNodes.GetCount() > 0) {\r
1402         FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition();\r
1403         CXFA_Node* pPendingNode = (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos);\r
1404         pProcessor->m_rgPendingNodes.RemoveAt(pos);\r
1405         CXFA_ContentLayoutItemImpl* pPendingLayoutItem = NULL;\r
1406         CXFA_ItemLayoutProcessor *pPendingProcessor = FX_NEW CXFA_ItemLayoutProcessor(pPendingNode, NULL);\r
1407 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1408         pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;\r
1409 #endif\r
1410         pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
1411         pPendingLayoutItem = pPendingProcessor->HasLayoutItem() ? pPendingProcessor->ExtractLayoutItem() : NULL;\r
1412         delete pPendingProcessor;\r
1413         if(pPendingLayoutItem) {\r
1414             XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor, pPendingLayoutItem);\r
1415             if(pProcessor->m_bBreakPending) {\r
1416                 fTotalHeight += pPendingLayoutItem->m_sSize.y;\r
1417             }\r
1418         }\r
1419     }\r
1420     return fTotalHeight;\r
1421 }\r
1422 FX_FLOAT        CXFA_ItemLayoutProcessor::InsertKeepLayoutItems()\r
1423 {\r
1424     FX_FLOAT fTotalHeight = 0;\r
1425     if(m_arrayKeepItems.GetSize()) {\r
1426         if(m_pLayoutItem == NULL) {\r
1427             m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
1428             m_pLayoutItem->m_sSize.Set(0, 0);\r
1429         }\r
1430         for(int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0 ; iIndex --) {\r
1431             XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this, m_arrayKeepItems[iIndex]);\r
1432             fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;\r
1433         }\r
1434         m_arrayKeepItems.RemoveAll();\r
1435     }\r
1436     return fTotalHeight;\r
1437 }\r
1438 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue,\r
1439         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>& rgCurLineLayoutItem, FX_FLOAT& fContentCurRowAvailWidth,\r
1440         FX_FLOAT& fContentCurRowHeight, FX_FLOAT& fContentCurRowY, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, XFA_ItemLayoutProcessorResult& result)\r
1441 {\r
1442     if(pParentProcessor == NULL || pChildProcessor == NULL) {\r
1443         return FALSE;\r
1444     }\r
1445     if(pParentProcessor->m_pCurChildNode->GetIntact() != XFA_ATTRIBUTEENUM_None || !pChildProcessor->m_bHasAvailHeight) {\r
1446         if(XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {\r
1447             FX_FLOAT fChildWidth, fChildHeight;\r
1448             pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1449             CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> keepLayoutItems;\r
1450             if(pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, fChildHeight, keepLayoutItems)) {\r
1451                 m_arrayKeepItems.RemoveAll();\r
1452                 for(int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {\r
1453                     CXFA_ContentLayoutItemImpl* pItem = keepLayoutItems.GetAt(iIndex);\r
1454                     pParentProcessor->m_pLayoutItem->RemoveChild(pItem);\r
1455                     fContentCurRowY -= pItem->m_sSize.y;\r
1456                     m_arrayKeepItems.Add(pItem);\r
1457                 }\r
1458                 bAddedItemInRow = TRUE;\r
1459                 bForceEndPage = TRUE;\r
1460                 result =  XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1461                 return TRUE;\r
1462             }\r
1463             rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());\r
1464             bAddedItemInRow = TRUE;\r
1465             fContentCurRowAvailWidth -= fChildWidth;\r
1466             if(fContentCurRowHeight < fChildHeight ) {\r
1467                 fContentCurRowHeight = fChildHeight;\r
1468             }\r
1469             result = eRetValue;\r
1470             return TRUE;\r
1471         }\r
1472     }\r
1473     return FALSE;\r
1474 }\r
1475 FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(CXFA_ContentLayoutItemImpl* pParentLayoutItem,  FX_FLOAT fChildHeight, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> &pKeepItems)\r
1476 {\r
1477     if(pParentLayoutItem == NULL) {\r
1478         return FALSE;\r
1479     }\r
1480     FX_FLOAT fItemsHeight = 0;\r
1481     for(CXFA_ContentLayoutItemImpl* pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pParentLayoutItem->m_pFirstChild; pChildLayoutItem; pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pChildLayoutItem->m_pNextSibling) {\r
1482         if(XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {\r
1483             pKeepItems.Add(pChildLayoutItem);\r
1484             fItemsHeight += pChildLayoutItem->m_sSize.y;\r
1485         } else {\r
1486             pKeepItems.RemoveAll();\r
1487             fItemsHeight = 0;\r
1488         }\r
1489     }\r
1490     fItemsHeight += fChildHeight;\r
1491     if(m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {\r
1492         return TRUE;\r
1493     }\r
1494     return FALSE;\r
1495 }\r
1496 void    CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode)\r
1497 {\r
1498     if(!pFormNode) {\r
1499         return;\r
1500     }\r
1501     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormNode);\r
1502     for(CXFA_Node *pNode = sIterator.MoveToNext(); pNode; pNode = sIterator.MoveToNext()) {\r
1503         if(pNode->IsContainerNode()) {\r
1504             CXFA_Node* pBindNode = pNode->GetBindData();\r
1505             if (pBindNode) {\r
1506                 pBindNode->RemoveBindItem(pNode);\r
1507                 pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);\r
1508             }\r
1509         }\r
1510         pNode->SetFlag(XFA_NODEFLAG_UnusedNode);\r
1511     }\r
1512 }\r
1513 void    CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItemImpl* pTrailerItem, CXFA_Node* pFormNode)\r
1514 {\r
1515     ProcessUnUseBinds(pLeaderNode);\r
1516     ProcessUnUseBinds(pTrailerNode);\r
1517     if(pFormNode == NULL) {\r
1518         return;\r
1519     }\r
1520     if(pFormNode->GetClassID() == XFA_ELEMENT_Overflow || pFormNode->GetClassID() == XFA_ELEMENT_Break) {\r
1521         pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);\r
1522     }\r
1523     if(pLeaderNode && pFormNode) {\r
1524         pFormNode->RemoveChild(pLeaderNode);\r
1525     }\r
1526     if(pTrailerNode && pFormNode) {\r
1527         pFormNode->RemoveChild(pTrailerNode);\r
1528     }\r
1529     if(pTrailerItem) {\r
1530         XFA_ReleaseLayoutItem(pTrailerItem);\r
1531     }\r
1532 }\r
1533 static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(CXFA_ItemLayoutProcessor* pThis, CXFA_ItemLayoutProcessor*& pProcessor,\r
1534         FX_BOOL bContainerWidthAutoSize, FX_BOOL bContainerHeightAutoSize, FX_FLOAT fContainerHeight, XFA_ATTRIBUTEENUM eFlowStrategy, uint8_t& uCurHAlignState, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> (&rgCurLineLayoutItems)[3],\r
1535         FX_BOOL bUseBreakControl, FX_FLOAT fAvailHeight, FX_FLOAT fRealHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT& fContentWidthLimit, FX_FLOAT& fContentCurRowAvailWidth,\r
1536         FX_FLOAT& fContentCurRowHeight, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, CXFA_LayoutContext* pLayoutContext = NULL, FX_BOOL bNewRow = FALSE)\r
1537 {\r
1538     FX_BOOL bTakeSpace = XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);\r
1539     uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));\r
1540     if(bContainerWidthAutoSize) {\r
1541         uHAlign = 0;\r
1542     }\r
1543     if((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) || (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {\r
1544         return XFA_ItemLayoutProcessorResult_RowFullBreak;\r
1545     }\r
1546     uCurHAlignState = uHAlign;\r
1547     FX_BOOL bIsOwnSplite = pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;\r
1548     FX_BOOL bUseRealHeight = bTakeSpace && bContainerHeightAutoSize &&  bIsOwnSplite\r
1549                              && pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == XFA_ATTRIBUTEENUM_None;\r
1550     FX_BOOL bIsTransHeight = bTakeSpace;\r
1551     if(bIsTransHeight && !bIsOwnSplite) {\r
1552         FX_BOOL bRootForceTb = FALSE;\r
1553         XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pProcessor->m_pFormNode, bRootForceTb);\r
1554         if(eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {\r
1555             bIsTransHeight = FALSE;\r
1556         }\r
1557     }\r
1558     FX_BOOL bUseInherited = FALSE;\r
1559     CXFA_LayoutContext  layoutContext;\r
1560     if (pThis->m_pPageMgr) {\r
1561         CXFA_Node* pOverflowNode = pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);\r
1562         if(pOverflowNode) {\r
1563             layoutContext.m_pOverflowNode = pOverflowNode;\r
1564             layoutContext.m_pOverflowProcessor = pThis;\r
1565             pLayoutContext = &layoutContext;\r
1566         }\r
1567     }\r
1568     XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;\r
1569     if(!bNewRow || pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {\r
1570         eRetValue = pProcessor->DoLayout(bTakeSpace ? bUseBreakControl : FALSE, bUseRealHeight ?\r
1571                                          fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, pLayoutContext);\r
1572         pProcessor->m_ePreProcessRs = eRetValue;\r
1573     } else {\r
1574         eRetValue = pProcessor->m_ePreProcessRs;\r
1575         pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;\r
1576     }\r
1577     if (pProcessor->HasLayoutItem() == FALSE)   {\r
1578         return eRetValue;\r
1579     }\r
1580     FX_FLOAT fChildWidth, fChildHeight;\r
1581     pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1582     if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {\r
1583         fRealHeight = XFA_LAYOUT_FLOAT_MAX;\r
1584         fAvailHeight = XFA_LAYOUT_FLOAT_MAX;\r
1585     }\r
1586     if (!bTakeSpace || (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) || (fContentWidthLimit - fContentCurRowAvailWidth <= XFA_LAYOUT_FLOAT_PERCISION)) {\r
1587         CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL, *pFormNode = NULL;\r
1588         CXFA_ContentLayoutItemImpl* pTrailerLayoutItem = NULL;\r
1589         FX_BOOL bIsAddTrailerHeight = FALSE;\r
1590         if(pThis->m_pPageMgr && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {\r
1591             pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);\r
1592             if(pFormNode == NULL && pLayoutContext && pLayoutContext->m_pOverflowProcessor) {\r
1593                 pFormNode = pLayoutContext->m_pOverflowNode;\r
1594                 bUseInherited = TRUE;\r
1595             }\r
1596             if(pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, FALSE)) {\r
1597                 if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {\r
1598                     if(pOverflowTrailerNode) {\r
1599                         CXFA_ItemLayoutProcessor *pOverflowLeaderProcessor = FX_NEW CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);\r
1600 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1601                         pOverflowLeaderProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;\r
1602 #endif\r
1603                         pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
1604                         pTrailerLayoutItem = pOverflowLeaderProcessor->HasLayoutItem() ? pOverflowLeaderProcessor->ExtractLayoutItem() : NULL;\r
1605                         delete pOverflowLeaderProcessor;\r
1606                     }\r
1607                     if(bUseInherited) {\r
1608                         bIsAddTrailerHeight = pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);\r
1609                     } else {\r
1610                         bIsAddTrailerHeight = pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);\r
1611                     }\r
1612                     if(bIsAddTrailerHeight) {\r
1613                         FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;\r
1614                         fChildHeight += fTrailerHeight;\r
1615                         bIsAddTrailerHeight = TRUE;\r
1616                     }\r
1617                 }\r
1618             }\r
1619         }\r
1620         if(!bTakeSpace || fContentCurRowY + fChildHeight <= fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||\r
1621                 (!bContainerHeightAutoSize && pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= fContainerHeight)) {\r
1622             if(!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1623                 if(pProcessor->m_bUseInheriated) {\r
1624                     if(pTrailerLayoutItem) {\r
1625                         XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);\r
1626                     }\r
1627                     if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1628                         XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1629                     }\r
1630                     pProcessor->m_bUseInheriated = FALSE;\r
1631                 } else {\r
1632                     if(bIsAddTrailerHeight) {\r
1633                         fChildHeight -= pTrailerLayoutItem->m_sSize.y;\r
1634                     }\r
1635                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1636                 }\r
1637                 CXFA_ContentLayoutItemImpl* pChildLayoutItem = pProcessor->ExtractLayoutItem();\r
1638                 if(XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {\r
1639                     pThis->m_arrayKeepItems.Add(pChildLayoutItem);\r
1640                 } else {\r
1641                     pThis->m_arrayKeepItems.RemoveAll();\r
1642                 }\r
1643                 rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);\r
1644                 bAddedItemInRow = TRUE;\r
1645                 if(bTakeSpace) {\r
1646                     fContentCurRowAvailWidth -= fChildWidth;\r
1647                     if(fContentCurRowHeight < fChildHeight ) {\r
1648                         fContentCurRowHeight = fChildHeight;\r
1649                     }\r
1650                 }\r
1651                 return XFA_ItemLayoutProcessorResult_Done;\r
1652             } else {\r
1653                 if(eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {\r
1654                     if(pProcessor->m_bUseInheriated) {\r
1655                         if(pTrailerLayoutItem) {\r
1656                             XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);\r
1657                         }\r
1658                         if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1659                             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1660                         }\r
1661                         pProcessor->m_bUseInheriated = FALSE;\r
1662                     } else {\r
1663                         if(bIsAddTrailerHeight) {\r
1664                             fChildHeight -= pTrailerLayoutItem->m_sSize.y;\r
1665                         }\r
1666                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1667                     }\r
1668                 }\r
1669                 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1670                 bAddedItemInRow = TRUE;\r
1671                 fContentCurRowAvailWidth -= fChildWidth;\r
1672                 if(fContentCurRowHeight < fChildHeight ) {\r
1673                     fContentCurRowHeight = fChildHeight;\r
1674                 }\r
1675                 return eRetValue;\r
1676             }\r
1677         } else {\r
1678             XFA_ItemLayoutProcessorResult eResult;\r
1679             if(pThis->ProcessKeepForSplite(pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],\r
1680                                            fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, bAddedItemInRow, bForceEndPage, eResult)) {\r
1681                 return eResult;\r
1682             }\r
1683             bForceEndPage = TRUE;\r
1684             FX_FLOAT fSplitPos = pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);\r
1685             if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1686                 XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1687                 if(eLayout == XFA_ATTRIBUTEENUM_Tb && eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1688                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1689                     rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1690                     bAddedItemInRow = TRUE;\r
1691                     if(bTakeSpace) {\r
1692                         fContentCurRowAvailWidth -= fChildWidth;\r
1693                         if(fContentCurRowHeight < fChildHeight ) {\r
1694                             fContentCurRowHeight = fChildHeight;\r
1695                         }\r
1696                     }\r
1697                     return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1698                 }\r
1699                 CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;\r
1700                 if(pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {\r
1701                     pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);\r
1702                 }\r
1703                 if(pTrailerLayoutItem && bIsAddTrailerHeight) {\r
1704                     XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);\r
1705                 } else {\r
1706                     pProcessor->SplitLayoutItem(fSplitPos);\r
1707                 }\r
1708                 if(bUseInherited) {\r
1709                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1710                     pThis->m_bUseInheriated = TRUE;\r
1711                 } else {\r
1712                     if(pProcessor->m_pLayoutItem->m_pFirstChild && pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling == NULL\r
1713                             && pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {\r
1714                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1715                     } else {\r
1716                         if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1717                             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1718                         }\r
1719                     }\r
1720                 }\r
1721                 if(pProcessor->m_pLayoutItem->m_pNextSibling) {\r
1722                     pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1723                     rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1724                     bAddedItemInRow = TRUE;\r
1725                     if(bTakeSpace) {\r
1726                         fContentCurRowAvailWidth -= fChildWidth;\r
1727                         if(fContentCurRowHeight < fChildHeight ) {\r
1728                             fContentCurRowHeight = fChildHeight;\r
1729                         }\r
1730                     }\r
1731                 }\r
1732                 return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1733             } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {\r
1734                 pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1735                 if(pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {\r
1736                     CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;\r
1737                     if(pThis->m_pPageMgr) {\r
1738                         if(pFormNode == NULL && pLayoutContext != NULL) {\r
1739                             pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;\r
1740                         }\r
1741                         pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);\r
1742                     }\r
1743                     if(bUseInherited) {\r
1744                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1745                         pThis->m_bUseInheriated = TRUE;\r
1746                     }\r
1747                     return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1748                 }\r
1749                 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1750                 bAddedItemInRow = TRUE;\r
1751                 if(bTakeSpace) {\r
1752                     fContentCurRowAvailWidth -= fChildWidth;\r
1753                     if(fContentCurRowHeight < fChildHeight ) {\r
1754                         fContentCurRowHeight = fChildHeight;\r
1755                     }\r
1756                 }\r
1757                 if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1758                     bForceEndPage = FALSE;\r
1759                 }\r
1760                 return eRetValue;\r
1761             } else {\r
1762                 XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1763                 if(pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && eLayout == XFA_ATTRIBUTEENUM_Tb) {\r
1764                     if(pThis->m_pPageMgr) {\r
1765                         pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);\r
1766                     }\r
1767                     if(pTrailerLayoutItem) {\r
1768                         XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem);\r
1769                     }\r
1770                     if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1771                         XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1772                     }\r
1773                 } else {\r
1774                     if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1775                         if(pFormNode == NULL && pLayoutContext != NULL) {\r
1776                             pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;\r
1777                         }\r
1778                         if(pThis->m_pPageMgr) {\r
1779                             pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);\r
1780                         }\r
1781                         if(bUseInherited) {\r
1782                             pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1783                             pThis->m_bUseInheriated = TRUE;\r
1784                         }\r
1785                     }\r
1786                 }\r
1787                 return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1788             }\r
1789         }\r
1790     } else {\r
1791         return XFA_ItemLayoutProcessorResult_RowFullBreak;\r
1792     }\r
1793     return XFA_ItemLayoutProcessorResult_Done;\r
1794 }\r
1795 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(FX_BOOL bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext, FX_BOOL bRootForceTb)\r
1796 {\r
1797     m_bHasAvailHeight = TRUE;\r
1798     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
1799     FX_BOOL bBreakDone = FALSE;\r
1800     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
1801     FX_BOOL  bForceEndPage = FALSE;\r
1802     FX_BOOL  bIsManualBreak = FALSE;\r
1803     if(m_pCurChildPreprocessor) {\r
1804         m_pCurChildPreprocessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;\r
1805     }\r
1806     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
1807     if (pContext && pContext->m_bCurColumnWidthAvaiable) {\r
1808         bContainerWidthAutoSize = FALSE;\r
1809         fContainerWidth = pContext->m_fCurColumnWidth;\r
1810     }\r
1811     if(!bContainerHeightAutoSize) {\r
1812         fContainerHeight -= m_fUsedSize;\r
1813     }\r
1814     if(!bContainerHeightAutoSize) {\r
1815         CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);\r
1816         FX_BOOL bFocrTb = FALSE;\r
1817         if(pParentNode && XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) == XFA_ATTRIBUTEENUM_Row) {\r
1818             CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);\r
1819             if(pChildContainer && pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode)) {\r
1820                 fContainerHeight = 0;\r
1821                 bContainerHeightAutoSize = TRUE;\r
1822             }\r
1823         }\r
1824     }\r
1825     CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1826     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1827     if(pMarginNode) {\r
1828         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1829         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1830         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1831         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1832     }\r
1833     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
1834     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
1835     FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;\r
1836     if(fAvailHeight < 0) {\r
1837         m_bHasAvailHeight = FALSE;\r
1838     }\r
1839     fRealHeight = fRealHeight - fTopInset - fBottomInset;\r
1840     FX_FLOAT fContentCurRowY = 0;\r
1841     CXFA_ContentLayoutItemImpl* pLayoutChild = NULL;\r
1842     if(m_pLayoutItem != NULL) {\r
1843         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done && eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {\r
1844             pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;\r
1845             for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1846                 if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {\r
1847                     pLayoutChild = pLayoutNext;\r
1848                 }\r
1849             }\r
1850         }\r
1851         for(CXFA_ContentLayoutItemImpl* pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutTempChild != pLayoutChild; pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)pLayoutTempChild->m_pNextSibling) {\r
1852             if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutTempChild->m_pFormNode)) {\r
1853                 FX_FLOAT fChildContentWidth = pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;\r
1854                 FX_FLOAT fChildContentHeight = pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;\r
1855                 if(fContentCalculatedWidth < fChildContentWidth) {\r
1856                     fContentCalculatedWidth = fChildContentWidth;\r
1857                 }\r
1858                 if(fContentCalculatedHeight < fChildContentHeight) {\r
1859                     fContentCalculatedHeight = fChildContentHeight;\r
1860                 }\r
1861             }\r
1862         }\r
1863         if (pLayoutChild) {\r
1864             fContentCurRowY = pLayoutChild->m_sPos.y;\r
1865         } else {\r
1866             fContentCurRowY = fContentCalculatedHeight;\r
1867         }\r
1868     }\r
1869     fContentCurRowY += InsertKeepLayoutItems();\r
1870     if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {\r
1871         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
1872     }\r
1873     fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);\r
1874     if(m_pCurChildPreprocessor && m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {\r
1875         if(XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {\r
1876             m_pKeepHeadNode = m_pCurChildNode;\r
1877             m_bIsProcessKeep = TRUE;\r
1878             m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;\r
1879         }\r
1880     }\r
1881     while(m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {\r
1882         FX_FLOAT fContentCurRowHeight = 0;\r
1883         FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;\r
1884         m_fWidthLimite = fContentCurRowAvailWidth;\r
1885         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgCurLineLayoutItems[3];\r
1886         uint8_t uCurHAlignState = (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);\r
1887         if (pLayoutChild) {\r
1888             for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1889                 if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {\r
1890                     pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;\r
1891                     m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;\r
1892                     break;\r
1893                 }\r
1894                 uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));\r
1895                 rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);\r
1896                 if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {\r
1897                     if (uHAlign > uCurHAlignState) {\r
1898                         uCurHAlignState = uHAlign;\r
1899                     }\r
1900                 } else if (uHAlign < uCurHAlignState) {\r
1901                     uCurHAlignState = uHAlign;\r
1902                 }\r
1903                 if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {\r
1904                     if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {\r
1905                         fContentCurRowHeight = pLayoutNext->m_sSize.y;\r
1906                     }\r
1907                     fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;\r
1908                 }\r
1909             }\r
1910             if ((CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild == pLayoutChild) {\r
1911                 m_pLayoutItem->m_pFirstChild = NULL;\r
1912             } else {\r
1913                 CXFA_ContentLayoutItemImpl* pLayoutNext = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;\r
1914                 for (; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1915                     if ((CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling == pLayoutChild) {\r
1916                         pLayoutNext->m_pNextSibling = NULL;\r
1917                         break;\r
1918                     }\r
1919                 }\r
1920             }\r
1921             CXFA_ContentLayoutItemImpl* pLayoutNextTemp = (CXFA_ContentLayoutItemImpl*)pLayoutChild;\r
1922             while (pLayoutNextTemp) {\r
1923                 pLayoutNextTemp->m_pParent = NULL;\r
1924                 CXFA_ContentLayoutItemImpl* pSaveLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNextTemp->m_pNextSibling;\r
1925                 pLayoutNextTemp->m_pNextSibling = NULL;\r
1926                 pLayoutNextTemp = pSaveLayoutNext;\r
1927             }\r
1928             pLayoutChild = NULL;\r
1929         }\r
1930         while(m_pCurChildNode) {\r
1931             CXFA_ItemLayoutProcessor* pProcessor = NULL;\r
1932             FX_BOOL bAddedItemInRow = FALSE;\r
1933             fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);\r
1934             switch(m_nCurChildNodeStage) {\r
1935                 case XFA_ItemLayoutProcessorStages_Keep:\r
1936                 case XFA_ItemLayoutProcessorStages_None:\r
1937                     break;\r
1938                 case XFA_ItemLayoutProcessorStages_BreakBefore: {\r
1939                         for(int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize(); iIndex++) {\r
1940                             CXFA_ContentLayoutItemImpl* pItem = m_arrayKeepItems.GetAt(iIndex);\r
1941                             m_pLayoutItem->RemoveChild(pItem);\r
1942                             fContentCalculatedHeight -= pItem->m_sSize.y;\r
1943                         }\r
1944                         CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;\r
1945                         FX_BOOL bCreatePage = FALSE;\r
1946                         if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form\r
1947                                 && bCreatePage) {\r
1948                             if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
1949                                 XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);\r
1950                             }\r
1951                             if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {\r
1952                                 if(m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == XFA_ELEMENT_Form && m_pLayoutItem == NULL) {\r
1953                                     XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode, TRUE);\r
1954                                 } else {\r
1955                                     CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);\r
1956 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1957                                     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1958 #endif\r
1959                                     XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1960                                             rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
1961                                             fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
1962                                     delete pProcessor;\r
1963                                     pProcessor = NULL;\r
1964                                 }\r
1965                             }\r
1966                             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
1967                             bForceEndPage = TRUE;\r
1968                             bIsManualBreak = TRUE;\r
1969                             goto SuspendAndCreateNewRow;\r
1970                         }\r
1971                     }\r
1972                     break;\r
1973                 case XFA_ItemLayoutProcessorStages_BreakAfter: {\r
1974                         XFA_ItemLayoutProcessorResult eResult;\r
1975                         CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;\r
1976                         FX_BOOL bCreatePage = FALSE;\r
1977                         if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {\r
1978                             if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {\r
1979                                 CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);\r
1980 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1981                                 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1982 #endif\r
1983                                 eResult = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1984                                           rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
1985                                           fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
1986                                 delete pProcessor;\r
1987                                 pProcessor = NULL;\r
1988                             }\r
1989                             if(!bCreatePage) {\r
1990                                 if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
1991                                     CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,\r
1992                                                               fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);\r
1993                                     rgCurLineLayoutItems->RemoveAll();\r
1994                                     CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, NULL);\r
1995 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1996                                     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1997 #endif\r
1998                                     XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1999                                             rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2000                                             fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
2001                                     delete pProcessor;\r
2002                                     pProcessor = NULL;\r
2003                                 }\r
2004                             } else {\r
2005                                 if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
2006                                     XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);\r
2007                                 }\r
2008                             }\r
2009                             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
2010                             if(bCreatePage) {\r
2011                                 bForceEndPage = TRUE;\r
2012                                 bIsManualBreak = TRUE;\r
2013                                 if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {\r
2014                                     bBreakDone = TRUE;\r
2015                                 }\r
2016                             }\r
2017                             goto SuspendAndCreateNewRow;\r
2018                         }\r
2019                     }\r
2020                     break;\r
2021                 case XFA_ItemLayoutProcessorStages_BookendLeader: {\r
2022                         CXFA_Node* pLeaderNode = NULL;\r
2023                         if (m_pCurChildPreprocessor) {\r
2024                             pProcessor = m_pCurChildPreprocessor;\r
2025                             m_pCurChildPreprocessor = NULL;\r
2026                         } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, TRUE, pLeaderNode)) {\r
2027                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);\r
2028 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2029                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2030 #endif\r
2031                         }\r
2032                         if(pProcessor) {\r
2033                             if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2034                                     rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2035                                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {\r
2036                                 goto SuspendAndCreateNewRow;\r
2037                             } else {\r
2038                                 delete pProcessor;\r
2039                                 pProcessor = NULL;\r
2040                             }\r
2041                         }\r
2042                     }\r
2043                     break;\r
2044                 case XFA_ItemLayoutProcessorStages_BookendTrailer: {\r
2045                         CXFA_Node* pTrailerNode = NULL;\r
2046                         if (m_pCurChildPreprocessor) {\r
2047                             pProcessor = m_pCurChildPreprocessor;\r
2048                             m_pCurChildPreprocessor = NULL;\r
2049                         } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, FALSE, pTrailerNode)) {\r
2050                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);\r
2051 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2052                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2053 #endif\r
2054                         }\r
2055                         if(pProcessor) {\r
2056                             if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2057                                     rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2058                                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {\r
2059                                 goto SuspendAndCreateNewRow;\r
2060                             } else {\r
2061                                 delete pProcessor;\r
2062                                 pProcessor = NULL;\r
2063                             }\r
2064                         }\r
2065                     }\r
2066                     break;\r
2067                 case XFA_ItemLayoutProcessorStages_Container:\r
2068                     ASSERT(m_pCurChildNode->IsContainerNode());\r
2069                     if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
2070                         break;\r
2071                     }\r
2072                     if(fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION && XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {\r
2073                         bForceEndPage = TRUE;\r
2074                         goto SuspendAndCreateNewRow;\r
2075                     }\r
2076                     if(m_pCurChildNode->IsContainerNode()) {\r
2077                         FX_BOOL bNewRow = FALSE;\r
2078                         if (m_pCurChildPreprocessor) {\r
2079                             pProcessor = m_pCurChildPreprocessor;\r
2080                             m_pCurChildPreprocessor = NULL;\r
2081                             bNewRow = TRUE;\r
2082                         } else {\r
2083                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
2084 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2085                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2086 #endif\r
2087                         }\r
2088                         XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);\r
2089                         XFA_ItemLayoutProcessorResult rs = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2090                                                            rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2091                                                            fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext, bNewRow);\r
2092                         switch(rs) {\r
2093                             case XFA_ItemLayoutProcessorResult_ManualBreak:\r
2094                                 bIsManualBreak = TRUE;\r
2095                             case XFA_ItemLayoutProcessorResult_PageFullBreak:\r
2096                                 bForceEndPage = TRUE;\r
2097                             case XFA_ItemLayoutProcessorResult_RowFullBreak:\r
2098                                 goto SuspendAndCreateNewRow;\r
2099                             case XFA_ItemLayoutProcessorResult_Done:\r
2100                             default:\r
2101                                 fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);\r
2102                                 delete pProcessor;\r
2103                                 pProcessor = NULL;\r
2104                         }\r
2105                     }\r
2106                     break;\r
2107                 case XFA_ItemLayoutProcessorStages_Done:\r
2108                     break;\r
2109                 default:\r
2110                     break;\r
2111             }\r
2112             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
2113             if(bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {\r
2114                 break;\r
2115             } else {\r
2116                 continue;\r
2117             }\r
2118 SuspendAndCreateNewRow:\r
2119             if (pProcessor) {\r
2120                 m_pCurChildPreprocessor = pProcessor;\r
2121             }\r
2122             break;\r
2123         }\r
2124         CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,\r
2125                                   fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit, bRootForceTb);\r
2126         m_fWidthLimite = fContentCurRowAvailWidth;\r
2127         if(bForceEndPage) {\r
2128             break;\r
2129         }\r
2130     }\r
2131     FX_BOOL bRetValue = (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && m_rgPendingNodes.GetCount() == 0);\r
2132     if(bBreakDone) {\r
2133         bRetValue = FALSE;\r
2134     }\r
2135     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
2136     if(fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || bRetValue) {\r
2137         if(m_pLayoutItem == NULL) {\r
2138             m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2139         }\r
2140         if(fContainerHeight < 0 ) {\r
2141             fContainerHeight = 0;\r
2142         }\r
2143         SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
2144         if(bForceEndPage) {\r
2145             m_fUsedSize = 0;\r
2146         } else {\r
2147             m_fUsedSize += m_pLayoutItem->m_sSize.y;\r
2148         }\r
2149     }\r
2150     return bRetValue ? XFA_ItemLayoutProcessorResult_Done : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak : XFA_ItemLayoutProcessorResult_PageFullBreak);\r
2151 }\r
2152 FX_BOOL    CXFA_ItemLayoutProcessor::CalculateRowChildPosition(CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>(&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, FX_BOOL bContainerHeightAutoSize,\r
2153         FX_BOOL bContainerWidthAutoSize, FX_FLOAT& fContentCalculatedWidth, FX_FLOAT& fContentCalculatedHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit,  FX_BOOL bRootForceTb)\r
2154 {\r
2155     int32_t nGroupLengths[3] = {0, 0, 0};\r
2156     FX_FLOAT  fGroupWidths[3] = {0, 0, 0};\r
2157     int32_t nTotalLength = 0;\r
2158     for(int32_t i = 0; i < 3; i ++) {\r
2159         nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();\r
2160         for(int32_t c = nGroupLengths[i], j = 0; j < c; j++) {\r
2161             nTotalLength++;\r
2162             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[i][j]->m_pFormNode)) {\r
2163                 fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;\r
2164             }\r
2165         }\r
2166     }\r
2167     if(!nTotalLength) {\r
2168         if(bContainerHeightAutoSize) {\r
2169             FX_FLOAT fNewHeight = fContentCurRowY;\r
2170             if(fContentCalculatedHeight > fNewHeight) {\r
2171                 fContentCalculatedHeight = fNewHeight;\r
2172             }\r
2173         }\r
2174         return FALSE;\r
2175     }\r
2176     if(m_pLayoutItem == NULL) {\r
2177         m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2178     }\r
2179     if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {\r
2180         FX_FLOAT fCurPos;\r
2181         fCurPos = 0;\r
2182         for(int32_t c = nGroupLengths[0], j = 0; j < c; j++) {\r
2183             if(bRootForceTb) {\r
2184                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2185                 CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode, rgCurLineLayoutItems[0][j]->m_sSize.x, rgCurLineLayoutItems[0][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2186                 rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2187             } else {\r
2188                 rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2189                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {\r
2190                     fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;\r
2191                 }\r
2192             }\r
2193             m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);\r
2194             m_fLastRowWidth = fCurPos;\r
2195         }\r
2196         fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] - fGroupWidths[2]) / 2;\r
2197         for(int32_t c = nGroupLengths[1], j = 0; j < c; j++) {\r
2198             if(bRootForceTb) {\r
2199                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2200                 CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode, rgCurLineLayoutItems[1][j]->m_sSize.x, rgCurLineLayoutItems[1][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2201                 rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2202             } else {\r
2203                 rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2204                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {\r
2205                     fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;\r
2206                 }\r
2207             }\r
2208             m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);\r
2209             m_fLastRowWidth = fCurPos;\r
2210         }\r
2211         fCurPos = fContentWidthLimit - fGroupWidths[2];\r
2212         for(int32_t c = nGroupLengths[2], j = 0; j < c; j++) {\r
2213             if(bRootForceTb) {\r
2214                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2215                 CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode, rgCurLineLayoutItems[2][j]->m_sSize.x, rgCurLineLayoutItems[2][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2216                 rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2217             } else {\r
2218                 rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2219                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {\r
2220                     fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;\r
2221                 }\r
2222             }\r
2223             m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);\r
2224             m_fLastRowWidth = fCurPos;\r
2225         }\r
2226     } else {\r
2227         FX_FLOAT fCurPos;\r
2228         fCurPos = fGroupWidths[0];\r
2229         for(int32_t c = nGroupLengths[0], j = 0; j < c; j++) {\r
2230             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {\r
2231                 fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;\r
2232             }\r
2233             rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2234             m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);\r
2235             m_fLastRowWidth = fCurPos;\r
2236         }\r
2237         fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] - fGroupWidths[2]) / 2;\r
2238         for(int32_t c = nGroupLengths[1], j = 0; j < c; j++) {\r
2239             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {\r
2240                 fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;\r
2241             }\r
2242             rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2243             m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);\r
2244             m_fLastRowWidth = fCurPos;\r
2245         }\r
2246         fCurPos = fContentWidthLimit;\r
2247         for(int32_t c = nGroupLengths[2], j = 0; j < c; j++) {\r
2248             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {\r
2249                 fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;\r
2250             }\r
2251             rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2252             m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);\r
2253             m_fLastRowWidth = fCurPos;\r
2254         }\r
2255     }\r
2256     m_fLastRowY = fContentCurRowY;\r
2257     fContentCurRowY += fContentCurRowHeight;\r
2258     if(bContainerWidthAutoSize) {\r
2259         FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];\r
2260         if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
2261             fChildSuppliedWidth = fContentWidthLimit;\r
2262         }\r
2263         if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
2264             fContentCalculatedWidth = fChildSuppliedWidth;\r
2265         }\r
2266     }\r
2267     if(bContainerHeightAutoSize) {\r
2268         FX_FLOAT fChildSuppliedHeight = fContentCurRowY;\r
2269         if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
2270             fContentCalculatedHeight = fChildSuppliedHeight;\r
2271         }\r
2272     }\r
2273     return TRUE;\r
2274 }\r
2275 CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(CXFA_Node* pSubformSet)\r
2276 {\r
2277     if(pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {\r
2278         CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);\r
2279         while(pParent) {\r
2280             if(pParent->GetClassID() != XFA_ELEMENT_SubformSet) {\r
2281                 return pParent;\r
2282             }\r
2283             pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);\r
2284         }\r
2285     }\r
2286     return pSubformSet;\r
2287 }\r
2288 void CXFA_ItemLayoutProcessor::DoLayoutField()\r
2289 {\r
2290     if(m_pLayoutItem != NULL) {\r
2291         return;\r
2292     }\r
2293     ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);\r
2294     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2295     if (!m_pLayoutItem) {\r
2296         return;\r
2297     }\r
2298     CXFA_Document* pDocument = m_pFormNode->GetDocument();\r
2299     IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();\r
2300     FX_FLOAT fHeight = -1;\r
2301     FX_FLOAT fWidth = -1;\r
2302     pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);\r
2303     int32_t nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
2304     nRotate = XFA_MapRotation(nRotate);\r
2305     if(nRotate == 90 || nRotate == 270) {\r
2306         FX_FLOAT fTmp = fWidth;\r
2307         fWidth = fHeight;\r
2308         fHeight = fTmp;\r
2309     }\r
2310     SetCurrentComponentSize(fWidth, fHeight);\r
2311 }\r
2312 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(FX_BOOL bUseBreakControl, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext)\r
2313 {\r
2314     XFA_ELEMENT eClassID = m_pFormNode->GetClassID();\r
2315     switch(eClassID) {\r
2316         case XFA_ELEMENT_Subform:\r
2317         case XFA_ELEMENT_Area:\r
2318         case XFA_ELEMENT_ExclGroup:\r
2319         case XFA_ELEMENT_SubformSet: {\r
2320                 FX_BOOL bRootForceTb = FALSE;\r
2321                 CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);\r
2322                 XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);\r
2323                 switch(eLayoutStrategy) {\r
2324                     case XFA_ATTRIBUTEENUM_Tb:\r
2325                     case XFA_ATTRIBUTEENUM_Lr_tb:\r
2326                     case XFA_ATTRIBUTEENUM_Rl_tb:\r
2327                         return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy, fHeightLimit, fRealHeight, pContext, bRootForceTb);\r
2328                     case XFA_ATTRIBUTEENUM_Position:\r
2329                     case XFA_ATTRIBUTEENUM_Row:\r
2330                     case XFA_ATTRIBUTEENUM_Rl_row:\r
2331                     default:\r
2332                         DoLayoutPositionedContainer(pContext);\r
2333                         m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2334                         return XFA_ItemLayoutProcessorResult_Done;\r
2335                     case XFA_ATTRIBUTEENUM_Table:\r
2336                         DoLayoutTableContainer(pLayoutNode);\r
2337                         m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2338                         return XFA_ItemLayoutProcessorResult_Done;\r
2339                 }\r
2340             }\r
2341         case XFA_ELEMENT_Draw:\r
2342         case XFA_ELEMENT_Field:\r
2343             DoLayoutField();\r
2344             m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2345             return XFA_ItemLayoutProcessorResult_Done;\r
2346         case XFA_ELEMENT_ContentArea:\r
2347             return XFA_ItemLayoutProcessorResult_Done;\r
2348         default:\r
2349             return XFA_ItemLayoutProcessorResult_Done;\r
2350     }\r
2351 }\r
2352 void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)\r
2353 {\r
2354     ASSERT(m_pLayoutItem);\r
2355     fAbsoluteX = m_pLayoutItem->m_sPos.x;\r
2356     fAbsoluteY = m_pLayoutItem->m_sPos.y;\r
2357 }\r
2358 void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight)\r
2359 {\r
2360     ASSERT(m_pLayoutItem);\r
2361     fWidth = m_pLayoutItem->m_sSize.x;\r
2362     fHeight = m_pLayoutItem->m_sSize.y;\r
2363 }\r
2364 void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY)\r
2365 {\r
2366     ASSERT(m_pLayoutItem);\r
2367     m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2368 }\r
2369 void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight)\r
2370 {\r
2371     ASSERT(m_pLayoutItem);\r
2372     m_pLayoutItem->m_sSize.Set(fWidth, fHeight);\r
2373 }\r
2374 FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode)\r
2375 {\r
2376     if(pFormNode == NULL) {\r
2377         return FALSE;\r
2378     }\r
2379     CXFA_Node* pTemplate = pFormNode->GetTemplateNode();\r
2380     if (!pTemplate) {\r
2381         pTemplate = pFormNode;\r
2382     }\r
2383     CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur);\r
2384     int32_t iMax = NodeOccur.GetMax();\r
2385     if (iMax > -1) {\r
2386         int32_t iCount = (int32_t)(uintptr_t)m_PendingNodesCount.GetValueAt(pTemplate);\r
2387         if (iCount >= iMax) {\r
2388             return FALSE;\r
2389         }\r
2390         iCount++;\r
2391         m_PendingNodesCount.SetAt(pTemplate, (FX_LPVOID)(uintptr_t)(iCount));\r
2392         return TRUE;\r
2393     }\r
2394     return TRUE;\r
2395 }\r