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