// 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 "xfa/fxfa/parser/cxfa_itemlayoutprocessor.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/logging.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_containerlayoutitem.h"
#include "xfa/fxfa/parser/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_keep.h"
#include "xfa/fxfa/parser/cxfa_layoutcontext.h"
#include "xfa/fxfa/parser/cxfa_layoutpagemgr.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_margin.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
#include "xfa/fxfa/parser/cxfa_para.h"
#include "xfa/fxfa/parser/cxfa_traversestrategy_xfanode.h"
#include "xfa/fxfa/parser/xfa_utils.h"

namespace {

std::vector<WideString> SeparateStringW(const wchar_t* pStr,
                                        int32_t iStrLen,
                                        wchar_t delimiter) {
  std::vector<WideString> ret;
  if (!pStr)
    return ret;
  if (iStrLen < 0)
    iStrLen = wcslen(pStr);

  const wchar_t* pToken = pStr;
  const wchar_t* pEnd = pStr + iStrLen;
  while (true) {
    if (pStr >= pEnd || delimiter == *pStr) {
      ret.push_back(WideString(pToken, pStr - pToken));
      pToken = pStr + 1;
      if (pStr >= pEnd)
        break;
    }
    pStr++;
  }
  return ret;
}

void UpdateWidgetSize(CXFA_ContentLayoutItem* pLayoutItem,
                      float* fWidth,
                      float* fHeight) {
  CXFA_Node* pNode = pLayoutItem->m_pFormNode;
  switch (pNode->GetElementType()) {
    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.width;
      if (*fHeight < -XFA_LAYOUT_FLOAT_PERCISION)
        *fHeight = pLayoutItem->m_sSize.height;
      break;
    }
    case XFA_Element::Draw:
    case XFA_Element::Field: {
      pNode->GetDocument()->GetNotify()->StartFieldDrawLayout(pNode, *fWidth,
                                                              *fHeight);
      break;
    }
    default:
      NOTREACHED();
  }
}

CFX_SizeF CalculateContainerSpecifiedSize(CXFA_Node* pFormNode,
                                          bool* bContainerWidthAutoSize,
                                          bool* bContainerHeightAutoSize) {
  *bContainerWidthAutoSize = true;
  *bContainerHeightAutoSize = true;

  XFA_Element eType = pFormNode->GetElementType();

  CFX_SizeF containerSize;
  if (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) {
    Optional<CXFA_Measurement> wValue =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::W, false);
    if (wValue && wValue->GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
      containerSize.width = wValue->ToUnit(XFA_Unit::Pt);
      *bContainerWidthAutoSize = false;
    }

    Optional<CXFA_Measurement> hValue =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::H, false);
    if (hValue && hValue->GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
      containerSize.height = hValue->ToUnit(XFA_Unit::Pt);
      *bContainerHeightAutoSize = false;
    }
  }

  if (*bContainerWidthAutoSize && eType == XFA_Element::Subform) {
    Optional<CXFA_Measurement> maxW =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxW, false);
    if (maxW && maxW->GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
      containerSize.width = maxW->ToUnit(XFA_Unit::Pt);
      *bContainerWidthAutoSize = false;
    }

    Optional<CXFA_Measurement> maxH =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxH, false);
    if (maxH && maxH->GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
      containerSize.height = maxH->ToUnit(XFA_Unit::Pt);
      *bContainerHeightAutoSize = false;
    }
  }
  return containerSize;
}

CFX_SizeF CalculateContainerComponentSizeFromContentSize(
    CXFA_Node* pFormNode,
    bool bContainerWidthAutoSize,
    float fContentCalculatedWidth,
    bool bContainerHeightAutoSize,
    float fContentCalculatedHeight,
    const CFX_SizeF& currentContainerSize) {
  CFX_SizeF componentSize = currentContainerSize;
  CXFA_Margin* pMarginNode =
      pFormNode->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  if (bContainerWidthAutoSize) {
    componentSize.width = fContentCalculatedWidth;
    if (pMarginNode) {
      Optional<CXFA_Measurement> leftInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::LeftInset, false);
      if (leftInset)
        componentSize.width += leftInset->ToUnit(XFA_Unit::Pt);

      Optional<CXFA_Measurement> rightInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::RightInset, false);
      if (rightInset)
        componentSize.width += rightInset->ToUnit(XFA_Unit::Pt);
    }
  }

  if (bContainerHeightAutoSize) {
    componentSize.height = fContentCalculatedHeight;
    if (pMarginNode) {
      Optional<CXFA_Measurement> topInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::TopInset, false);
      if (topInset)
        componentSize.height += topInset->ToUnit(XFA_Unit::Pt);

      Optional<CXFA_Measurement> bottomInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::BottomInset,
                                              false);
      if (bottomInset)
        componentSize.height += bottomInset->ToUnit(XFA_Unit::Pt);
    }
  }
  return componentSize;
}

void RelocateTableRowCells(CXFA_ContentLayoutItem* pLayoutRow,
                           const std::vector<float>& rgSpecifiedColumnWidths,
                           XFA_AttributeEnum eLayout) {
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      pLayoutRow->m_pFormNode, &bContainerWidthAutoSize,
      &bContainerHeightAutoSize);
  CXFA_Margin* pMarginNode =
      pLayoutRow->m_pFormNode->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  float fLeftInset = 0;
  float fTopInset = 0;
  float fRightInset = 0;
  float fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()
                     ->GetMeasure(XFA_Attribute::LeftInset)
                     .ToUnit(XFA_Unit::Pt);
    fTopInset = pMarginNode->JSObject()
                    ->GetMeasure(XFA_Attribute::TopInset)
                    .ToUnit(XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()
                      ->GetMeasure(XFA_Attribute::RightInset)
                      .ToUnit(XFA_Unit::Pt);
    fBottomInset = pMarginNode->JSObject()
                       ->GetMeasure(XFA_Attribute::BottomInset)
                       .ToUnit(XFA_Unit::Pt);
  }

  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - fLeftInset - fRightInset;
  float fContentCurrentHeight =
      pLayoutRow->m_sSize.height - fTopInset - fBottomInset;
  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fCurrentColX = 0;
  int32_t nCurrentColIdx = 0;
  bool bMetWholeRowCell = false;

  for (auto* pLayoutChild =
           static_cast<CXFA_ContentLayoutItem*>(pLayoutRow->m_pFirstChild);
       pLayoutChild; pLayoutChild = static_cast<CXFA_ContentLayoutItem*>(
                         pLayoutChild->m_pNextSibling)) {
    int32_t nOriginalColSpan =
        pLayoutChild->m_pFormNode->JSObject()->GetInteger(
            XFA_Attribute::ColSpan);
    int32_t nColSpan = nOriginalColSpan;
    float fColSpanWidth = 0;
    if (nColSpan == -1 ||
        nCurrentColIdx + nColSpan >
            pdfium::CollectionSize<int32_t>(rgSpecifiedColumnWidths)) {
      nColSpan = pdfium::CollectionSize<int32_t>(rgSpecifiedColumnWidths) -
                 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.height);
    }
    if (nOriginalColSpan == -1)
      bMetWholeRowCell = true;

    pLayoutChild->m_sPos = CFX_PointF(fCurrentColX, 0);
    pLayoutChild->m_sSize.width = fColSpanWidth;
    if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode))
      continue;

    fCurrentColX += fColSpanWidth;
    nCurrentColIdx += nColSpan;
    float fNewHeight = bContainerHeightAutoSize ? -1 : fContentCurrentHeight;
    UpdateWidgetSize(pLayoutChild, &fColSpanWidth, &fNewHeight);
    pLayoutChild->m_sSize.height = fNewHeight;
    if (bContainerHeightAutoSize) {
      fContentCalculatedHeight =
          std::max(fContentCalculatedHeight, pLayoutChild->m_sSize.height);
    }
  }

  if (bContainerHeightAutoSize) {
    for (CXFA_ContentLayoutItem* pLayoutChild =
             (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
         pLayoutChild;
         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
      UpdateWidgetSize(pLayoutChild, &pLayoutChild->m_sSize.width,
                       &fContentCalculatedHeight);
      float fOldChildHeight = pLayoutChild->m_sSize.height;
      pLayoutChild->m_sSize.height = fContentCalculatedHeight;
      CXFA_Para* pParaNode =
          pLayoutChild->m_pFormNode->GetFirstChildByClass<CXFA_Para>(
              XFA_Element::Para);
      if (pParaNode && pLayoutChild->m_pFirstChild) {
        float fOffHeight = fContentCalculatedHeight - fOldChildHeight;
        XFA_AttributeEnum eVType =
            pParaNode->JSObject()->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) {
    float fChildSuppliedWidth = fCurrentColX;
    if (fContentWidthLimit < FLT_MAX &&
        fContentWidthLimit > fChildSuppliedWidth) {
      fChildSuppliedWidth = fContentWidthLimit;
    }
    fContentCalculatedWidth =
        std::max(fContentCalculatedWidth, fChildSuppliedWidth);
  } else {
    fContentCalculatedWidth = containerSize.width - fLeftInset - fRightInset;
  }

  if (pLayoutRow->m_pFormNode->JSObject()->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.width;
    }
  }
  pLayoutRow->m_sSize = CalculateContainerComponentSizeFromContentSize(
      pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      bContainerHeightAutoSize, fContentCalculatedHeight, containerSize);
}

void UpdatePendingItemLayout(CXFA_ItemLayoutProcessor* pProcessor,
                             CXFA_ContentLayoutItem* pLayoutItem) {
  XFA_AttributeEnum eLayout =
      pLayoutItem->m_pFormNode->JSObject()->GetEnum(XFA_Attribute::Layout);
  switch (eLayout) {
    case XFA_AttributeEnum::Row:
    case XFA_AttributeEnum::Rl_row:
      RelocateTableRowCells(pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths,
                            eLayout);
      break;
    default:
      break;
  }
}

void AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor* pProcessor,
                           float fSplitPos,
                           CXFA_ContentLayoutItem* pTrailerLayoutItem,
                           bool bUseInherited) {
  if (!pTrailerLayoutItem)
    return;

  float fHeight = pTrailerLayoutItem->m_sSize.height;
  if (bUseInherited) {
    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;
  }

  UpdatePendingItemLayout(pProcessor, pTrailerLayoutItem);
  CXFA_Margin* pMarginNode =
      pProcessor->m_pFormNode->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  float fLeftInset = 0;
  float fTopInset = 0;
  float fRightInset = 0;
  float fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()
                     ->GetMeasure(XFA_Attribute::LeftInset)
                     .ToUnit(XFA_Unit::Pt);
    fTopInset = pMarginNode->JSObject()
                    ->GetMeasure(XFA_Attribute::TopInset)
                    .ToUnit(XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()
                      ->GetMeasure(XFA_Attribute::RightInset)
                      .ToUnit(XFA_Unit::Pt);
    fBottomInset = pMarginNode->JSObject()
                       ->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.width +=
        pTrailerLayoutItem->m_sSize.width;
    pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
    return;
  }

  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->JSObject()->GetEnum(
      XFA_Attribute::HAlign)) {
    case XFA_AttributeEnum::Right:
      pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.width -
                                     fRightInset -
                                     pTrailerLayoutItem->m_sSize.width;
      break;
    case XFA_AttributeEnum::Center:
      pTrailerLayoutItem->m_sPos.x =
          (pProcessor->m_pLayoutItem->m_sSize.width - fLeftInset - fRightInset -
           pTrailerLayoutItem->m_sSize.width) /
          2;
      break;
    case XFA_AttributeEnum::Left:
    default:
      pTrailerLayoutItem->m_sPos.x = fLeftInset;
      break;
  }
  pProcessor->m_pLayoutItem->m_sSize.height += fHeight;
  pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
}

void AddLeaderAfterSplit(CXFA_ItemLayoutProcessor* pProcessor,
                         CXFA_ContentLayoutItem* pLeaderLayoutItem) {
  UpdatePendingItemLayout(pProcessor, pLeaderLayoutItem);

  CXFA_Margin* pMarginNode =
      pProcessor->m_pFormNode->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  float fLeftInset = 0;
  float fRightInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()
                     ->GetMeasure(XFA_Attribute::LeftInset)
                     .ToUnit(XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()
                      ->GetMeasure(XFA_Attribute::RightInset)
                      .ToUnit(XFA_Unit::Pt);
  }

  float fHeight = pLeaderLayoutItem->m_sSize.height;
  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->JSObject()->GetEnum(
      XFA_Attribute::HAlign)) {
    case XFA_AttributeEnum::Right:
      pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.width -
                                    fRightInset -
                                    pLeaderLayoutItem->m_sSize.width;
      break;
    case XFA_AttributeEnum::Center:
      pLeaderLayoutItem->m_sPos.x =
          (pProcessor->m_pLayoutItem->m_sSize.width - fLeftInset - fRightInset -
           pLeaderLayoutItem->m_sSize.width) /
          2;
      break;
    case XFA_AttributeEnum::Left:
    default:
      pLeaderLayoutItem->m_sPos.x = fLeftInset;
      break;
  }
  pProcessor->m_pLayoutItem->m_sSize.height += fHeight;
  pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);
}

void AddPendingNode(CXFA_ItemLayoutProcessor* pProcessor,
                    CXFA_Node* pPendingNode,
                    bool bBreakPending) {
  pProcessor->m_PendingNodes.push_back(pPendingNode);
  pProcessor->m_bBreakPending = bBreakPending;
}

float InsertPendingItems(CXFA_ItemLayoutProcessor* pProcessor,
                         CXFA_Node* pCurChildNode) {
  float fTotalHeight = 0;
  if (pProcessor->m_PendingNodes.empty())
    return fTotalHeight;

  if (!pProcessor->m_pLayoutItem) {
    pProcessor->m_pLayoutItem =
        pProcessor->CreateContentLayoutItem(pCurChildNode);
    pProcessor->m_pLayoutItem->m_sSize.clear();
  }

  while (!pProcessor->m_PendingNodes.empty()) {
    auto pPendingProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
        pProcessor->m_PendingNodes.front(), nullptr);
    pProcessor->m_PendingNodes.pop_front();
    pPendingProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr);
    CXFA_ContentLayoutItem* pPendingLayoutItem =
        pPendingProcessor->HasLayoutItem()
            ? pPendingProcessor->ExtractLayoutItem()
            : nullptr;
    if (pPendingLayoutItem) {
      AddLeaderAfterSplit(pProcessor, pPendingLayoutItem);
      if (pProcessor->m_bBreakPending)
        fTotalHeight += pPendingLayoutItem->m_sSize.height;
    }
  }
  return fTotalHeight;
}

XFA_AttributeEnum GetLayout(CXFA_Node* pFormNode, bool* bRootForceTb) {
  *bRootForceTb = false;
  Optional<XFA_AttributeEnum> layoutMode =
      pFormNode->JSObject()->TryEnum(XFA_Attribute::Layout, false);
  if (layoutMode)
    return *layoutMode;

  CXFA_Node* pParentNode = pFormNode->GetParent();
  if (pParentNode && pParentNode->GetElementType() == XFA_Element::Form) {
    *bRootForceTb = true;
    return XFA_AttributeEnum::Tb;
  }
  return XFA_AttributeEnum::Position;
}

bool ExistContainerKeep(CXFA_Node* pCurNode, bool bPreFind) {
  if (!pCurNode || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode))
    return false;

  CXFA_Node* pPreContainer = bPreFind ? pCurNode->GetPrevContainerSibling()
                                      : pCurNode->GetNextContainerSibling();
  if (!pPreContainer)
    return false;

  CXFA_Keep* pKeep =
      pCurNode->GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
  if (pKeep) {
    XFA_Attribute eKeepType = XFA_Attribute::Previous;
    if (!bPreFind)
      eKeepType = XFA_Attribute::Next;

    Optional<XFA_AttributeEnum> previous =
        pKeep->JSObject()->TryEnum(eKeepType, false);
    if (previous) {
      if (*previous == XFA_AttributeEnum::ContentArea ||
          *previous == XFA_AttributeEnum::PageArea) {
        return true;
      }
    }
  }

  pKeep = pPreContainer->GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
  if (!pKeep)
    return false;

  XFA_Attribute eKeepType = XFA_Attribute::Next;
  if (!bPreFind)
    eKeepType = XFA_Attribute::Previous;

  Optional<XFA_AttributeEnum> next =
      pKeep->JSObject()->TryEnum(eKeepType, false);
  if (!next)
    return false;
  if (*next == XFA_AttributeEnum::ContentArea ||
      *next == XFA_AttributeEnum::PageArea) {
    return true;
  }
  return false;
}

bool FindBreakNode(CXFA_Node* pContainerNode,
                   CXFA_Node*& pCurActionNode,
                   XFA_ItemLayoutProcessorStages* nCurStage,
                   bool bBreakBefore) {
  bool bFindRs = false;
  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
       pBreakNode = pBreakNode->GetNextSibling()) {
    XFA_Attribute eAttributeType = XFA_Attribute::Before;
    if (!bBreakBefore)
      eAttributeType = XFA_Attribute::After;

    switch (pBreakNode->GetElementType()) {
      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->JSObject()->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;
}

void DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
  CXFA_FFNotify* pNotify = pGenerateNode->GetDocument()->GetNotify();
  CXFA_LayoutProcessor* 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 =
        static_cast<CXFA_ContentLayoutItem*>(
            pNode->JSObject()->GetLayoutItem());
    CXFA_ContentLayoutItem* pNextLayoutItem = nullptr;
    while (pCurLayoutItem) {
      pNextLayoutItem = pCurLayoutItem->m_pNext;
      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
      delete pCurLayoutItem;
      pCurLayoutItem = pNextLayoutItem;
    }
  }
  pGenerateNode->GetParent()->RemoveChild(pGenerateNode, true);
}

uint8_t 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;
  }
}

XFA_ItemLayoutProcessorResult InsertFlowedItem(
    CXFA_ItemLayoutProcessor* pThis,
    CXFA_ItemLayoutProcessor* pProcessor,
    bool bContainerWidthAutoSize,
    bool bContainerHeightAutoSize,
    float fContainerHeight,
    XFA_AttributeEnum eFlowStrategy,
    uint8_t* uCurHAlignState,
    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
    bool bUseBreakControl,
    float fAvailHeight,
    float fRealHeight,
    float fContentWidthLimit,
    float* fContentCurRowY,
    float* fContentCurRowAvailWidth,
    float* fContentCurRowHeight,
    bool* bAddedItemInRow,
    bool* bForceEndPage,
    CXFA_LayoutContext* pLayoutContext,
    bool bNewRow) {
  bool bTakeSpace =
      XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);
  uint8_t uHAlign = HAlignEnumToInt(
      pThis->m_pCurChildNode->JSObject()->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;
  bool bIsOwnSplit =
      pProcessor->m_pFormNode->GetIntact() == XFA_AttributeEnum::None;
  bool bUseRealHeight = bTakeSpace && bContainerHeightAutoSize && bIsOwnSplit &&
                        pProcessor->m_pFormNode->GetParent()->GetIntact() ==
                            XFA_AttributeEnum::None;
  bool bIsTransHeight = bTakeSpace;
  if (bIsTransHeight && !bIsOwnSplit) {
    bool bRootForceTb = false;
    XFA_AttributeEnum eLayoutStrategy =
        GetLayout(pProcessor->m_pFormNode, &bRootForceTb);
    if (eLayoutStrategy == XFA_AttributeEnum::Lr_tb ||
        eLayoutStrategy == XFA_AttributeEnum::Rl_tb) {
      bIsTransHeight = false;
    }
  }

  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 : FLT_MAX,
        bIsTransHeight ? fRealHeight - *fContentCurRowY : FLT_MAX,
        pLayoutContext);
    pProcessor->m_ePreProcessRs = eRetValue;
  } else {
    eRetValue = pProcessor->m_ePreProcessRs;
    pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult::Done;
  }
  if (pProcessor->HasLayoutItem() == false)
    return eRetValue;

  CFX_SizeF childSize = pProcessor->GetCurrentComponentSize();
  if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {
    fRealHeight = FLT_MAX;
    fAvailHeight = FLT_MAX;
  }
  if (bTakeSpace && (childSize.width >
                     *fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) &&
      (fContentWidthLimit - *fContentCurRowAvailWidth >
       XFA_LAYOUT_FLOAT_PERCISION)) {
    return XFA_ItemLayoutProcessorResult::RowFullBreak;
  }

  CXFA_Node* pOverflowLeaderNode = nullptr;
  CXFA_Node* pOverflowTrailerNode = nullptr;
  CXFA_Node* pFormNode = nullptr;
  CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr;
  bool bIsAddTrailerHeight = false;
  if (pThis->m_pPageMgr &&
      pProcessor->m_pFormNode->GetIntact() == XFA_AttributeEnum::None) {
    pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);
    if (!pFormNode && 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) {
          auto pOverflowLeaderProcessor =
              pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pOverflowTrailerNode,
                                                           nullptr);
          pOverflowLeaderProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr);
          pTrailerLayoutItem =
              pOverflowLeaderProcessor->HasLayoutItem()
                  ? pOverflowLeaderProcessor->ExtractLayoutItem()
                  : nullptr;
        }

        bIsAddTrailerHeight =
            bUseInherited
                ? pThis->IsAddNewRowForTrailer(pTrailerLayoutItem)
                : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
        if (bIsAddTrailerHeight) {
          childSize.height += pTrailerLayoutItem->m_sSize.height;
          bIsAddTrailerHeight = true;
        }
      }
    }
  }

  if (!bTakeSpace ||
      *fContentCurRowY + childSize.height <=
          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)
          AddTrailerBeforeSplit(pProcessor, childSize.height,
                                pTrailerLayoutItem, false);
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
          AddPendingNode(pProcessor, pOverflowLeaderNode, false);

        pProcessor->m_bUseInheriated = false;
      } else {
        if (bIsAddTrailerHeight)
          childSize.height -= pTrailerLayoutItem->m_sSize.height;

        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
      }

      CXFA_ContentLayoutItem* pChildLayoutItem =
          pProcessor->ExtractLayoutItem();
      if (ExistContainerKeep(pProcessor->m_pFormNode, false) &&
          pProcessor->m_pFormNode->GetIntact() == XFA_AttributeEnum::None) {
        pThis->m_arrayKeepItems.push_back(pChildLayoutItem);
      } else {
        pThis->m_arrayKeepItems.clear();
      }
      rgCurLineLayoutItems[uHAlign].push_back(pChildLayoutItem);
      *bAddedItemInRow = true;
      if (bTakeSpace) {
        *fContentCurRowAvailWidth -= childSize.width;
        *fContentCurRowHeight =
            std::max(*fContentCurRowHeight, childSize.height);
      }
      return XFA_ItemLayoutProcessorResult::Done;
    }

    if (eRetValue == XFA_ItemLayoutProcessorResult::PageFullBreak) {
      if (pProcessor->m_bUseInheriated) {
        if (pTrailerLayoutItem) {
          AddTrailerBeforeSplit(pProcessor, childSize.height,
                                pTrailerLayoutItem, false);
        }
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
          AddPendingNode(pProcessor, pOverflowLeaderNode, false);

        pProcessor->m_bUseInheriated = false;
      } else {
        if (bIsAddTrailerHeight)
          childSize.height -= pTrailerLayoutItem->m_sSize.height;

        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
      }
    }
    rgCurLineLayoutItems[uHAlign].push_back(pProcessor->ExtractLayoutItem());
    *bAddedItemInRow = true;
    *fContentCurRowAvailWidth -= childSize.width;
    *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height);
    return eRetValue;
  }

  XFA_ItemLayoutProcessorResult eResult;
  if (pThis->ProcessKeepForSplit(
          pThis, pProcessor, eRetValue, &rgCurLineLayoutItems[uHAlign],
          fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY,
          bAddedItemInRow, bForceEndPage, &eResult)) {
    return eResult;
  }

  *bForceEndPage = true;
  float fSplitPos = pProcessor->FindSplitPos(fAvailHeight - *fContentCurRowY);
  if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
    XFA_AttributeEnum eLayout =
        pProcessor->m_pFormNode->JSObject()->GetEnum(XFA_Attribute::Layout);
    if (eLayout == XFA_AttributeEnum::Tb &&
        eRetValue == XFA_ItemLayoutProcessorResult::Done) {
      pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                       pOverflowTrailerNode, pTrailerLayoutItem,
                                       pFormNode);
      rgCurLineLayoutItems[uHAlign].push_back(pProcessor->ExtractLayoutItem());
      *bAddedItemInRow = true;
      if (bTakeSpace) {
        *fContentCurRowAvailWidth -= childSize.width;
        *fContentCurRowHeight =
            std::max(*fContentCurRowHeight, childSize.height);
      }
      return XFA_ItemLayoutProcessorResult::PageFullBreak;
    }

    CXFA_Node* pTempLeaderNode = nullptr;
    CXFA_Node* pTempTrailerNode = nullptr;
    if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated &&
        eRetValue != XFA_ItemLayoutProcessorResult::PageFullBreak) {
      pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
                                         pTempTrailerNode, false, true);
    }
    if (pTrailerLayoutItem && bIsAddTrailerHeight) {
      AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem,
                            bUseInherited);
    } else {
      pProcessor->SplitLayoutItem(fSplitPos);
    }

    if (bUseInherited) {
      pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                       pOverflowTrailerNode, pTrailerLayoutItem,
                                       pFormNode);
      pThis->m_bUseInheriated = true;
    } else {
      CXFA_LayoutItem* firstChild = pProcessor->m_pLayoutItem->m_pFirstChild;
      if (firstChild && !firstChild->m_pNextSibling &&
          firstChild->m_pFormNode->IsLayoutGeneratedNode()) {
        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
      } else if (pProcessor->JudgeLeaderOrTrailerForOccur(
                     pOverflowLeaderNode)) {
        AddPendingNode(pProcessor, pOverflowLeaderNode, false);
      }
    }

    if (pProcessor->m_pLayoutItem->m_pNextSibling) {
      childSize = pProcessor->GetCurrentComponentSize();
      rgCurLineLayoutItems[uHAlign].push_back(pProcessor->ExtractLayoutItem());
      *bAddedItemInRow = true;
      if (bTakeSpace) {
        *fContentCurRowAvailWidth -= childSize.width;
        *fContentCurRowHeight =
            std::max(*fContentCurRowHeight, childSize.height);
      }
    }
    return XFA_ItemLayoutProcessorResult::PageFullBreak;
  }

  if (*fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {
    childSize = pProcessor->GetCurrentComponentSize();
    if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(childSize.height)) {
      CXFA_Node* pTempLeaderNode = nullptr;
      CXFA_Node* pTempTrailerNode = nullptr;
      if (pThis->m_pPageMgr) {
        if (!pFormNode && pLayoutContext)
          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].push_back(pProcessor->ExtractLayoutItem());
    *bAddedItemInRow = true;
    if (bTakeSpace) {
      *fContentCurRowAvailWidth -= childSize.width;
      *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height);
    }
    if (eRetValue == XFA_ItemLayoutProcessorResult::Done)
      *bForceEndPage = false;

    return eRetValue;
  }

  XFA_AttributeEnum eLayout =
      pProcessor->m_pFormNode->JSObject()->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)
      AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, false);
    if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
      AddPendingNode(pProcessor, pOverflowLeaderNode, false);

    return XFA_ItemLayoutProcessorResult::PageFullBreak;
  }

  if (eRetValue != XFA_ItemLayoutProcessorResult::Done)
    return XFA_ItemLayoutProcessorResult::PageFullBreak;

  if (!pFormNode && pLayoutContext)
    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;
}

bool FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem,
                            float fCurVerticalOffset,
                            float* fProposedSplitPos,
                            bool* bAppChange,
                            bool bCalculateMargin) {
  CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;
  if (*fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION ||
      *fProposedSplitPos > fCurVerticalOffset + pLayoutItem->m_sSize.height -
                               XFA_LAYOUT_FLOAT_PERCISION) {
    return false;
  }

  switch (pFormNode->GetIntact()) {
    case XFA_AttributeEnum::None: {
      bool bAnyChanged = false;
      CXFA_Document* pDocument = pFormNode->GetDocument();
      CXFA_FFNotify* pNotify = pDocument->GetNotify();
      float fCurTopMargin = 0, fCurBottomMargin = 0;
      CXFA_Margin* pMarginNode =
          pFormNode->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
      if (pMarginNode && bCalculateMargin) {
        fCurTopMargin = pMarginNode->JSObject()
                            ->GetMeasure(XFA_Attribute::TopInset)
                            .ToUnit(XFA_Unit::Pt);
        fCurBottomMargin = pMarginNode->JSObject()
                               ->GetMeasure(XFA_Attribute::BottomInset)
                               .ToUnit(XFA_Unit::Pt);
      }
      bool bChanged = true;
      while (bChanged) {
        bChanged = false;
        {
          float fRelSplitPos = *fProposedSplitPos - fCurVerticalOffset;
          if (pFormNode->FindSplitPos(pNotify->GetHDOC()->GetDocView(),
                                      pLayoutItem->GetIndex(), fRelSplitPos)) {
            bAnyChanged = true;
            bChanged = true;
            *fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;
            *bAppChange = true;
            if (*fProposedSplitPos <=
                fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
              return true;
            }
          }
        }
        float fRelSplitPos = *fProposedSplitPos - fCurBottomMargin;
        for (CXFA_ContentLayoutItem* pChildItem =
                 (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
             pChildItem;
             pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
          float fChildOffset =
              fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
          bool bChange = false;
          if (FindLayoutItemSplitPos(pChildItem, fChildOffset, &fRelSplitPos,
                                     &bChange, bCalculateMargin)) {
            if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION &&
                bChange) {
              *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;
    }
    case XFA_AttributeEnum::ContentArea:
    case XFA_AttributeEnum::PageArea: {
      *fProposedSplitPos = fCurVerticalOffset;
      return true;
    }
    default:
      return false;
  }
}

CFX_PointF CalculatePositionedContainerPos(CXFA_Node* pNode,
                                           const CFX_SizeF& size) {
  XFA_AttributeEnum eAnchorType =
      pNode->JSObject()->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}};

  CFX_PointF pos(
      pNode->JSObject()->GetMeasure(XFA_Attribute::X).ToUnit(XFA_Unit::Pt),
      pNode->JSObject()->GetMeasure(XFA_Attribute::Y).ToUnit(XFA_Unit::Pt));
  int32_t nRotate =
      XFA_MapRotation(pNode->JSObject()->GetInteger(XFA_Attribute::Rotate)) /
      90;
  int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];
  switch (nAbsoluteAnchorType / 3) {
    case 1:
      pos.y -= size.height / 2;
      break;
    case 2:
      pos.y -= size.height;
      break;
    default:
      break;
  }
  switch (nAbsoluteAnchorType % 3) {
    case 1:
      pos.x -= size.width / 2;
      break;
    case 2:
      pos.x -= size.width;
      break;
    default:
      break;
  }
  return pos;
}

}  // namespace

CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode,
                                                   CXFA_LayoutPageMgr* pPageMgr)
    : m_pFormNode(pNode),
      m_pLayoutItem(nullptr),
      m_pCurChildNode(XFA_LAYOUT_INVALIDNODE),
      m_fUsedSize(0),
      m_pPageMgr(pPageMgr),
      m_bBreakPending(true),
      m_fLastRowWidth(0),
      m_fLastRowY(0),
      m_bUseInheriated(false),
      m_ePreProcessRs(XFA_ItemLayoutProcessorResult::Done),
      m_bKeepBreakFinish(false),
      m_bIsProcessKeep(false),
      m_pKeepHeadNode(nullptr),
      m_pKeepTailNode(nullptr),
      m_pOldLayoutItem(nullptr),
      m_pCurChildPreprocessor(nullptr),
      m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages::None),
      m_fWidthLimite(0),
      m_bHasAvailHeight(true) {
  ASSERT(m_pFormNode && (m_pFormNode->IsContainerNode() ||
                         m_pFormNode->GetElementType() == XFA_Element::Form));
  m_pOldLayoutItem = static_cast<CXFA_ContentLayoutItem*>(
      m_pFormNode->JSObject()->GetLayoutItem());
}

CXFA_ItemLayoutProcessor::~CXFA_ItemLayoutProcessor() {}

CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(
    CXFA_Node* pFormNode) {
  if (!pFormNode)
    return nullptr;

  CXFA_ContentLayoutItem* pLayoutItem = nullptr;
  if (m_pOldLayoutItem) {
    pLayoutItem = m_pOldLayoutItem;
    m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;
    return pLayoutItem;
  }
  pLayoutItem =
      pFormNode->GetDocument()->GetNotify()->OnCreateContentLayoutItem(
          pFormNode);
  CXFA_ContentLayoutItem* pPrevLayoutItem =
      static_cast<CXFA_ContentLayoutItem*>(
          pFormNode->JSObject()->GetLayoutItem());
  if (pPrevLayoutItem) {
    while (pPrevLayoutItem->m_pNext)
      pPrevLayoutItem = pPrevLayoutItem->m_pNext;

    pPrevLayoutItem->m_pNext = pLayoutItem;
    pLayoutItem->m_pPrev = pPrevLayoutItem;
  } else {
    pFormNode->JSObject()->SetLayoutItem(pLayoutItem);
  }
  return pLayoutItem;
}

float CXFA_ItemLayoutProcessor::FindSplitPos(float fProposedSplitPos) {
  ASSERT(m_pLayoutItem);
  XFA_AttributeEnum eLayout = m_pFormNode->JSObject()
                                  ->TryEnum(XFA_Attribute::Layout, true)
                                  .value_or(XFA_AttributeEnum::Position);
  bool bCalculateMargin = eLayout != XFA_AttributeEnum::Position;
  while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
    bool bAppChange = false;
    if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, &fProposedSplitPos,
                                &bAppChange, bCalculateMargin)) {
      break;
    }
  }
  return fProposedSplitPos;
}

void CXFA_ItemLayoutProcessor::SplitLayoutItem(
    CXFA_ContentLayoutItem* pLayoutItem,
    CXFA_ContentLayoutItem* pSecondParent,
    float fSplitPos) {
  float fCurTopMargin = 0, fCurBottomMargin = 0;
  XFA_AttributeEnum eLayout = m_pFormNode->JSObject()
                                  ->TryEnum(XFA_Attribute::Layout, true)
                                  .value_or(XFA_AttributeEnum::Position);
  bool bCalculateMargin = true;
  if (eLayout == XFA_AttributeEnum::Position)
    bCalculateMargin = false;

  CXFA_Margin* pMarginNode =
      pLayoutItem->m_pFormNode->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  if (pMarginNode && bCalculateMargin) {
    fCurTopMargin = pMarginNode->JSObject()
                        ->GetMeasure(XFA_Attribute::TopInset)
                        .ToUnit(XFA_Unit::Pt);
    fCurBottomMargin = pMarginNode->JSObject()
                           ->GetMeasure(XFA_Attribute::BottomInset)
                           .ToUnit(XFA_Unit::Pt);
  }

  CXFA_ContentLayoutItem* pSecondLayoutItem = nullptr;
  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.width = pLayoutItem->m_sSize.width;
  pSecondLayoutItem->m_sPos.y = 0;
  pSecondLayoutItem->m_sSize.height = pLayoutItem->m_sSize.height - fSplitPos;
  pLayoutItem->m_sSize.height -= pSecondLayoutItem->m_sSize.height;
  if (pLayoutItem->m_pFirstChild)
    pSecondLayoutItem->m_sSize.height += fCurTopMargin;

  if (pSecondParent) {
    pSecondParent->AddChild(pSecondLayoutItem);
    if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {
      pSecondParent->m_sSize.height += fCurTopMargin;
      CXFA_ContentLayoutItem* pParentItem =
          (CXFA_ContentLayoutItem*)pSecondParent->m_pParent;
      while (pParentItem) {
        pParentItem->m_sSize.height += 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 = nullptr;

  float lHeightForKeep = 0;
  float fAddMarginHeight = 0;
  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
  for (CXFA_ContentLayoutItem *pChildItem = pChildren, *pChildNext = nullptr;
       pChildItem; pChildItem = pChildNext) {
    pChildNext = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling;
    pChildItem->m_pNextSibling = nullptr;
    if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                         XFA_LAYOUT_FLOAT_PERCISION) {
      if (!ExistContainerKeep(pChildItem->m_pFormNode, true)) {
        pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
        pChildItem->m_sPos.y += lHeightForKeep;
        pChildItem->m_sPos.y += fAddMarginHeight;
        pSecondLayoutItem->AddChild(pChildItem);
        continue;
      }
      if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {
        for (auto* pPreItem : keepLayoutItems) {
          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.height > lHeightForKeep) {
            pPreItem->m_sPos.y = lHeightForKeep;
            lHeightForKeep += pPreItem->m_sSize.height;
            pSecondLayoutItem->m_sSize.height += pPreItem->m_sSize.height;
            if (pSecondParent)
              pSecondParent->m_sSize.height += pPreItem->m_sSize.height;
          }
          pSecondLayoutItem->AddChild(pPreItem);
        }
      }
      pChildItem->m_sPos.y -= fSplitPos;
      pChildItem->m_sPos.y += lHeightForKeep;
      pChildItem->m_sPos.y += fAddMarginHeight;
      pSecondLayoutItem->AddChild(pChildItem);
      continue;
    }
    if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >=
        fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y +
            pChildItem->m_sSize.height) {
      pLayoutItem->AddChild(pChildItem);
      if (ExistContainerKeep(pChildItem->m_pFormNode, false))
        keepLayoutItems.push_back(pChildItem);
      else
        keepLayoutItems.clear();
      continue;
    }

    float fOldHeight = pSecondLayoutItem->m_sSize.height;
    SplitLayoutItem(
        pChildItem, pSecondLayoutItem,
        fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
    fAddMarginHeight = pSecondLayoutItem->m_sSize.height - fOldHeight;
    pLayoutItem->AddChild(pChildItem);
  }
}

void CXFA_ItemLayoutProcessor::SplitLayoutItem(float fSplitPos) {
  ASSERT(m_pLayoutItem);
  SplitLayoutItem(m_pLayoutItem, nullptr, fSplitPos);
}

CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() {
  CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
  if (pLayoutItem) {
    m_pLayoutItem =
        static_cast<CXFA_ContentLayoutItem*>(pLayoutItem->m_pNextSibling);
    pLayoutItem->m_pNextSibling = nullptr;
  }

  if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Done ||
      !ToContentLayoutItem(m_pOldLayoutItem)) {
    return pLayoutItem;
  }

  if (m_pOldLayoutItem->m_pPrev)
    m_pOldLayoutItem->m_pPrev->m_pNext = nullptr;

  CXFA_FFNotify* pNotify =
      m_pOldLayoutItem->m_pFormNode->GetDocument()->GetNotify();
  CXFA_LayoutProcessor* pDocLayout =
      m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
  CXFA_ContentLayoutItem* pOldLayoutItem = m_pOldLayoutItem;
  while (pOldLayoutItem) {
    CXFA_ContentLayoutItem* pNextOldLayoutItem = pOldLayoutItem->m_pNext;
    pNotify->OnLayoutItemRemoving(pDocLayout, pOldLayoutItem);
    if (pOldLayoutItem->m_pParent)
      pOldLayoutItem->m_pParent->RemoveChild(pOldLayoutItem);

    delete pOldLayoutItem;
    pOldLayoutItem = pNextOldLayoutItem;
  }
  m_pOldLayoutItem = nullptr;
  return pLayoutItem;
}

void CXFA_ItemLayoutProcessor::GotoNextContainerNode(
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    CXFA_Node* pParentContainer,
    bool bUsePageBreak) {
  CXFA_Node* pEntireContainer = pParentContainer;
  CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;
  switch (nCurStage) {
    case XFA_ItemLayoutProcessorStages::BreakBefore:
    case XFA_ItemLayoutProcessorStages::BreakAfter: {
      pChildContainer = pCurActionNode->GetParent();
      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->GetFirstChild();
      if (!m_bKeepBreakFinish &&
          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->GetFirstChild()
                                           : pCurActionNode->GetNextSibling();
             pBookendNode; pBookendNode = pBookendNode->GetNextSibling()) {
          switch (pBookendNode->GetElementType()) {
            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->GetNextSibling();
            if (!m_bKeepBreakFinish &&
                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->GetFirstChild();
          if (!m_bKeepBreakFinish &&
              FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage,
                            false)) {
            return;
          }
        } else {
          CXFA_Node* pBreakAfterNode = pCurActionNode->GetNextSibling();
          if (FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage,
                            false)) {
            return;
          }
        }
        goto CheckNextChildContainer;
      }
    }

    CheckNextChildContainer : {
      CXFA_Node* pNextChildContainer =
          pChildContainer == XFA_LAYOUT_INVALIDNODE
              ? pEntireContainer->GetFirstContainerChild()
              : pChildContainer->GetNextContainerSibling();
      while (pNextChildContainer &&
             pNextChildContainer->IsLayoutGeneratedNode()) {
        CXFA_Node* pSaveNode = pNextChildContainer;
        pNextChildContainer = pNextChildContainer->GetNextContainerSibling();
        if (pSaveNode->IsUnusedNode())
          DeleteLayoutGeneratedNode(pSaveNode);
      }
      if (!pNextChildContainer)
        goto NoMoreChildContainer;

      bool bLastKeep = false;
      if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage,
                                       pNextChildContainer, bLastKeep)) {
        return;
      }
      if (!m_bKeepBreakFinish && !bLastKeep &&
          FindBreakNode(pNextChildContainer->GetFirstChild(), 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->GetFirstChild()
                                           : pCurActionNode->GetNextSibling();
             pBookendNode; pBookendNode = pBookendNode->GetNextSibling()) {
          switch (pBookendNode->GetElementType()) {
            case XFA_Element::Bookend:
            case XFA_Element::Break:
              pCurActionNode = pBookendNode;
              nCurStage = XFA_ItemLayoutProcessorStages::BookendTrailer;
              return;
            default:
              break;
          }
        }
    }
    default:
      pCurActionNode = nullptr;
      nCurStage = XFA_ItemLayoutProcessorStages::Done;
  }
}

bool CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(
    CXFA_Node*& pCurActionNode,
    XFA_ItemLayoutProcessorStages& nCurStage,
    CXFA_Node*& pNextContainer,
    bool& bLastKeepNode) {
  const bool bCanSplit = pNextContainer->GetIntact() == XFA_AttributeEnum::None;
  bool bNextKeep = false;
  if (ExistContainerKeep(pNextContainer, false))
    bNextKeep = true;

  if (bNextKeep && !bCanSplit) {
    if (!m_bIsProcessKeep && !m_bKeepBreakFinish) {
      m_pKeepHeadNode = pNextContainer;
      m_bIsProcessKeep = true;
    }
    return false;
  }

  if (m_bIsProcessKeep && m_pKeepHeadNode) {
    m_pKeepTailNode = pNextContainer;
    if (!m_bKeepBreakFinish &&
        FindBreakNode(pNextContainer->GetFirstChild(), pCurActionNode,
                      &nCurStage, true)) {
      return true;
    }

    pNextContainer = m_pKeepHeadNode;
    m_bKeepBreakFinish = true;
    m_pKeepHeadNode = nullptr;
    m_pKeepTailNode = nullptr;
    m_bIsProcessKeep = false;
  } else {
    if (m_bKeepBreakFinish)
      bLastKeepNode = true;
    m_bKeepBreakFinish = false;
  }

  return false;
}

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 = nullptr;
    m_pKeepTailNode = nullptr;
    m_bIsProcessKeep = false;
    nCurStage = XFA_ItemLayoutProcessorStages::Container;
    return true;
  }

  CXFA_Node* pBreakAfterNode = pContainerNode->GetFirstChild();
  return FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage, false);
}

bool XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) {
  XFA_AttributeEnum ePresence = pNode->JSObject()
                                    ->TryEnum(XFA_Attribute::Presence, true)
                                    .value_or(XFA_AttributeEnum::Visible);
  return ePresence == XFA_AttributeEnum::Visible ||
         ePresence == XFA_AttributeEnum::Invisible;
}

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 = nullptr;
  for (GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode,
                             false);
       pCurChildNode; GotoNextContainerNode(pCurChildNode, nCurChildNodeStage,
                                            pFormNode, false)) {
    if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container)
      continue;
    if (pCurChildNode->GetElementType() == XFA_Element::Variables)
      continue;

    auto pProcessor =
        pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pCurChildNode, nullptr);
    pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr);
    if (!pProcessor->HasLayoutItem())
      continue;

    pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos(
        pCurChildNode, pProcessor->GetCurrentComponentSize()));
    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
    if (!pBeforeItem)
      pPageAreaLayoutItem->AddHeadChild(pProcessItem);
    else
      pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);

    pBeforeItem = pProcessItem;
  }

  pBeforeItem = nullptr;
  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;
  while (pLayoutItem) {
    if (!pLayoutItem->IsContentLayoutItem() ||
        pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::Draw) {
      pLayoutItem = pLayoutItem->m_pNextSibling;
      continue;
    }
    if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::Draw)
      continue;

    CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling;
    pPageAreaLayoutItem->RemoveChild(pLayoutItem);
    if (!pBeforeItem)
      pPageAreaLayoutItem->AddHeadChild(pLayoutItem);
    else
      pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);

    pBeforeItem = pLayoutItem;
    pLayoutItem = pNextLayoutItem;
  }
}

void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(
    CXFA_LayoutContext* pContext) {
  if (m_pLayoutItem)
    return;

  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  bool bIgnoreXY = (m_pFormNode->JSObject()
                        ->TryEnum(XFA_Attribute::Layout, true)
                        .value_or(XFA_AttributeEnum::Position) !=
                    XFA_AttributeEnum::Position);
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize);

  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fHiddenContentCalculatedWidth = 0;
  float fHiddenContentCalculatedHeight = 0;
  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
    GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode,
                          false);
  }

  int32_t iColIndex = 0;
  for (; m_pCurChildNode; GotoNextContainerNode(
           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false)) {
    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container)
      continue;
    if (m_pCurChildNode->GetElementType() == XFA_Element::Variables)
      continue;

    auto pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
        m_pCurChildNode, m_pPageMgr);
    if (pContext && pContext->m_prgSpecifiedColumnWidths) {
      int32_t iColSpan =
          m_pCurChildNode->JSObject()->GetInteger(XFA_Attribute::ColSpan);
      if (iColSpan <= pdfium::CollectionSize<int32_t>(
                          *pContext->m_prgSpecifiedColumnWidths) -
                          iColIndex) {
        pContext->m_fCurColumnWidth = 0;
        pContext->m_bCurColumnWidthAvaiable = true;
        if (iColSpan == -1) {
          iColSpan = pdfium::CollectionSize<int32_t>(
              *pContext->m_prgSpecifiedColumnWidths);
        }
        for (int32_t i = 0; iColIndex + i < iColSpan; ++i) {
          pContext->m_fCurColumnWidth +=
              (*pContext->m_prgSpecifiedColumnWidths)[iColIndex + i];
        }
        if (pContext->m_fCurColumnWidth == 0)
          pContext->m_bCurColumnWidthAvaiable = false;

        iColIndex += iColSpan >= 0 ? iColSpan : 0;
      }
    }

    pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, pContext);
    if (!pProcessor->HasLayoutItem())
      continue;

    CFX_SizeF size = pProcessor->GetCurrentComponentSize();
    bool bChangeParentSize = false;
    if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode))
      bChangeParentSize = true;

    CFX_PointF absolutePos;
    if (!bIgnoreXY)
      absolutePos = CalculatePositionedContainerPos(m_pCurChildNode, size);

    pProcessor->SetCurrentComponentPos(absolutePos);
    if (bContainerWidthAutoSize) {
      float fChildSuppliedWidth = absolutePos.x + size.width;
      if (bChangeParentSize) {
        fContentCalculatedWidth =
            std::max(fContentCalculatedWidth, fChildSuppliedWidth);
      } else {
        if (fHiddenContentCalculatedWidth < fChildSuppliedWidth &&
            m_pCurChildNode->GetElementType() != XFA_Element::Subform) {
          fHiddenContentCalculatedWidth = fChildSuppliedWidth;
        }
      }
    }

    if (bContainerHeightAutoSize) {
      float fChildSuppliedHeight = absolutePos.y + size.height;
      if (bChangeParentSize) {
        fContentCalculatedHeight =
            std::max(fContentCalculatedHeight, fChildSuppliedHeight);
      } else {
        if (fHiddenContentCalculatedHeight < fChildSuppliedHeight &&
            m_pCurChildNode->GetElementType() != XFA_Element::Subform) {
          fHiddenContentCalculatedHeight = fChildSuppliedHeight;
        }
      }
    }
    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
  }

  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;

  containerSize = CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      bContainerHeightAutoSize, fContentCalculatedHeight, containerSize);
  SetCurrentComponentSize(containerSize);
}

void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) {
  if (m_pLayoutItem)
    return;
  if (!pLayoutNode)
    pLayoutNode = m_pFormNode;

  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);

  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize);
  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  CXFA_Margin* pMarginNode =
      m_pFormNode->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  float fLeftInset = 0;
  float fRightInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()
                     ->GetMeasure(XFA_Attribute::LeftInset)
                     .ToUnit(XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()
                      ->GetMeasure(XFA_Attribute::RightInset)
                      .ToUnit(XFA_Unit::Pt);
  }

  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - fLeftInset - fRightInset;
  WideString wsColumnWidths =
      pLayoutNode->JSObject()->GetCData(XFA_Attribute::ColumnWidths);
  if (!wsColumnWidths.IsEmpty()) {
    auto widths = SeparateStringW(wsColumnWidths.c_str(),
                                  wsColumnWidths.GetLength(), L' ');
    for (auto& width : widths) {
      width.TrimLeft(L' ');
      if (width.IsEmpty())
        continue;

      m_rgSpecifiedColumnWidths.push_back(
          CXFA_Measurement(width.AsStringView()).ToUnit(XFA_Unit::Pt));
    }
  }

  int32_t iSpecifiedColumnCount =
      pdfium::CollectionSize<int32_t>(m_rgSpecifiedColumnWidths);
  CXFA_LayoutContext layoutContext;
  layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
  CXFA_LayoutContext* pLayoutContext =
      iSpecifiedColumnCount > 0 ? &layoutContext : nullptr;
  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
    GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode,
                          false);
  }

  for (; m_pCurChildNode; GotoNextContainerNode(
           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false)) {
    layoutContext.m_bCurColumnWidthAvaiable = false;
    layoutContext.m_fCurColumnWidth = 0;
    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container)
      continue;

    auto pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
        m_pCurChildNode, m_pPageMgr);
    pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, pLayoutContext);
    if (!pProcessor->HasLayoutItem())
      continue;

    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
  }

  int32_t iRowCount = 0;
  int32_t iColCount = 0;
  {
    std::vector<CXFA_ContentLayoutItem*> rgRowItems;
    std::vector<int32_t> rgRowItemsSpan;
    std::vector<float> rgRowItemsWidth;
    for (auto* pLayoutChild =
             static_cast<CXFA_ContentLayoutItem*>(m_pLayoutItem->m_pFirstChild);
         pLayoutChild; pLayoutChild = static_cast<CXFA_ContentLayoutItem*>(
                           pLayoutChild->m_pNextSibling)) {
      if (pLayoutChild->m_pFormNode->GetElementType() != XFA_Element::Subform)
        continue;
      if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode))
        continue;

      XFA_AttributeEnum eLayout =
          pLayoutChild->m_pFormNode->JSObject()->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.push_back(pRowLayoutCell);
        int32_t iColSpan = pRowLayoutCell->m_pFormNode->JSObject()->GetInteger(
            XFA_Attribute::ColSpan);
        rgRowItemsSpan.push_back(iColSpan);
        rgRowItemsWidth.push_back(pRowLayoutCell->m_sSize.width);
      }
    }

    iRowCount = pdfium::CollectionSize<int32_t>(rgRowItems);
    iColCount = 0;
    bool bMoreColumns = true;
    while (bMoreColumns) {
      bMoreColumns = false;
      bool bAutoCol = false;
      for (int32_t i = 0; i < iRowCount; i++) {
        while (rgRowItems[i] && (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 = nullptr;
          }
          rgRowItems[i] = pNewCell;
          rgRowItemsSpan[i] =
              pNewCell ? pNewCell->m_pFormNode->JSObject()->GetInteger(
                             XFA_Attribute::ColSpan)
                       : 0;
          rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.width : 0;
        }
        CXFA_ContentLayoutItem* pCell = rgRowItems[i];
        if (!pCell)
          continue;

        bMoreColumns = true;
        if (rgRowItemsSpan[i] != 1)
          continue;

        if (iColCount >= iSpecifiedColumnCount) {
          int32_t c = iColCount + 1 - pdfium::CollectionSize<int32_t>(
                                          m_rgSpecifiedColumnWidths);
          for (int32_t j = 0; j < c; j++)
            m_rgSpecifiedColumnWidths.push_back(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)
        continue;

      float fFinalColumnWidth = 0.0f;
      if (pdfium::IndexInBounds(m_rgSpecifiedColumnWidths, iColCount))
        fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];

      for (int32_t i = 0; i < iRowCount; ++i) {
        if (!rgRowItems[i])
          continue;
        --rgRowItemsSpan[i];
        rgRowItemsWidth[i] -= fFinalColumnWidth;
      }
      ++iColCount;
    }
  }

  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->GetElementType() == XFA_Element::Subform) {
      XFA_AttributeEnum eSubformLayout =
          pLayoutChild->m_pFormNode->JSObject()->GetEnum(XFA_Attribute::Layout);
      if (eSubformLayout == XFA_AttributeEnum::Row ||
          eSubformLayout == XFA_AttributeEnum::Rl_row) {
        RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths,
                              eSubformLayout);
      }
    }

    pLayoutChild->m_sPos.y = fCurrentRowY;
    if (bContainerWidthAutoSize) {
      pLayoutChild->m_sPos.x = 0;
    } else {
      switch (pLayoutChild->m_pFormNode->JSObject()->GetEnum(
          XFA_Attribute::HAlign)) {
        case XFA_AttributeEnum::Center:
          pLayoutChild->m_sPos.x =
              (fContentWidthLimit - pLayoutChild->m_sSize.width) / 2;
          break;
        case XFA_AttributeEnum::Right:
          pLayoutChild->m_sPos.x =
              fContentWidthLimit - pLayoutChild->m_sSize.width;
          break;
        case XFA_AttributeEnum::Left:
        default:
          pLayoutChild->m_sPos.x = 0;
          break;
      }
    }

    if (bContainerWidthAutoSize) {
      float fChildSuppliedWidth =
          pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.width;
      if (fContentWidthLimit < FLT_MAX &&
          fContentWidthLimit > fChildSuppliedWidth) {
        fChildSuppliedWidth = fContentWidthLimit;
      }
      fContentCalculatedWidth =
          std::max(fContentCalculatedWidth, fChildSuppliedWidth);
    }
    fCurrentRowY += pLayoutChild->m_sSize.height;
  }

  if (bContainerHeightAutoSize)
    fContentCalculatedHeight = std::max(fContentCalculatedHeight, fCurrentRowY);

  containerSize = CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      bContainerHeightAutoSize, fContentCalculatedHeight, containerSize);
  SetCurrentComponentSize(containerSize);
}

bool CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(
    CXFA_ContentLayoutItem* pTrailerItem) {
  if (!pTrailerItem)
    return false;

  float fWidth = pTrailerItem->m_sSize.width;
  XFA_AttributeEnum eLayout =
      m_pFormNode->JSObject()->GetEnum(XFA_Attribute::Layout);
  return eLayout == XFA_AttributeEnum::Tb || m_fWidthLimite <= fWidth;
}

float CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() {
  if (m_arrayKeepItems.empty())
    return 0;

  if (!m_pLayoutItem) {
    m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
    m_pLayoutItem->m_sSize.clear();
  }

  float fTotalHeight = 0;
  for (auto iter = m_arrayKeepItems.rbegin(); iter != m_arrayKeepItems.rend();
       iter++) {
    AddLeaderAfterSplit(this, *iter);
    fTotalHeight += (*iter)->m_sSize.height;
  }
  m_arrayKeepItems.clear();

  return fTotalHeight;
}

bool CXFA_ItemLayoutProcessor::ProcessKeepForSplit(
    CXFA_ItemLayoutProcessor* pParentProcessor,
    CXFA_ItemLayoutProcessor* pChildProcessor,
    XFA_ItemLayoutProcessorResult eRetValue,
    std::vector<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem,
    float* fContentCurRowAvailWidth,
    float* fContentCurRowHeight,
    float* fContentCurRowY,
    bool* bAddedItemInRow,
    bool* bForceEndPage,
    XFA_ItemLayoutProcessorResult* result) {
  if (!pParentProcessor || !pChildProcessor)
    return false;

  if (pParentProcessor->m_pCurChildNode->GetIntact() ==
          XFA_AttributeEnum::None &&
      pChildProcessor->m_bHasAvailHeight)
    return false;

  if (!ExistContainerKeep(pParentProcessor->m_pCurChildNode, true))
    return false;

  CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize();
  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
  if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem,
                                         childSize.height, &keepLayoutItems)) {
    m_arrayKeepItems.clear();

    for (auto* item : keepLayoutItems) {
      pParentProcessor->m_pLayoutItem->RemoveChild(item);
      *fContentCurRowY -= item->m_sSize.height;
      m_arrayKeepItems.push_back(item);
    }
    *bAddedItemInRow = true;
    *bForceEndPage = true;
    *result = XFA_ItemLayoutProcessorResult::PageFullBreak;
    return true;
  }

  rgCurLineLayoutItem->push_back(pChildProcessor->ExtractLayoutItem());
  *bAddedItemInRow = true;
  *fContentCurRowAvailWidth -= childSize.width;
  *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height);
  *result = eRetValue;

  return true;
}

bool CXFA_ItemLayoutProcessor::JudgePutNextPage(
    CXFA_ContentLayoutItem* pParentLayoutItem,
    float fChildHeight,
    std::vector<CXFA_ContentLayoutItem*>* pKeepItems) {
  if (!pParentLayoutItem)
    return false;

  float fItemsHeight = 0;
  for (CXFA_ContentLayoutItem* pChildLayoutItem =
           (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild;
       pChildLayoutItem;
       pChildLayoutItem =
           (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) {
    if (ExistContainerKeep(pChildLayoutItem->m_pFormNode, false)) {
      pKeepItems->push_back(pChildLayoutItem);
      fItemsHeight += pChildLayoutItem->m_sSize.height;
    } else {
      pKeepItems->clear();
      fItemsHeight = 0;
    }
  }
  fItemsHeight += fChildHeight;
  return m_pPageMgr->GetNextAvailContentHeight(fItemsHeight);
}

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->SetBindingNode(nullptr);
      }
    }
    pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
  }
}

void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(
    CXFA_Node* pLeaderNode,
    CXFA_Node* pTrailerNode,
    CXFA_ContentLayoutItem* pTrailerItem,
    CXFA_Node* pFormNode) {
  ProcessUnUseBinds(pLeaderNode);
  ProcessUnUseBinds(pTrailerNode);
  if (!pFormNode)
    return;

  if (pFormNode->GetElementType() == XFA_Element::Overflow ||
      pFormNode->GetElementType() == XFA_Element::Break) {
    pFormNode = pFormNode->GetParent();
  }
  if (pLeaderNode && pFormNode)
    pFormNode->RemoveChild(pLeaderNode, true);
  if (pTrailerNode && pFormNode)
    pFormNode->RemoveChild(pTrailerNode, true);
  if (pTrailerItem)
    XFA_ReleaseLayoutItem(pTrailerItem);
}

XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(
    bool bUseBreakControl,
    XFA_AttributeEnum eFlowStrategy,
    float fHeightLimit,
    float fRealHeight,
    CXFA_LayoutContext* pContext,
    bool bRootForceTb) {
  m_bHasAvailHeight = true;
  bool bBreakDone = false;
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  bool bForceEndPage = false;
  bool bIsManualBreak = false;
  if (m_pCurChildPreprocessor) {
    m_pCurChildPreprocessor->m_ePreProcessRs =
        XFA_ItemLayoutProcessorResult::Done;
  }

  CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize);
  if (pContext && pContext->m_bCurColumnWidthAvaiable) {
    bContainerWidthAutoSize = false;
    containerSize.width = pContext->m_fCurColumnWidth;
  }
  if (!bContainerHeightAutoSize)
    containerSize.height -= m_fUsedSize;

  if (!bContainerHeightAutoSize) {
    CXFA_Node* pParentNode = m_pFormNode->GetParent();
    bool bFocrTb = false;
    if (pParentNode &&
        GetLayout(pParentNode, &bFocrTb) == XFA_AttributeEnum::Row) {
      CXFA_Node* pChildContainer = m_pFormNode->GetFirstContainerChild();
      if (pChildContainer && pChildContainer->GetNextContainerSibling()) {
        containerSize.height = 0;
        bContainerHeightAutoSize = true;
      }
    }
  }

  CXFA_Margin* pMarginNode =
      m_pFormNode->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  float fLeftInset = 0;
  float fTopInset = 0;
  float fRightInset = 0;
  float fBottomInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()
                     ->GetMeasure(XFA_Attribute::LeftInset)
                     .ToUnit(XFA_Unit::Pt);
    fTopInset = pMarginNode->JSObject()
                    ->GetMeasure(XFA_Attribute::TopInset)
                    .ToUnit(XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()
                      ->GetMeasure(XFA_Attribute::RightInset)
                      .ToUnit(XFA_Unit::Pt);
    fBottomInset = pMarginNode->JSObject()
                       ->GetMeasure(XFA_Attribute::BottomInset)
                       .ToUnit(XFA_Unit::Pt);
  }
  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - fLeftInset - fRightInset;
  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fAvailHeight = fHeightLimit - fTopInset - fBottomInset;
  if (fAvailHeight < 0)
    m_bHasAvailHeight = false;

  fRealHeight = fRealHeight - fTopInset - fBottomInset;
  float fContentCurRowY = 0;
  CXFA_ContentLayoutItem* pLayoutChild = nullptr;
  if (m_pLayoutItem) {
    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))
        continue;

      fContentCalculatedWidth = std::max(
          fContentCalculatedWidth,
          pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.width);
      fContentCalculatedHeight = std::max(
          fContentCalculatedHeight,
          pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.height);
    }

    if (pLayoutChild)
      fContentCurRowY = pLayoutChild->m_sPos.y;
    else
      fContentCurRowY = fContentCalculatedHeight;
  }

  fContentCurRowY += InsertKeepLayoutItems();
  if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::None) {
    GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode,
                          true);
  }

  fContentCurRowY += InsertPendingItems(this, m_pFormNode);
  if (m_pCurChildPreprocessor &&
      m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Container) {
    if (ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), false)) {
      m_pKeepHeadNode = m_pCurChildNode;
      m_bIsProcessKeep = true;
      m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::Keep;
    }
  }

  while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Done) {
    float fContentCurRowHeight = 0;
    float fContentCurRowAvailWidth = fContentWidthLimit;
    m_fWidthLimite = fContentCurRowAvailWidth;
    std::vector<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 && 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 =
            HAlignEnumToInt(pLayoutNext->m_pFormNode->JSObject()->GetEnum(
                XFA_Attribute::HAlign));
        rgCurLineLayoutItems[uHAlign].push_back(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.height > fContentCurRowHeight)
            fContentCurRowHeight = pLayoutNext->m_sSize.height;
          fContentCurRowAvailWidth -= pLayoutNext->m_sSize.width;
        }
      }

      if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild ==
          pLayoutChild) {
        m_pLayoutItem->m_pFirstChild = nullptr;
      } 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 = nullptr;
            break;
          }
        }
      }

      CXFA_ContentLayoutItem* pLayoutNextTemp =
          (CXFA_ContentLayoutItem*)pLayoutChild;
      while (pLayoutNextTemp) {
        pLayoutNextTemp->m_pParent = nullptr;
        CXFA_ContentLayoutItem* pSaveLayoutNext =
            (CXFA_ContentLayoutItem*)pLayoutNextTemp->m_pNextSibling;
        pLayoutNextTemp->m_pNextSibling = nullptr;
        pLayoutNextTemp = pSaveLayoutNext;
      }
      pLayoutChild = nullptr;
    }

    while (m_pCurChildNode) {
      std::unique_ptr<CXFA_ItemLayoutProcessor> pProcessor;
      bool bAddedItemInRow = false;
      fContentCurRowY += InsertPendingItems(this, m_pFormNode);
      switch (m_nCurChildNodeStage) {
        case XFA_ItemLayoutProcessorStages::Keep:
        case XFA_ItemLayoutProcessorStages::None:
          break;
        case XFA_ItemLayoutProcessorStages::BreakBefore: {
          for (auto* item : m_arrayKeepItems) {
            m_pLayoutItem->RemoveChild(item);
            fContentCalculatedHeight -= item->m_sSize.height;
          }

          CXFA_Node* pLeaderNode = nullptr;
          CXFA_Node* pTrailerNode = nullptr;
          bool bCreatePage = false;
          if (!bUseBreakControl || !m_pPageMgr ||
              !m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, true,
                                                     pLeaderNode, pTrailerNode,
                                                     bCreatePage) ||
              m_pFormNode->GetElementType() == XFA_Element::Form ||
              !bCreatePage) {
            break;
          }

          if (JudgeLeaderOrTrailerForOccur(pLeaderNode))
            AddPendingNode(this, pLeaderNode, true);

          if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
            if (m_pFormNode->GetParent()->GetElementType() ==
                    XFA_Element::Form &&
                !m_pLayoutItem) {
              AddPendingNode(this, pTrailerNode, true);
            } else {
              auto pTempProcessor =
                  pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pTrailerNode,
                                                               nullptr);
              InsertFlowedItem(
                  this, pTempProcessor.get(), bContainerWidthAutoSize,
                  bContainerHeightAutoSize, containerSize.height, eFlowStrategy,
                  &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX,
                  FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, pContext, false);
            }
          }
          GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage,
                                m_pFormNode, true);
          bForceEndPage = true;
          bIsManualBreak = true;
          goto SuspendAndCreateNewRow;
        }
        case XFA_ItemLayoutProcessorStages::BreakAfter: {
          CXFA_Node* pLeaderNode = nullptr;
          CXFA_Node* pTrailerNode = nullptr;
          bool bCreatePage = false;
          if (!bUseBreakControl || !m_pPageMgr ||
              !m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, false,
                                                     pLeaderNode, pTrailerNode,
                                                     bCreatePage) ||
              m_pFormNode->GetElementType() == XFA_Element::Form) {
            break;
          }

          if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
            auto pTempProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
                pTrailerNode, nullptr);
            InsertFlowedItem(
                this, pTempProcessor.get(), bContainerWidthAutoSize,
                bContainerHeightAutoSize, containerSize.height, eFlowStrategy,
                &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX, FLT_MAX,
                fContentWidthLimit, &fContentCurRowY, &fContentCurRowAvailWidth,
                &fContentCurRowHeight, &bAddedItemInRow, &bForceEndPage,
                pContext, false);
          }
          if (!bCreatePage) {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
              CalculateRowChildPosition(
                  rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize,
                  bContainerWidthAutoSize, &fContentCalculatedWidth,
                  &fContentCalculatedHeight, &fContentCurRowY,
                  fContentCurRowHeight, fContentWidthLimit, false);
              rgCurLineLayoutItems->clear();
              auto pTempProcessor =
                  pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pLeaderNode,
                                                               nullptr);
              InsertFlowedItem(
                  this, pTempProcessor.get(), bContainerWidthAutoSize,
                  bContainerHeightAutoSize, containerSize.height, eFlowStrategy,
                  &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX,
                  FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, pContext, false);
            }
          } else {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode))
              AddPendingNode(this, pLeaderNode, true);
          }

          GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage,
                                m_pFormNode, true);
          if (bCreatePage) {
            bForceEndPage = true;
            bIsManualBreak = true;
            if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Done)
              bBreakDone = true;
          }
          goto SuspendAndCreateNewRow;
        }
        case XFA_ItemLayoutProcessorStages::BookendLeader: {
          CXFA_Node* pLeaderNode = nullptr;
          if (m_pCurChildPreprocessor) {
            pProcessor.reset(m_pCurChildPreprocessor);
            m_pCurChildPreprocessor = nullptr;
          } else if (m_pPageMgr &&
                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
                         m_pCurChildNode, true, pLeaderNode)) {
            pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
                pLeaderNode, m_pPageMgr);
          }

          if (pProcessor) {
            if (InsertFlowedItem(
                    this, pProcessor.get(), bContainerWidthAutoSize,
                    bContainerHeightAutoSize, containerSize.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, pContext,
                    false) != XFA_ItemLayoutProcessorResult::Done) {
              goto SuspendAndCreateNewRow;
            } else {
              pProcessor.reset();
            }
          }
          break;
        }
        case XFA_ItemLayoutProcessorStages::BookendTrailer: {
          CXFA_Node* pTrailerNode = nullptr;
          if (m_pCurChildPreprocessor) {
            pProcessor.reset(m_pCurChildPreprocessor);
            m_pCurChildPreprocessor = nullptr;
          } else if (m_pPageMgr &&
                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
                         m_pCurChildNode, false, pTrailerNode)) {
            pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
                pTrailerNode, m_pPageMgr);
          }
          if (pProcessor) {
            if (InsertFlowedItem(
                    this, pProcessor.get(), bContainerWidthAutoSize,
                    bContainerHeightAutoSize, containerSize.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, pContext,
                    false) != XFA_ItemLayoutProcessorResult::Done) {
              goto SuspendAndCreateNewRow;
            } else {
              pProcessor.reset();
            }
          }
          break;
        }
        case XFA_ItemLayoutProcessorStages::Container: {
          ASSERT(m_pCurChildNode->IsContainerNode());
          if (m_pCurChildNode->GetElementType() == XFA_Element::Variables)
            break;
          if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION &&
              XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
            bForceEndPage = true;
            goto SuspendAndCreateNewRow;
          }
          if (!m_pCurChildNode->IsContainerNode())
            break;

          bool bNewRow = false;
          if (m_pCurChildPreprocessor) {
            pProcessor.reset(m_pCurChildPreprocessor);
            m_pCurChildPreprocessor = nullptr;
            bNewRow = true;
          } else {
            pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(
                m_pCurChildNode, m_pPageMgr);
          }

          InsertPendingItems(pProcessor.get(), m_pCurChildNode);
          XFA_ItemLayoutProcessorResult rs = InsertFlowedItem(
              this, pProcessor.get(), bContainerWidthAutoSize,
              bContainerHeightAutoSize, containerSize.height, eFlowStrategy,
              &uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
              fAvailHeight, fRealHeight, fContentWidthLimit, &fContentCurRowY,
              &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 +=
                  InsertPendingItems(pProcessor.get(), m_pCurChildNode);
              pProcessor.reset();
          }
          break;
        }
        case XFA_ItemLayoutProcessorStages::Done:
          break;
        default:
          break;
      }
      GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode,
                            true);
      if (bAddedItemInRow && eFlowStrategy == XFA_AttributeEnum::Tb)
        break;
      continue;
    SuspendAndCreateNewRow:
      if (pProcessor)
        m_pCurChildPreprocessor = pProcessor.release();
      break;
    }

    CalculateRowChildPosition(
        rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize,
        bContainerWidthAutoSize, &fContentCalculatedWidth,
        &fContentCalculatedHeight, &fContentCurRowY, fContentCurRowHeight,
        fContentWidthLimit, bRootForceTb);
    m_fWidthLimite = fContentCurRowAvailWidth;
    if (bForceEndPage)
      break;
  }

  bool bRetValue =
      m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Done &&
      m_PendingNodes.empty();
  if (bBreakDone)
    bRetValue = false;

  containerSize = CalculateContainerComponentSizeFromContentSize(
      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
      bContainerHeightAutoSize, fContentCalculatedHeight, containerSize);

  if (containerSize.height >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem ||
      bRetValue) {
    if (!m_pLayoutItem)
      m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
    containerSize.height = std::max(containerSize.height, 0.f);

    SetCurrentComponentSize(containerSize);
    if (bForceEndPage)
      m_fUsedSize = 0;
    else
      m_fUsedSize += m_pLayoutItem->m_sSize.height;
  }

  return bRetValue
             ? XFA_ItemLayoutProcessorResult::Done
             : (bIsManualBreak ? XFA_ItemLayoutProcessorResult::ManualBreak
                               : XFA_ItemLayoutProcessorResult::PageFullBreak);
}

bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition(
    std::vector<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3],
    XFA_AttributeEnum eFlowStrategy,
    bool bContainerHeightAutoSize,
    bool bContainerWidthAutoSize,
    float* fContentCalculatedWidth,
    float* fContentCalculatedHeight,
    float* fContentCurRowY,
    float fContentCurRowHeight,
    float fContentWidthLimit,
    bool bRootForceTb) {
  int32_t nGroupLengths[3] = {0, 0, 0};
  float fGroupWidths[3] = {0, 0, 0};
  int32_t nTotalLength = 0;
  for (int32_t i = 0; i < 3; i++) {
    nGroupLengths[i] = pdfium::CollectionSize<int32_t>(rgCurLineLayoutItems[i]);
    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.width;
      }
    }
  }
  if (!nTotalLength) {
    if (bContainerHeightAutoSize) {
      *fContentCalculatedHeight =
          std::min(*fContentCalculatedHeight, *fContentCurRowY);
    }
    return false;
  }
  if (!m_pLayoutItem)
    m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);

  if (eFlowStrategy != XFA_AttributeEnum::Rl_tb) {
    float fCurPos;
    fCurPos = 0;
    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
      if (bRootForceTb) {
        rgCurLineLayoutItems[0][j]->m_sPos = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[0][j]->m_pFormNode,
            rgCurLineLayoutItems[0][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[0][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[0][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.width;
        }
      }
      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) {
        rgCurLineLayoutItems[1][j]->m_sPos = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[1][j]->m_pFormNode,
            rgCurLineLayoutItems[1][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[1][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[1][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.width;
        }
      }
      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) {
        rgCurLineLayoutItems[2][j]->m_sPos = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[2][j]->m_pFormNode,
            rgCurLineLayoutItems[2][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[2][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (XFA_ItemLayoutProcessor_IsTakingSpace(
                rgCurLineLayoutItems[2][j]->m_pFormNode)) {
          fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.width;
        }
      }
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
      m_fLastRowWidth = fCurPos;
    }
  } else {
    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.width;
      }
      rgCurLineLayoutItems[0][j]->m_sPos =
          CFX_PointF(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.width;
      }
      rgCurLineLayoutItems[1][j]->m_sPos =
          CFX_PointF(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.width;
      }
      rgCurLineLayoutItems[2][j]->m_sPos =
          CFX_PointF(fCurPos, *fContentCurRowY);
      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
      m_fLastRowWidth = fCurPos;
    }
  }
  m_fLastRowY = *fContentCurRowY;
  *fContentCurRowY += fContentCurRowHeight;
  if (bContainerWidthAutoSize) {
    float fChildSuppliedWidth = fGroupWidths[0];
    if (fContentWidthLimit < FLT_MAX &&
        fContentWidthLimit > fChildSuppliedWidth) {
      fChildSuppliedWidth = fContentWidthLimit;
    }
    *fContentCalculatedWidth =
        std::max(*fContentCalculatedWidth, fChildSuppliedWidth);
  }
  if (bContainerHeightAutoSize) {
    *fContentCalculatedHeight =
        std::max(*fContentCalculatedHeight, *fContentCurRowY);
  }
  return true;
}

CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(
    CXFA_Node* pSubformSet) {
  if (pSubformSet && pSubformSet->GetElementType() == XFA_Element::SubformSet) {
    CXFA_Node* pParent = pSubformSet->GetParent();
    while (pParent) {
      if (pParent->GetElementType() != XFA_Element::SubformSet)
        return pParent;
      pParent = pParent->GetParent();
    }
  }
  return pSubformSet;
}

void CXFA_ItemLayoutProcessor::DoLayoutField() {
  if (m_pLayoutItem)
    return;

  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
  if (!m_pLayoutItem)
    return;

  CXFA_Document* pDocument = m_pFormNode->GetDocument();
  CXFA_FFNotify* pNotify = pDocument->GetNotify();
  CFX_SizeF size(-1, -1);
  pNotify->StartFieldDrawLayout(m_pFormNode, size.width, size.height);

  int32_t nRotate = XFA_MapRotation(
      m_pFormNode->JSObject()->GetInteger(XFA_Attribute::Rotate));
  if (nRotate == 90 || nRotate == 270)
    std::swap(size.width, size.height);

  SetCurrentComponentSize(size);
}

XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(
    bool bUseBreakControl,
    float fHeightLimit,
    float fRealHeight,
    CXFA_LayoutContext* pContext) {
  switch (m_pFormNode->GetElementType()) {
    case XFA_Element::Subform:
    case XFA_Element::Area:
    case XFA_Element::ExclGroup:
    case XFA_Element::SubformSet: {
      bool bRootForceTb = false;
      CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);
      XFA_AttributeEnum eLayoutStrategy = 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;
  }
}

CFX_SizeF CXFA_ItemLayoutProcessor::GetCurrentComponentSize() {
  return CFX_SizeF(m_pLayoutItem->m_sSize.width, m_pLayoutItem->m_sSize.height);
}

void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(const CFX_PointF& pos) {
  m_pLayoutItem->m_sPos = pos;
}

void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(const CFX_SizeF& size) {
  m_pLayoutItem->m_sSize = size;
}

bool CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(
    CXFA_Node* pFormNode) {
  if (!pFormNode)
    return false;

  CXFA_Node* pTemplate = pFormNode->GetTemplateNodeIfExists();
  if (!pTemplate)
    pTemplate = pFormNode;

  int32_t iMax =
      pTemplate->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur)->GetMax();
  if (iMax < 0)
    return true;

  int32_t iCount = m_PendingNodesCount[pTemplate];
  if (iCount >= iMax)
    return false;

  m_PendingNodesCount[pTemplate] = iCount + 1;
  return true;
}
