Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[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(FX_INT32 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     FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);\r
716     FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);\r
717     FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
718     nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360) / 90;\r
719     XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);\r
720     FX_INT32 nAnchorType = 0;\r
721     switch(eAnchorType) {\r
722         case XFA_ATTRIBUTEENUM_TopLeft:\r
723             nAnchorType = 0;\r
724             break;\r
725         case XFA_ATTRIBUTEENUM_TopCenter:\r
726             nAnchorType = 1;\r
727             break;\r
728         case XFA_ATTRIBUTEENUM_TopRight:\r
729             nAnchorType = 2;\r
730             break;\r
731         case XFA_ATTRIBUTEENUM_MiddleLeft:\r
732             nAnchorType = 3;\r
733             break;\r
734         case XFA_ATTRIBUTEENUM_MiddleCenter:\r
735             nAnchorType = 4;\r
736             break;\r
737         case XFA_ATTRIBUTEENUM_MiddleRight:\r
738             nAnchorType = 5;\r
739             break;\r
740         case XFA_ATTRIBUTEENUM_BottomLeft:\r
741             nAnchorType = 6;\r
742             break;\r
743         case XFA_ATTRIBUTEENUM_BottomCenter:\r
744             nAnchorType = 7;\r
745             break;\r
746         case XFA_ATTRIBUTEENUM_BottomRight:\r
747             nAnchorType = 8;\r
748             break;\r
749         default:\r
750             break;\r
751     }\r
752     static const FX_UINT8 nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, {6, 3, 0, 7, 4, 1, 8, 5, 2}, {8, 7, 6, 5, 4, 3, 2, 1, 0}, {2, 5, 8, 1, 4, 7, 0, 3, 6}};\r
753     FX_INT32 nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];\r
754     fAbsoluteX = fAnchorX;\r
755     fAbsoluteY = fAnchorY;\r
756     switch(nAbsoluteAnchorType / 3) {\r
757         case 1:\r
758             fAbsoluteY -= fHeight / 2;\r
759             break;\r
760         case 2:\r
761             fAbsoluteY -= fHeight;\r
762             break;\r
763         default:\r
764             break;\r
765     }\r
766     switch(nAbsoluteAnchorType % 3) {\r
767         case 1:\r
768             fAbsoluteX -= fWidth / 2;\r
769             break;\r
770         case 2:\r
771             fAbsoluteX -= fWidth;\r
772             break;\r
773         default:\r
774             break;\r
775     }\r
776 }\r
777 static FX_BOOL XFA_ItemLayoutProcessor_FloatAlmostEqual(FX_FLOAT f1, FX_FLOAT f2)\r
778 {\r
779     return f1 >= f2 - XFA_LAYOUT_FLOAT_PERCISION && f1 <= f2 + XFA_LAYOUT_FLOAT_PERCISION;\r
780 }\r
781 static FX_BOOL XFA_ItemLayoutProcessor_FloatGreaterThan(FX_FLOAT f1, FX_FLOAT f2)\r
782 {\r
783     return f1 > f2 + XFA_LAYOUT_FLOAT_PERCISION;\r
784 }\r
785 static FX_BOOL XFA_ItemLayoutProcessor_FloatLessThan(FX_FLOAT f1, FX_FLOAT f2)\r
786 {\r
787     return f1 < f2 - XFA_LAYOUT_FLOAT_PERCISION;\r
788 }\r
789 FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node *pNode, CXFA_Node *pParentNode)\r
790 {\r
791     return FALSE;\r
792 }\r
793 void CXFA_ItemLayoutProcessor::DoLayoutPageArea(CXFA_ContainerLayoutItemImpl* pPageAreaLayoutItem)\r
794 {\r
795     CXFA_Node *pFormNode = pPageAreaLayoutItem->m_pFormNode;\r
796     CXFA_Node *pCurChildNode = XFA_LAYOUT_INVALIDNODE;\r
797     XFA_ItemLayoutProcessorStages nCurChildNodeStage = XFA_ItemLayoutProcessorStages_None;\r
798     CXFA_LayoutItemImpl* pBeforeItem = NULL;\r
799     for(XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);\r
800             pCurChildNode;\r
801             XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {\r
802         if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
803             continue;\r
804         }\r
805         if(pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
806             continue;\r
807         }\r
808         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pCurChildNode, NULL);\r
809 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
810         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
811 #endif\r
812         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
813         if(!pProcessor->HasLayoutItem()) {\r
814             delete pProcessor;\r
815             continue;\r
816         }\r
817         FX_FLOAT fWidth, fHeight;\r
818         pProcessor->GetCurrentComponentSize(fWidth, fHeight);\r
819         FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;\r
820         CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);\r
821         pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);\r
822         CXFA_LayoutItemImpl* pProcessItem = pProcessor->ExtractLayoutItem();\r
823         if(pBeforeItem == NULL) {\r
824             pPageAreaLayoutItem->AddHeadChild(pProcessItem);\r
825         } else {\r
826             pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);\r
827         }\r
828         pBeforeItem = pProcessItem;\r
829         delete pProcessor;\r
830     }\r
831     pBeforeItem = NULL;\r
832     CXFA_LayoutItemImpl* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;\r
833     while (pLayoutItem) {\r
834         if (!pLayoutItem->IsContentLayoutItem() || pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {\r
835             pLayoutItem = pLayoutItem->m_pNextSibling;\r
836             continue;\r
837         }\r
838         if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {\r
839             CXFA_LayoutItemImpl* pNextLayoutItem = pLayoutItem->m_pNextSibling;\r
840             pPageAreaLayoutItem->RemoveChild(pLayoutItem);\r
841             if (pBeforeItem == NULL) {\r
842                 pPageAreaLayoutItem->AddHeadChild(pLayoutItem);\r
843             } else {\r
844                 pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);\r
845             }\r
846             pBeforeItem = pLayoutItem;\r
847             pLayoutItem = pNextLayoutItem;\r
848         }\r
849     }\r
850 }\r
851 void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(CXFA_LayoutContext* pContext)\r
852 {\r
853     if(m_pLayoutItem != NULL) {\r
854         return;\r
855     }\r
856     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
857     FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) != XFA_ATTRIBUTEENUM_Position);\r
858     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
859     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
860     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
861     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
862     FX_FLOAT fHiddenContentCalculatedWidth = 0, fHiddenContentCalculatedHeight = 0;\r
863     if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {\r
864         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);\r
865     }\r
866     FX_INT32 iColIndex = 0;\r
867     for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {\r
868         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
869             continue;\r
870         }\r
871         if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
872             continue;\r
873         }\r
874         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
875 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
876         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
877 #endif\r
878         if (pContext && pContext->m_prgSpecifiedColumnWidths) {\r
879             FX_INT32 iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
880             if (iColSpan <= pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {\r
881                 pContext->m_fCurColumnWidth = 0;\r
882                 pContext->m_bCurColumnWidthAvaiable = TRUE;\r
883                 if(iColSpan == -1) {\r
884                     iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();\r
885                 }\r
886                 for (FX_INT32 i = 0; i < iColSpan; i++) {\r
887                     pContext->m_fCurColumnWidth += pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);\r
888                 }\r
889                 if(pContext->m_fCurColumnWidth == 0) {\r
890                     pContext->m_bCurColumnWidthAvaiable = FALSE;\r
891                 }\r
892                 iColIndex += iColSpan;\r
893             }\r
894         }\r
895         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pContext);\r
896         if(!pProcessor->HasLayoutItem()) {\r
897             delete pProcessor;\r
898             continue;\r
899         }\r
900         FX_FLOAT fWidth, fHeight;\r
901         pProcessor->GetCurrentComponentSize(fWidth, fHeight);\r
902         FX_BOOL bChangeParentSize = FALSE;\r
903         if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {\r
904             bChangeParentSize = TRUE;\r
905         }\r
906         FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;\r
907         if(!bIgnoreXY) {\r
908             CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);\r
909         }\r
910         pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);\r
911         if(bContainerWidthAutoSize) {\r
912             FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;\r
913             if(bChangeParentSize) {\r
914                 if(fContentCalculatedWidth < fChildSuppliedWidth) {\r
915                     fContentCalculatedWidth = fChildSuppliedWidth;\r
916                 }\r
917             } else {\r
918                 if(fHiddenContentCalculatedWidth < fChildSuppliedWidth && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {\r
919                     fHiddenContentCalculatedWidth = fChildSuppliedWidth;\r
920                 }\r
921             }\r
922         }\r
923         if(bContainerHeightAutoSize) {\r
924             FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;\r
925             if(bChangeParentSize) {\r
926                 if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
927                     fContentCalculatedHeight = fChildSuppliedHeight;\r
928                 }\r
929             } else {\r
930                 if(fHiddenContentCalculatedHeight < fChildSuppliedHeight && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {\r
931                     fHiddenContentCalculatedHeight = fChildSuppliedHeight;\r
932                 }\r
933             }\r
934         }\r
935         m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());\r
936         delete pProcessor;\r
937     }\r
938     XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();\r
939     if(fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {\r
940         fContentCalculatedWidth = fHiddenContentCalculatedWidth;\r
941     }\r
942     if(fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {\r
943         fContentCalculatedHeight = fHiddenContentCalculatedHeight;\r
944     }\r
945     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
946     SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
947 }\r
948 static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT& fWidth, FX_FLOAT& fHeight)\r
949 {\r
950     CXFA_Node *pNode = pLayoutItem->m_pFormNode;\r
951     ASSERT(pNode);\r
952     XFA_ELEMENT eClassID = pNode->GetClassID();\r
953     switch(eClassID) {\r
954         case XFA_ELEMENT_Subform:\r
955         case XFA_ELEMENT_Area:\r
956         case XFA_ELEMENT_ExclGroup:\r
957         case XFA_ELEMENT_SubformSet: {\r
958                 if(fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {\r
959                     fWidth = pLayoutItem->m_sSize.x;\r
960                 }\r
961                 if(fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {\r
962                     fHeight = pLayoutItem->m_sSize.y;\r
963                 }\r
964                 break;\r
965             }\r
966         case XFA_ELEMENT_Draw:\r
967         case XFA_ELEMENT_Field: {\r
968                 pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(pNode, fWidth, fHeight);\r
969                 break;\r
970             }\r
971         default:\r
972             ASSERT(FALSE);\r
973     }\r
974 }\r
975 static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(CXFA_ContentLayoutItemImpl* pLayoutRow, const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, XFA_ATTRIBUTEENUM eLayout)\r
976 {\r
977     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
978     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
979     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
980     CXFA_Node* pMarginNode = pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
981     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
982     if(pMarginNode) {\r
983         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
984         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
985         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
986         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
987     }\r
988     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
989     FX_FLOAT fContentCurrentHeight = pLayoutRow->m_sSize.y - fTopInset - fBottomInset;\r
990     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
991     FX_FLOAT fCurrentColX = 0;\r
992     FX_INT32 nCurrentColIdx = 0;\r
993     FX_BOOL  bMetWholeRowCell = FALSE;\r
994     for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
995         FX_INT32 nOriginalColSpan = pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
996         FX_INT32 nColSpan = nOriginalColSpan;\r
997         FX_FLOAT fColSpanWidth = 0;\r
998         if(nColSpan == -1 || nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {\r
999             nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;\r
1000         }\r
1001         for(FX_INT32 i = 0; i < nColSpan; i ++) {\r
1002             fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];\r
1003         }\r
1004         if (nColSpan != nOriginalColSpan) {\r
1005             fColSpanWidth = bMetWholeRowCell ? 0 : FX_MAX(fColSpanWidth, pLayoutChild->m_sSize.y);\r
1006         }\r
1007         if(nOriginalColSpan == -1) {\r
1008             bMetWholeRowCell = TRUE;\r
1009         }\r
1010         pLayoutChild->m_sPos.Set(fCurrentColX, 0);\r
1011         pLayoutChild->m_sSize.x = fColSpanWidth;\r
1012         if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1013             fCurrentColX += fColSpanWidth;\r
1014             nCurrentColIdx += nColSpan;\r
1015             FX_FLOAT fNewHeight = bContainerHeightAutoSize ? -1 : fContentCurrentHeight;\r
1016             XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth, fNewHeight);\r
1017             pLayoutChild->m_sSize.y = fNewHeight;\r
1018             if(bContainerHeightAutoSize) {\r
1019                 FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;\r
1020                 if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
1021                     fContentCalculatedHeight = fChildSuppliedHeight;\r
1022                 }\r
1023             }\r
1024         }\r
1025     }\r
1026     if(bContainerHeightAutoSize) {\r
1027         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1028             XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);\r
1029             FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;\r
1030             pLayoutChild->m_sSize.y = fContentCalculatedHeight;\r
1031             CXFA_Node* pParaNode = pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);\r
1032             if(pParaNode && pLayoutChild->m_pFirstChild) {\r
1033                 FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;\r
1034                 XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);\r
1035                 switch(eVType) {\r
1036                     case XFA_ATTRIBUTEENUM_Middle:\r
1037                         fOffHeight = fOffHeight / 2;\r
1038                         break;\r
1039                     case XFA_ATTRIBUTEENUM_Bottom:\r
1040                         break;\r
1041                     case XFA_ATTRIBUTEENUM_Top:\r
1042                     default:\r
1043                         fOffHeight = 0;\r
1044                         break;\r
1045                 }\r
1046                 if(fOffHeight > 0) {\r
1047                     for(CXFA_ContentLayoutItemImpl* pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild; pInnerLayoutChild; pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pInnerLayoutChild->m_pNextSibling) {\r
1048                         pInnerLayoutChild->m_sPos.y += fOffHeight;\r
1049                     }\r
1050                 }\r
1051             }\r
1052         }\r
1053     }\r
1054     if(bContainerWidthAutoSize) {\r
1055         FX_FLOAT fChildSuppliedWidth = fCurrentColX;\r
1056         if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
1057             fChildSuppliedWidth = fContentWidthLimit;\r
1058         }\r
1059         if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
1060             fContentCalculatedWidth = fChildSuppliedWidth;\r
1061         }\r
1062     } else {\r
1063         fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;\r
1064     }\r
1065     if(pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == XFA_ATTRIBUTEENUM_Rl_row) {\r
1066         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1067             pLayoutChild->m_sPos.x = fContentCalculatedWidth - pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;\r
1068         }\r
1069     }\r
1070     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
1071     pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight);\r
1072 }\r
1073 void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode)\r
1074 {\r
1075     if(m_pLayoutItem != NULL) {\r
1076         return;\r
1077     }\r
1078     if(pLayoutNode == NULL) {\r
1079         pLayoutNode = m_pFormNode;\r
1080     }\r
1081     ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);\r
1082     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
1083     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
1084     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
1085     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
1086     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
1087     CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1088     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1089     if(pMarginNode) {\r
1090         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1091         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1092         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1093         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1094     }\r
1095     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
1096     CFX_WideStringC wsColumnWidths;\r
1097     if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {\r
1098         CFX_WideStringArray widths;\r
1099         if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(), L' ', widths) > 0) {\r
1100             FX_INT32 iCols = widths.GetSize();\r
1101             CFX_WideString wsWidth;\r
1102             for (FX_INT32 i = 0; i < iCols; i++) {\r
1103                 wsWidth = widths[i];\r
1104                 wsWidth.TrimLeft(L' ');\r
1105                 if (!wsWidth.IsEmpty()) {\r
1106                     CXFA_Measurement measure(wsWidth);\r
1107                     m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));\r
1108                 }\r
1109             }\r
1110         }\r
1111     }\r
1112     FX_INT32 iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();\r
1113     CXFA_LayoutContext layoutContext;\r
1114     layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;\r
1115     CXFA_LayoutContext* pLayoutContext = iSpecifiedColumnCount > 0  ? &layoutContext : NULL;\r
1116     if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {\r
1117         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);\r
1118     }\r
1119     for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {\r
1120         layoutContext.m_bCurColumnWidthAvaiable = FALSE;\r
1121         layoutContext.m_fCurColumnWidth = 0;\r
1122         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {\r
1123             continue;\r
1124         }\r
1125         CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
1126 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1127         pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1128 #endif\r
1129         pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pLayoutContext);\r
1130         if(!pProcessor->HasLayoutItem()) {\r
1131             delete pProcessor;\r
1132             continue;\r
1133         }\r
1134         m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());\r
1135         delete pProcessor;\r
1136     }\r
1137     FX_INT32 iRowCount = 0, iColCount = 0;\r
1138     {\r
1139         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgRowItems;\r
1140         CFX_ArrayTemplate<FX_INT32> rgRowItemsSpan;\r
1141         CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;\r
1142         for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1143             if(pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {\r
1144                 continue;\r
1145             }\r
1146             if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1147                 continue;\r
1148             }\r
1149             XFA_ATTRIBUTEENUM eLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1150             if(eLayout != XFA_ATTRIBUTEENUM_Row && eLayout != XFA_ATTRIBUTEENUM_Rl_row) {\r
1151                 continue;\r
1152             }\r
1153             if (CXFA_ContentLayoutItemImpl* pRowLayoutCell = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild) {\r
1154                 rgRowItems.Add(pRowLayoutCell);\r
1155                 FX_INT32 iColSpan = pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);\r
1156                 rgRowItemsSpan.Add(iColSpan);\r
1157                 rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);\r
1158             }\r
1159         }\r
1160         iRowCount = rgRowItems.GetSize();\r
1161         iColCount = 0;\r
1162         FX_BOOL bMoreColumns = TRUE;\r
1163         while(bMoreColumns) {\r
1164             bMoreColumns = FALSE;\r
1165             FX_BOOL bAutoCol = FALSE;\r
1166             for(FX_INT32 i = 0; i < iRowCount; i ++) {\r
1167                 while(rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 || !XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode))) {\r
1168                     CXFA_ContentLayoutItemImpl* pNewCell = (CXFA_ContentLayoutItemImpl*)rgRowItems[i]->m_pNextSibling;\r
1169                     if(rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode)) {\r
1170                         pNewCell = NULL;\r
1171                     }\r
1172                     rgRowItems[i] = pNewCell;\r
1173                     rgRowItemsSpan[i] = pNewCell ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan) : 0;\r
1174                     rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;\r
1175                 }\r
1176                 CXFA_ContentLayoutItemImpl* pCell = rgRowItems[i];\r
1177                 if(!pCell) {\r
1178                     continue;\r
1179                 }\r
1180                 bMoreColumns = TRUE;\r
1181                 if (rgRowItemsSpan[i] == 1) {\r
1182                     if (iColCount >= iSpecifiedColumnCount) {\r
1183                         for (FX_INT32 j = 0, c = iColCount + 1 - m_rgSpecifiedColumnWidths.GetSize(); j < c; j ++) {\r
1184                             m_rgSpecifiedColumnWidths.Add(0);\r
1185                         }\r
1186                     }\r
1187                     if (m_rgSpecifiedColumnWidths[iColCount] < XFA_LAYOUT_FLOAT_PERCISION) {\r
1188                         bAutoCol = TRUE;\r
1189                     }\r
1190                     if (bAutoCol && m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {\r
1191                         m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];\r
1192                     }\r
1193                 }\r
1194             }\r
1195             if(bMoreColumns) {\r
1196                 FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];\r
1197                 for(FX_INT32 i = 0; i < iRowCount; i ++) {\r
1198                     if(!rgRowItems[i]) {\r
1199                         continue;\r
1200                     }\r
1201                     rgRowItemsSpan[i]--;\r
1202                     rgRowItemsWidth[i] -= fFinalColumnWidth;\r
1203                 }\r
1204                 iColCount ++;\r
1205             }\r
1206         }\r
1207     }\r
1208     FX_FLOAT fCurrentRowY = 0;\r
1209     for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {\r
1210         if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {\r
1211             continue;\r
1212         }\r
1213         if(pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {\r
1214             XFA_ATTRIBUTEENUM eSubformLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1215             if(eSubformLayout == XFA_ATTRIBUTEENUM_Row || eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {\r
1216                 XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);\r
1217             }\r
1218         }\r
1219         pLayoutChild->m_sPos.y = fCurrentRowY;\r
1220         if(bContainerWidthAutoSize) {\r
1221             pLayoutChild->m_sPos.x = 0;\r
1222         } else {\r
1223             switch(pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1224                 case XFA_ATTRIBUTEENUM_Left:\r
1225                 default:\r
1226                     pLayoutChild->m_sPos.x = 0;\r
1227                     break;\r
1228                 case XFA_ATTRIBUTEENUM_Center:\r
1229                     pLayoutChild->m_sPos.x = (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2 ;\r
1230                     break;\r
1231                 case XFA_ATTRIBUTEENUM_Right:\r
1232                     pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;\r
1233                     break;\r
1234             }\r
1235         }\r
1236         if(bContainerWidthAutoSize) {\r
1237             FX_FLOAT fChildSuppliedWidth = pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;\r
1238             if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
1239                 fChildSuppliedWidth = fContentWidthLimit;\r
1240             }\r
1241             if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
1242                 fContentCalculatedWidth = fChildSuppliedWidth;\r
1243             }\r
1244         }\r
1245         fCurrentRowY += pLayoutChild->m_sSize.y;\r
1246     }\r
1247     if(bContainerHeightAutoSize) {\r
1248         FX_FLOAT fChildSuppliedHeight = fCurrentRowY;\r
1249         if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
1250             fContentCalculatedHeight = fChildSuppliedHeight;\r
1251         }\r
1252     }\r
1253     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
1254     SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
1255 }\r
1256 static FX_UINT8 XFA_ItemLayoutProcessor_HAlignEnumToInt(XFA_ATTRIBUTEENUM eHAlign)\r
1257 {\r
1258     switch(eHAlign) {\r
1259         case XFA_ATTRIBUTEENUM_Center:\r
1260             return 1;\r
1261         case XFA_ATTRIBUTEENUM_Right:\r
1262             return 2;\r
1263         case XFA_ATTRIBUTEENUM_Left:\r
1264         default:\r
1265             return 0;\r
1266     }\r
1267 }\r
1268 static void     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLayoutItem)\r
1269 {\r
1270     XFA_ATTRIBUTEENUM eLayout = pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1271     switch(eLayout) {\r
1272         case XFA_ATTRIBUTEENUM_Row:\r
1273         case XFA_ATTRIBUTEENUM_Rl_row:\r
1274             XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);\r
1275             break;\r
1276         default:\r
1277             break;\r
1278     }\r
1279 }\r
1280 FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(CXFA_ContentLayoutItemImpl* pTrailerItem)\r
1281 {\r
1282     if(!pTrailerItem) {\r
1283         return FALSE;\r
1284     }\r
1285     FX_FLOAT fWidth = pTrailerItem->m_sSize.x;\r
1286     XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1287     if(eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {\r
1288         return FALSE;\r
1289     }\r
1290     return TRUE;\r
1291 }\r
1292 static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor* pProcessor, FX_FLOAT fSplitPos, CXFA_ContentLayoutItemImpl* pTrailerLayoutItem, FX_BOOL bUseInherited = FALSE)\r
1293 {\r
1294     if(!pTrailerLayoutItem) {\r
1295         return;\r
1296     }\r
1297     FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;\r
1298     if(bUseInherited) {\r
1299         FX_FLOAT fNewSplitPos = 0;\r
1300         if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {\r
1301             fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);\r
1302         }\r
1303         if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1304             pProcessor->SplitLayoutItem(fNewSplitPos);\r
1305         }\r
1306         return;\r
1307     }\r
1308     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pTrailerLayoutItem);\r
1309     CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1310     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1311     if(pMarginNode) {\r
1312         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1313         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1314         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1315         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1316     }\r
1317     FX_FLOAT fWidth = pTrailerLayoutItem->m_sSize.x;\r
1318     XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1319     if(!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {\r
1320         pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;\r
1321         pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;\r
1322         pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;\r
1323         pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);\r
1324         return;\r
1325     }\r
1326     FX_FLOAT fNewSplitPos = 0;\r
1327     if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {\r
1328         fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);\r
1329     }\r
1330     if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1331         pProcessor->SplitLayoutItem(fNewSplitPos);\r
1332         pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;\r
1333     } else {\r
1334         pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;\r
1335     }\r
1336     switch(pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1337         case XFA_ATTRIBUTEENUM_Left:\r
1338         default:\r
1339             pTrailerLayoutItem->m_sPos.x = fLeftInset;\r
1340             break;\r
1341         case XFA_ATTRIBUTEENUM_Right:\r
1342             pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pTrailerLayoutItem->m_sSize.x;\r
1343             break;\r
1344         case XFA_ATTRIBUTEENUM_Center:\r
1345             pTrailerLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pTrailerLayoutItem->m_sSize.x) / 2;\r
1346             break;\r
1347     }\r
1348     pProcessor->m_pLayoutItem->m_sSize.y += fHeight;\r
1349     pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);\r
1350 };\r
1351 static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLeaderLayoutItem)\r
1352 {\r
1353     XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);\r
1354     CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1355     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1356     if(pMarginNode) {\r
1357         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1358         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1359         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1360         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1361     }\r
1362     FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;\r
1363     for (CXFA_ContentLayoutItemImpl* pChildItem = (CXFA_ContentLayoutItemImpl*)pProcessor->m_pLayoutItem->m_pFirstChild; pChildItem; pChildItem = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling) {\r
1364         pChildItem->m_sPos.y += fHeight;\r
1365     }\r
1366     pLeaderLayoutItem->m_sPos.y = 0;\r
1367     switch(pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {\r
1368         case XFA_ATTRIBUTEENUM_Left:\r
1369         default:\r
1370             pLeaderLayoutItem->m_sPos.x = fLeftInset;\r
1371             break;\r
1372         case XFA_ATTRIBUTEENUM_Right:\r
1373             pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pLeaderLayoutItem->m_sSize.x;\r
1374             break;\r
1375         case XFA_ATTRIBUTEENUM_Center:\r
1376             pLeaderLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pLeaderLayoutItem->m_sSize.x) / 2;\r
1377             break;\r
1378     }\r
1379     pProcessor->m_pLayoutItem->m_sSize.y += fHeight;\r
1380     pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);\r
1381 };\r
1382 static void XFA_ItemLayoutProcessor_AddPendingNode(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pPendingNode, FX_BOOL bBreakPending)\r
1383 {\r
1384     pProcessor->m_rgPendingNodes.AddTail(pPendingNode);\r
1385     pProcessor->m_bBreakPending = bBreakPending;\r
1386 }\r
1387 static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pCurChildNode)\r
1388 {\r
1389     FX_FLOAT fTotalHeight = 0;\r
1390     if(pProcessor->m_rgPendingNodes.GetCount() < 1) {\r
1391         return fTotalHeight;\r
1392     }\r
1393     if(pProcessor->m_pLayoutItem == NULL) {\r
1394         pProcessor->m_pLayoutItem = pProcessor->CreateContentLayoutItem(pCurChildNode);\r
1395         pProcessor->m_pLayoutItem->m_sSize.Set(0, 0);\r
1396     }\r
1397     while(pProcessor->m_rgPendingNodes.GetCount() > 0) {\r
1398         FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition();\r
1399         CXFA_Node* pPendingNode = (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos);\r
1400         pProcessor->m_rgPendingNodes.RemoveAt(pos);\r
1401         CXFA_ContentLayoutItemImpl* pPendingLayoutItem = NULL;\r
1402         CXFA_ItemLayoutProcessor *pPendingProcessor = FX_NEW CXFA_ItemLayoutProcessor(pPendingNode, NULL);\r
1403 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1404         pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;\r
1405 #endif\r
1406         pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
1407         pPendingLayoutItem = pPendingProcessor->HasLayoutItem() ? pPendingProcessor->ExtractLayoutItem() : NULL;\r
1408         delete pPendingProcessor;\r
1409         if(pPendingLayoutItem) {\r
1410             XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor, pPendingLayoutItem);\r
1411             if(pProcessor->m_bBreakPending) {\r
1412                 fTotalHeight += pPendingLayoutItem->m_sSize.y;\r
1413             }\r
1414         }\r
1415     }\r
1416     return fTotalHeight;\r
1417 }\r
1418 FX_FLOAT        CXFA_ItemLayoutProcessor::InsertKeepLayoutItems()\r
1419 {\r
1420     FX_FLOAT fTotalHeight = 0;\r
1421     if(m_arrayKeepItems.GetSize()) {\r
1422         if(m_pLayoutItem == NULL) {\r
1423             m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
1424             m_pLayoutItem->m_sSize.Set(0, 0);\r
1425         }\r
1426         for(FX_INT32 iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0 ; iIndex --) {\r
1427             XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this, m_arrayKeepItems[iIndex]);\r
1428             fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;\r
1429         }\r
1430         m_arrayKeepItems.RemoveAll();\r
1431     }\r
1432     return fTotalHeight;\r
1433 }\r
1434 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue,\r
1435         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>& rgCurLineLayoutItem, FX_FLOAT& fContentCurRowAvailWidth,\r
1436         FX_FLOAT& fContentCurRowHeight, FX_FLOAT& fContentCurRowY, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, XFA_ItemLayoutProcessorResult& result)\r
1437 {\r
1438     if(pParentProcessor == NULL || pChildProcessor == NULL) {\r
1439         return FALSE;\r
1440     }\r
1441     if(pParentProcessor->m_pCurChildNode->GetIntact() != XFA_ATTRIBUTEENUM_None || !pChildProcessor->m_bHasAvailHeight) {\r
1442         if(XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {\r
1443             FX_FLOAT fChildWidth, fChildHeight;\r
1444             pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1445             CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> keepLayoutItems;\r
1446             if(pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, fChildHeight, keepLayoutItems)) {\r
1447                 m_arrayKeepItems.RemoveAll();\r
1448                 for(FX_INT32 iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {\r
1449                     CXFA_ContentLayoutItemImpl* pItem = keepLayoutItems.GetAt(iIndex);\r
1450                     pParentProcessor->m_pLayoutItem->RemoveChild(pItem);\r
1451                     fContentCurRowY -= pItem->m_sSize.y;\r
1452                     m_arrayKeepItems.Add(pItem);\r
1453                 }\r
1454                 bAddedItemInRow = TRUE;\r
1455                 bForceEndPage = TRUE;\r
1456                 result =  XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1457                 return TRUE;\r
1458             }\r
1459             rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());\r
1460             bAddedItemInRow = TRUE;\r
1461             fContentCurRowAvailWidth -= fChildWidth;\r
1462             if(fContentCurRowHeight < fChildHeight ) {\r
1463                 fContentCurRowHeight = fChildHeight;\r
1464             }\r
1465             result = eRetValue;\r
1466             return TRUE;\r
1467         }\r
1468     }\r
1469     return FALSE;\r
1470 }\r
1471 FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(CXFA_ContentLayoutItemImpl* pParentLayoutItem,  FX_FLOAT fChildHeight, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> &pKeepItems)\r
1472 {\r
1473     if(pParentLayoutItem == NULL) {\r
1474         return FALSE;\r
1475     }\r
1476     FX_FLOAT fItemsHeight = 0;\r
1477     for(CXFA_ContentLayoutItemImpl* pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pParentLayoutItem->m_pFirstChild; pChildLayoutItem; pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pChildLayoutItem->m_pNextSibling) {\r
1478         if(XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {\r
1479             pKeepItems.Add(pChildLayoutItem);\r
1480             fItemsHeight += pChildLayoutItem->m_sSize.y;\r
1481         } else {\r
1482             pKeepItems.RemoveAll();\r
1483             fItemsHeight = 0;\r
1484         }\r
1485     }\r
1486     fItemsHeight += fChildHeight;\r
1487     if(m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {\r
1488         return TRUE;\r
1489     }\r
1490     return FALSE;\r
1491 }\r
1492 void    CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode)\r
1493 {\r
1494     if(!pFormNode) {\r
1495         return;\r
1496     }\r
1497     CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormNode);\r
1498     for(CXFA_Node *pNode = sIterator.MoveToNext(); pNode; pNode = sIterator.MoveToNext()) {\r
1499         if(pNode->IsContainerNode()) {\r
1500             CXFA_Node* pBindNode = pNode->GetBindData();\r
1501             if (pBindNode) {\r
1502                 pBindNode->RemoveBindItem(pNode);\r
1503                 pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);\r
1504             }\r
1505         }\r
1506         pNode->SetFlag(XFA_NODEFLAG_UnusedNode);\r
1507     }\r
1508 }\r
1509 void    CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItemImpl* pTrailerItem, CXFA_Node* pFormNode)\r
1510 {\r
1511     ProcessUnUseBinds(pLeaderNode);\r
1512     ProcessUnUseBinds(pTrailerNode);\r
1513     if(pFormNode == NULL) {\r
1514         return;\r
1515     }\r
1516     if(pFormNode->GetClassID() == XFA_ELEMENT_Overflow || pFormNode->GetClassID() == XFA_ELEMENT_Break) {\r
1517         pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);\r
1518     }\r
1519     if(pLeaderNode && pFormNode) {\r
1520         pFormNode->RemoveChild(pLeaderNode);\r
1521     }\r
1522     if(pTrailerNode && pFormNode) {\r
1523         pFormNode->RemoveChild(pTrailerNode);\r
1524     }\r
1525     if(pTrailerItem) {\r
1526         XFA_ReleaseLayoutItem(pTrailerItem);\r
1527     }\r
1528 }\r
1529 static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(CXFA_ItemLayoutProcessor* pThis, CXFA_ItemLayoutProcessor*& pProcessor,\r
1530         FX_BOOL bContainerWidthAutoSize, FX_BOOL bContainerHeightAutoSize, FX_FLOAT fContainerHeight, XFA_ATTRIBUTEENUM eFlowStrategy, FX_UINT8& uCurHAlignState, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> (&rgCurLineLayoutItems)[3],\r
1531         FX_BOOL bUseBreakControl, FX_FLOAT fAvailHeight, FX_FLOAT fRealHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT& fContentWidthLimit, FX_FLOAT& fContentCurRowAvailWidth,\r
1532         FX_FLOAT& fContentCurRowHeight, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, CXFA_LayoutContext* pLayoutContext = NULL, FX_BOOL bNewRow = FALSE)\r
1533 {\r
1534     FX_BOOL bTakeSpace = XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);\r
1535     FX_UINT8 uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));\r
1536     if(bContainerWidthAutoSize) {\r
1537         uHAlign = 0;\r
1538     }\r
1539     if((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) || (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {\r
1540         return XFA_ItemLayoutProcessorResult_RowFullBreak;\r
1541     }\r
1542     uCurHAlignState = uHAlign;\r
1543     FX_BOOL bIsOwnSplite = pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;\r
1544     FX_BOOL bUseRealHeight = bTakeSpace && bContainerHeightAutoSize &&  bIsOwnSplite\r
1545                              && pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == XFA_ATTRIBUTEENUM_None;\r
1546     FX_BOOL bIsTransHeight = bTakeSpace;\r
1547     if(bIsTransHeight && !bIsOwnSplite) {\r
1548         FX_BOOL bRootForceTb = FALSE;\r
1549         XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pProcessor->m_pFormNode, bRootForceTb);\r
1550         if(eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {\r
1551             bIsTransHeight = FALSE;\r
1552         }\r
1553     }\r
1554     FX_BOOL bUseInherited = FALSE;\r
1555     CXFA_LayoutContext  layoutContext;\r
1556     if (pThis->m_pPageMgr) {\r
1557         CXFA_Node* pOverflowNode = pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);\r
1558         if(pOverflowNode) {\r
1559             layoutContext.m_pOverflowNode = pOverflowNode;\r
1560             layoutContext.m_pOverflowProcessor = pThis;\r
1561             pLayoutContext = &layoutContext;\r
1562         }\r
1563     }\r
1564     XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;\r
1565     if(!bNewRow || pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {\r
1566         eRetValue = pProcessor->DoLayout(bTakeSpace ? bUseBreakControl : FALSE, bUseRealHeight ?\r
1567                                          fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, pLayoutContext);\r
1568         pProcessor->m_ePreProcessRs = eRetValue;\r
1569     } else {\r
1570         eRetValue = pProcessor->m_ePreProcessRs;\r
1571         pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;\r
1572     }\r
1573     if (pProcessor->HasLayoutItem() == FALSE)   {\r
1574         return eRetValue;\r
1575     }\r
1576     FX_FLOAT fChildWidth, fChildHeight;\r
1577     pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1578     if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {\r
1579         fRealHeight = XFA_LAYOUT_FLOAT_MAX;\r
1580         fAvailHeight = XFA_LAYOUT_FLOAT_MAX;\r
1581     }\r
1582     if (!bTakeSpace || (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) || (fContentWidthLimit - fContentCurRowAvailWidth <= XFA_LAYOUT_FLOAT_PERCISION)) {\r
1583         CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL, *pFormNode = NULL;\r
1584         CXFA_ContentLayoutItemImpl* pTrailerLayoutItem = NULL;\r
1585         FX_BOOL bIsAddTrailerHeight = FALSE;\r
1586         if(pThis->m_pPageMgr && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {\r
1587             pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);\r
1588             if(pFormNode == NULL && pLayoutContext && pLayoutContext->m_pOverflowProcessor) {\r
1589                 pFormNode = pLayoutContext->m_pOverflowNode;\r
1590                 bUseInherited = TRUE;\r
1591             }\r
1592             if(pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, FALSE)) {\r
1593                 if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {\r
1594                     if(pOverflowTrailerNode) {\r
1595                         CXFA_ItemLayoutProcessor *pOverflowLeaderProcessor = FX_NEW CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);\r
1596 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1597                         pOverflowLeaderProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;\r
1598 #endif\r
1599                         pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);\r
1600                         pTrailerLayoutItem = pOverflowLeaderProcessor->HasLayoutItem() ? pOverflowLeaderProcessor->ExtractLayoutItem() : NULL;\r
1601                         delete pOverflowLeaderProcessor;\r
1602                     }\r
1603                     if(bUseInherited) {\r
1604                         bIsAddTrailerHeight = pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);\r
1605                     } else {\r
1606                         bIsAddTrailerHeight = pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);\r
1607                     }\r
1608                     if(bIsAddTrailerHeight) {\r
1609                         FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;\r
1610                         fChildHeight += fTrailerHeight;\r
1611                         bIsAddTrailerHeight = TRUE;\r
1612                     }\r
1613                 }\r
1614             }\r
1615         }\r
1616         if(!bTakeSpace || fContentCurRowY + fChildHeight <= fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||\r
1617                 (!bContainerHeightAutoSize && pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= fContainerHeight)) {\r
1618             if(!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1619                 if(pProcessor->m_bUseInheriated) {\r
1620                     if(pTrailerLayoutItem) {\r
1621                         XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);\r
1622                     }\r
1623                     if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1624                         XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1625                     }\r
1626                     pProcessor->m_bUseInheriated = FALSE;\r
1627                 } else {\r
1628                     if(bIsAddTrailerHeight) {\r
1629                         fChildHeight -= pTrailerLayoutItem->m_sSize.y;\r
1630                     }\r
1631                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1632                 }\r
1633                 CXFA_ContentLayoutItemImpl* pChildLayoutItem = pProcessor->ExtractLayoutItem();\r
1634                 if(XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {\r
1635                     pThis->m_arrayKeepItems.Add(pChildLayoutItem);\r
1636                 } else {\r
1637                     pThis->m_arrayKeepItems.RemoveAll();\r
1638                 }\r
1639                 rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);\r
1640                 bAddedItemInRow = TRUE;\r
1641                 if(bTakeSpace) {\r
1642                     fContentCurRowAvailWidth -= fChildWidth;\r
1643                     if(fContentCurRowHeight < fChildHeight ) {\r
1644                         fContentCurRowHeight = fChildHeight;\r
1645                     }\r
1646                 }\r
1647                 return XFA_ItemLayoutProcessorResult_Done;\r
1648             } else {\r
1649                 if(eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {\r
1650                     if(pProcessor->m_bUseInheriated) {\r
1651                         if(pTrailerLayoutItem) {\r
1652                             XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);\r
1653                         }\r
1654                         if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1655                             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1656                         }\r
1657                         pProcessor->m_bUseInheriated = FALSE;\r
1658                     } else {\r
1659                         if(bIsAddTrailerHeight) {\r
1660                             fChildHeight -= pTrailerLayoutItem->m_sSize.y;\r
1661                         }\r
1662                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1663                     }\r
1664                 }\r
1665                 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1666                 bAddedItemInRow = TRUE;\r
1667                 fContentCurRowAvailWidth -= fChildWidth;\r
1668                 if(fContentCurRowHeight < fChildHeight ) {\r
1669                     fContentCurRowHeight = fChildHeight;\r
1670                 }\r
1671                 return eRetValue;\r
1672             }\r
1673         } else {\r
1674             XFA_ItemLayoutProcessorResult eResult;\r
1675             if(pThis->ProcessKeepForSplite(pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],\r
1676                                            fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, bAddedItemInRow, bForceEndPage, eResult)) {\r
1677                 return eResult;\r
1678             }\r
1679             bForceEndPage = TRUE;\r
1680             FX_FLOAT fSplitPos = pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);\r
1681             if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {\r
1682                 XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1683                 if(eLayout == XFA_ATTRIBUTEENUM_Tb && eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1684                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1685                     rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1686                     bAddedItemInRow = TRUE;\r
1687                     if(bTakeSpace) {\r
1688                         fContentCurRowAvailWidth -= fChildWidth;\r
1689                         if(fContentCurRowHeight < fChildHeight ) {\r
1690                             fContentCurRowHeight = fChildHeight;\r
1691                         }\r
1692                     }\r
1693                     return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1694                 }\r
1695                 CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;\r
1696                 if(pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {\r
1697                     pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);\r
1698                 }\r
1699                 if(pTrailerLayoutItem && bIsAddTrailerHeight) {\r
1700                     XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);\r
1701                 } else {\r
1702                     pProcessor->SplitLayoutItem(fSplitPos);\r
1703                 }\r
1704                 if(bUseInherited) {\r
1705                     pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1706                     pThis->m_bUseInheriated = TRUE;\r
1707                 } else {\r
1708                     if(pProcessor->m_pLayoutItem->m_pFirstChild && pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling == NULL\r
1709                             && pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {\r
1710                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1711                     } else {\r
1712                         if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1713                             XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1714                         }\r
1715                     }\r
1716                 }\r
1717                 if(pProcessor->m_pLayoutItem->m_pNextSibling) {\r
1718                     pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1719                     rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1720                     bAddedItemInRow = TRUE;\r
1721                     if(bTakeSpace) {\r
1722                         fContentCurRowAvailWidth -= fChildWidth;\r
1723                         if(fContentCurRowHeight < fChildHeight ) {\r
1724                             fContentCurRowHeight = fChildHeight;\r
1725                         }\r
1726                     }\r
1727                 }\r
1728                 return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1729             } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {\r
1730                 pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);\r
1731                 if(pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {\r
1732                     CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;\r
1733                     if(pThis->m_pPageMgr) {\r
1734                         if(pFormNode == NULL && pLayoutContext != NULL) {\r
1735                             pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;\r
1736                         }\r
1737                         pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);\r
1738                     }\r
1739                     if(bUseInherited) {\r
1740                         pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1741                         pThis->m_bUseInheriated = TRUE;\r
1742                     }\r
1743                     return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1744                 }\r
1745                 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());\r
1746                 bAddedItemInRow = TRUE;\r
1747                 if(bTakeSpace) {\r
1748                     fContentCurRowAvailWidth -= fChildWidth;\r
1749                     if(fContentCurRowHeight < fChildHeight ) {\r
1750                         fContentCurRowHeight = fChildHeight;\r
1751                     }\r
1752                 }\r
1753                 if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1754                     bForceEndPage = FALSE;\r
1755                 }\r
1756                 return eRetValue;\r
1757             } else {\r
1758                 XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);\r
1759                 if(pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && eLayout == XFA_ATTRIBUTEENUM_Tb) {\r
1760                     if(pThis->m_pPageMgr) {\r
1761                         pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);\r
1762                     }\r
1763                     if(pTrailerLayoutItem) {\r
1764                         XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem);\r
1765                     }\r
1766                     if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {\r
1767                         XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);\r
1768                     }\r
1769                 } else {\r
1770                     if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {\r
1771                         if(pFormNode == NULL && pLayoutContext != NULL) {\r
1772                             pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;\r
1773                         }\r
1774                         if(pThis->m_pPageMgr) {\r
1775                             pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);\r
1776                         }\r
1777                         if(bUseInherited) {\r
1778                             pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);\r
1779                             pThis->m_bUseInheriated = TRUE;\r
1780                         }\r
1781                     }\r
1782                 }\r
1783                 return XFA_ItemLayoutProcessorResult_PageFullBreak;\r
1784             }\r
1785         }\r
1786     } else {\r
1787         return XFA_ItemLayoutProcessorResult_RowFullBreak;\r
1788     }\r
1789     return XFA_ItemLayoutProcessorResult_Done;\r
1790 }\r
1791 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(FX_BOOL bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext, FX_BOOL bRootForceTb)\r
1792 {\r
1793     m_bHasAvailHeight = TRUE;\r
1794     FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;\r
1795     FX_BOOL bBreakDone = FALSE;\r
1796     FX_BOOL  bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;\r
1797     FX_BOOL  bForceEndPage = FALSE;\r
1798     FX_BOOL  bIsManualBreak = FALSE;\r
1799     if(m_pCurChildPreprocessor) {\r
1800         m_pCurChildPreprocessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;\r
1801     }\r
1802     XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);\r
1803     if (pContext && pContext->m_bCurColumnWidthAvaiable) {\r
1804         bContainerWidthAutoSize = FALSE;\r
1805         fContainerWidth = pContext->m_fCurColumnWidth;\r
1806     }\r
1807     if(!bContainerHeightAutoSize) {\r
1808         fContainerHeight -= m_fUsedSize;\r
1809     }\r
1810     if(!bContainerHeightAutoSize) {\r
1811         CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);\r
1812         FX_BOOL bFocrTb = FALSE;\r
1813         if(pParentNode && XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) == XFA_ATTRIBUTEENUM_Row) {\r
1814             CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);\r
1815             if(pChildContainer && pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode)) {\r
1816                 fContainerHeight = 0;\r
1817                 bContainerHeightAutoSize = TRUE;\r
1818             }\r
1819         }\r
1820     }\r
1821     CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);\r
1822     FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;\r
1823     if(pMarginNode) {\r
1824         fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);\r
1825         fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);\r
1826         fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);\r
1827         fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);\r
1828     }\r
1829     FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;\r
1830     FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;\r
1831     FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;\r
1832     if(fAvailHeight < 0) {\r
1833         m_bHasAvailHeight = FALSE;\r
1834     }\r
1835     fRealHeight = fRealHeight - fTopInset - fBottomInset;\r
1836     FX_FLOAT fContentCurRowY = 0;\r
1837     CXFA_ContentLayoutItemImpl* pLayoutChild = NULL;\r
1838     if(m_pLayoutItem != NULL) {\r
1839         if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done && eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {\r
1840             pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;\r
1841             for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1842                 if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {\r
1843                     pLayoutChild = pLayoutNext;\r
1844                 }\r
1845             }\r
1846         }\r
1847         for(CXFA_ContentLayoutItemImpl* pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutTempChild != pLayoutChild; pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)pLayoutTempChild->m_pNextSibling) {\r
1848             if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutTempChild->m_pFormNode)) {\r
1849                 FX_FLOAT fChildContentWidth = pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;\r
1850                 FX_FLOAT fChildContentHeight = pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;\r
1851                 if(fContentCalculatedWidth < fChildContentWidth) {\r
1852                     fContentCalculatedWidth = fChildContentWidth;\r
1853                 }\r
1854                 if(fContentCalculatedHeight < fChildContentHeight) {\r
1855                     fContentCalculatedHeight = fChildContentHeight;\r
1856                 }\r
1857             }\r
1858         }\r
1859         if (pLayoutChild) {\r
1860             fContentCurRowY = pLayoutChild->m_sPos.y;\r
1861         } else {\r
1862             fContentCurRowY = fContentCalculatedHeight;\r
1863         }\r
1864     }\r
1865     fContentCurRowY += InsertKeepLayoutItems();\r
1866     if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {\r
1867         XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
1868     }\r
1869     fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);\r
1870     if(m_pCurChildPreprocessor && m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {\r
1871         if(XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {\r
1872             m_pKeepHeadNode = m_pCurChildNode;\r
1873             m_bIsProcessKeep = TRUE;\r
1874             m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;\r
1875         }\r
1876     }\r
1877     while(m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {\r
1878         FX_FLOAT fContentCurRowHeight = 0;\r
1879         FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;\r
1880         m_fWidthLimite = fContentCurRowAvailWidth;\r
1881         CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgCurLineLayoutItems[3];\r
1882         FX_UINT8 uCurHAlignState = (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);\r
1883         if (pLayoutChild) {\r
1884             for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1885                 if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {\r
1886                     pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;\r
1887                     m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;\r
1888                     break;\r
1889                 }\r
1890                 FX_UINT8 uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));\r
1891                 rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);\r
1892                 if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {\r
1893                     if (uHAlign > uCurHAlignState) {\r
1894                         uCurHAlignState = uHAlign;\r
1895                     }\r
1896                 } else if (uHAlign < uCurHAlignState) {\r
1897                     uCurHAlignState = uHAlign;\r
1898                 }\r
1899                 if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {\r
1900                     if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {\r
1901                         fContentCurRowHeight = pLayoutNext->m_sSize.y;\r
1902                     }\r
1903                     fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;\r
1904                 }\r
1905             }\r
1906             if ((CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild == pLayoutChild) {\r
1907                 m_pLayoutItem->m_pFirstChild = NULL;\r
1908             } else {\r
1909                 CXFA_ContentLayoutItemImpl* pLayoutNext = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;\r
1910                 for (; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {\r
1911                     if ((CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling == pLayoutChild) {\r
1912                         pLayoutNext->m_pNextSibling = NULL;\r
1913                         break;\r
1914                     }\r
1915                 }\r
1916             }\r
1917             CXFA_ContentLayoutItemImpl* pLayoutNextTemp = (CXFA_ContentLayoutItemImpl*)pLayoutChild;\r
1918             while (pLayoutNextTemp) {\r
1919                 pLayoutNextTemp->m_pParent = NULL;\r
1920                 CXFA_ContentLayoutItemImpl* pSaveLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNextTemp->m_pNextSibling;\r
1921                 pLayoutNextTemp->m_pNextSibling = NULL;\r
1922                 pLayoutNextTemp = pSaveLayoutNext;\r
1923             }\r
1924             pLayoutChild = NULL;\r
1925         }\r
1926         while(m_pCurChildNode) {\r
1927             CXFA_ItemLayoutProcessor* pProcessor = NULL;\r
1928             FX_BOOL bAddedItemInRow = FALSE;\r
1929             fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);\r
1930             switch(m_nCurChildNodeStage) {\r
1931                 case XFA_ItemLayoutProcessorStages_Keep:\r
1932                 case XFA_ItemLayoutProcessorStages_None:\r
1933                     break;\r
1934                 case XFA_ItemLayoutProcessorStages_BreakBefore: {\r
1935                         for(FX_INT32 iIndex = 0; iIndex < m_arrayKeepItems.GetSize(); iIndex++) {\r
1936                             CXFA_ContentLayoutItemImpl* pItem = m_arrayKeepItems.GetAt(iIndex);\r
1937                             m_pLayoutItem->RemoveChild(pItem);\r
1938                             fContentCalculatedHeight -= pItem->m_sSize.y;\r
1939                         }\r
1940                         CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;\r
1941                         FX_BOOL bCreatePage = FALSE;\r
1942                         if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form\r
1943                                 && bCreatePage) {\r
1944                             if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
1945                                 XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);\r
1946                             }\r
1947                             if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {\r
1948                                 if(m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == XFA_ELEMENT_Form && m_pLayoutItem == NULL) {\r
1949                                     XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode, TRUE);\r
1950                                 } else {\r
1951                                     CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);\r
1952 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1953                                     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1954 #endif\r
1955                                     XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1956                                             rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
1957                                             fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
1958                                     delete pProcessor;\r
1959                                     pProcessor = NULL;\r
1960                                 }\r
1961                             }\r
1962                             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
1963                             bForceEndPage = TRUE;\r
1964                             bIsManualBreak = TRUE;\r
1965                             goto SuspendAndCreateNewRow;\r
1966                         }\r
1967                     }\r
1968                     break;\r
1969                 case XFA_ItemLayoutProcessorStages_BreakAfter: {\r
1970                         XFA_ItemLayoutProcessorResult eResult;\r
1971                         CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;\r
1972                         FX_BOOL bCreatePage = FALSE;\r
1973                         if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {\r
1974                             if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {\r
1975                                 CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);\r
1976 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1977                                 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1978 #endif\r
1979                                 eResult = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1980                                           rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
1981                                           fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
1982                                 delete pProcessor;\r
1983                                 pProcessor = NULL;\r
1984                             }\r
1985                             if(!bCreatePage) {\r
1986                                 if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
1987                                     CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,\r
1988                                                               fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);\r
1989                                     rgCurLineLayoutItems->RemoveAll();\r
1990                                     CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, NULL);\r
1991 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
1992                                     pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
1993 #endif\r
1994                                     XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
1995                                             rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
1996                                             fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);\r
1997                                     delete pProcessor;\r
1998                                     pProcessor = NULL;\r
1999                                 }\r
2000                             } else {\r
2001                                 if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {\r
2002                                     XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);\r
2003                                 }\r
2004                             }\r
2005                             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
2006                             if(bCreatePage) {\r
2007                                 bForceEndPage = TRUE;\r
2008                                 bIsManualBreak = TRUE;\r
2009                                 if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {\r
2010                                     bBreakDone = TRUE;\r
2011                                 }\r
2012                             }\r
2013                             goto SuspendAndCreateNewRow;\r
2014                         }\r
2015                     }\r
2016                     break;\r
2017                 case XFA_ItemLayoutProcessorStages_BookendLeader: {\r
2018                         CXFA_Node* pLeaderNode = NULL;\r
2019                         if (m_pCurChildPreprocessor) {\r
2020                             pProcessor = m_pCurChildPreprocessor;\r
2021                             m_pCurChildPreprocessor = NULL;\r
2022                         } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, TRUE, pLeaderNode)) {\r
2023                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);\r
2024 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2025                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2026 #endif\r
2027                         }\r
2028                         if(pProcessor) {\r
2029                             if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2030                                     rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2031                                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {\r
2032                                 goto SuspendAndCreateNewRow;\r
2033                             } else {\r
2034                                 delete pProcessor;\r
2035                                 pProcessor = NULL;\r
2036                             }\r
2037                         }\r
2038                     }\r
2039                     break;\r
2040                 case XFA_ItemLayoutProcessorStages_BookendTrailer: {\r
2041                         CXFA_Node* pTrailerNode = NULL;\r
2042                         if (m_pCurChildPreprocessor) {\r
2043                             pProcessor = m_pCurChildPreprocessor;\r
2044                             m_pCurChildPreprocessor = NULL;\r
2045                         } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, FALSE, pTrailerNode)) {\r
2046                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);\r
2047 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2048                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2049 #endif\r
2050                         }\r
2051                         if(pProcessor) {\r
2052                             if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2053                                     rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2054                                     fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {\r
2055                                 goto SuspendAndCreateNewRow;\r
2056                             } else {\r
2057                                 delete pProcessor;\r
2058                                 pProcessor = NULL;\r
2059                             }\r
2060                         }\r
2061                     }\r
2062                     break;\r
2063                 case XFA_ItemLayoutProcessorStages_Container:\r
2064                     ASSERT(m_pCurChildNode->IsContainerNode());\r
2065                     if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {\r
2066                         break;\r
2067                     }\r
2068                     if(fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION && XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {\r
2069                         bForceEndPage = TRUE;\r
2070                         goto SuspendAndCreateNewRow;\r
2071                     }\r
2072                     if(m_pCurChildNode->IsContainerNode()) {\r
2073                         FX_BOOL bNewRow = FALSE;\r
2074                         if (m_pCurChildPreprocessor) {\r
2075                             pProcessor = m_pCurChildPreprocessor;\r
2076                             m_pCurChildPreprocessor = NULL;\r
2077                             bNewRow = TRUE;\r
2078                         } else {\r
2079                             pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);\r
2080 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_\r
2081                             pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;\r
2082 #endif\r
2083                         }\r
2084                         XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);\r
2085                         XFA_ItemLayoutProcessorResult rs = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,\r
2086                                                            rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,\r
2087                                                            fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext, bNewRow);\r
2088                         switch(rs) {\r
2089                             case XFA_ItemLayoutProcessorResult_ManualBreak:\r
2090                                 bIsManualBreak = TRUE;\r
2091                             case XFA_ItemLayoutProcessorResult_PageFullBreak:\r
2092                                 bForceEndPage = TRUE;\r
2093                             case XFA_ItemLayoutProcessorResult_RowFullBreak:\r
2094                                 goto SuspendAndCreateNewRow;\r
2095                             case XFA_ItemLayoutProcessorResult_Done:\r
2096                             default:\r
2097                                 fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);\r
2098                                 delete pProcessor;\r
2099                                 pProcessor = NULL;\r
2100                         }\r
2101                     }\r
2102                     break;\r
2103                 case XFA_ItemLayoutProcessorStages_Done:\r
2104                     break;\r
2105                 default:\r
2106                     break;\r
2107             }\r
2108             XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);\r
2109             if(bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {\r
2110                 break;\r
2111             } else {\r
2112                 continue;\r
2113             }\r
2114 SuspendAndCreateNewRow:\r
2115             if (pProcessor) {\r
2116                 m_pCurChildPreprocessor = pProcessor;\r
2117             }\r
2118             break;\r
2119         }\r
2120         CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,\r
2121                                   fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit, bRootForceTb);\r
2122         m_fWidthLimite = fContentCurRowAvailWidth;\r
2123         if(bForceEndPage) {\r
2124             break;\r
2125         }\r
2126     }\r
2127     FX_BOOL bRetValue = (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && m_rgPendingNodes.GetCount() == 0);\r
2128     if(bBreakDone) {\r
2129         bRetValue = FALSE;\r
2130     }\r
2131     XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);\r
2132     if(fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || bRetValue) {\r
2133         if(m_pLayoutItem == NULL) {\r
2134             m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2135         }\r
2136         if(fContainerHeight < 0 ) {\r
2137             fContainerHeight = 0;\r
2138         }\r
2139         SetCurrentComponentSize(fContainerWidth, fContainerHeight);\r
2140         if(bForceEndPage) {\r
2141             m_fUsedSize = 0;\r
2142         } else {\r
2143             m_fUsedSize += m_pLayoutItem->m_sSize.y;\r
2144         }\r
2145     }\r
2146     return bRetValue ? XFA_ItemLayoutProcessorResult_Done : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak : XFA_ItemLayoutProcessorResult_PageFullBreak);\r
2147 }\r
2148 FX_BOOL    CXFA_ItemLayoutProcessor::CalculateRowChildPosition(CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>(&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, FX_BOOL bContainerHeightAutoSize,\r
2149         FX_BOOL bContainerWidthAutoSize, FX_FLOAT& fContentCalculatedWidth, FX_FLOAT& fContentCalculatedHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit,  FX_BOOL bRootForceTb)\r
2150 {\r
2151     FX_INT32 nGroupLengths[3] = {0, 0, 0};\r
2152     FX_FLOAT  fGroupWidths[3] = {0, 0, 0};\r
2153     FX_INT32 nTotalLength = 0;\r
2154     for(FX_INT32 i = 0; i < 3; i ++) {\r
2155         nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();\r
2156         for(FX_INT32 c = nGroupLengths[i], j = 0; j < c; j++) {\r
2157             nTotalLength++;\r
2158             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[i][j]->m_pFormNode)) {\r
2159                 fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;\r
2160             }\r
2161         }\r
2162     }\r
2163     if(!nTotalLength) {\r
2164         if(bContainerHeightAutoSize) {\r
2165             FX_FLOAT fNewHeight = fContentCurRowY;\r
2166             if(fContentCalculatedHeight > fNewHeight) {\r
2167                 fContentCalculatedHeight = fNewHeight;\r
2168             }\r
2169         }\r
2170         return FALSE;\r
2171     }\r
2172     if(m_pLayoutItem == NULL) {\r
2173         m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2174     }\r
2175     if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {\r
2176         FX_FLOAT fCurPos;\r
2177         fCurPos = 0;\r
2178         for(FX_INT32 c = nGroupLengths[0], j = 0; j < c; j++) {\r
2179             if(bRootForceTb) {\r
2180                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2181                 CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode, rgCurLineLayoutItems[0][j]->m_sSize.x, rgCurLineLayoutItems[0][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2182                 rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2183             } else {\r
2184                 rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2185                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {\r
2186                     fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;\r
2187                 }\r
2188             }\r
2189             m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);\r
2190             m_fLastRowWidth = fCurPos;\r
2191         }\r
2192         fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] - fGroupWidths[2]) / 2;\r
2193         for(FX_INT32 c = nGroupLengths[1], j = 0; j < c; j++) {\r
2194             if(bRootForceTb) {\r
2195                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2196                 CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode, rgCurLineLayoutItems[1][j]->m_sSize.x, rgCurLineLayoutItems[1][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2197                 rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2198             } else {\r
2199                 rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2200                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {\r
2201                     fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;\r
2202                 }\r
2203             }\r
2204             m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);\r
2205             m_fLastRowWidth = fCurPos;\r
2206         }\r
2207         fCurPos = fContentWidthLimit - fGroupWidths[2];\r
2208         for(FX_INT32 c = nGroupLengths[2], j = 0; j < c; j++) {\r
2209             if(bRootForceTb) {\r
2210                 FX_FLOAT fAbsoluteX, fAbsoluteY;\r
2211                 CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode, rgCurLineLayoutItems[2][j]->m_sSize.x, rgCurLineLayoutItems[2][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);\r
2212                 rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2213             } else {\r
2214                 rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2215                 if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {\r
2216                     fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;\r
2217                 }\r
2218             }\r
2219             m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);\r
2220             m_fLastRowWidth = fCurPos;\r
2221         }\r
2222     } else {\r
2223         FX_FLOAT fCurPos;\r
2224         fCurPos = fGroupWidths[0];\r
2225         for(FX_INT32 c = nGroupLengths[0], j = 0; j < c; j++) {\r
2226             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {\r
2227                 fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;\r
2228             }\r
2229             rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2230             m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);\r
2231             m_fLastRowWidth = fCurPos;\r
2232         }\r
2233         fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] - fGroupWidths[2]) / 2;\r
2234         for(FX_INT32 c = nGroupLengths[1], j = 0; j < c; j++) {\r
2235             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {\r
2236                 fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;\r
2237             }\r
2238             rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2239             m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);\r
2240             m_fLastRowWidth = fCurPos;\r
2241         }\r
2242         fCurPos = fContentWidthLimit;\r
2243         for(FX_INT32 c = nGroupLengths[2], j = 0; j < c; j++) {\r
2244             if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {\r
2245                 fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;\r
2246             }\r
2247             rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);\r
2248             m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);\r
2249             m_fLastRowWidth = fCurPos;\r
2250         }\r
2251     }\r
2252     m_fLastRowY = fContentCurRowY;\r
2253     fContentCurRowY += fContentCurRowHeight;\r
2254     if(bContainerWidthAutoSize) {\r
2255         FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];\r
2256         if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {\r
2257             fChildSuppliedWidth = fContentWidthLimit;\r
2258         }\r
2259         if (fContentCalculatedWidth < fChildSuppliedWidth) {\r
2260             fContentCalculatedWidth = fChildSuppliedWidth;\r
2261         }\r
2262     }\r
2263     if(bContainerHeightAutoSize) {\r
2264         FX_FLOAT fChildSuppliedHeight = fContentCurRowY;\r
2265         if(fContentCalculatedHeight < fChildSuppliedHeight) {\r
2266             fContentCalculatedHeight = fChildSuppliedHeight;\r
2267         }\r
2268     }\r
2269     return TRUE;\r
2270 }\r
2271 CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(CXFA_Node* pSubformSet)\r
2272 {\r
2273     if(pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {\r
2274         CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);\r
2275         while(pParent) {\r
2276             if(pParent->GetClassID() != XFA_ELEMENT_SubformSet) {\r
2277                 return pParent;\r
2278             }\r
2279             pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);\r
2280         }\r
2281     }\r
2282     return pSubformSet;\r
2283 }\r
2284 void CXFA_ItemLayoutProcessor::DoLayoutField()\r
2285 {\r
2286     if(m_pLayoutItem != NULL) {\r
2287         return;\r
2288     }\r
2289     ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);\r
2290     m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);\r
2291     if (!m_pLayoutItem) {\r
2292         return;\r
2293     }\r
2294     CXFA_Document* pDocument = m_pFormNode->GetDocument();\r
2295     IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();\r
2296     FX_FLOAT fHeight = -1;\r
2297     FX_FLOAT fWidth = -1;\r
2298     pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);\r
2299     FX_INT32 nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());\r
2300     nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360);\r
2301     if(nRotate == 90 || nRotate == 270) {\r
2302         FX_FLOAT fTmp = fWidth;\r
2303         fWidth = fHeight;\r
2304         fHeight = fTmp;\r
2305     }\r
2306     SetCurrentComponentSize(fWidth, fHeight);\r
2307 }\r
2308 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(FX_BOOL bUseBreakControl, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext)\r
2309 {\r
2310     XFA_ELEMENT eClassID = m_pFormNode->GetClassID();\r
2311     switch(eClassID) {\r
2312         case XFA_ELEMENT_Subform:\r
2313         case XFA_ELEMENT_Area:\r
2314         case XFA_ELEMENT_ExclGroup:\r
2315         case XFA_ELEMENT_SubformSet: {\r
2316                 FX_BOOL bRootForceTb = FALSE;\r
2317                 CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);\r
2318                 XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);\r
2319                 switch(eLayoutStrategy) {\r
2320                     case XFA_ATTRIBUTEENUM_Tb:\r
2321                     case XFA_ATTRIBUTEENUM_Lr_tb:\r
2322                     case XFA_ATTRIBUTEENUM_Rl_tb:\r
2323                         return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy, fHeightLimit, fRealHeight, pContext, bRootForceTb);\r
2324                     case XFA_ATTRIBUTEENUM_Position:\r
2325                     case XFA_ATTRIBUTEENUM_Row:\r
2326                     case XFA_ATTRIBUTEENUM_Rl_row:\r
2327                     default:\r
2328                         DoLayoutPositionedContainer(pContext);\r
2329                         m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2330                         return XFA_ItemLayoutProcessorResult_Done;\r
2331                     case XFA_ATTRIBUTEENUM_Table:\r
2332                         DoLayoutTableContainer(pLayoutNode);\r
2333                         m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2334                         return XFA_ItemLayoutProcessorResult_Done;\r
2335                 }\r
2336             }\r
2337         case XFA_ELEMENT_Draw:\r
2338         case XFA_ELEMENT_Field:\r
2339             DoLayoutField();\r
2340             m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;\r
2341             return XFA_ItemLayoutProcessorResult_Done;\r
2342         case XFA_ELEMENT_ContentArea:\r
2343             return XFA_ItemLayoutProcessorResult_Done;\r
2344         default:\r
2345             return XFA_ItemLayoutProcessorResult_Done;\r
2346     }\r
2347 }\r
2348 void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)\r
2349 {\r
2350     ASSERT(m_pLayoutItem);\r
2351     fAbsoluteX = m_pLayoutItem->m_sPos.x;\r
2352     fAbsoluteY = m_pLayoutItem->m_sPos.y;\r
2353 }\r
2354 void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight)\r
2355 {\r
2356     ASSERT(m_pLayoutItem);\r
2357     fWidth = m_pLayoutItem->m_sSize.x;\r
2358     fHeight = m_pLayoutItem->m_sSize.y;\r
2359 }\r
2360 void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY)\r
2361 {\r
2362     ASSERT(m_pLayoutItem);\r
2363     m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY);\r
2364 }\r
2365 void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight)\r
2366 {\r
2367     ASSERT(m_pLayoutItem);\r
2368     m_pLayoutItem->m_sSize.Set(fWidth, fHeight);\r
2369 }\r
2370 FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode)\r
2371 {\r
2372     if(pFormNode == NULL) {\r
2373         return FALSE;\r
2374     }\r
2375     CXFA_Node* pTemplate = pFormNode->GetTemplateNode();\r
2376     if (!pTemplate) {\r
2377         pTemplate = pFormNode;\r
2378     }\r
2379     CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur);\r
2380     FX_INT32 iMax = NodeOccur.GetMax();\r
2381     if (iMax > -1) {\r
2382         FX_INT32 iCount = (FX_INT32)(FX_UINTPTR)m_PendingNodesCount.GetValueAt(pTemplate);\r
2383         if (iCount >= iMax) {\r
2384             return FALSE;\r
2385         }\r
2386         iCount++;\r
2387         m_PendingNodesCount.SetAt(pTemplate, (FX_LPVOID)(FX_UINTPTR)(iCount));\r
2388         return TRUE;\r
2389     }\r
2390     return TRUE;\r
2391 }\r