// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include <algorithm>

#include "xfa/src/foxitlib.h"
#include "xfa/src/fxfa/src/common/xfa_utils.h"
#include "xfa/src/fxfa/src/common/xfa_object.h"
#include "xfa/src/fxfa/src/common/xfa_document.h"
#include "xfa/src/fxfa/src/common/xfa_parser.h"
#include "xfa/src/fxfa/src/common/xfa_script.h"
#include "xfa/src/fxfa/src/common/xfa_docdata.h"
#include "xfa/src/fxfa/src/common/xfa_doclayout.h"
#include "xfa/src/fxfa/src/common/xfa_localemgr.h"
#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
#include "xfa_document_layout_imp.h"
#include "xfa_layout_itemlayout.h"
#include "xfa_layout_pagemgr_new.h"
#include "xfa_layout_appadapter.h"
CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode,
                                                   CXFA_LayoutPageMgr* pPageMgr)
    : m_bKeepBreakFinish(FALSE),
      m_bIsProcessKeep(FALSE),
      m_pKeepHeadNode(nullptr),
      m_pKeepTailNode(nullptr),
      m_pFormNode(pNode),
      m_pLayoutItem(nullptr),
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
      m_pOldLayoutItem(nullptr),
#else
      m_pPageMgrCreateItem(nullptr),
#endif
      m_pCurChildNode(XFA_LAYOUT_INVALIDNODE),
      m_pCurChildPreprocessor(nullptr),
      m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None),
      m_fUsedSize(0),
      m_pPageMgr(pPageMgr),
      m_bBreakPending(TRUE),
      m_fLastRowWidth(0),
      m_fLastRowY(0),
      m_fWidthLimite(0),
      m_bUseInheriated(FALSE),
      m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done),
      m_bHasAvailHeight(TRUE) {
  FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() ||
                               m_pFormNode->GetClassID() == XFA_ELEMENT_Form));
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
  m_pOldLayoutItem =
      (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
#endif
}
CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(
    CXFA_Node* pFormNode) {
  if (!pFormNode) {
    return NULL;
  }
  CXFA_ContentLayoutItem* pLayoutItem = NULL;
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
  if (m_pOldLayoutItem) {
    pLayoutItem = m_pOldLayoutItem;
    m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;
    return pLayoutItem;
  }
  pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument()
                    ->GetParser()
                    ->GetNotify()
                    ->OnCreateLayoutItem(pFormNode);
#else
  pLayoutItem =
      (CXFA_ContentLayoutItem*)m_pPageMgrCreateItem->FindOrCreateLayoutItem(
          pFormNode);
#endif
  CXFA_ContentLayoutItem* pPrevLayoutItem =
      (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
  if (pPrevLayoutItem) {
    while (pPrevLayoutItem->m_pNext) {
      pPrevLayoutItem = pPrevLayoutItem->m_pNext;
    }
    pPrevLayoutItem->m_pNext = pLayoutItem;
    pLayoutItem->m_pPrev = pPrevLayoutItem;
  } else {
    pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem);
  }
  return pLayoutItem;
}
FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos(
    CXFA_ContentLayoutItem* pLayoutItem,
    FX_FLOAT fCurVerticalOffset,
    FX_FLOAT& fProposedSplitPos,
    FX_BOOL& bAppChange,
    FX_BOOL bCalculateMargin) {
  CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;
  if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION &&
      fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y -
                               XFA_LAYOUT_FLOAT_PERCISION) {
    switch (pFormNode->GetIntact()) {
      case XFA_ATTRIBUTEENUM_None: {
        FX_BOOL bAnyChanged = FALSE;
        CXFA_Document* pDocument = pFormNode->GetDocument();
        IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
        FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
        CXFA_Node* pMarginNode =
            pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
        if (pMarginNode && bCalculateMargin) {
          fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
                              .ToUnit(XFA_UNIT_Pt);
          fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset)
                                 .ToUnit(XFA_UNIT_Pt);
        }
        FX_BOOL bChanged = TRUE;
        while (bChanged) {
          bChanged = FALSE;
          {
            FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset;
            if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(),
                                      fRelSplitPos)) {
              bAnyChanged = TRUE;
              bChanged = TRUE;
              fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;
              bAppChange = TRUE;
              if (fProposedSplitPos <=
                  fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
                return TRUE;
              }
            }
          }
          FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin;
          for (CXFA_ContentLayoutItem* pChildItem =
                   (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
               pChildItem;
               pChildItem =
                   (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
            FX_FLOAT fChildOffset =
                fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
            FX_BOOL bAppChange = FALSE;
            if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos,
                                       bAppChange, bCalculateMargin)) {
              if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION &&
                  bAppChange) {
                fProposedSplitPos = fRelSplitPos - fCurTopMargin;
              } else {
                fProposedSplitPos = fRelSplitPos + fCurBottomMargin;
              }
              bAnyChanged = TRUE;
              bChanged = TRUE;
              if (fProposedSplitPos <=
                  fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
                return TRUE;
              }
              if (bAnyChanged) {
                break;
              }
            }
          }
        }
        return bAnyChanged;
      } break;
      case XFA_ATTRIBUTEENUM_ContentArea:
      case XFA_ATTRIBUTEENUM_PageArea: {
        fProposedSplitPos = fCurVerticalOffset;
        return TRUE;
      }
      default:
        return FALSE;
    }
  }
  return FALSE;
}
static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(
    CXFA_Node* pFormNode,
    FX_BOOL& bRootForceTb) {
  bRootForceTb = FALSE;
  XFA_ATTRIBUTEENUM eLayoutMode;
  if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) {
    return eLayoutMode;
  }
  CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) {
    bRootForceTb = TRUE;
    return XFA_ATTRIBUTEENUM_Tb;
  }
  return XFA_ATTRIBUTEENUM_Position;
}
static FX_BOOL XFA_ExistContainerKeep(CXFA_Node* pCurNode, FX_BOOL bPreFind) {
  if (pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) {
    return FALSE;
  }
  XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling;
  if (!bPreFind) {
    eItemType = XFA_NODEITEM_NextSibling;
  }
  CXFA_Node* pPreContainer =
      pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode);
  if (pPreContainer == NULL) {
    return FALSE;
  }
  CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep);
  if (pKeep) {
    XFA_ATTRIBUTEENUM ePrevious;
    XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous;
    if (!bPreFind) {
      eKeepType = XFA_ATTRIBUTE_Next;
    }
    if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) {
      if (ePrevious == XFA_ATTRIBUTEENUM_ContentArea ||
          ePrevious == XFA_ATTRIBUTEENUM_PageArea) {
        return TRUE;
      }
    }
  }
  pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep);
  if (!pKeep) {
    return FALSE;
  }
  XFA_ATTRIBUTEENUM eNext;
  XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next;
  if (!bPreFind) {
    eKeepType = XFA_ATTRIBUTE_Previous;
  }
  if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) {
    return FALSE;
  }
  if (eNext == XFA_ATTRIBUTEENUM_ContentArea ||
      eNext == XFA_ATTRIBUTEENUM_PageArea) {
    return TRUE;
  }
  return FALSE;
}
FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos) {
  ASSERT(m_pLayoutItem);
  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
  FX_BOOL bCalculateMargin = TRUE;
  if (eLayout == XFA_ATTRIBUTEENUM_Position) {
    bCalculateMargin = FALSE;
  }
  while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
    FX_BOOL bAppChange = FALSE;
    if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange,
                                bCalculateMargin)) {
      break;
    }
  }
  return fProposedSplitPos;
}
void CXFA_ItemLayoutProcessor::SplitLayoutItem(
    CXFA_ContentLayoutItem* pLayoutItem,
    CXFA_ContentLayoutItem* pSecondParent,
    FX_FLOAT fSplitPos) {
  FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
  FX_BOOL bCalculateMargin = TRUE;
  if (eLayout == XFA_ATTRIBUTEENUM_Position) {
    bCalculateMargin = FALSE;
  }
  CXFA_Node* pMarginNode =
      pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  if (pMarginNode && bCalculateMargin) {
    fCurTopMargin =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fCurBottomMargin =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  CXFA_ContentLayoutItem* pSecondLayoutItem = NULL;
  if (m_pCurChildPreprocessor &&
      m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) {
    pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
        pLayoutItem->m_pFormNode);
  } else {
    pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode);
  }
  pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x;
  pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x;
  pSecondLayoutItem->m_sPos.y = 0;
  pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos;
  pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y;
  if (pLayoutItem->m_pFirstChild) {
    pSecondLayoutItem->m_sSize.y += fCurTopMargin;
  }
  if (pSecondParent) {
    pSecondParent->AddChild(pSecondLayoutItem);
    if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {
      pSecondParent->m_sSize.y += fCurTopMargin;
      CXFA_ContentLayoutItem* pParentItem =
          (CXFA_ContentLayoutItem*)pSecondParent->m_pParent;
      while (pParentItem) {
        pParentItem->m_sSize.y += fCurTopMargin;
        pParentItem = (CXFA_ContentLayoutItem*)pParentItem->m_pParent;
      }
    }
  } else {
    pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent;
    pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling;
    pLayoutItem->m_pNextSibling = pSecondLayoutItem;
  }
  CXFA_ContentLayoutItem* pChildren =
      (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
  pLayoutItem->m_pFirstChild = NULL;
  FX_FLOAT lHeightForKeep = 0;
  CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
  FX_FLOAT fAddMarginHeight = 0;
  for (CXFA_ContentLayoutItem* pChildItem = pChildren, * pChildNext = NULL;
       pChildItem; pChildItem = pChildNext) {
    pChildNext = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling;
    pChildItem->m_pNextSibling = NULL;
    if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                         XFA_LAYOUT_FLOAT_PERCISION) {
      if (!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) {
        pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
        pChildItem->m_sPos.y += lHeightForKeep;
        pChildItem->m_sPos.y += fAddMarginHeight;
        pSecondLayoutItem->AddChild(pChildItem);
      } else {
        if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {
          for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize();
               iIndex++) {
            CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex];
            pLayoutItem->RemoveChild(pPreItem);
            pPreItem->m_sPos.y -= fSplitPos;
            if (pPreItem->m_sPos.y < 0) {
              pPreItem->m_sPos.y = 0;
            }
            if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) {
              pPreItem->m_sPos.y = lHeightForKeep;
              lHeightForKeep += pPreItem->m_sSize.y;
              pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y;
              if (pSecondParent) {
                pSecondParent->m_sSize.y += pPreItem->m_sSize.y;
              }
            }
            pSecondLayoutItem->AddChild(pPreItem);
          }
        }
        pChildItem->m_sPos.y -= fSplitPos;
        pChildItem->m_sPos.y += lHeightForKeep;
        pChildItem->m_sPos.y += fAddMarginHeight;
        pSecondLayoutItem->AddChild(pChildItem);
      }
    } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >=
               fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y +
                   pChildItem->m_sSize.y) {
      pLayoutItem->AddChild(pChildItem);
      if (XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) {
        keepLayoutItems.Add(pChildItem);
      } else {
        keepLayoutItems.RemoveAll();
      }
    } else {
      FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y;
      SplitLayoutItem(
          pChildItem, pSecondLayoutItem,
          fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
      fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight;
      pLayoutItem->AddChild(pChildItem);
    }
  }
}
void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) {
  ASSERT(m_pLayoutItem);
  SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos);
  return;
}

IXFA_LayoutPage* CXFA_LayoutItem::GetPage() const {
  for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode;
       pCurNode = pCurNode->m_pParent) {
    if (pCurNode->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea)
      return static_cast<CXFA_ContainerLayoutItem*>(pCurNode);
  }
  return nullptr;
}

CXFA_Node* CXFA_LayoutItem::GetFormNode() const {
  return m_pFormNode;
}

void CXFA_LayoutItem::GetRect(CFX_RectF& rtLayout, FX_BOOL bRelative) const {
  ASSERT(m_bIsContentLayoutItem);
  const CXFA_ContentLayoutItem* pThis =
      static_cast<const CXFA_ContentLayoutItem*>(this);
  CFX_PointF sPos = pThis->m_sPos;
  CFX_SizeF sSize = pThis->m_sSize;
  if (!bRelative) {
    for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem;
         pLayoutItem = pLayoutItem->m_pParent) {
      if (CXFA_ContentLayoutItem* pContent =
              pLayoutItem->AsContentLayoutItem()) {
        sPos += pContent->m_sPos;
        if (CXFA_Node* pMarginNode =
                pLayoutItem->m_pFormNode->GetFirstChildByClass(
                    XFA_ELEMENT_Margin)) {
          sPos.Add(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset)
                       .ToUnit(XFA_UNIT_Pt),
                   pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
                       .ToUnit(XFA_UNIT_Pt));
        }
      } else {
        if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
          sPos.Add(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X)
                       .ToUnit(XFA_UNIT_Pt),
                   pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y)
                       .ToUnit(XFA_UNIT_Pt));
          break;
        } else if (pLayoutItem->m_pFormNode->GetClassID() ==
                   XFA_ELEMENT_PageArea) {
          break;
        }
      }
    }
  }
  rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y);
}

CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const {
  return m_pParent;
}

const CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const {
  ASSERT(m_bIsContentLayoutItem);
  const CXFA_ContentLayoutItem* pCurNode =
      static_cast<const CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pPrev) {
    pCurNode = pCurNode->m_pPrev;
  }
  return pCurNode;
}

CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() {
  ASSERT(m_bIsContentLayoutItem);
  CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pPrev) {
    pCurNode = pCurNode->m_pPrev;
  }
  return pCurNode;
}

CXFA_LayoutItem* CXFA_LayoutItem::GetLast() {
  ASSERT(m_bIsContentLayoutItem);
  CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pNext) {
    pCurNode = pCurNode->m_pNext;
  }
  return pCurNode;
}

const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const {
  ASSERT(m_bIsContentLayoutItem);
  const CXFA_ContentLayoutItem* pCurNode =
      static_cast<const CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pNext) {
    pCurNode = pCurNode->m_pNext;
  }
  return pCurNode;
}

CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const {
  ASSERT(m_bIsContentLayoutItem);
  return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev;
}

CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const {
  ASSERT(m_bIsContentLayoutItem);
  return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext;
}

int32_t CXFA_LayoutItem::GetIndex() const {
  ASSERT(m_bIsContentLayoutItem);
  int32_t iIndex = 0;
  const CXFA_ContentLayoutItem* pCurNode =
      static_cast<const CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pPrev) {
    pCurNode = pCurNode->m_pPrev;
    ++iIndex;
  }
  return iIndex;
}

int32_t CXFA_LayoutItem::GetCount() const {
  ASSERT(m_bIsContentLayoutItem);
  int32_t iCount = GetIndex() + 1;
  const CXFA_ContentLayoutItem* pCurNode =
      static_cast<const CXFA_ContentLayoutItem*>(this);
  while (pCurNode->m_pNext) {
    pCurNode = pCurNode->m_pNext;
    iCount++;
  }
  return iCount;
}

void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) {
  if (pChildItem->m_pParent) {
    pChildItem->m_pParent->RemoveChild(pChildItem);
  }
  pChildItem->m_pParent = this;
  if (m_pFirstChild == NULL) {
    m_pFirstChild = pChildItem;
  } else {
    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
    while (pExistingChildItem->m_pNextSibling) {
      pExistingChildItem = pExistingChildItem->m_pNextSibling;
    }
    pExistingChildItem->m_pNextSibling = pChildItem;
  }
}
void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) {
  if (pChildItem->m_pParent) {
    pChildItem->m_pParent->RemoveChild(pChildItem);
  }
  pChildItem->m_pParent = this;
  if (m_pFirstChild == NULL) {
    m_pFirstChild = pChildItem;
  } else {
    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
    m_pFirstChild = pChildItem;
    m_pFirstChild->m_pNextSibling = pExistingChildItem;
  }
}
void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem,
                                  CXFA_LayoutItem* pChildItem) {
  if (pBeforeItem->m_pParent != this) {
    return;
  }
  if (pChildItem->m_pParent) {
    pChildItem->m_pParent = NULL;
  }
  pChildItem->m_pParent = this;
  CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling;
  pBeforeItem->m_pNextSibling = pChildItem;
  pChildItem->m_pNextSibling = pExistingChildItem;
}
void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) {
  if (pChildItem->m_pParent != this) {
    return;
  }
  if (m_pFirstChild == pChildItem) {
    m_pFirstChild = pChildItem->m_pNextSibling;
  } else {
    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
    while (pExistingChildItem &&
           pExistingChildItem->m_pNextSibling != pChildItem) {
      pExistingChildItem = pExistingChildItem->m_pNextSibling;
    }
    if (pExistingChildItem) {
      pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling;
    }
  }
  pChildItem->m_pNextSibling = NULL;
  pChildItem->m_pParent = NULL;
}
CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() {
  CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
  if (pLayoutItem) {
    m_pLayoutItem = (CXFA_ContentLayoutItem*)pLayoutItem->m_pNextSibling;
    pLayoutItem->m_pNextSibling = NULL;
  }
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
  if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
      ToContentLayoutItem(m_pOldLayoutItem)) {
    if (m_pOldLayoutItem->m_pPrev) {
      m_pOldLayoutItem->m_pPrev->m_pNext = NULL;
    }
    IXFA_Notify* pNotify =
        m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();
    IXFA_DocLayout* pDocLayout =
        m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
    CXFA_ContentLayoutItem* pOldLayoutItem = m_pOldLayoutItem;
    while (pOldLayoutItem) {
      CXFA_ContentLayoutItem* pNextOldLayoutItem = pOldLayoutItem->m_pNext;
      pNotify->OnLayoutEvent(pDocLayout, pOldLayoutItem,
                             XFA_LAYOUTEVENT_ItemRemoving);
      delete pOldLayoutItem;
      pOldLayoutItem = pNextOldLayoutItem;
    }
    m_pOldLayoutItem = NULL;
  }
#endif
  return pLayoutItem;
}
static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode(
    CXFA_Node* pContainerNode,
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    FX_BOOL bBreakBefore) {
  FX_BOOL bFindRs = FALSE;
  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
       pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before;
    if (!bBreakBefore) {
      eAttributeType = XFA_ATTRIBUTE_After;
    }
    switch (pBreakNode->GetClassID()) {
      case XFA_ELEMENT_BreakBefore: {
        if (bBreakBefore) {
          pCurActionNode = pBreakNode;
          nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
          bFindRs = TRUE;
        }
      } break;
      case XFA_ELEMENT_BreakAfter: {
        if (!bBreakBefore) {
          pCurActionNode = pBreakNode;
          nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
          bFindRs = TRUE;
        }
      } break;
      case XFA_ELEMENT_Break:
        if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) {
          pCurActionNode = pBreakNode;
          nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
          if (!bBreakBefore) {
            nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
          }
          bFindRs = TRUE;
          break;
        }
      default:
        break;
    }
    if (bFindRs) {
      break;
    }
  }
  return bFindRs;
}
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
  IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify();
  IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout();
  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
      pGenerateNode);
  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
       pNode = sIterator.MoveToNext()) {
    CXFA_ContentLayoutItem* pCurLayoutItem =
        (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
    CXFA_ContentLayoutItem* pNextLayoutItem = NULL;
    while (pCurLayoutItem) {
      pNextLayoutItem = pCurLayoutItem->m_pNext;
      pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem,
                             XFA_LAYOUTEVENT_ItemRemoving);
      delete pCurLayoutItem;
      pCurLayoutItem = pNextLayoutItem;
    }
  }
  pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode);
}
#endif
void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode(
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    CXFA_Node* pParentContainer,
    FX_BOOL bUsePageBreak) {
  CXFA_Node* pEntireContainer = pParentContainer;
  CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;
  switch (nCurStage) {
    case XFA_ItemLayoutProcessorStages_BreakBefore:
    case XFA_ItemLayoutProcessorStages_BreakAfter: {
      pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent);
    } break;
    case XFA_ItemLayoutProcessorStages_Keep:
    case XFA_ItemLayoutProcessorStages_Container:
      pChildContainer = pCurActionNode;
      break;
    default:
      pChildContainer = XFA_LAYOUT_INVALIDNODE;
      break;
  }
  switch (nCurStage) {
    case XFA_ItemLayoutProcessorStages_Keep: {
      CXFA_Node* pBreakAfterNode =
          pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
      if (!m_bKeepBreakFinish &&
          XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
                                                nCurStage, FALSE)) {
        return;
      }
      goto CheckNextChildContainer;
    }
    case XFA_ItemLayoutProcessorStages_None: {
      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
      case XFA_ItemLayoutProcessorStages_BookendLeader:
        for (CXFA_Node* pBookendNode =
                 pCurActionNode == XFA_LAYOUT_INVALIDNODE
                     ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
                     : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
             pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
                               XFA_NODEITEM_NextSibling)) {
          switch (pBookendNode->GetClassID()) {
            case XFA_ELEMENT_Bookend:
            case XFA_ELEMENT_Break:
              pCurActionNode = pBookendNode;
              nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader;
              return;
            default:
              break;
          }
        }
    }
      {
        pCurActionNode = XFA_LAYOUT_INVALIDNODE;
        case XFA_ItemLayoutProcessorStages_BreakBefore:
          if (pCurActionNode != XFA_LAYOUT_INVALIDNODE) {
            CXFA_Node* pBreakBeforeNode =
                pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
            if (!m_bKeepBreakFinish &&
                XFA_ItemLayoutProcessor_FindBreakNode(
                    pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) {
              return;
            }
            if (m_bIsProcessKeep) {
              if (ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage,
                                                 pChildContainer)) {
                return;
              }
              goto CheckNextChildContainer;
            }
            pCurActionNode = pChildContainer;
            nCurStage = XFA_ItemLayoutProcessorStages_Container;
            return;
          }
          goto CheckNextChildContainer;
      }
    case XFA_ItemLayoutProcessorStages_Container: {
      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
      case XFA_ItemLayoutProcessorStages_BreakAfter: {
        if (pCurActionNode == XFA_LAYOUT_INVALIDNODE) {
          CXFA_Node* pBreakAfterNode =
              pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
          if (!m_bKeepBreakFinish &&
              XFA_ItemLayoutProcessor_FindBreakNode(
                  pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
            return;
          }
        } else {
          CXFA_Node* pBreakAfterNode =
              pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
          if (XFA_ItemLayoutProcessor_FindBreakNode(
                  pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
            return;
          }
        }
        goto CheckNextChildContainer;
      }
    }
    CheckNextChildContainer : {
      CXFA_Node* pNextChildContainer =
          pChildContainer == XFA_LAYOUT_INVALIDNODE
              ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild,
                                              XFA_OBJECTTYPE_ContainerNode)
              : pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
                                             XFA_OBJECTTYPE_ContainerNode);
      while (pNextChildContainer &&
             pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {
        CXFA_Node* pSaveNode = pNextChildContainer;
        pNextChildContainer = pNextChildContainer->GetNodeItem(
            XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
        if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
          XFA_DeleteLayoutGeneratedNode(pSaveNode);
        }
#endif
      }
      if (!pNextChildContainer) {
        goto NoMoreChildContainer;
      }
      FX_BOOL bLastKeep = FALSE;
      if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage,
                                       pNextChildContainer, bLastKeep)) {
        return;
      }
      if (!m_bKeepBreakFinish && !bLastKeep &&
          XFA_ItemLayoutProcessor_FindBreakNode(
              pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
              pCurActionNode, nCurStage, TRUE)) {
        return;
      }
      pCurActionNode = pNextChildContainer;
      if (m_bIsProcessKeep) {
        nCurStage = XFA_ItemLayoutProcessorStages_Keep;
      } else {
        nCurStage = XFA_ItemLayoutProcessorStages_Container;
      }
      return;
    }
    NoMoreChildContainer : {
      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
      case XFA_ItemLayoutProcessorStages_BookendTrailer:
        for (CXFA_Node* pBookendNode =
                 pCurActionNode == XFA_LAYOUT_INVALIDNODE
                     ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
                     : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
             pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
                               XFA_NODEITEM_NextSibling)) {
          switch (pBookendNode->GetClassID()) {
            case XFA_ELEMENT_Bookend:
            case XFA_ELEMENT_Break:
              pCurActionNode = pBookendNode;
              nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer;
              return;
            default:
              break;
          }
        }
    }
    default:
      pCurActionNode = NULL;
      nCurStage = XFA_ItemLayoutProcessorStages_Done;
  }
}
FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    CXFA_Node*& pNextContainer,
    FX_BOOL& bLastKeepNode) {
  FX_BOOL bCanSplite = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None;
  FX_BOOL bNextKeep = FALSE;
  if (XFA_ExistContainerKeep(pNextContainer, FALSE)) {
    bNextKeep = TRUE;
  }
  if (bNextKeep && !bCanSplite) {
    if (!m_bIsProcessKeep && !m_bKeepBreakFinish) {
      m_pKeepHeadNode = pNextContainer;
      m_bIsProcessKeep = TRUE;
    }
  } else {
    if (m_bIsProcessKeep && m_pKeepHeadNode != NULL) {
      m_pKeepTailNode = pNextContainer;
      if (!m_bKeepBreakFinish &&
          XFA_ItemLayoutProcessor_FindBreakNode(
              pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
              pCurActionNode, nCurStage, TRUE)) {
        return TRUE;
      } else {
        pNextContainer = m_pKeepHeadNode;
        m_bKeepBreakFinish = TRUE;
        m_pKeepHeadNode = NULL;
        m_pKeepTailNode = NULL;
        m_bIsProcessKeep = FALSE;
      }
    } else {
      if (m_bKeepBreakFinish) {
        bLastKeepNode = TRUE;
      }
      m_bKeepBreakFinish = FALSE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore(
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    CXFA_Node* pContainerNode) {
  if (m_pKeepTailNode == pContainerNode) {
    pCurActionNode = m_pKeepHeadNode;
    m_bKeepBreakFinish = TRUE;
    m_pKeepHeadNode = NULL;
    m_pKeepTailNode = NULL;
    m_bIsProcessKeep = FALSE;
    nCurStage = XFA_ItemLayoutProcessorStages_Container;
    return TRUE;
  }
  CXFA_Node* pBreakAfterNode =
      pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  if (XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
                                            nCurStage, FALSE)) {
    return TRUE;
  }
  return FALSE;
}
FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) {
  XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
  return ePresence == XFA_ATTRIBUTEENUM_Visible ||
         ePresence == XFA_ATTRIBUTEENUM_Invisible;
}
static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
    CXFA_Node* pFormNode,
    FX_FLOAT& fContainerWidth,
    FX_FLOAT& fContainerHeight,
    FX_BOOL& bContainerWidthAutoSize,
    FX_BOOL& bContainerHeightAutoSize) {
  fContainerWidth = 0;
  fContainerHeight = 0;
  bContainerWidthAutoSize = TRUE;
  bContainerHeightAutoSize = TRUE;
  XFA_ELEMENT eClassID = pFormNode->GetClassID();
  CXFA_Measurement mTmpValue;
  if (bContainerWidthAutoSize &&
      (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
      pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) &&
      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
    fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
    bContainerWidthAutoSize = FALSE;
  }
  if (bContainerHeightAutoSize &&
      (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
      pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) &&
      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
    fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
    bContainerHeightAutoSize = FALSE;
  }
  if (bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform &&
      pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) &&
      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
    fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
    bContainerWidthAutoSize = FALSE;
  }
  if (bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform &&
      pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) &&
      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
    fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
    bContainerHeightAutoSize = FALSE;
  }
}
static inline void
XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
    CXFA_Node* pFormNode,
    FX_BOOL bContainerWidthAutoSize,
    FX_FLOAT fContentCalculatedWidth,
    FX_FLOAT& fContainerWidth,
    FX_BOOL bContainerHeightAutoSize,
    FX_FLOAT fContentCalculatedHeight,
    FX_FLOAT& fContainerHeight) {
  CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  CXFA_Measurement mTmpValue;
  if (bContainerWidthAutoSize) {
    fContainerWidth = fContentCalculatedWidth;
    if (pMarginNode) {
      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) {
        fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
      }
      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) {
        fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
      }
    }
  }
  if (bContainerHeightAutoSize) {
    fContainerHeight = fContentCalculatedHeight;
    if (pMarginNode) {
      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) {
        fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
      }
      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue,
                                  FALSE)) {
        fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
      }
    }
  }
}
void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(
    CXFA_Node* pNode,
    FX_FLOAT fWidth,
    FX_FLOAT fHeight,
    FX_FLOAT& fAbsoluteX,
    FX_FLOAT& fAbsoluteY) {
  XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
  int32_t nAnchorType = 0;
  switch (eAnchorType) {
    case XFA_ATTRIBUTEENUM_TopLeft:
      nAnchorType = 0;
      break;
    case XFA_ATTRIBUTEENUM_TopCenter:
      nAnchorType = 1;
      break;
    case XFA_ATTRIBUTEENUM_TopRight:
      nAnchorType = 2;
      break;
    case XFA_ATTRIBUTEENUM_MiddleLeft:
      nAnchorType = 3;
      break;
    case XFA_ATTRIBUTEENUM_MiddleCenter:
      nAnchorType = 4;
      break;
    case XFA_ATTRIBUTEENUM_MiddleRight:
      nAnchorType = 5;
      break;
    case XFA_ATTRIBUTEENUM_BottomLeft:
      nAnchorType = 6;
      break;
    case XFA_ATTRIBUTEENUM_BottomCenter:
      nAnchorType = 7;
      break;
    case XFA_ATTRIBUTEENUM_BottomRight:
      nAnchorType = 8;
      break;
    default:
      break;
  }
  static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8},
                                         {6, 3, 0, 7, 4, 1, 8, 5, 2},
                                         {8, 7, 6, 5, 4, 3, 2, 1, 0},
                                         {2, 5, 8, 1, 4, 7, 0, 3, 6}};

  FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
  FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
  int32_t nRotate =
      FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
  nRotate = XFA_MapRotation(nRotate) / 90;
  int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];
  fAbsoluteX = fAnchorX;
  fAbsoluteY = fAnchorY;
  switch (nAbsoluteAnchorType / 3) {
    case 1:
      fAbsoluteY -= fHeight / 2;
      break;
    case 2:
      fAbsoluteY -= fHeight;
      break;
    default:
      break;
  }
  switch (nAbsoluteAnchorType % 3) {
    case 1:
      fAbsoluteX -= fWidth / 2;
      break;
    case 2:
      fAbsoluteX -= fWidth;
      break;
    default:
      break;
  }
}
FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(
    CXFA_LayoutProcessor* pLayoutProcessor,
    CXFA_Node* pNode,
    CXFA_Node* pParentNode) {
  return FALSE;
}
void CXFA_ItemLayoutProcessor::DoLayoutPageArea(
    CXFA_ContainerLayoutItem* pPageAreaLayoutItem) {
  CXFA_Node* pFormNode = pPageAreaLayoutItem->m_pFormNode;
  CXFA_Node* pCurChildNode = XFA_LAYOUT_INVALIDNODE;
  XFA_ItemLayoutProcessorStages nCurChildNodeStage =
      XFA_ItemLayoutProcessorStages_None;
  CXFA_LayoutItem* pBeforeItem = NULL;
  for (XFA_ItemLayoutProcessor_GotoNextContainerNode(
           pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);
       pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
           pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {
    if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
      continue;
    }
    if (pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
      continue;
    }
    CXFA_ItemLayoutProcessor* pProcessor =
        new CXFA_ItemLayoutProcessor(pCurChildNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
    pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
    if (!pProcessor->HasLayoutItem()) {
      delete pProcessor;
      continue;
    }
    FX_FLOAT fWidth, fHeight;
    pProcessor->GetCurrentComponentSize(fWidth, fHeight);
    FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
    CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX,
                                    fAbsoluteY);
    pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
    if (pBeforeItem == NULL) {
      pPageAreaLayoutItem->AddHeadChild(pProcessItem);
    } else {
      pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);
    }
    pBeforeItem = pProcessItem;
    delete pProcessor;
  }
  pBeforeItem = NULL;
  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;
  while (pLayoutItem) {
    if (!pLayoutItem->IsContentLayoutItem() ||
        pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {
      pLayoutItem = pLayoutItem->m_pNextSibling;
      continue;
    }
    if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {
      CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling;
      pPageAreaLayoutItem->RemoveChild(pLayoutItem);
      if (pBeforeItem == NULL) {
        pPageAreaLayoutItem->AddHeadChild(pLayoutItem);
      } else {
        pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);
      }
      pBeforeItem = pLayoutItem;
      pLayoutItem = pNextLayoutItem;
    }
  }
}
void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(
    CXFA_LayoutContext* pContext) {
  if (m_pLayoutItem != NULL) {
    return;
  }
  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) !=
                       XFA_ATTRIBUTEENUM_Position);
  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
      bContainerHeightAutoSize);
  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
  FX_FLOAT fHiddenContentCalculatedWidth = 0,
           fHiddenContentCalculatedHeight = 0;
  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
    XFA_ItemLayoutProcessor_GotoNextContainerNode(
        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
  }
  int32_t iColIndex = 0;
  for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
      continue;
    }
    if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
      continue;
    }
    CXFA_ItemLayoutProcessor* pProcessor =
        new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
    pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
    if (pContext && pContext->m_prgSpecifiedColumnWidths) {
      int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
      if (iColSpan <=
          pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {
        pContext->m_fCurColumnWidth = 0;
        pContext->m_bCurColumnWidthAvaiable = TRUE;
        if (iColSpan == -1) {
          iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();
        }
        for (int32_t i = 0; i < iColSpan; i++) {
          pContext->m_fCurColumnWidth +=
              pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);
        }
        if (pContext->m_fCurColumnWidth == 0) {
          pContext->m_bCurColumnWidthAvaiable = FALSE;
        }
        iColIndex += iColSpan;
      }
    }
    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
                         pContext);
    if (!pProcessor->HasLayoutItem()) {
      delete pProcessor;
      continue;
    }
    FX_FLOAT fWidth, fHeight;
    pProcessor->GetCurrentComponentSize(fWidth, fHeight);
    FX_BOOL bChangeParentSize = FALSE;
    if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
      bChangeParentSize = TRUE;
    }
    FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
    if (!bIgnoreXY) {
      CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight,
                                      fAbsoluteX, fAbsoluteY);
    }
    pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
    if (bContainerWidthAutoSize) {
      FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;
      if (bChangeParentSize) {
        if (fContentCalculatedWidth < fChildSuppliedWidth) {
          fContentCalculatedWidth = fChildSuppliedWidth;
        }
      } else {
        if (fHiddenContentCalculatedWidth < fChildSuppliedWidth &&
            m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
          fHiddenContentCalculatedWidth = fChildSuppliedWidth;
        }
      }
    }
    if (bContainerHeightAutoSize) {
      FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;
      if (bChangeParentSize) {
        if (fContentCalculatedHeight < fChildSuppliedHeight) {
          fContentCalculatedHeight = fChildSuppliedHeight;
        }
      } else {
        if (fHiddenContentCalculatedHeight < fChildSuppliedHeight &&
            m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
          fHiddenContentCalculatedHeight = fChildSuppliedHeight;
        }
      }
    }
    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
    delete pProcessor;
  }
  XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();
  if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {
    fContentCalculatedWidth = fHiddenContentCalculatedWidth;
  }
  if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {
    fContentCalculatedHeight = fHiddenContentCalculatedHeight;
  }
  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
      fContainerHeight);
  SetCurrentComponentSize(fContainerWidth, fContainerHeight);
}
static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(
    CXFA_ContentLayoutItem* pLayoutItem,
    FX_FLOAT& fWidth,
    FX_FLOAT& fHeight) {
  CXFA_Node* pNode = pLayoutItem->m_pFormNode;
  ASSERT(pNode);
  XFA_ELEMENT eClassID = pNode->GetClassID();
  switch (eClassID) {
    case XFA_ELEMENT_Subform:
    case XFA_ELEMENT_Area:
    case XFA_ELEMENT_ExclGroup:
    case XFA_ELEMENT_SubformSet: {
      if (fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {
        fWidth = pLayoutItem->m_sSize.x;
      }
      if (fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {
        fHeight = pLayoutItem->m_sSize.y;
      }
      break;
    }
    case XFA_ELEMENT_Draw:
    case XFA_ELEMENT_Field: {
      pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(
          pNode, fWidth, fHeight);
      break;
    }
    default:
      ASSERT(FALSE);
  }
}
static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(
    CXFA_ContentLayoutItem* pLayoutRow,
    const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths,
    XFA_ATTRIBUTEENUM eLayout) {
  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
      pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight,
      bContainerWidthAutoSize, bContainerHeightAutoSize);
  CXFA_Node* pMarginNode =
      pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
    fTopInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fRightInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
    fBottomInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  FX_FLOAT fContentWidthLimit =
      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
                              : fContainerWidth - fLeftInset - fRightInset;
  FX_FLOAT fContentCurrentHeight =
      pLayoutRow->m_sSize.y - fTopInset - fBottomInset;
  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
  FX_FLOAT fCurrentColX = 0;
  int32_t nCurrentColIdx = 0;
  FX_BOOL bMetWholeRowCell = FALSE;
  for (CXFA_ContentLayoutItem* pLayoutChild =
           (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
       pLayoutChild;
       pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
    int32_t nOriginalColSpan =
        pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
    int32_t nColSpan = nOriginalColSpan;
    FX_FLOAT fColSpanWidth = 0;
    if (nColSpan == -1 ||
        nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {
      nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;
    }
    for (int32_t i = 0; i < nColSpan; i++) {
      fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];
    }
    if (nColSpan != nOriginalColSpan) {
      fColSpanWidth = bMetWholeRowCell ? 0 : std::max(fColSpanWidth,
                                                      pLayoutChild->m_sSize.y);
    }
    if (nOriginalColSpan == -1) {
      bMetWholeRowCell = TRUE;
    }
    pLayoutChild->m_sPos.Set(fCurrentColX, 0);
    pLayoutChild->m_sSize.x = fColSpanWidth;
    if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
      fCurrentColX += fColSpanWidth;
      nCurrentColIdx += nColSpan;
      FX_FLOAT fNewHeight =
          bContainerHeightAutoSize ? -1 : fContentCurrentHeight;
      XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth,
                                               fNewHeight);
      pLayoutChild->m_sSize.y = fNewHeight;
      if (bContainerHeightAutoSize) {
        FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;
        if (fContentCalculatedHeight < fChildSuppliedHeight) {
          fContentCalculatedHeight = fChildSuppliedHeight;
        }
      }
    }
  }
  if (bContainerHeightAutoSize) {
    for (CXFA_ContentLayoutItem* pLayoutChild =
             (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
         pLayoutChild;
         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
      XFA_ItemLayoutProcessor_UpdateWidgetSize(
          pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);
      FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;
      pLayoutChild->m_sSize.y = fContentCalculatedHeight;
      CXFA_Node* pParaNode =
          pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);
      if (pParaNode && pLayoutChild->m_pFirstChild) {
        FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;
        XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);
        switch (eVType) {
          case XFA_ATTRIBUTEENUM_Middle:
            fOffHeight = fOffHeight / 2;
            break;
          case XFA_ATTRIBUTEENUM_Bottom:
            break;
          case XFA_ATTRIBUTEENUM_Top:
          default:
            fOffHeight = 0;
            break;
        }
        if (fOffHeight > 0) {
          for (CXFA_ContentLayoutItem* pInnerLayoutChild =
                   (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild;
               pInnerLayoutChild;
               pInnerLayoutChild =
                   (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) {
            pInnerLayoutChild->m_sPos.y += fOffHeight;
          }
        }
      }
    }
  }
  if (bContainerWidthAutoSize) {
    FX_FLOAT fChildSuppliedWidth = fCurrentColX;
    if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
        fContentWidthLimit > fChildSuppliedWidth) {
      fChildSuppliedWidth = fContentWidthLimit;
    }
    if (fContentCalculatedWidth < fChildSuppliedWidth) {
      fContentCalculatedWidth = fChildSuppliedWidth;
    }
  } else {
    fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;
  }
  if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) ==
      XFA_ATTRIBUTEENUM_Rl_row) {
    for (CXFA_ContentLayoutItem* pLayoutChild =
             (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
         pLayoutChild;
         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
      pLayoutChild->m_sPos.x = fContentCalculatedWidth -
                               pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;
    }
  }
  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
      pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
      fContainerHeight);
  pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight);
}
void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) {
  if (m_pLayoutItem != NULL) {
    return;
  }
  if (pLayoutNode == NULL) {
    pLayoutNode = m_pFormNode;
  }
  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
      bContainerHeightAutoSize);
  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
  CXFA_Node* pMarginNode =
      m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
    fTopInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fRightInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
    fBottomInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  FX_FLOAT fContentWidthLimit =
      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
                              : fContainerWidth - fLeftInset - fRightInset;
  CFX_WideStringC wsColumnWidths;
  if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {
    CFX_WideStringArray widths;
    if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(),
                           L' ', widths) > 0) {
      int32_t iCols = widths.GetSize();
      CFX_WideString wsWidth;
      for (int32_t i = 0; i < iCols; i++) {
        wsWidth = widths[i];
        wsWidth.TrimLeft(L' ');
        if (!wsWidth.IsEmpty()) {
          CXFA_Measurement measure(wsWidth);
          m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));
        }
      }
    }
  }
  int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();
  CXFA_LayoutContext layoutContext;
  layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
  CXFA_LayoutContext* pLayoutContext =
      iSpecifiedColumnCount > 0 ? &layoutContext : NULL;
  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
    XFA_ItemLayoutProcessor_GotoNextContainerNode(
        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
  }
  for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
    layoutContext.m_bCurColumnWidthAvaiable = FALSE;
    layoutContext.m_fCurColumnWidth = 0;
    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
      continue;
    }
    CXFA_ItemLayoutProcessor* pProcessor =
        new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
    pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
                         pLayoutContext);
    if (!pProcessor->HasLayoutItem()) {
      delete pProcessor;
      continue;
    }
    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
    delete pProcessor;
  }
  int32_t iRowCount = 0, iColCount = 0;
  {
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgRowItems;
    CFX_ArrayTemplate<int32_t> rgRowItemsSpan;
    CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;
    for (CXFA_ContentLayoutItem* pLayoutChild =
             (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
         pLayoutChild;
         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
      if (pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {
        continue;
      }
      if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
        continue;
      }
      XFA_ATTRIBUTEENUM eLayout =
          pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
      if (eLayout != XFA_ATTRIBUTEENUM_Row &&
          eLayout != XFA_ATTRIBUTEENUM_Rl_row) {
        continue;
      }
      if (CXFA_ContentLayoutItem* pRowLayoutCell =
              (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild) {
        rgRowItems.Add(pRowLayoutCell);
        int32_t iColSpan =
            pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
        rgRowItemsSpan.Add(iColSpan);
        rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);
      }
    }
    iRowCount = rgRowItems.GetSize();
    iColCount = 0;
    FX_BOOL bMoreColumns = TRUE;
    while (bMoreColumns) {
      bMoreColumns = FALSE;
      FX_BOOL bAutoCol = FALSE;
      for (int32_t i = 0; i < iRowCount; i++) {
        while (rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 ||
                                         !XFA_ItemLayoutProcessor_IsTakingSpace(
                                             rgRowItems[i]->m_pFormNode))) {
          CXFA_ContentLayoutItem* pNewCell =
              (CXFA_ContentLayoutItem*)rgRowItems[i]->m_pNextSibling;
          if (rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(
                                           rgRowItems[i]->m_pFormNode)) {
            pNewCell = NULL;
          }
          rgRowItems[i] = pNewCell;
          rgRowItemsSpan[i] =
              pNewCell
                  ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan)
                  : 0;
          rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;
        }
        CXFA_ContentLayoutItem* pCell = rgRowItems[i];
        if (!pCell) {
          continue;
        }
        bMoreColumns = TRUE;
        if (rgRowItemsSpan[i] == 1) {
          if (iColCount >= iSpecifiedColumnCount) {
            for (int32_t j = 0, c = iColCount + 1 -
                                    m_rgSpecifiedColumnWidths.GetSize();
                 j < c; j++) {
              m_rgSpecifiedColumnWidths.Add(0);
            }
          }
          if (m_rgSpecifiedColumnWidths[iColCount] <
              XFA_LAYOUT_FLOAT_PERCISION) {
            bAutoCol = TRUE;
          }
          if (bAutoCol &&
              m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {
            m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];
          }
        }
      }
      if (bMoreColumns) {
        FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];
        for (int32_t i = 0; i < iRowCount; i++) {
          if (!rgRowItems[i]) {
            continue;
          }
          rgRowItemsSpan[i]--;
          rgRowItemsWidth[i] -= fFinalColumnWidth;
        }
        iColCount++;
      }
    }
  }
  FX_FLOAT fCurrentRowY = 0;
  for (CXFA_ContentLayoutItem* pLayoutChild =
           (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
       pLayoutChild;
       pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
    if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
      continue;
    }
    if (pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {
      XFA_ATTRIBUTEENUM eSubformLayout =
          pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
      if (eSubformLayout == XFA_ATTRIBUTEENUM_Row ||
          eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {
        XFA_ItemLayoutProcessor_RelocateTableRowCells(
            pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);
      }
    }
    pLayoutChild->m_sPos.y = fCurrentRowY;
    if (bContainerWidthAutoSize) {
      pLayoutChild->m_sPos.x = 0;
    } else {
      switch (pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
        case XFA_ATTRIBUTEENUM_Left:
        default:
          pLayoutChild->m_sPos.x = 0;
          break;
        case XFA_ATTRIBUTEENUM_Center:
          pLayoutChild->m_sPos.x =
              (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2;
          break;
        case XFA_ATTRIBUTEENUM_Right:
          pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;
          break;
      }
    }
    if (bContainerWidthAutoSize) {
      FX_FLOAT fChildSuppliedWidth =
          pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;
      if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
          fContentWidthLimit > fChildSuppliedWidth) {
        fChildSuppliedWidth = fContentWidthLimit;
      }
      if (fContentCalculatedWidth < fChildSuppliedWidth) {
        fContentCalculatedWidth = fChildSuppliedWidth;
      }
    }
    fCurrentRowY += pLayoutChild->m_sSize.y;
  }
  if (bContainerHeightAutoSize) {
    FX_FLOAT fChildSuppliedHeight = fCurrentRowY;
    if (fContentCalculatedHeight < fChildSuppliedHeight) {
      fContentCalculatedHeight = fChildSuppliedHeight;
    }
  }
  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
      fContainerHeight);
  SetCurrentComponentSize(fContainerWidth, fContainerHeight);
}
static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt(
    XFA_ATTRIBUTEENUM eHAlign) {
  switch (eHAlign) {
    case XFA_ATTRIBUTEENUM_Center:
      return 1;
    case XFA_ATTRIBUTEENUM_Right:
      return 2;
    case XFA_ATTRIBUTEENUM_Left:
    default:
      return 0;
  }
}
static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout(
    CXFA_ItemLayoutProcessor* pProcessor,
    CXFA_ContentLayoutItem* pLayoutItem) {
  XFA_ATTRIBUTEENUM eLayout =
      pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
  switch (eLayout) {
    case XFA_ATTRIBUTEENUM_Row:
    case XFA_ATTRIBUTEENUM_Rl_row:
      XFA_ItemLayoutProcessor_RelocateTableRowCells(
          pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);
      break;
    default:
      break;
  }
}
FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(
    CXFA_ContentLayoutItem* pTrailerItem) {
  if (!pTrailerItem) {
    return FALSE;
  }
  FX_FLOAT fWidth = pTrailerItem->m_sSize.x;
  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
  if (eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {
    return FALSE;
  }
  return TRUE;
}
static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
    CXFA_ItemLayoutProcessor* pProcessor,
    FX_FLOAT fSplitPos,
    CXFA_ContentLayoutItem* pTrailerLayoutItem,
    FX_BOOL bUseInherited = FALSE) {
  if (!pTrailerLayoutItem) {
    return;
  }
  FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;
  if (bUseInherited) {
    FX_FLOAT fNewSplitPos = 0;
    if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
      fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
    }
    if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
      pProcessor->SplitLayoutItem(fNewSplitPos);
    }
    return;
  }
  XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor,
                                                 pTrailerLayoutItem);
  CXFA_Node* pMarginNode =
      pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
    fTopInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fRightInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
    fBottomInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {
    pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;
    pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;
    pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;
    pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
    return;
  }
  FX_FLOAT fNewSplitPos = 0;
  if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
    fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
  }
  if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
    pProcessor->SplitLayoutItem(fNewSplitPos);
    pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;
  } else {
    pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;
  }
  switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
    case XFA_ATTRIBUTEENUM_Left:
    default:
      pTrailerLayoutItem->m_sPos.x = fLeftInset;
      break;
    case XFA_ATTRIBUTEENUM_Right:
      pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
                                     fRightInset -
                                     pTrailerLayoutItem->m_sSize.x;
      break;
    case XFA_ATTRIBUTEENUM_Center:
      pTrailerLayoutItem->m_sPos.x =
          (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
           pTrailerLayoutItem->m_sSize.x) /
          2;
      break;
  }
  pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
  pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
};
static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(
    CXFA_ItemLayoutProcessor* pProcessor,
    CXFA_ContentLayoutItem* pLeaderLayoutItem) {
  XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);
  CXFA_Node* pMarginNode =
      pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
    fTopInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fRightInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
    fBottomInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;
  for (CXFA_ContentLayoutItem* pChildItem =
           (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild;
       pChildItem;
       pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
    pChildItem->m_sPos.y += fHeight;
  }
  pLeaderLayoutItem->m_sPos.y = 0;
  switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
    case XFA_ATTRIBUTEENUM_Left:
    default:
      pLeaderLayoutItem->m_sPos.x = fLeftInset;
      break;
    case XFA_ATTRIBUTEENUM_Right:
      pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
                                    fRightInset - pLeaderLayoutItem->m_sSize.x;
      break;
    case XFA_ATTRIBUTEENUM_Center:
      pLeaderLayoutItem->m_sPos.x =
          (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
           pLeaderLayoutItem->m_sSize.x) /
          2;
      break;
  }
  pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
  pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);
};
static void XFA_ItemLayoutProcessor_AddPendingNode(
    CXFA_ItemLayoutProcessor* pProcessor,
    CXFA_Node* pPendingNode,
    FX_BOOL bBreakPending) {
  pProcessor->m_rgPendingNodes.AddTail(pPendingNode);
  pProcessor->m_bBreakPending = bBreakPending;
}
static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(
    CXFA_ItemLayoutProcessor* pProcessor,
    CXFA_Node* pCurChildNode) {
  FX_FLOAT fTotalHeight = 0;
  if (pProcessor->m_rgPendingNodes.GetCount() < 1) {
    return fTotalHeight;
  }
  if (pProcessor->m_pLayoutItem == NULL) {
    pProcessor->m_pLayoutItem =
        pProcessor->CreateContentLayoutItem(pCurChildNode);
    pProcessor->m_pLayoutItem->m_sSize.Set(0, 0);
  }
  while (pProcessor->m_rgPendingNodes.GetCount() > 0) {
    FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition();
    CXFA_Node* pPendingNode =
        (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos);
    pProcessor->m_rgPendingNodes.RemoveAt(pos);
    CXFA_ContentLayoutItem* pPendingLayoutItem = NULL;
    CXFA_ItemLayoutProcessor* pPendingProcessor =
        new CXFA_ItemLayoutProcessor(pPendingNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
    pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;
#endif
    pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
    pPendingLayoutItem = pPendingProcessor->HasLayoutItem()
                             ? pPendingProcessor->ExtractLayoutItem()
                             : NULL;
    delete pPendingProcessor;
    if (pPendingLayoutItem) {
      XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor,
                                                  pPendingLayoutItem);
      if (pProcessor->m_bBreakPending) {
        fTotalHeight += pPendingLayoutItem->m_sSize.y;
      }
    }
  }
  return fTotalHeight;
}
FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() {
  FX_FLOAT fTotalHeight = 0;
  if (m_arrayKeepItems.GetSize()) {
    if (m_pLayoutItem == NULL) {
      m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
      m_pLayoutItem->m_sSize.Set(0, 0);
    }
    for (int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0;
         iIndex--) {
      XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this,
                                                  m_arrayKeepItems[iIndex]);
      fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;
    }
    m_arrayKeepItems.RemoveAll();
  }
  return fTotalHeight;
}
FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(
    CXFA_ItemLayoutProcessor* pParentProcessor,
    CXFA_ItemLayoutProcessor* pChildProcessor,
    XFA_ItemLayoutProcessorResult eRetValue,
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem,
    FX_FLOAT& fContentCurRowAvailWidth,
    FX_FLOAT& fContentCurRowHeight,
    FX_FLOAT& fContentCurRowY,
    FX_BOOL& bAddedItemInRow,
    FX_BOOL& bForceEndPage,
    XFA_ItemLayoutProcessorResult& result) {
  if (pParentProcessor == NULL || pChildProcessor == NULL) {
    return FALSE;
  }
  if (pParentProcessor->m_pCurChildNode->GetIntact() !=
          XFA_ATTRIBUTEENUM_None ||
      !pChildProcessor->m_bHasAvailHeight) {
    if (XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {
      FX_FLOAT fChildWidth, fChildHeight;
      pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
      CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
      if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem,
                                             fChildHeight, keepLayoutItems)) {
        m_arrayKeepItems.RemoveAll();
        for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {
          CXFA_ContentLayoutItem* pItem = keepLayoutItems.GetAt(iIndex);
          pParentProcessor->m_pLayoutItem->RemoveChild(pItem);
          fContentCurRowY -= pItem->m_sSize.y;
          m_arrayKeepItems.Add(pItem);
        }
        bAddedItemInRow = TRUE;
        bForceEndPage = TRUE;
        result = XFA_ItemLayoutProcessorResult_PageFullBreak;
        return TRUE;
      }
      rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());
      bAddedItemInRow = TRUE;
      fContentCurRowAvailWidth -= fChildWidth;
      if (fContentCurRowHeight < fChildHeight) {
        fContentCurRowHeight = fChildHeight;
      }
      result = eRetValue;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(
    CXFA_ContentLayoutItem* pParentLayoutItem,
    FX_FLOAT fChildHeight,
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems) {
  if (pParentLayoutItem == NULL) {
    return FALSE;
  }
  FX_FLOAT fItemsHeight = 0;
  for (CXFA_ContentLayoutItem* pChildLayoutItem =
           (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild;
       pChildLayoutItem;
       pChildLayoutItem =
           (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) {
    if (XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {
      pKeepItems.Add(pChildLayoutItem);
      fItemsHeight += pChildLayoutItem->m_sSize.y;
    } else {
      pKeepItems.RemoveAll();
      fItemsHeight = 0;
    }
  }
  fItemsHeight += fChildHeight;
  if (m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {
    return TRUE;
  }
  return FALSE;
}
void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
  if (!pFormNode) {
    return;
  }
  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
      pFormNode);
  for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
       pNode = sIterator.MoveToNext()) {
    if (pNode->IsContainerNode()) {
      CXFA_Node* pBindNode = pNode->GetBindData();
      if (pBindNode) {
        pBindNode->RemoveBindItem(pNode);
        pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
      }
    }
    pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
  }
}
void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(
    CXFA_Node* pLeaderNode,
    CXFA_Node* pTrailerNode,
    CXFA_ContentLayoutItem* pTrailerItem,
    CXFA_Node* pFormNode) {
  ProcessUnUseBinds(pLeaderNode);
  ProcessUnUseBinds(pTrailerNode);
  if (pFormNode == NULL) {
    return;
  }
  if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow ||
      pFormNode->GetClassID() == XFA_ELEMENT_Break) {
    pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
  }
  if (pLeaderNode && pFormNode) {
    pFormNode->RemoveChild(pLeaderNode);
  }
  if (pTrailerNode && pFormNode) {
    pFormNode->RemoveChild(pTrailerNode);
  }
  if (pTrailerItem) {
    XFA_ReleaseLayoutItem(pTrailerItem);
  }
}
static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(
    CXFA_ItemLayoutProcessor* pThis,
    CXFA_ItemLayoutProcessor*& pProcessor,
    FX_BOOL bContainerWidthAutoSize,
    FX_BOOL bContainerHeightAutoSize,
    FX_FLOAT fContainerHeight,
    XFA_ATTRIBUTEENUM eFlowStrategy,
    uint8_t& uCurHAlignState,
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
    FX_BOOL bUseBreakControl,
    FX_FLOAT fAvailHeight,
    FX_FLOAT fRealHeight,
    FX_FLOAT& fContentCurRowY,
    FX_FLOAT& fContentWidthLimit,
    FX_FLOAT& fContentCurRowAvailWidth,
    FX_FLOAT& fContentCurRowHeight,
    FX_BOOL& bAddedItemInRow,
    FX_BOOL& bForceEndPage,
    CXFA_LayoutContext* pLayoutContext = NULL,
    FX_BOOL bNewRow = FALSE) {
  FX_BOOL bTakeSpace =
      XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);
  uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
      pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));
  if (bContainerWidthAutoSize) {
    uHAlign = 0;
  }
  if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) ||
      (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {
    return XFA_ItemLayoutProcessorResult_RowFullBreak;
  }
  uCurHAlignState = uHAlign;
  FX_BOOL bIsOwnSplite =
      pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;
  FX_BOOL bUseRealHeight =
      bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite &&
      pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() ==
          XFA_ATTRIBUTEENUM_None;
  FX_BOOL bIsTransHeight = bTakeSpace;
  if (bIsTransHeight && !bIsOwnSplite) {
    FX_BOOL bRootForceTb = FALSE;
    XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(
        pProcessor->m_pFormNode, bRootForceTb);
    if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb ||
        eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {
      bIsTransHeight = FALSE;
    }
  }
  FX_BOOL bUseInherited = FALSE;
  CXFA_LayoutContext layoutContext;
  if (pThis->m_pPageMgr) {
    CXFA_Node* pOverflowNode =
        pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);
    if (pOverflowNode) {
      layoutContext.m_pOverflowNode = pOverflowNode;
      layoutContext.m_pOverflowProcessor = pThis;
      pLayoutContext = &layoutContext;
    }
  }
  XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;
  if (!bNewRow ||
      pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {
    eRetValue = pProcessor->DoLayout(
        bTakeSpace ? bUseBreakControl : FALSE,
        bUseRealHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
        bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
        pLayoutContext);
    pProcessor->m_ePreProcessRs = eRetValue;
  } else {
    eRetValue = pProcessor->m_ePreProcessRs;
    pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;
  }
  if (pProcessor->HasLayoutItem() == FALSE) {
    return eRetValue;
  }
  FX_FLOAT fChildWidth, fChildHeight;
  pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
  if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {
    fRealHeight = XFA_LAYOUT_FLOAT_MAX;
    fAvailHeight = XFA_LAYOUT_FLOAT_MAX;
  }
  if (!bTakeSpace ||
      (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) ||
      (fContentWidthLimit - fContentCurRowAvailWidth <=
       XFA_LAYOUT_FLOAT_PERCISION)) {
    CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL,
              *pFormNode = NULL;
    CXFA_ContentLayoutItem* pTrailerLayoutItem = NULL;
    FX_BOOL bIsAddTrailerHeight = FALSE;
    if (pThis->m_pPageMgr &&
        pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
      pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);
      if (pFormNode == NULL && pLayoutContext &&
          pLayoutContext->m_pOverflowProcessor) {
        pFormNode = pLayoutContext->m_pOverflowNode;
        bUseInherited = TRUE;
      }
      if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
                                             pOverflowTrailerNode, FALSE,
                                             FALSE)) {
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
          if (pOverflowTrailerNode) {
            CXFA_ItemLayoutProcessor* pOverflowLeaderProcessor =
                new CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
            pOverflowLeaderProcessor->m_pPageMgrCreateItem =
                pProcessor->m_pPageMgrCreateItem;
#endif
            pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
            pTrailerLayoutItem =
                pOverflowLeaderProcessor->HasLayoutItem()
                    ? pOverflowLeaderProcessor->ExtractLayoutItem()
                    : NULL;
            delete pOverflowLeaderProcessor;
          }
          if (bUseInherited) {
            bIsAddTrailerHeight =
                pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);
          } else {
            bIsAddTrailerHeight =
                pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
          }
          if (bIsAddTrailerHeight) {
            FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;
            fChildHeight += fTrailerHeight;
            bIsAddTrailerHeight = TRUE;
          }
        }
      }
    }
    if (!bTakeSpace ||
        fContentCurRowY + fChildHeight <=
            fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||
        (!bContainerHeightAutoSize &&
         pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >=
             fContainerHeight)) {
      if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {
        if (pProcessor->m_bUseInheriated) {
          if (pTrailerLayoutItem) {
            XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
                pProcessor, fChildHeight, pTrailerLayoutItem);
          }
          if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
            XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
                                                   pOverflowLeaderNode, FALSE);
          }
          pProcessor->m_bUseInheriated = FALSE;
        } else {
          if (bIsAddTrailerHeight) {
            fChildHeight -= pTrailerLayoutItem->m_sSize.y;
          }
          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                           pOverflowTrailerNode,
                                           pTrailerLayoutItem, pFormNode);
        }
        CXFA_ContentLayoutItem* pChildLayoutItem =
            pProcessor->ExtractLayoutItem();
        if (XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) &&
            pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
          pThis->m_arrayKeepItems.Add(pChildLayoutItem);
        } else {
          pThis->m_arrayKeepItems.RemoveAll();
        }
        rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);
        bAddedItemInRow = TRUE;
        if (bTakeSpace) {
          fContentCurRowAvailWidth -= fChildWidth;
          if (fContentCurRowHeight < fChildHeight) {
            fContentCurRowHeight = fChildHeight;
          }
        }
        return XFA_ItemLayoutProcessorResult_Done;
      } else {
        if (eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {
          if (pProcessor->m_bUseInheriated) {
            if (pTrailerLayoutItem) {
              XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
                  pProcessor, fChildHeight, pTrailerLayoutItem);
            }
            if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
              XFA_ItemLayoutProcessor_AddPendingNode(
                  pProcessor, pOverflowLeaderNode, FALSE);
            }
            pProcessor->m_bUseInheriated = FALSE;
          } else {
            if (bIsAddTrailerHeight) {
              fChildHeight -= pTrailerLayoutItem->m_sSize.y;
            }
            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                             pOverflowTrailerNode,
                                             pTrailerLayoutItem, pFormNode);
          }
        }
        rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
        bAddedItemInRow = TRUE;
        fContentCurRowAvailWidth -= fChildWidth;
        if (fContentCurRowHeight < fChildHeight) {
          fContentCurRowHeight = fChildHeight;
        }
        return eRetValue;
      }
    } else {
      XFA_ItemLayoutProcessorResult eResult;
      if (pThis->ProcessKeepForSplite(
              pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],
              fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY,
              bAddedItemInRow, bForceEndPage, eResult)) {
        return eResult;
      }
      bForceEndPage = TRUE;
      FX_FLOAT fSplitPos =
          pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);
      if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
        XFA_ATTRIBUTEENUM eLayout =
            pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
        if (eLayout == XFA_ATTRIBUTEENUM_Tb &&
            eRetValue == XFA_ItemLayoutProcessorResult_Done) {
          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                           pOverflowTrailerNode,
                                           pTrailerLayoutItem, pFormNode);
          rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
          bAddedItemInRow = TRUE;
          if (bTakeSpace) {
            fContentCurRowAvailWidth -= fChildWidth;
            if (fContentCurRowHeight < fChildHeight) {
              fContentCurRowHeight = fChildHeight;
            }
          }
          return XFA_ItemLayoutProcessorResult_PageFullBreak;
        }
        CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
        if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated &&
            eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {
          pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
                                             pTempTrailerNode, FALSE, TRUE);
        }
        if (pTrailerLayoutItem && bIsAddTrailerHeight) {
          XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
              pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);
        } else {
          pProcessor->SplitLayoutItem(fSplitPos);
        }
        if (bUseInherited) {
          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                           pOverflowTrailerNode,
                                           pTrailerLayoutItem, pFormNode);
          pThis->m_bUseInheriated = TRUE;
        } else {
          if (pProcessor->m_pLayoutItem->m_pFirstChild &&
              pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling ==
                  NULL &&
              pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(
                  XFA_NODEFLAG_LayoutGeneratedNode)) {
            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                             pOverflowTrailerNode,
                                             pTrailerLayoutItem, pFormNode);
          } else {
            if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
              XFA_ItemLayoutProcessor_AddPendingNode(
                  pProcessor, pOverflowLeaderNode, FALSE);
            }
          }
        }
        if (pProcessor->m_pLayoutItem->m_pNextSibling) {
          pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
          rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
          bAddedItemInRow = TRUE;
          if (bTakeSpace) {
            fContentCurRowAvailWidth -= fChildWidth;
            if (fContentCurRowHeight < fChildHeight) {
              fContentCurRowHeight = fChildHeight;
            }
          }
        }
        return XFA_ItemLayoutProcessorResult_PageFullBreak;
      } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {
        pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
        if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {
          CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
          if (pThis->m_pPageMgr) {
            if (pFormNode == NULL && pLayoutContext != NULL) {
              pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
            }
            pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
                                               pTempTrailerNode, FALSE, TRUE);
          }
          if (bUseInherited) {
            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                             pOverflowTrailerNode,
                                             pTrailerLayoutItem, pFormNode);
            pThis->m_bUseInheriated = TRUE;
          }
          return XFA_ItemLayoutProcessorResult_PageFullBreak;
        }
        rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
        bAddedItemInRow = TRUE;
        if (bTakeSpace) {
          fContentCurRowAvailWidth -= fChildWidth;
          if (fContentCurRowHeight < fChildHeight) {
            fContentCurRowHeight = fChildHeight;
          }
        }
        if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
          bForceEndPage = FALSE;
        }
        return eRetValue;
      } else {
        XFA_ATTRIBUTEENUM eLayout =
            pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
        if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None &&
            eLayout == XFA_ATTRIBUTEENUM_Tb) {
          if (pThis->m_pPageMgr) {
            pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
                                               pOverflowTrailerNode, FALSE,
                                               TRUE);
          }
          if (pTrailerLayoutItem) {
            XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos,
                                                          pTrailerLayoutItem);
          }
          if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
            XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
                                                   pOverflowLeaderNode, FALSE);
          }
        } else {
          if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
            if (pFormNode == NULL && pLayoutContext != NULL) {
              pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
            }
            if (pThis->m_pPageMgr) {
              pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
                                                 pOverflowTrailerNode, FALSE,
                                                 TRUE);
            }
            if (bUseInherited) {
              pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                               pOverflowTrailerNode,
                                               pTrailerLayoutItem, pFormNode);
              pThis->m_bUseInheriated = TRUE;
            }
          }
        }
        return XFA_ItemLayoutProcessorResult_PageFullBreak;
      }
    }
  } else {
    return XFA_ItemLayoutProcessorResult_RowFullBreak;
  }
  return XFA_ItemLayoutProcessorResult_Done;
}
XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(
    FX_BOOL bUseBreakControl,
    XFA_ATTRIBUTEENUM eFlowStrategy,
    FX_FLOAT fHeightLimit,
    FX_FLOAT fRealHeight,
    CXFA_LayoutContext* pContext,
    FX_BOOL bRootForceTb) {
  m_bHasAvailHeight = TRUE;
  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
  FX_BOOL bBreakDone = FALSE;
  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
  FX_BOOL bForceEndPage = FALSE;
  FX_BOOL bIsManualBreak = FALSE;
  if (m_pCurChildPreprocessor) {
    m_pCurChildPreprocessor->m_ePreProcessRs =
        XFA_ItemLayoutProcessorResult_Done;
  }
  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
      bContainerHeightAutoSize);
  if (pContext && pContext->m_bCurColumnWidthAvaiable) {
    bContainerWidthAutoSize = FALSE;
    fContainerWidth = pContext->m_fCurColumnWidth;
  }
  if (!bContainerHeightAutoSize) {
    fContainerHeight -= m_fUsedSize;
  }
  if (!bContainerHeightAutoSize) {
    CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
    FX_BOOL bFocrTb = FALSE;
    if (pParentNode &&
        XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) ==
            XFA_ATTRIBUTEENUM_Row) {
      CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(
          XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
      if (pChildContainer &&
          pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
                                       XFA_OBJECTTYPE_ContainerNode)) {
        fContainerHeight = 0;
        bContainerHeightAutoSize = TRUE;
      }
    }
  }
  CXFA_Node* pMarginNode =
      m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
    fTopInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
    fRightInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
    fBottomInset =
        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
  }
  FX_FLOAT fContentWidthLimit =
      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
                              : fContainerWidth - fLeftInset - fRightInset;
  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
  FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;
  if (fAvailHeight < 0) {
    m_bHasAvailHeight = FALSE;
  }
  fRealHeight = fRealHeight - fTopInset - fBottomInset;
  FX_FLOAT fContentCurRowY = 0;
  CXFA_ContentLayoutItem* pLayoutChild = NULL;
  if (m_pLayoutItem != NULL) {
    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done &&
        eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {
      pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
      for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
           pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
        if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {
          pLayoutChild = pLayoutNext;
        }
      }
    }
    for (CXFA_ContentLayoutItem* pLayoutTempChild =
             (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
         pLayoutTempChild != pLayoutChild;
         pLayoutTempChild =
             (CXFA_ContentLayoutItem*)pLayoutTempChild->m_pNextSibling) {
      if (XFA_ItemLayoutProcessor_IsTakingSpace(
              pLayoutTempChild->m_pFormNode)) {
        FX_FLOAT fChildContentWidth =
            pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;
        FX_FLOAT fChildContentHeight =
            pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;
        if (fContentCalculatedWidth < fChildContentWidth) {
          fContentCalculatedWidth = fChildContentWidth;
        }
        if (fContentCalculatedHeight < fChildContentHeight) {
          fContentCalculatedHeight = fChildContentHeight;
        }
      }
    }
    if (pLayoutChild) {
      fContentCurRowY = pLayoutChild->m_sPos.y;
    } else {
      fContentCurRowY = fContentCalculatedHeight;
    }
  }
  fContentCurRowY += InsertKeepLayoutItems();
  if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {
    XFA_ItemLayoutProcessor_GotoNextContainerNode(
        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
  }
  fContentCurRowY +=
      XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
  if (m_pCurChildPreprocessor &&
      m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {
    if (XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {
      m_pKeepHeadNode = m_pCurChildNode;
      m_bIsProcessKeep = TRUE;
      m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;
    }
  }
  while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {
    FX_FLOAT fContentCurRowHeight = 0;
    FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;
    m_fWidthLimite = fContentCurRowAvailWidth;
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3];
    uint8_t uCurHAlignState =
        (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);
    if (pLayoutChild) {
      for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
           pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
        if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor &&
            m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {
          pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;
          m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
          break;
        }
        uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
            pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));
        rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);
        if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {
          if (uHAlign > uCurHAlignState) {
            uCurHAlignState = uHAlign;
          }
        } else if (uHAlign < uCurHAlignState) {
          uCurHAlignState = uHAlign;
        }
        if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {
          if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {
            fContentCurRowHeight = pLayoutNext->m_sSize.y;
          }
          fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;
        }
      }
      if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild ==
          pLayoutChild) {
        m_pLayoutItem->m_pFirstChild = NULL;
      } else {
        CXFA_ContentLayoutItem* pLayoutNext =
            (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
        for (; pLayoutNext;
             pLayoutNext =
                 (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
          if ((CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling ==
              pLayoutChild) {
            pLayoutNext->m_pNextSibling = NULL;
            break;
          }
        }
      }
      CXFA_ContentLayoutItem* pLayoutNextTemp =
          (CXFA_ContentLayoutItem*)pLayoutChild;
      while (pLayoutNextTemp) {
        pLayoutNextTemp->m_pParent = NULL;
        CXFA_ContentLayoutItem* pSaveLayoutNext =
            (CXFA_ContentLayoutItem*)pLayoutNextTemp->m_pNextSibling;
        pLayoutNextTemp->m_pNextSibling = NULL;
        pLayoutNextTemp = pSaveLayoutNext;
      }
      pLayoutChild = NULL;
    }
    while (m_pCurChildNode) {
      CXFA_ItemLayoutProcessor* pProcessor = NULL;
      FX_BOOL bAddedItemInRow = FALSE;
      fContentCurRowY +=
          XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
      switch (m_nCurChildNodeStage) {
        case XFA_ItemLayoutProcessorStages_Keep:
        case XFA_ItemLayoutProcessorStages_None:
          break;
        case XFA_ItemLayoutProcessorStages_BreakBefore: {
          for (int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize();
               iIndex++) {
            CXFA_ContentLayoutItem* pItem = m_arrayKeepItems.GetAt(iIndex);
            m_pLayoutItem->RemoveChild(pItem);
            fContentCalculatedHeight -= pItem->m_sSize.y;
          }
          CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
          FX_BOOL bCreatePage = FALSE;
          if (bUseBreakControl && m_pPageMgr &&
              m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE,
                                                    pLeaderNode, pTrailerNode,
                                                    bCreatePage) &&
              m_pFormNode->GetClassID() != XFA_ELEMENT_Form && bCreatePage) {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
              XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
            }
            if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
              if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() ==
                      XFA_ELEMENT_Form &&
                  m_pLayoutItem == NULL) {
                XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode,
                                                       TRUE);
              } else {
                CXFA_ItemLayoutProcessor* pProcessor =
                    new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
                pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
                XFA_ItemLayoutProcessor_InsertFlowedItem(
                    this, pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                    uCurHAlignState, rgCurLineLayoutItems, FALSE,
                    XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
                    fContentWidthLimit, fContentCurRowAvailWidth,
                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                    pContext);
                delete pProcessor;
                pProcessor = NULL;
              }
            }
            XFA_ItemLayoutProcessor_GotoNextContainerNode(
                m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
            bForceEndPage = TRUE;
            bIsManualBreak = TRUE;
            goto SuspendAndCreateNewRow;
          }
        } break;
        case XFA_ItemLayoutProcessorStages_BreakAfter: {
          XFA_ItemLayoutProcessorResult eResult;
          CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
          FX_BOOL bCreatePage = FALSE;
          if (bUseBreakControl && m_pPageMgr &&
              m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE,
                                                    pLeaderNode, pTrailerNode,
                                                    bCreatePage) &&
              m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {
            if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
              CXFA_ItemLayoutProcessor* pProcessor =
                  new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
              pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
              eResult = XFA_ItemLayoutProcessor_InsertFlowedItem(
                  this, pProcessor, bContainerWidthAutoSize,
                  bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                  uCurHAlignState, rgCurLineLayoutItems, FALSE,
                  XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
                  fContentWidthLimit, fContentCurRowAvailWidth,
                  fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                  pContext);
              delete pProcessor;
              pProcessor = NULL;
            }
            if (!bCreatePage) {
              if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
                CalculateRowChildPosition(
                    rgCurLineLayoutItems, eFlowStrategy,
                    bContainerHeightAutoSize, bContainerWidthAutoSize,
                    fContentCalculatedWidth, fContentCalculatedHeight,
                    fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);
                rgCurLineLayoutItems->RemoveAll();
                CXFA_ItemLayoutProcessor* pProcessor =
                    new CXFA_ItemLayoutProcessor(pLeaderNode, NULL);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
                pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
                XFA_ItemLayoutProcessor_InsertFlowedItem(
                    this, pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                    uCurHAlignState, rgCurLineLayoutItems, FALSE,
                    XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
                    fContentWidthLimit, fContentCurRowAvailWidth,
                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                    pContext);
                delete pProcessor;
                pProcessor = NULL;
              }
            } else {
              if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
                XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
              }
            }
            XFA_ItemLayoutProcessor_GotoNextContainerNode(
                m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
            if (bCreatePage) {
              bForceEndPage = TRUE;
              bIsManualBreak = TRUE;
              if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {
                bBreakDone = TRUE;
              }
            }
            goto SuspendAndCreateNewRow;
          }
        } break;
        case XFA_ItemLayoutProcessorStages_BookendLeader: {
          CXFA_Node* pLeaderNode = NULL;
          if (m_pCurChildPreprocessor) {
            pProcessor = m_pCurChildPreprocessor;
            m_pCurChildPreprocessor = NULL;
          } else if (m_pPageMgr &&
                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
                         m_pCurChildNode, TRUE, pLeaderNode)) {
            pProcessor = new CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
            pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
          }
          if (pProcessor) {
            if (XFA_ItemLayoutProcessor_InsertFlowedItem(
                    this, pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
                    fAvailHeight, fRealHeight, fContentCurRowY,
                    fContentWidthLimit, fContentCurRowAvailWidth,
                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                    pContext) != XFA_ItemLayoutProcessorResult_Done) {
              goto SuspendAndCreateNewRow;
            } else {
              delete pProcessor;
              pProcessor = NULL;
            }
          }
        } break;
        case XFA_ItemLayoutProcessorStages_BookendTrailer: {
          CXFA_Node* pTrailerNode = NULL;
          if (m_pCurChildPreprocessor) {
            pProcessor = m_pCurChildPreprocessor;
            m_pCurChildPreprocessor = NULL;
          } else if (m_pPageMgr &&
                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
                         m_pCurChildNode, FALSE, pTrailerNode)) {
            pProcessor = new CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
            pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
          }
          if (pProcessor) {
            if (XFA_ItemLayoutProcessor_InsertFlowedItem(
                    this, pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
                    fAvailHeight, fRealHeight, fContentCurRowY,
                    fContentWidthLimit, fContentCurRowAvailWidth,
                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                    pContext) != XFA_ItemLayoutProcessorResult_Done) {
              goto SuspendAndCreateNewRow;
            } else {
              delete pProcessor;
              pProcessor = NULL;
            }
          }
        } break;
        case XFA_ItemLayoutProcessorStages_Container:
          ASSERT(m_pCurChildNode->IsContainerNode());
          if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
            break;
          }
          if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION &&
              XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
            bForceEndPage = TRUE;
            goto SuspendAndCreateNewRow;
          }
          if (m_pCurChildNode->IsContainerNode()) {
            FX_BOOL bNewRow = FALSE;
            if (m_pCurChildPreprocessor) {
              pProcessor = m_pCurChildPreprocessor;
              m_pCurChildPreprocessor = NULL;
              bNewRow = TRUE;
            } else {
              pProcessor =
                  new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
              pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
#endif
            }
            XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor,
                                                       m_pCurChildNode);
            XFA_ItemLayoutProcessorResult rs =
                XFA_ItemLayoutProcessor_InsertFlowedItem(
                    this, pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
                    fAvailHeight, fRealHeight, fContentCurRowY,
                    fContentWidthLimit, fContentCurRowAvailWidth,
                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
                    pContext, bNewRow);
            switch (rs) {
              case XFA_ItemLayoutProcessorResult_ManualBreak:
                bIsManualBreak = TRUE;
              case XFA_ItemLayoutProcessorResult_PageFullBreak:
                bForceEndPage = TRUE;
              case XFA_ItemLayoutProcessorResult_RowFullBreak:
                goto SuspendAndCreateNewRow;
              case XFA_ItemLayoutProcessorResult_Done:
              default:
                fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(
                    pProcessor, m_pCurChildNode);
                delete pProcessor;
                pProcessor = NULL;
            }
          }
          break;
        case XFA_ItemLayoutProcessorStages_Done:
          break;
        default:
          break;
      }
      XFA_ItemLayoutProcessor_GotoNextContainerNode(
          m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
      if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {
        break;
      } else {
        continue;
      }
    SuspendAndCreateNewRow:
      if (pProcessor) {
        m_pCurChildPreprocessor = pProcessor;
      }
      break;
    }
    CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy,
                              bContainerHeightAutoSize, bContainerWidthAutoSize,
                              fContentCalculatedWidth, fContentCalculatedHeight,
                              fContentCurRowY, fContentCurRowHeight,
                              fContentWidthLimit, bRootForceTb);
    m_fWidthLimite = fContentCurRowAvailWidth;
    if (bForceEndPage) {
      break;
    }
  }
  FX_BOOL bRetValue =
      (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
       m_rgPendingNodes.GetCount() == 0);
  if (bBreakDone) {
    bRetValue = FALSE;
  }
  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
      fContainerHeight);
  if (fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem ||
      bRetValue) {
    if (m_pLayoutItem == NULL) {
      m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
    }
    if (fContainerHeight < 0) {
      fContainerHeight = 0;
    }
    SetCurrentComponentSize(fContainerWidth, fContainerHeight);
    if (bForceEndPage) {
      m_fUsedSize = 0;
    } else {
      m_fUsedSize += m_pLayoutItem->m_sSize.y;
    }
  }
  return bRetValue
             ? XFA_ItemLayoutProcessorResult_Done
             : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak
                               : XFA_ItemLayoutProcessorResult_PageFullBreak);
}
FX_BOOL CXFA_ItemLayoutProcessor::CalculateRowChildPosition(
    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
    XFA_ATTRIBUTEENUM eFlowStrategy,
    FX_BOOL bContainerHeightAutoSize,
    FX_BOOL bContainerWidthAutoSize,
    FX_FLOAT& fContentCalculatedWidth,
    FX_FLOAT& fContentCalculatedHeight,
    FX_FLOAT& fContentCurRowY,
    FX_FLOAT fContentCurRowHeight,
    FX_FLOAT fContentWidthLimit,
    FX_BOOL bRootForceTb) {
  int32_t nGroupLengths[3] = {0, 0, 0};
  FX_FLOAT fGroupWidths[3] = {0, 0, 0};
  int32_t nTotalLength = 0;
  for (int32_t i = 0; i < 3; i++) {
    nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();
    for (int32_t c = nGroupLengths[i], j = 0; j < c; j++) {
      nTotalLength++;
      if (XFA_ItemLayoutProcessor_IsTakingSpace(
              rgCurLineLayoutItems[i][j]->m_pFormNode)) {
        fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;
      }
    }
  }
  if (!nTotalLength) {
    if (bContainerHeightAutoSize) {
      FX_FLOAT fNewHeight = fContentCurRowY;
      if (fContentCalculatedHeight > fNewHeight) {
        fContentCalculatedHeight = fNewHeight;
      }
    }
    return FALSE;
  }
  if (m_pLayoutItem == NULL) {
    m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  }
  if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {
    FX_FLOAT fCurPos;
    fCurPos = 0;
    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
      if (bRootForceTb) {
        FX_FLOAT fAbsoluteX, fAbsoluteY;
        CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode,
                                        rgCurLineLayoutItems[0][j]->m_sSize.x,
                                        rgCurLineLayoutItems[0][j]->m_sSize.y,
                                        fAbsoluteX, fAbsoluteY);
        rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
      } else {
        rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[0][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;
        }
      }
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
      m_fLastRowWidth = fCurPos;
    }
    fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] -
               fGroupWidths[2]) /
              2;
    for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
      if (bRootForceTb) {
        FX_FLOAT fAbsoluteX, fAbsoluteY;
        CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode,
                                        rgCurLineLayoutItems[1][j]->m_sSize.x,
                                        rgCurLineLayoutItems[1][j]->m_sSize.y,
                                        fAbsoluteX, fAbsoluteY);
        rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
      } else {
        rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[1][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;
        }
      }
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
      m_fLastRowWidth = fCurPos;
    }
    fCurPos = fContentWidthLimit - fGroupWidths[2];
    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
      if (bRootForceTb) {
        FX_FLOAT fAbsoluteX, fAbsoluteY;
        CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode,
                                        rgCurLineLayoutItems[2][j]->m_sSize.x,
                                        rgCurLineLayoutItems[2][j]->m_sSize.y,
                                        fAbsoluteX, fAbsoluteY);
        rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
      } else {
        rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[2][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;
        }
      }
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
      m_fLastRowWidth = fCurPos;
    }
  } else {
    FX_FLOAT fCurPos;
    fCurPos = fGroupWidths[0];
    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
      if (XFA_ItemLayoutProcessor_IsTakingSpace(
              rgCurLineLayoutItems[0][j]->m_pFormNode)) {
        fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;
      }
      rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
      m_fLastRowWidth = fCurPos;
    }
    fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] -
               fGroupWidths[2]) /
              2;
    for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
      if (XFA_ItemLayoutProcessor_IsTakingSpace(
              rgCurLineLayoutItems[1][j]->m_pFormNode)) {
        fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;
      }
      rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
      m_fLastRowWidth = fCurPos;
    }
    fCurPos = fContentWidthLimit;
    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
      if (XFA_ItemLayoutProcessor_IsTakingSpace(
              rgCurLineLayoutItems[2][j]->m_pFormNode)) {
        fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;
      }
      rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
      m_fLastRowWidth = fCurPos;
    }
  }
  m_fLastRowY = fContentCurRowY;
  fContentCurRowY += fContentCurRowHeight;
  if (bContainerWidthAutoSize) {
    FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];
    if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
        fContentWidthLimit > fChildSuppliedWidth) {
      fChildSuppliedWidth = fContentWidthLimit;
    }
    if (fContentCalculatedWidth < fChildSuppliedWidth) {
      fContentCalculatedWidth = fChildSuppliedWidth;
    }
  }
  if (bContainerHeightAutoSize) {
    FX_FLOAT fChildSuppliedHeight = fContentCurRowY;
    if (fContentCalculatedHeight < fChildSuppliedHeight) {
      fContentCalculatedHeight = fChildSuppliedHeight;
    }
  }
  return TRUE;
}
CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(
    CXFA_Node* pSubformSet) {
  if (pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {
    CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);
    while (pParent) {
      if (pParent->GetClassID() != XFA_ELEMENT_SubformSet) {
        return pParent;
      }
      pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
    }
  }
  return pSubformSet;
}
void CXFA_ItemLayoutProcessor::DoLayoutField() {
  if (m_pLayoutItem != NULL) {
    return;
  }
  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  if (!m_pLayoutItem) {
    return;
  }
  CXFA_Document* pDocument = m_pFormNode->GetDocument();
  IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
  FX_FLOAT fHeight = -1;
  FX_FLOAT fWidth = -1;
  pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);
  int32_t nRotate =
      FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
  nRotate = XFA_MapRotation(nRotate);
  if (nRotate == 90 || nRotate == 270) {
    FX_FLOAT fTmp = fWidth;
    fWidth = fHeight;
    fHeight = fTmp;
  }
  SetCurrentComponentSize(fWidth, fHeight);
}
XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(
    FX_BOOL bUseBreakControl,
    FX_FLOAT fHeightLimit,
    FX_FLOAT fRealHeight,
    CXFA_LayoutContext* pContext) {
  XFA_ELEMENT eClassID = m_pFormNode->GetClassID();
  switch (eClassID) {
    case XFA_ELEMENT_Subform:
    case XFA_ELEMENT_Area:
    case XFA_ELEMENT_ExclGroup:
    case XFA_ELEMENT_SubformSet: {
      FX_BOOL bRootForceTb = FALSE;
      CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);
      XFA_ATTRIBUTEENUM eLayoutStrategy =
          XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);
      switch (eLayoutStrategy) {
        case XFA_ATTRIBUTEENUM_Tb:
        case XFA_ATTRIBUTEENUM_Lr_tb:
        case XFA_ATTRIBUTEENUM_Rl_tb:
          return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy,
                                         fHeightLimit, fRealHeight, pContext,
                                         bRootForceTb);
        case XFA_ATTRIBUTEENUM_Position:
        case XFA_ATTRIBUTEENUM_Row:
        case XFA_ATTRIBUTEENUM_Rl_row:
        default:
          DoLayoutPositionedContainer(pContext);
          m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
          return XFA_ItemLayoutProcessorResult_Done;
        case XFA_ATTRIBUTEENUM_Table:
          DoLayoutTableContainer(pLayoutNode);
          m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
          return XFA_ItemLayoutProcessorResult_Done;
      }
    }
    case XFA_ELEMENT_Draw:
    case XFA_ELEMENT_Field:
      DoLayoutField();
      m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
      return XFA_ItemLayoutProcessorResult_Done;
    case XFA_ELEMENT_ContentArea:
      return XFA_ItemLayoutProcessorResult_Done;
    default:
      return XFA_ItemLayoutProcessorResult_Done;
  }
}
void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX,
                                                      FX_FLOAT& fAbsoluteY) {
  ASSERT(m_pLayoutItem);
  fAbsoluteX = m_pLayoutItem->m_sPos.x;
  fAbsoluteY = m_pLayoutItem->m_sPos.y;
}
void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth,
                                                       FX_FLOAT& fHeight) {
  ASSERT(m_pLayoutItem);
  fWidth = m_pLayoutItem->m_sSize.x;
  fHeight = m_pLayoutItem->m_sSize.y;
}
void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX,
                                                      FX_FLOAT fAbsoluteY) {
  ASSERT(m_pLayoutItem);
  m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY);
}
void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth,
                                                       FX_FLOAT fHeight) {
  ASSERT(m_pLayoutItem);
  m_pLayoutItem->m_sSize.Set(fWidth, fHeight);
}
FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(
    CXFA_Node* pFormNode) {
  if (pFormNode == NULL) {
    return FALSE;
  }
  CXFA_Node* pTemplate = pFormNode->GetTemplateNode();
  if (!pTemplate) {
    pTemplate = pFormNode;
  }
  CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur);
  int32_t iMax = NodeOccur.GetMax();
  if (iMax > -1) {
    int32_t iCount =
        (int32_t)(uintptr_t)m_PendingNodesCount.GetValueAt(pTemplate);
    if (iCount >= iMax) {
      return FALSE;
    }
    iCount++;
    m_PendingNodesCount.SetAt(pTemplate, (void*)(uintptr_t)(iCount));
    return TRUE;
  }
  return TRUE;
}
