// 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/layout/cxfa_contentlayoutprocessor.h"

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

#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/compiler_specific.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/cxfa_ffwidget.h"
#include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
#include "xfa/fxfa/layout/cxfa_viewlayoutitem.h"
#include "xfa/fxfa/layout/cxfa_viewlayoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_keep.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> SeparateStringOnSpace(
    pdfium::span<const wchar_t> spStr) {
  std::vector<WideString> ret;
  if (spStr.empty())
    return ret;

  size_t nPos = 0;
  size_t nToken = 0;
  while (nPos < spStr.size()) {
    if (spStr[nPos] == L' ') {
      ret.emplace_back(WideStringView(spStr.subspan(nToken, nPos - nToken)));
      nToken = nPos + 1;
    }
    nPos++;
  }
  ret.emplace_back(WideStringView(spStr.subspan(nToken, nPos - nToken)));
  return ret;
}

void UpdateWidgetSize(CXFA_ContentLayoutItem* pLayoutItem,
                      float* pWidth,
                      float* pHeight) {
  CXFA_Node* pNode = pLayoutItem->GetFormNode();
  switch (pNode->GetElementType()) {
    case XFA_Element::Subform:
    case XFA_Element::Area:
    case XFA_Element::ExclGroup:
    case XFA_Element::SubformSet: {
      if (*pWidth < -kXFALayoutPrecision)
        *pWidth = pLayoutItem->m_sSize.width;
      if (*pHeight < -kXFALayoutPrecision)
        *pHeight = pLayoutItem->m_sSize.height;
      break;
    }
    case XFA_Element::Draw:
    case XFA_Element::Field: {
      pNode->GetDocument()->GetNotify()->StartFieldDrawLayout(pNode, pWidth,
                                                              pHeight);
      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() > kXFALayoutPrecision) {
      containerSize.width = wValue->ToUnit(XFA_Unit::Pt);
      *bContainerWidthAutoSize = false;
    }

    Optional<CXFA_Measurement> hValue =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::H, false);
    if (hValue && hValue->GetValue() > kXFALayoutPrecision) {
      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() > kXFALayoutPrecision) {
      containerSize.width = maxW->ToUnit(XFA_Unit::Pt);
      *bContainerWidthAutoSize = false;
    }

    Optional<CXFA_Measurement> maxH =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxH, false);
    if (maxH && maxH->GetValue() > kXFALayoutPrecision) {
      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;
}

CFX_FloatRect GetMarginInset(const CXFA_Margin* pMargin) {
  CFX_FloatRect inset;
  if (!pMargin)
    return inset;

  inset.left = pMargin->JSObject()->GetMeasureInUnit(XFA_Attribute::LeftInset,
                                                     XFA_Unit::Pt);
  inset.top = pMargin->JSObject()->GetMeasureInUnit(XFA_Attribute::TopInset,
                                                    XFA_Unit::Pt);
  inset.right = pMargin->JSObject()->GetMeasureInUnit(XFA_Attribute::RightInset,
                                                      XFA_Unit::Pt);
  inset.bottom = pMargin->JSObject()->GetMeasureInUnit(
      XFA_Attribute::BottomInset, XFA_Unit::Pt);
  return inset;
}

void RelocateTableRowCells(const RetainPtr<CXFA_ContentLayoutItem>& pLayoutRow,
                           const std::vector<float>& rgSpecifiedColumnWidths,
                           XFA_AttributeValue eLayout) {
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      pLayoutRow->GetFormNode(), &bContainerWidthAutoSize,
      &bContainerHeightAutoSize);
  CXFA_Margin* pMargin =
      pLayoutRow->GetFormNode()->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  CFX_FloatRect inset = GetMarginInset(pMargin);
  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - inset.left - inset.right;
  float fContentCurrentHeight =
      pLayoutRow->m_sSize.height - inset.top - inset.bottom;
  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fCurrentColX = 0;
  int32_t nCurrentColIdx = 0;
  bool bMetWholeRowCell = false;

  for (CXFA_LayoutItem* pIter = pLayoutRow->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
    if (!pLayoutChild)
      continue;

    int32_t nOriginalColSpan =
        pLayoutChild->GetFormNode()->JSObject()->GetInteger(
            XFA_Attribute::ColSpan);
    if (nOriginalColSpan <= 0 && nOriginalColSpan != -1)
      continue;

    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 (!pLayoutChild->GetFormNode()->PresenceRequiresSpace())
      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_LayoutItem* pIter = pLayoutRow->GetFirstChild(); pIter;
         pIter = pIter->GetNextSibling()) {
      CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
      if (!pLayoutChild)
        continue;

      UpdateWidgetSize(pLayoutChild, &pLayoutChild->m_sSize.width,
                       &fContentCalculatedHeight);
      float fOldChildHeight = pLayoutChild->m_sSize.height;
      pLayoutChild->m_sSize.height = fContentCalculatedHeight;
      CXFA_Para* pParaNode =
          pLayoutChild->GetFormNode()->GetFirstChildByClass<CXFA_Para>(
              XFA_Element::Para);
      if (pParaNode && pLayoutChild->GetFirstChild()) {
        float fOffHeight = fContentCalculatedHeight - fOldChildHeight;
        XFA_AttributeValue eVType =
            pParaNode->JSObject()->GetEnum(XFA_Attribute::VAlign);
        switch (eVType) {
          case XFA_AttributeValue::Middle:
            fOffHeight = fOffHeight / 2;
            break;
          case XFA_AttributeValue::Bottom:
            break;
          case XFA_AttributeValue::Top:
          default:
            fOffHeight = 0;
            break;
        }
        if (fOffHeight > 0) {
          for (CXFA_LayoutItem* pInnerIter = pLayoutChild->GetFirstChild();
               pInnerIter; pInnerIter = pInnerIter->GetNextSibling()) {
            CXFA_ContentLayoutItem* pInnerChild =
                pInnerIter->AsContentLayoutItem();
            if (!pInnerChild)
              continue;

            pInnerChild->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 - inset.left - inset.right;
  }

  if (pLayoutRow->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout) ==
      XFA_AttributeValue::Rl_row) {
    for (CXFA_LayoutItem* pIter = pLayoutRow->GetFirstChild(); pIter;
         pIter = pIter->GetNextSibling()) {
      CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
      if (!pLayoutChild)
        continue;

      pLayoutChild->m_sPos.x = fContentCalculatedWidth -
                               pLayoutChild->m_sPos.x -
                               pLayoutChild->m_sSize.width;
    }
  }
  pLayoutRow->m_sSize = CalculateContainerComponentSizeFromContentSize(
      pLayoutRow->GetFormNode(), bContainerWidthAutoSize,
      fContentCalculatedWidth, bContainerHeightAutoSize,
      fContentCalculatedHeight, containerSize);
}

XFA_AttributeValue GetLayout(CXFA_Node* pFormNode, bool* bRootForceTb) {
  *bRootForceTb = false;
  Optional<XFA_AttributeValue> 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_AttributeValue::Tb;
  }
  return XFA_AttributeValue::Position;
}

bool ExistContainerKeep(CXFA_Node* pCurNode, bool bPreFind) {
  if (!pCurNode || !pCurNode->PresenceRequiresSpace())
    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_AttributeValue> previous =
        pKeep->JSObject()->TryEnum(eKeepType, false);
    if (previous) {
      if (*previous == XFA_AttributeValue::ContentArea ||
          *previous == XFA_AttributeValue::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_AttributeValue> next =
      pKeep->JSObject()->TryEnum(eKeepType, false);
  if (!next)
    return false;
  if (*next == XFA_AttributeValue::ContentArea ||
      *next == XFA_AttributeValue::PageArea) {
    return true;
  }
  return false;
}

Optional<CXFA_ContentLayoutProcessor::Stage> FindBreakNode(
    CXFA_Node* pContainerNode,
    bool bBreakBefore,
    CXFA_Node** pCurActionNode) {
  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
       pBreakNode = pBreakNode->GetNextSibling()) {
    XFA_Attribute eAttributeType =
        bBreakBefore ? XFA_Attribute::Before : XFA_Attribute::After;

    switch (pBreakNode->GetElementType()) {
      case XFA_Element::BreakBefore: {
        if (!bBreakBefore)
          break;

        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakBefore;
      }
      case XFA_Element::BreakAfter: {
        if (bBreakBefore)
          break;

        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakAfter;
      }
      case XFA_Element::Break:
        if (pBreakNode->JSObject()->GetEnum(eAttributeType) ==
            XFA_AttributeValue::Auto) {
          break;
        }

        *pCurActionNode = pBreakNode;
        return bBreakBefore ? CXFA_ContentLayoutProcessor::Stage::kBreakBefore
                            : CXFA_ContentLayoutProcessor::Stage::kBreakAfter;
      default:
        break;
    }
  }
  return {};
}

void DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
  CXFA_FFNotify* pNotify = pGenerateNode->GetDocument()->GetNotify();
  auto* pDocLayout =
      CXFA_LayoutProcessor::FromDocument(pGenerateNode->GetDocument());
  CXFA_NodeIterator sIterator(pGenerateNode);
  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
       pNode = sIterator.MoveToNext()) {
    RetainPtr<CXFA_ContentLayoutItem> pCurLayoutItem(
        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem()));
    while (pCurLayoutItem) {
      CXFA_ContentLayoutItem* pNextLayoutItem = pCurLayoutItem->GetNext();
      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem.Get());
      pCurLayoutItem.Reset(pNextLayoutItem);
    }
  }
  pGenerateNode->GetParent()->RemoveChildAndNotify(pGenerateNode, true);
}

uint8_t HAlignEnumToInt(XFA_AttributeValue eHAlign) {
  switch (eHAlign) {
    case XFA_AttributeValue::Center:
      return 1;
    case XFA_AttributeValue::Right:
      return 2;
    case XFA_AttributeValue::Left:
    default:
      return 0;
  }
}

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

  switch (pFormNode->GetIntact()) {
    case XFA_AttributeValue::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()->GetMeasureInUnit(
            XFA_Attribute::TopInset, XFA_Unit::Pt);
        fCurBottomMargin = pMarginNode->JSObject()->GetMeasureInUnit(
            XFA_Attribute::BottomInset, XFA_Unit::Pt);
      }
      bool bChanged = true;
      while (bChanged) {
        bChanged = false;
        {
          Optional<float> fRelSplitPos = pFormNode->FindSplitPos(
              pNotify->GetHDOC()->GetDocView(), pLayoutItem->GetIndex(),
              *fProposedSplitPos - fCurVerticalOffset);
          if (fRelSplitPos.has_value()) {
            bAnyChanged = true;
            bChanged = true;
            *fProposedSplitPos = fCurVerticalOffset + fRelSplitPos.value();
            *bAppChange = true;
            if (*fProposedSplitPos <=
                fCurVerticalOffset + kXFALayoutPrecision) {
              return true;
            }
          }
        }
        float fRelSplitPos = *fProposedSplitPos - fCurBottomMargin;
        for (CXFA_LayoutItem* pIter = pLayoutItem->GetFirstChild(); pIter;
             pIter = pIter->GetNextSibling()) {
          CXFA_ContentLayoutItem* pChildItem = pIter->AsContentLayoutItem();
          if (!pChildItem)
            continue;

          float fChildOffset =
              fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
          bool bChange = false;
          if (FindLayoutItemSplitPos(pChildItem, fChildOffset, &fRelSplitPos,
                                     &bChange, bCalculateMargin)) {
            if (fRelSplitPos - fChildOffset < kXFALayoutPrecision && bChange) {
              *fProposedSplitPos = fRelSplitPos - fCurTopMargin;
            } else {
              *fProposedSplitPos = fRelSplitPos + fCurBottomMargin;
            }
            bAnyChanged = true;
            bChanged = true;
            if (*fProposedSplitPos <=
                fCurVerticalOffset + kXFALayoutPrecision) {
              return true;
            }
            if (bAnyChanged)
              break;
          }
        }
      }
      return bAnyChanged;
    }
    case XFA_AttributeValue::ContentArea:
    case XFA_AttributeValue::PageArea: {
      *fProposedSplitPos = fCurVerticalOffset;
      return true;
    }
    default:
      return false;
  }
}

CFX_PointF CalculatePositionedContainerPos(CXFA_Node* pNode,
                                           const CFX_SizeF& size) {
  XFA_AttributeValue eAnchorType =
      pNode->JSObject()->GetEnum(XFA_Attribute::AnchorType);
  int32_t nAnchorType = 0;
  switch (eAnchorType) {
    case XFA_AttributeValue::TopLeft:
      nAnchorType = 0;
      break;
    case XFA_AttributeValue::TopCenter:
      nAnchorType = 1;
      break;
    case XFA_AttributeValue::TopRight:
      nAnchorType = 2;
      break;
    case XFA_AttributeValue::MiddleLeft:
      nAnchorType = 3;
      break;
    case XFA_AttributeValue::MiddleCenter:
      nAnchorType = 4;
      break;
    case XFA_AttributeValue::MiddleRight:
      nAnchorType = 5;
      break;
    case XFA_AttributeValue::BottomLeft:
      nAnchorType = 6;
      break;
    case XFA_AttributeValue::BottomCenter:
      nAnchorType = 7;
      break;
    case XFA_AttributeValue::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()->GetMeasureInUnit(XFA_Attribute::X, XFA_Unit::Pt),
      pNode->JSObject()->GetMeasureInUnit(XFA_Attribute::Y, 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_ContentLayoutProcessor::CXFA_ContentLayoutProcessor(
    CXFA_Node* pNode,
    CXFA_ViewLayoutProcessor* pViewLayoutProcessor)
    : m_pFormNode(pNode), m_pViewLayoutProcessor(pViewLayoutProcessor) {
  ASSERT(GetFormNode());
  ASSERT(GetFormNode()->IsContainerNode() ||
         GetFormNode()->GetElementType() == XFA_Element::Form);
  m_pOldLayoutItem.Reset(
      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem()));
}

CXFA_ContentLayoutProcessor::~CXFA_ContentLayoutProcessor() {}

RetainPtr<CXFA_ContentLayoutItem>
CXFA_ContentLayoutProcessor::CreateContentLayoutItem(CXFA_Node* pFormNode) {
  if (!pFormNode)
    return nullptr;

  if (m_pOldLayoutItem) {
    RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pOldLayoutItem;
    m_pOldLayoutItem.Reset(m_pOldLayoutItem->GetNext());
    return pLayoutItem;
  }
  CXFA_FFNotify* pNotify = pFormNode->GetDocument()->GetNotify();
  auto pNewLayoutItem = pdfium::MakeRetain<CXFA_ContentLayoutItem>(
      pFormNode, pNotify->OnCreateContentLayoutItem(pFormNode));

  CXFA_ContentLayoutItem* pPrevLayoutItem =
      ToContentLayoutItem(pFormNode->JSObject()->GetLayoutItem());
  if (pPrevLayoutItem) {
    pPrevLayoutItem->GetLast()->InsertAfter(pNewLayoutItem.Get());
  } else {
    pFormNode->JSObject()->SetLayoutItem(pNewLayoutItem.Get());
  }
  return pNewLayoutItem;
}

float CXFA_ContentLayoutProcessor::FindSplitPos(float fProposedSplitPos) {
  ASSERT(m_pLayoutItem);
  auto value = GetFormNode()->JSObject()->TryEnum(XFA_Attribute::Layout, true);
  XFA_AttributeValue eLayout = value.value_or(XFA_AttributeValue::Position);
  bool bCalculateMargin = eLayout != XFA_AttributeValue::Position;
  while (fProposedSplitPos > kXFALayoutPrecision) {
    bool bAppChange = false;
    if (!FindLayoutItemSplitPos(m_pLayoutItem.Get(), 0, &fProposedSplitPos,
                                &bAppChange, bCalculateMargin)) {
      break;
    }
  }
  return fProposedSplitPos;
}

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

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

  RetainPtr<CXFA_ContentLayoutItem> pSecondLayoutItem;
  if (m_pCurChildPreprocessor &&
      m_pCurChildPreprocessor->GetFormNode() == pLayoutItem->GetFormNode()) {
    pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
        pLayoutItem->GetFormNode());
  } else {
    pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->GetFormNode());
  }
  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->GetFirstChild())
    pSecondLayoutItem->m_sSize.height += fCurTopMargin;

  bool bOrphanedItem = false;
  if (pSecondParent) {
    pSecondParent->AppendLastChild(pSecondLayoutItem);
    if (fCurTopMargin > 0 && pLayoutItem->GetFirstChild()) {
      pSecondParent->m_sSize.height += fCurTopMargin;
      for (CXFA_LayoutItem* pParentIter = pSecondParent->GetParent();
           pParentIter; pParentIter = pParentIter->GetParent()) {
        CXFA_ContentLayoutItem* pContentItem =
            pParentIter->AsContentLayoutItem();
        if (!pContentItem)
          continue;

        pContentItem->m_sSize.height += fCurTopMargin;
      }
    }
  } else if (pLayoutItem->GetParent()) {
    pLayoutItem->GetParent()->InsertAfter(pSecondLayoutItem, pLayoutItem);
  } else {
    // Parentless |pLayoutitem| would like to have |pSecondLayoutItem| as a
    // sibling, but that would violate the tree invariant. Instead, keep
    // it an orphan and add it as a child of |pLayoutItem| after performing
    // the split.
    bOrphanedItem = true;
  }

  std::vector<RetainPtr<CXFA_ContentLayoutItem>> children;
  while (auto* pFirst = ToContentLayoutItem(pLayoutItem->GetFirstChild())) {
    children.emplace_back(pFirst);
    pLayoutItem->RemoveChild(children.back());
  }

  float lHeightForKeep = 0;
  float fAddMarginHeight = 0;
  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
  for (auto& pChildItem : children) {
    if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
                         kXFALayoutPrecision) {
      if (!ExistContainerKeep(pChildItem->GetFormNode(), true)) {
        pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
        pChildItem->m_sPos.y += lHeightForKeep;
        pChildItem->m_sPos.y += fAddMarginHeight;
        pSecondLayoutItem->AppendLastChild(pChildItem);
        continue;
      }
      if (lHeightForKeep < kXFALayoutPrecision) {
        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->AppendLastChild(pPreItem);
        }
      }
      pChildItem->m_sPos.y -= fSplitPos;
      pChildItem->m_sPos.y += lHeightForKeep;
      pChildItem->m_sPos.y += fAddMarginHeight;
      pSecondLayoutItem->AppendLastChild(pChildItem);
      continue;
    }
    if (fSplitPos + kXFALayoutPrecision >= fCurTopMargin + fCurBottomMargin +
                                               pChildItem->m_sPos.y +
                                               pChildItem->m_sSize.height) {
      pLayoutItem->AppendLastChild(pChildItem);
      if (ExistContainerKeep(pChildItem->GetFormNode(), false))
        keepLayoutItems.push_back(pChildItem);
      else
        keepLayoutItems.clear();
      continue;
    }

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

void CXFA_ContentLayoutProcessor::SplitLayoutItem(float fSplitPos) {
  ASSERT(m_pLayoutItem);
  SplitLayoutItem(m_pLayoutItem.Get(), nullptr, fSplitPos);
}

RetainPtr<CXFA_ContentLayoutItem>
CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
  RetainPtr<CXFA_ContentLayoutItem> pLayoutItem = m_pLayoutItem;
  if (pLayoutItem) {
    m_pLayoutItem.Reset(ToContentLayoutItem(pLayoutItem->GetNextSibling()));
    pLayoutItem->RemoveSelfIfParented();
  }
  if (m_nCurChildNodeStage != Stage::kDone || !m_pOldLayoutItem)
    return pLayoutItem;

  CXFA_FFNotify* pNotify =
      m_pOldLayoutItem->GetFormNode()->GetDocument()->GetNotify();
  auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(
      m_pOldLayoutItem->GetFormNode()->GetDocument());

  while (m_pOldLayoutItem) {
    RetainPtr<CXFA_ContentLayoutItem> pToDeleteItem = m_pOldLayoutItem;
    m_pOldLayoutItem.Reset(pToDeleteItem->GetNext());
    if (pToDeleteItem == pLayoutItem)
      break;
    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem.Get());
    pToDeleteItem->RemoveSelfIfParented();
  }
  return pLayoutItem;
}

void CXFA_ContentLayoutProcessor::GotoNextContainerNodeSimple(
    bool bUsePageBreak) {
  m_nCurChildNodeStage = GotoNextContainerNode(
      m_nCurChildNodeStage, bUsePageBreak, GetFormNode(), &m_pCurChildNode);
}

CXFA_ContentLayoutProcessor::Stage
CXFA_ContentLayoutProcessor::GotoNextContainerNode(Stage nCurStage,
                                                   bool bUsePageBreak,
                                                   CXFA_Node* pParentContainer,
                                                   CXFA_Node** pCurActionNode) {
  CXFA_Node* pChildContainer = nullptr;
  switch (nCurStage) {
    case Stage::kBreakBefore:
    case Stage::kBreakAfter: {
      pChildContainer = (*pCurActionNode)->GetParent();
      break;
    }
    case Stage::kKeep:
    case Stage::kContainer:
      pChildContainer = *pCurActionNode;
      break;
    default:
      pChildContainer = nullptr;
      break;
  }

  Optional<Stage> ret;
  switch (nCurStage) {
    case Stage::kKeep:
      ret = HandleKeep(pChildContainer->GetFirstChild(), pCurActionNode);
      if (ret.has_value())
        return ret.value();
      break;

    case Stage::kNone:
      *pCurActionNode = nullptr;
      FALLTHROUGH;

    case Stage::kBookendLeader:
      ret = HandleBookendLeader(pParentContainer, pCurActionNode);
      if (ret.has_value())
        return ret.value();

      *pCurActionNode = nullptr;
      FALLTHROUGH;

    case Stage::kBreakBefore:
      ret = HandleBreakBefore(pChildContainer, pCurActionNode);
      if (ret.has_value())
        return ret.value();
      break;

    case Stage::kContainer:
      *pCurActionNode = nullptr;
      FALLTHROUGH;

    case Stage::kBreakAfter:
      ret = HandleBreakAfter(pChildContainer, pCurActionNode);
      if (ret.has_value())
        return ret.value();
      break;

    case Stage::kBookendTrailer:
      ret = HandleBookendTrailer(pParentContainer, pCurActionNode);
      if (ret.has_value())
        return ret.value();
      FALLTHROUGH;

    default:
      *pCurActionNode = nullptr;
      return Stage::kDone;
  }

  ret = HandleCheckNextChildContainer(pParentContainer, pChildContainer,
                                      pCurActionNode);
  if (ret.has_value())
    return ret.value();

  *pCurActionNode = nullptr;
  ret = HandleBookendTrailer(pParentContainer, pCurActionNode);
  if (ret.has_value())
    return ret.value();

  *pCurActionNode = nullptr;
  return Stage::kDone;
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::ProcessKeepNodesForCheckNext(
    CXFA_Node** pCurActionNode,
    CXFA_Node** pNextContainer,
    bool* pLastKeepNode) {
  const bool bCanSplit =
      (*pNextContainer)->GetIntact() == XFA_AttributeValue::None;
  const bool bNextKeep = ExistContainerKeep(*pNextContainer, false);

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

  if (!m_bIsProcessKeep || !m_pKeepHeadNode) {
    if (m_bKeepBreakFinish)
      *pLastKeepNode = true;
    m_bKeepBreakFinish = false;
    return {};
  }

  m_pKeepTailNode = *pNextContainer;
  if (m_bKeepBreakFinish) {
    *pNextContainer = m_pKeepHeadNode;
    ProcessKeepNodesEnd();
    return {};
  }

  Optional<Stage> ret =
      FindBreakNode((*pNextContainer)->GetFirstChild(), true, pCurActionNode);
  if (!ret.has_value()) {
    *pNextContainer = m_pKeepHeadNode;
    ProcessKeepNodesEnd();
    return {};
  }

  return ret;
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::ProcessKeepNodesForBreakBefore(
    CXFA_Node** pCurActionNode,
    CXFA_Node* pContainerNode) {
  if (m_pKeepTailNode == pContainerNode) {
    *pCurActionNode = m_pKeepHeadNode;
    ProcessKeepNodesEnd();
    return Stage::kContainer;
  }

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

void CXFA_ContentLayoutProcessor::DoLayoutPageArea(
    CXFA_ViewLayoutItem* pPageAreaLayoutItem) {
  CXFA_Node* pFormNode = pPageAreaLayoutItem->GetFormNode();
  CXFA_Node* pCurChildNode = nullptr;
  CXFA_LayoutItem* pBeforeItem = nullptr;
  for (Stage nCurChildNodeStage = GotoNextContainerNode(
           Stage::kNone, false, pFormNode, &pCurChildNode);
       pCurChildNode;
       nCurChildNodeStage = GotoNextContainerNode(nCurChildNodeStage, false,
                                                  pFormNode, &pCurChildNode)) {
    if (nCurChildNodeStage != Stage::kContainer)
      continue;
    if (pCurChildNode->GetElementType() == XFA_Element::Variables)
      continue;

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

    pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos(
        pCurChildNode, pProcessor->GetCurrentComponentSize()));
    RetainPtr<CXFA_LayoutItem> pProcessItem = pProcessor->ExtractLayoutItem();
    if (!pBeforeItem)
      pPageAreaLayoutItem->AppendFirstChild(pProcessItem);
    else
      pPageAreaLayoutItem->InsertAfter(pProcessItem, pBeforeItem);

    pBeforeItem = pProcessItem.Get();
  }

  pBeforeItem = nullptr;
  RetainPtr<CXFA_LayoutItem> pLayoutItem(pPageAreaLayoutItem->GetFirstChild());
  while (pLayoutItem) {
    if (!pLayoutItem->IsContentLayoutItem() ||
        pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw) {
      pLayoutItem.Reset(pLayoutItem->GetNextSibling());
      continue;
    }
    if (pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw)
      continue;

    CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->GetNextSibling();
    pPageAreaLayoutItem->RemoveChild(pLayoutItem);
    if (!pBeforeItem)
      pPageAreaLayoutItem->AppendFirstChild(pLayoutItem);
    else
      pPageAreaLayoutItem->InsertAfter(pLayoutItem, pBeforeItem);

    pBeforeItem = pLayoutItem.Get();
    pLayoutItem.Reset(pNextLayoutItem);
  }
}

void CXFA_ContentLayoutProcessor::DoLayoutPositionedContainer(
    Context* pContext) {
  if (m_pLayoutItem)
    return;

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

  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fHiddenContentCalculatedWidth = 0;
  float fHiddenContentCalculatedHeight = 0;
  if (!m_pCurChildNode)
    GotoNextContainerNodeSimple(false);

  int32_t iColIndex = 0;
  for (; m_pCurChildNode; GotoNextContainerNodeSimple(false)) {
    if (m_nCurChildNodeStage != Stage::kContainer)
      continue;
    if (m_pCurChildNode->GetElementType() == XFA_Element::Variables)
      continue;

    auto pProcessor = pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
        m_pCurChildNode, m_pViewLayoutProcessor.Get());
    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.0f;
        if (iColSpan == -1) {
          iColSpan = pdfium::CollectionSize<int32_t>(
              *pContext->m_prgSpecifiedColumnWidths);
        }
        for (int32_t i = 0; iColIndex + i < iColSpan; ++i) {
          pContext->m_fCurColumnWidth.value() +=
              (*pContext->m_prgSpecifiedColumnWidths)[iColIndex + i];
        }
        if (pContext->m_fCurColumnWidth.value() == 0)
          pContext->m_fCurColumnWidth.reset();

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

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

    CFX_SizeF size = pProcessor->GetCurrentComponentSize();
    bool bChangeParentSize = false;
    if (m_pCurChildNode->PresenceRequiresSpace())
      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->AppendLastChild(pProcessor->ExtractLayoutItem());
  }

  XFA_VERSION eVersion = GetFormNode()->GetDocument()->GetCurVersionMode();
  if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207)
    fContentCalculatedWidth = fHiddenContentCalculatedWidth;
  if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207)
    fContentCalculatedHeight = fHiddenContentCalculatedHeight;

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

void CXFA_ContentLayoutProcessor::DoLayoutTableContainer(
    CXFA_Node* pLayoutNode) {
  if (m_pLayoutItem)
    return;
  if (!pLayoutNode)
    pLayoutNode = GetFormNode();

  ASSERT(!m_pCurChildNode);

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

  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - fLeftInset - fRightInset;
  WideString wsColumnWidths =
      pLayoutNode->JSObject()->GetCData(XFA_Attribute::ColumnWidths);
  if (!wsColumnWidths.IsEmpty()) {
    for (auto& width : SeparateStringOnSpace(wsColumnWidths.span())) {
      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);
  Context layoutContext;
  layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
  Context* pLayoutContext =
      iSpecifiedColumnCount > 0 ? &layoutContext : nullptr;
  if (!m_pCurChildNode)
    GotoNextContainerNodeSimple(false);

  for (; m_pCurChildNode; GotoNextContainerNodeSimple(false)) {
    layoutContext.m_fCurColumnWidth.reset();
    if (m_nCurChildNodeStage != Stage::kContainer)
      continue;

    auto pProcessor = pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
        m_pCurChildNode, m_pViewLayoutProcessor.Get());
    pProcessor->DoLayoutInternal(false, FLT_MAX, FLT_MAX, pLayoutContext);
    if (!pProcessor->HasLayoutItem())
      continue;

    m_pLayoutItem->AppendLastChild(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 (CXFA_LayoutItem* pIter = m_pLayoutItem->GetFirstChild(); pIter;
         pIter = pIter->GetNextSibling()) {
      CXFA_ContentLayoutItem* pLayoutChild = pIter->AsContentLayoutItem();
      if (!pLayoutChild)
        continue;
      if (pLayoutChild->GetFormNode()->GetElementType() != XFA_Element::Subform)
        continue;
      if (!pLayoutChild->GetFormNode()->PresenceRequiresSpace())
        continue;

      XFA_AttributeValue eLayout =
          pLayoutChild->GetFormNode()->JSObject()->GetEnum(
              XFA_Attribute::Layout);
      if (eLayout != XFA_AttributeValue::Row &&
          eLayout != XFA_AttributeValue::Rl_row) {
        continue;
      }
      CXFA_ContentLayoutItem* pRowLayoutCell =
          ToContentLayoutItem(pLayoutChild->GetFirstChild());
      if (pRowLayoutCell) {
        rgRowItems.push_back(pRowLayoutCell);
        int32_t iColSpan =
            pRowLayoutCell->GetFormNode()->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 ||
                !rgRowItems[i]->GetFormNode()->PresenceRequiresSpace())) {
          CXFA_ContentLayoutItem* pNewCell =
              ToContentLayoutItem(rgRowItems[i]->GetNextSibling());
          if (rgRowItemsSpan[i] < 0 &&
              rgRowItems[i]->GetFormNode()->PresenceRequiresSpace()) {
            pNewCell = nullptr;
          }
          rgRowItems[i] = pNewCell;
          rgRowItemsSpan[i] =
              pNewCell ? pNewCell->GetFormNode()->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] < kXFALayoutPrecision)
          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_LayoutItem* pIter = m_pLayoutItem->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    RetainPtr<CXFA_ContentLayoutItem> pLayoutChild(
        pIter->AsContentLayoutItem());
    if (!pLayoutChild || !pLayoutChild->GetFormNode()->PresenceRequiresSpace())
      continue;

    if (pLayoutChild->GetFormNode()->GetElementType() == XFA_Element::Subform) {
      XFA_AttributeValue eSubformLayout =
          pLayoutChild->GetFormNode()->JSObject()->GetEnum(
              XFA_Attribute::Layout);
      if (eSubformLayout == XFA_AttributeValue::Row ||
          eSubformLayout == XFA_AttributeValue::Rl_row) {
        RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths,
                              eSubformLayout);
      }
    }

    pLayoutChild->m_sPos.y = fCurrentRowY;
    if (bContainerWidthAutoSize) {
      pLayoutChild->m_sPos.x = 0;
    } else {
      switch (pLayoutChild->GetFormNode()->JSObject()->GetEnum(
          XFA_Attribute::HAlign)) {
        case XFA_AttributeValue::Center:
          pLayoutChild->m_sPos.x =
              (fContentWidthLimit - pLayoutChild->m_sSize.width) / 2;
          break;
        case XFA_AttributeValue::Right:
          pLayoutChild->m_sPos.x =
              fContentWidthLimit - pLayoutChild->m_sSize.width;
          break;
        case XFA_AttributeValue::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(
      GetFormNode(), bContainerWidthAutoSize, fContentCalculatedWidth,
      bContainerHeightAutoSize, fContentCalculatedHeight, containerSize);
  SetCurrentComponentSize(containerSize);
}

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

  float fWidth = pTrailerItem->m_sSize.width;
  XFA_AttributeValue eLayout =
      GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
  return eLayout == XFA_AttributeValue::Tb || m_fWidthLimit <= fWidth;
}

float CXFA_ContentLayoutProcessor::InsertKeepLayoutItems() {
  if (m_ArrayKeepItems.empty())
    return 0;

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

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

  return fTotalHeight;
}

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

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

  if (!ExistContainerKeep(m_pCurChildNode, true))
    return false;

  CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize();
  std::vector<RetainPtr<CXFA_ContentLayoutItem>> keepLayoutItems;
  if (JudgePutNextPage(m_pLayoutItem.Get(), childSize.height,
                       &keepLayoutItems)) {
    m_ArrayKeepItems.clear();
    for (auto& item : keepLayoutItems) {
      m_pLayoutItem->RemoveChild(item);
      *fContentCurRowY -= item->m_sSize.height;
      m_ArrayKeepItems.push_back(item);
    }
    *bAddedItemInRow = true;
    *bForceEndPage = true;
    *result = Result::kPageFullBreak;
    return true;
  }

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

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

  float fItemsHeight = 0;
  for (CXFA_LayoutItem* pIter = pParentLayoutItem->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem(
        pIter->AsContentLayoutItem());
    if (!pChildLayoutItem)
      continue;

    if (ExistContainerKeep(pChildLayoutItem->GetFormNode(), false)) {
      pKeepItems->push_back(pChildLayoutItem);
      fItemsHeight += pChildLayoutItem->m_sSize.height;
    } else {
      pKeepItems->clear();
      fItemsHeight = 0;
    }
  }
  fItemsHeight += fChildHeight;
  return m_pViewLayoutProcessor->GetNextAvailContentHeight(fItemsHeight);
}

void CXFA_ContentLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
  if (!pFormNode)
    return;

  CXFA_NodeIterator 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);
  }
}

void CXFA_ContentLayoutProcessor::ProcessUnUseOverFlow(
    CXFA_Node* pLeaderNode,
    CXFA_Node* pTrailerNode,
    const RetainPtr<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->RemoveChildAndNotify(pLeaderNode, true);
  if (pTrailerNode && pFormNode)
    pFormNode->RemoveChildAndNotify(pTrailerNode, true);
  if (pTrailerItem)
    XFA_ReleaseLayoutItem(pTrailerItem);
}

CXFA_ContentLayoutProcessor::Result
CXFA_ContentLayoutProcessor::DoLayoutFlowedContainer(
    bool bUseBreakControl,
    XFA_AttributeValue eFlowStrategy,
    float fHeightLimit,
    float fRealHeight,
    Context* pContext,
    bool bRootForceTb) {
  m_bHasAvailHeight = true;
  if (m_pCurChildPreprocessor)
    m_pCurChildPreprocessor->m_ePreProcessRs = Result::kDone;

  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF container_size = CalculateContainerSpecifiedSize(
      GetFormNode(), &bContainerWidthAutoSize, &bContainerHeightAutoSize);
  AdjustContainerSpecifiedSize(pContext, &container_size,
                               &bContainerWidthAutoSize,
                               &bContainerHeightAutoSize);

  CXFA_Margin* pMargin =
      GetFormNode()->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  CFX_FloatRect inset = GetMarginInset(pMargin);
  float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : container_size.width - inset.left - inset.right;
  float fAvailHeight = fHeightLimit - inset.top - inset.bottom;
  if (fAvailHeight < 0)
    m_bHasAvailHeight = false;

  fRealHeight = fRealHeight - inset.top - inset.bottom;
  CFX_SizeF calculated_size;
  float fContentCurRowY = 0;
  CXFA_ContentLayoutItem* pLastChild = nullptr;
  if (m_pLayoutItem) {
    pLastChild = FindLastContentLayoutItem(eFlowStrategy);
    calculated_size = CalculateLayoutItemSize(pLastChild);
    fContentCurRowY =
        pLastChild ? pLastChild->m_sPos.y : calculated_size.height;
  }

  fContentCurRowY += InsertKeepLayoutItems();
  if (m_nCurChildNodeStage == Stage::kNone)
    GotoNextContainerNodeSimple(true);

  fContentCurRowY += InsertPendingItems(GetFormNode());
  if (m_pCurChildPreprocessor && m_nCurChildNodeStage == Stage::kContainer) {
    if (ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), false)) {
      m_pKeepHeadNode = m_pCurChildNode;
      m_bIsProcessKeep = true;
      m_nCurChildNodeStage = Stage::kKeep;
    }
  }

  bool bForceEndPage = false;
  bool bBreakDone = false;
  bool bIsManualBreak = false;
  while (m_nCurChildNodeStage != Stage::kDone) {
    float fContentCurRowHeight = 0;
    float fContentCurRowAvailWidth = fContentWidthLimit;
    m_fWidthLimit = fContentCurRowAvailWidth;
    std::vector<RetainPtr<CXFA_ContentLayoutItem>> rgCurLineLayoutItems[3];
    uint8_t uCurHAlignState =
        (eFlowStrategy != XFA_AttributeValue::Rl_tb ? 0 : 2);
    if (pLastChild) {
      for (CXFA_LayoutItem* pNext = pLastChild; pNext;
           pNext = pNext->GetNextSibling()) {
        CXFA_ContentLayoutItem* pLayoutNext = pNext->AsContentLayoutItem();
        if (!pLayoutNext)
          continue;
        if (!pLayoutNext->GetNextSibling() && m_pCurChildPreprocessor &&
            m_pCurChildPreprocessor->GetFormNode() ==
                pLayoutNext->GetFormNode()) {
          if (m_pCurChildPreprocessor->m_pLayoutItem)
            pLayoutNext->InsertAfter(
                m_pCurChildPreprocessor->m_pLayoutItem.Get());
          m_pCurChildPreprocessor->m_pLayoutItem.Reset(pLayoutNext);
          break;
        }
        uint8_t uHAlign =
            HAlignEnumToInt(pLayoutNext->GetFormNode()->JSObject()->GetEnum(
                XFA_Attribute::HAlign));
        rgCurLineLayoutItems[uHAlign].emplace_back(pLayoutNext);
        if (eFlowStrategy == XFA_AttributeValue::Lr_tb) {
          if (uHAlign > uCurHAlignState)
            uCurHAlignState = uHAlign;
        } else if (uHAlign < uCurHAlignState) {
          uCurHAlignState = uHAlign;
        }
        if (pLayoutNext->GetFormNode()->PresenceRequiresSpace()) {
          if (pLayoutNext->m_sSize.height > fContentCurRowHeight)
            fContentCurRowHeight = pLayoutNext->m_sSize.height;
          fContentCurRowAvailWidth -= pLayoutNext->m_sSize.width;
        }
      }

      RetainPtr<CXFA_ContentLayoutItem> pLayoutNextTemp(pLastChild);
      while (pLayoutNextTemp) {
        CXFA_ContentLayoutItem* pSaveLayoutNext =
            ToContentLayoutItem(pLayoutNextTemp->GetNextSibling());
        pLayoutNextTemp->RemoveSelfIfParented();
        pLayoutNextTemp.Reset(pSaveLayoutNext);
      }
      pLastChild = nullptr;
    }

    while (m_pCurChildNode) {
      std::unique_ptr<CXFA_ContentLayoutProcessor> pProcessor;
      bool bAddedItemInRow = false;
      fContentCurRowY += InsertPendingItems(GetFormNode());
      switch (m_nCurChildNodeStage) {
        case Stage::kKeep:
        case Stage::kNone:
          break;
        case Stage::kBreakBefore: {
          for (auto& item : m_ArrayKeepItems) {
            m_pLayoutItem->RemoveChild(item);
            calculated_size.height -= item->m_sSize.height;
          }

          if (!bUseBreakControl || !m_pViewLayoutProcessor)
            break;

          Optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
              m_pViewLayoutProcessor->ProcessBreakBefore(m_pCurChildNode);
          if (!break_data.has_value() || !break_data.value().bCreatePage ||
              GetFormNode()->GetElementType() == XFA_Element::Form) {
            break;
          }

          CXFA_Node* pLeaderNode = break_data.value().pLeader;
          CXFA_Node* pTrailerNode = break_data.value().pTrailer;
          if (JudgeLeaderOrTrailerForOccur(pLeaderNode))
            AddPendingNode(pLeaderNode, true);

          if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
            if (GetFormNode()->GetParent()->GetElementType() ==
                    XFA_Element::Form &&
                !m_pLayoutItem) {
              AddPendingNode(pTrailerNode, true);
            } else {
              auto pTempProcessor =
                  pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(pTrailerNode,
                                                                  nullptr);
              InsertFlowedItem(
                  pTempProcessor.get(), bContainerWidthAutoSize,
                  bContainerHeightAutoSize, container_size.height,
                  eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                  FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, pContext, false);
            }
          }
          GotoNextContainerNodeSimple(true);
          bForceEndPage = true;
          bIsManualBreak = true;
          goto SuspendAndCreateNewRow;
        }
        case Stage::kBreakAfter: {
          if (!bUseBreakControl || !m_pViewLayoutProcessor)
            break;

          Optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
              m_pViewLayoutProcessor->ProcessBreakAfter(m_pCurChildNode);
          if (!break_data.has_value() ||
              GetFormNode()->GetElementType() == XFA_Element::Form) {
            break;
          }

          CXFA_Node* pLeaderNode = break_data.value().pLeader;
          CXFA_Node* pTrailerNode = break_data.value().pTrailer;
          bool bCreatePage = break_data.value().bCreatePage;
          if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
            auto pTempProcessor =
                pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(pTrailerNode,
                                                                nullptr);
            InsertFlowedItem(pTempProcessor.get(), bContainerWidthAutoSize,
                             bContainerHeightAutoSize, container_size.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, &calculated_size.width,
                  &calculated_size.height, &fContentCurRowY,
                  fContentCurRowHeight, fContentWidthLimit, false);
              rgCurLineLayoutItems->clear();
              auto pTempProcessor =
                  pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(pLeaderNode,
                                                                  nullptr);
              InsertFlowedItem(
                  pTempProcessor.get(), bContainerWidthAutoSize,
                  bContainerHeightAutoSize, container_size.height,
                  eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                  FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, pContext, false);
            }
          } else {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode))
              AddPendingNode(pLeaderNode, true);
          }

          GotoNextContainerNodeSimple(true);
          if (bCreatePage) {
            bForceEndPage = true;
            bIsManualBreak = true;
            if (m_nCurChildNodeStage == Stage::kDone)
              bBreakDone = true;
          }
          goto SuspendAndCreateNewRow;
        }
        case Stage::kBookendLeader: {
          if (m_pCurChildPreprocessor) {
            pProcessor = std::move(m_pCurChildPreprocessor);
          } else if (m_pViewLayoutProcessor) {
            CXFA_Node* pLeaderNode =
                m_pViewLayoutProcessor->ProcessBookendLeader(m_pCurChildNode);
            if (pLeaderNode) {
              pProcessor = pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
                  pLeaderNode, m_pViewLayoutProcessor.Get());
            }
          }

          if (pProcessor) {
            if (InsertFlowedItem(
                    pProcessor.get(), bContainerWidthAutoSize,
                    bContainerHeightAutoSize, container_size.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, pContext,
                    false) != Result::kDone) {
              goto SuspendAndCreateNewRow;
            }
            pProcessor.reset();
          }
          break;
        }
        case Stage::kBookendTrailer: {
          if (m_pCurChildPreprocessor) {
            pProcessor = std::move(m_pCurChildPreprocessor);
          } else if (m_pViewLayoutProcessor) {
            CXFA_Node* pTrailerNode =
                m_pViewLayoutProcessor->ProcessBookendTrailer(m_pCurChildNode);
            if (pTrailerNode) {
              pProcessor = pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
                  pTrailerNode, m_pViewLayoutProcessor.Get());
            }
          }
          if (pProcessor) {
            if (InsertFlowedItem(
                    pProcessor.get(), bContainerWidthAutoSize,
                    bContainerHeightAutoSize, container_size.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, pContext,
                    false) != Result::kDone) {
              goto SuspendAndCreateNewRow;
            }
            pProcessor.reset();
          }
          break;
        }
        case Stage::kContainer: {
          ASSERT(m_pCurChildNode->IsContainerNode());
          if (m_pCurChildNode->GetElementType() == XFA_Element::Variables)
            break;
          if (fContentCurRowY >= fHeightLimit + kXFALayoutPrecision &&
              m_pCurChildNode->PresenceRequiresSpace()) {
            bForceEndPage = true;
            goto SuspendAndCreateNewRow;
          }
          if (!m_pCurChildNode->IsContainerNode())
            break;

          bool bNewRow = false;
          if (m_pCurChildPreprocessor) {
            pProcessor = std::move(m_pCurChildPreprocessor);
            bNewRow = true;
          } else {
            pProcessor = pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
                m_pCurChildNode, m_pViewLayoutProcessor.Get());
          }

          pProcessor->InsertPendingItems(m_pCurChildNode);
          Result rs = InsertFlowedItem(
              pProcessor.get(), bContainerWidthAutoSize,
              bContainerHeightAutoSize, container_size.height, eFlowStrategy,
              &uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
              fAvailHeight, fRealHeight, fContentWidthLimit, &fContentCurRowY,
              &fContentCurRowAvailWidth, &fContentCurRowHeight,
              &bAddedItemInRow, &bForceEndPage, pContext, bNewRow);
          switch (rs) {
            case Result::kManualBreak:
              bIsManualBreak = true;
              FALLTHROUGH;
            case Result::kPageFullBreak:
              bForceEndPage = true;
              FALLTHROUGH;
            case Result::kRowFullBreak:
              goto SuspendAndCreateNewRow;
            case Result::kDone:
            default:
              fContentCurRowY +=
                  pProcessor->InsertPendingItems(m_pCurChildNode);
              pProcessor.reset();
              break;
          }
          break;
        }
        case Stage::kDone:
          break;
        default:
          break;
      }
      GotoNextContainerNodeSimple(true);
      if (bAddedItemInRow && eFlowStrategy == XFA_AttributeValue::Tb)
        break;
      continue;
    SuspendAndCreateNewRow:
      if (pProcessor)
        m_pCurChildPreprocessor = std::move(pProcessor);
      break;
    }

    CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy,
                              bContainerHeightAutoSize, bContainerWidthAutoSize,
                              &calculated_size.width, &calculated_size.height,
                              &fContentCurRowY, fContentCurRowHeight,
                              fContentWidthLimit, bRootForceTb);
    m_fWidthLimit = fContentCurRowAvailWidth;
    if (bForceEndPage)
      break;
  }

  bool bRetValue =
      m_nCurChildNodeStage == Stage::kDone && m_PendingNodes.empty();
  if (bBreakDone)
    bRetValue = false;

  container_size = CalculateContainerComponentSizeFromContentSize(
      GetFormNode(), bContainerWidthAutoSize, calculated_size.width,
      bContainerHeightAutoSize, calculated_size.height, container_size);

  if (container_size.height >= kXFALayoutPrecision || m_pLayoutItem ||
      bRetValue) {
    if (!m_pLayoutItem)
      m_pLayoutItem = CreateContentLayoutItem(GetFormNode());
    container_size.height = std::max(container_size.height, 0.f);

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

  if (bRetValue)
    return Result::kDone;
  return bIsManualBreak ? Result::kManualBreak : Result::kPageFullBreak;
}

bool CXFA_ContentLayoutProcessor::CalculateRowChildPosition(
    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
    XFA_AttributeValue 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 (rgCurLineLayoutItems[i][j]->GetFormNode()->PresenceRequiresSpace())
        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(GetFormNode());

  if (eFlowStrategy != XFA_AttributeValue::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]->GetFormNode(),
            rgCurLineLayoutItems[0][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[0][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[0][j]->GetFormNode()->PresenceRequiresSpace())
          fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.width;
      }
      m_pLayoutItem->AppendLastChild(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]->GetFormNode(),
            rgCurLineLayoutItems[1][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[1][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[1][j]->GetFormNode()->PresenceRequiresSpace())
          fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.width;
      }
      m_pLayoutItem->AppendLastChild(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]->GetFormNode(),
            rgCurLineLayoutItems[2][j]->m_sSize);
      } else {
        rgCurLineLayoutItems[2][j]->m_sPos =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[2][j]->GetFormNode()->PresenceRequiresSpace())
          fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.width;
      }
      m_pLayoutItem->AppendLastChild(rgCurLineLayoutItems[2][j]);
      m_fLastRowWidth = fCurPos;
    }
  } else {
    float fCurPos;
    fCurPos = fGroupWidths[0];
    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
      if (rgCurLineLayoutItems[0][j]->GetFormNode()->PresenceRequiresSpace())
        fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.width;

      rgCurLineLayoutItems[0][j]->m_sPos =
          CFX_PointF(fCurPos, *fContentCurRowY);
      m_pLayoutItem->AppendLastChild(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 (rgCurLineLayoutItems[1][j]->GetFormNode()->PresenceRequiresSpace())
        fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.width;

      rgCurLineLayoutItems[1][j]->m_sPos =
          CFX_PointF(fCurPos, *fContentCurRowY);
      m_pLayoutItem->AppendLastChild(rgCurLineLayoutItems[1][j]);
      m_fLastRowWidth = fCurPos;
    }
    fCurPos = fContentWidthLimit;
    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
      if (rgCurLineLayoutItems[2][j]->GetFormNode()->PresenceRequiresSpace())
        fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.width;

      rgCurLineLayoutItems[2][j]->m_sPos =
          CFX_PointF(fCurPos, *fContentCurRowY);
      m_pLayoutItem->AppendLastChild(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_ContentLayoutProcessor::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_ContentLayoutProcessor::DoLayoutField() {
  if (m_pLayoutItem)
    return;

  ASSERT(!m_pCurChildNode);
  m_pLayoutItem = CreateContentLayoutItem(GetFormNode());
  if (!m_pLayoutItem)
    return;

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

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

  SetCurrentComponentSize(size);
}

CXFA_ContentLayoutProcessor::Result CXFA_ContentLayoutProcessor::DoLayout(
    bool bUseBreakControl,
    float fHeightLimit,
    float fRealHeight) {
  return DoLayoutInternal(bUseBreakControl, fHeightLimit, fRealHeight, nullptr);
}

CXFA_ContentLayoutProcessor::Result
CXFA_ContentLayoutProcessor::DoLayoutInternal(bool bUseBreakControl,
                                              float fHeightLimit,
                                              float fRealHeight,
                                              Context* pContext) {
  switch (GetFormNode()->GetElementType()) {
    case XFA_Element::Subform:
    case XFA_Element::Area:
    case XFA_Element::ExclGroup:
    case XFA_Element::SubformSet: {
      bool bRootForceTb = false;
      CXFA_Node* pLayoutNode = GetSubformSetParent(GetFormNode());
      XFA_AttributeValue eLayoutStrategy =
          GetLayout(pLayoutNode, &bRootForceTb);
      switch (eLayoutStrategy) {
        case XFA_AttributeValue::Tb:
        case XFA_AttributeValue::Lr_tb:
        case XFA_AttributeValue::Rl_tb:
          return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy,
                                         fHeightLimit, fRealHeight, pContext,
                                         bRootForceTb);
        case XFA_AttributeValue::Position:
        case XFA_AttributeValue::Row:
        case XFA_AttributeValue::Rl_row:
        default:
          DoLayoutPositionedContainer(pContext);
          m_nCurChildNodeStage = Stage::kDone;
          return Result::kDone;
        case XFA_AttributeValue::Table:
          DoLayoutTableContainer(pLayoutNode);
          m_nCurChildNodeStage = Stage::kDone;
          return Result::kDone;
      }
    }
    case XFA_Element::Draw:
    case XFA_Element::Field:
      DoLayoutField();
      m_nCurChildNodeStage = Stage::kDone;
      return Result::kDone;
    case XFA_Element::ContentArea:
    default:
      return Result::kDone;
  }
}

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

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

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

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

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

  auto* pOccur =
      pTemplate->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
  if (!pOccur)
    return false;

  int32_t iMax = pOccur->GetMax();
  if (iMax < 0)
    return true;

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

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

void CXFA_ContentLayoutProcessor::UpdatePendingItemLayout(
    const RetainPtr<CXFA_ContentLayoutItem>& pLayoutItem) {
  XFA_AttributeValue eLayout =
      pLayoutItem->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
  switch (eLayout) {
    case XFA_AttributeValue::Row:
    case XFA_AttributeValue::Rl_row:
      RelocateTableRowCells(pLayoutItem, m_rgSpecifiedColumnWidths, eLayout);
      break;
    default:
      break;
  }
}

void CXFA_ContentLayoutProcessor::AddTrailerBeforeSplit(
    float fSplitPos,
    const RetainPtr<CXFA_ContentLayoutItem>& pTrailerLayoutItem,
    bool bUseInherited) {
  if (!pTrailerLayoutItem)
    return;

  float fHeight = pTrailerLayoutItem->m_sSize.height;
  if (bUseInherited) {
    float fNewSplitPos = 0;
    if (fSplitPos - fHeight > kXFALayoutPrecision)
      fNewSplitPos = FindSplitPos(fSplitPos - fHeight);
    if (fNewSplitPos > kXFALayoutPrecision)
      SplitLayoutItem(fNewSplitPos);
    return;
  }

  UpdatePendingItemLayout(pTrailerLayoutItem);
  CXFA_Margin* pMargin =
      GetFormNode()->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  CFX_FloatRect inset = GetMarginInset(pMargin);
  if (!IsAddNewRowForTrailer(pTrailerLayoutItem.Get())) {
    pTrailerLayoutItem->m_sPos.y = m_fLastRowY;
    pTrailerLayoutItem->m_sPos.x = m_fLastRowWidth;
    m_pLayoutItem->m_sSize.width += pTrailerLayoutItem->m_sSize.width;
    m_pLayoutItem->AppendLastChild(pTrailerLayoutItem);
    return;
  }

  float fNewSplitPos = 0;
  if (fSplitPos - fHeight > kXFALayoutPrecision)
    fNewSplitPos = FindSplitPos(fSplitPos - fHeight);

  if (fNewSplitPos > kXFALayoutPrecision) {
    SplitLayoutItem(fNewSplitPos);
    pTrailerLayoutItem->m_sPos.y = fNewSplitPos - inset.top - inset.bottom;
  } else {
    pTrailerLayoutItem->m_sPos.y = fSplitPos - inset.top - inset.bottom;
  }

  switch (pTrailerLayoutItem->GetFormNode()->JSObject()->GetEnum(
      XFA_Attribute::HAlign)) {
    case XFA_AttributeValue::Right:
      pTrailerLayoutItem->m_sPos.x = m_pLayoutItem->m_sSize.width -
                                     inset.right -
                                     pTrailerLayoutItem->m_sSize.width;
      break;
    case XFA_AttributeValue::Center:
      pTrailerLayoutItem->m_sPos.x =
          (m_pLayoutItem->m_sSize.width - inset.left - inset.right -
           pTrailerLayoutItem->m_sSize.width) /
          2;
      break;
    case XFA_AttributeValue::Left:
    default:
      pTrailerLayoutItem->m_sPos.x = inset.left;
      break;
  }
  m_pLayoutItem->m_sSize.height += fHeight;
  m_pLayoutItem->AppendLastChild(pTrailerLayoutItem);
}

void CXFA_ContentLayoutProcessor::AddLeaderAfterSplit(
    const RetainPtr<CXFA_ContentLayoutItem>& pLeaderLayoutItem) {
  UpdatePendingItemLayout(pLeaderLayoutItem);

  CXFA_Margin* pMarginNode =
      GetFormNode()->GetFirstChildByClass<CXFA_Margin>(XFA_Element::Margin);
  float fLeftInset = 0;
  float fRightInset = 0;
  if (pMarginNode) {
    fLeftInset = pMarginNode->JSObject()->GetMeasureInUnit(
        XFA_Attribute::LeftInset, XFA_Unit::Pt);
    fRightInset = pMarginNode->JSObject()->GetMeasureInUnit(
        XFA_Attribute::RightInset, XFA_Unit::Pt);
  }

  float fHeight = pLeaderLayoutItem->m_sSize.height;
  for (CXFA_LayoutItem* pIter = m_pLayoutItem->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    CXFA_ContentLayoutItem* pContentItem = pIter->AsContentLayoutItem();
    if (!pContentItem)
      continue;

    pContentItem->m_sPos.y += fHeight;
  }
  pLeaderLayoutItem->m_sPos.y = 0;

  switch (pLeaderLayoutItem->GetFormNode()->JSObject()->GetEnum(
      XFA_Attribute::HAlign)) {
    case XFA_AttributeValue::Right:
      pLeaderLayoutItem->m_sPos.x = m_pLayoutItem->m_sSize.width - fRightInset -
                                    pLeaderLayoutItem->m_sSize.width;
      break;
    case XFA_AttributeValue::Center:
      pLeaderLayoutItem->m_sPos.x =
          (m_pLayoutItem->m_sSize.width - fLeftInset - fRightInset -
           pLeaderLayoutItem->m_sSize.width) /
          2;
      break;
    case XFA_AttributeValue::Left:
    default:
      pLeaderLayoutItem->m_sPos.x = fLeftInset;
      break;
  }
  m_pLayoutItem->m_sSize.height += fHeight;
  m_pLayoutItem->AppendLastChild(pLeaderLayoutItem);
}

void CXFA_ContentLayoutProcessor::AddPendingNode(CXFA_Node* pPendingNode,
                                                 bool bBreakPending) {
  m_PendingNodes.push_back(pPendingNode);
  m_bBreakPending = bBreakPending;
}

float CXFA_ContentLayoutProcessor::InsertPendingItems(
    CXFA_Node* pCurChildNode) {
  float fTotalHeight = 0;
  if (m_PendingNodes.empty())
    return fTotalHeight;

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

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

CXFA_ContentLayoutProcessor::Result
CXFA_ContentLayoutProcessor::InsertFlowedItem(
    CXFA_ContentLayoutProcessor* pProcessor,
    bool bContainerWidthAutoSize,
    bool bContainerHeightAutoSize,
    float fContainerHeight,
    XFA_AttributeValue eFlowStrategy,
    uint8_t* uCurHAlignState,
    std::vector<RetainPtr<CXFA_ContentLayoutItem>> (&rgCurLineLayoutItems)[3],
    bool bUseBreakControl,
    float fAvailHeight,
    float fRealHeight,
    float fContentWidthLimit,
    float* fContentCurRowY,
    float* fContentCurRowAvailWidth,
    float* fContentCurRowHeight,
    bool* bAddedItemInRow,
    bool* bForceEndPage,
    Context* pLayoutContext,
    bool bNewRow) {
  bool bTakeSpace = pProcessor->GetFormNode()->PresenceRequiresSpace();
  uint8_t uHAlign = HAlignEnumToInt(
      m_pCurChildNode->JSObject()->GetEnum(XFA_Attribute::HAlign));
  if (bContainerWidthAutoSize)
    uHAlign = 0;

  if ((eFlowStrategy != XFA_AttributeValue::Rl_tb &&
       uHAlign < *uCurHAlignState) ||
      (eFlowStrategy == XFA_AttributeValue::Rl_tb &&
       uHAlign > *uCurHAlignState)) {
    return Result::kRowFullBreak;
  }

  *uCurHAlignState = uHAlign;
  bool bIsOwnSplit =
      pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None;
  bool bUseRealHeight = bTakeSpace && bContainerHeightAutoSize && bIsOwnSplit &&
                        pProcessor->GetFormNode()->GetParent()->GetIntact() ==
                            XFA_AttributeValue::None;
  bool bIsTransHeight = bTakeSpace;
  if (bIsTransHeight && !bIsOwnSplit) {
    bool bRootForceTb = false;
    XFA_AttributeValue eLayoutStrategy =
        GetLayout(pProcessor->GetFormNode(), &bRootForceTb);
    if (eLayoutStrategy == XFA_AttributeValue::Lr_tb ||
        eLayoutStrategy == XFA_AttributeValue::Rl_tb) {
      bIsTransHeight = false;
    }
  }

  bool bUseInherited = false;
  Context layoutContext;
  if (m_pViewLayoutProcessor) {
    CXFA_Node* pOverflowNode =
        m_pViewLayoutProcessor->QueryOverflow(GetFormNode());
    if (pOverflowNode) {
      layoutContext.m_pOverflowNode = pOverflowNode;
      layoutContext.m_pOverflowProcessor = this;
      pLayoutContext = &layoutContext;
    }
  }

  Result eRetValue = Result::kDone;
  if (!bNewRow || pProcessor->m_ePreProcessRs == Result::kDone) {
    eRetValue = pProcessor->DoLayoutInternal(
        bTakeSpace && bUseBreakControl,
        bUseRealHeight ? fRealHeight - *fContentCurRowY : FLT_MAX,
        bIsTransHeight ? fRealHeight - *fContentCurRowY : FLT_MAX,
        pLayoutContext);
    pProcessor->m_ePreProcessRs = eRetValue;
  } else {
    eRetValue = pProcessor->m_ePreProcessRs;
    pProcessor->m_ePreProcessRs = Result::kDone;
  }
  if (!pProcessor->HasLayoutItem())
    return eRetValue;

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

  CXFA_Node* pOverflowLeaderNode = nullptr;
  CXFA_Node* pOverflowTrailerNode = nullptr;
  CXFA_Node* pFormNode = nullptr;
  RetainPtr<CXFA_ContentLayoutItem> pTrailerLayoutItem;
  bool bIsAddTrailerHeight = false;
  if (m_pViewLayoutProcessor &&
      pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
    pFormNode =
        m_pViewLayoutProcessor->QueryOverflow(pProcessor->GetFormNode());
    if (!pFormNode && pLayoutContext && pLayoutContext->m_pOverflowProcessor) {
      pFormNode = pLayoutContext->m_pOverflowNode.Get();
      bUseInherited = true;
    }
    Optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
        m_pViewLayoutProcessor->ProcessOverflow(pFormNode, false);
    if (overflow_data.has_value()) {
      pOverflowLeaderNode = overflow_data.value().pLeader;
      pOverflowTrailerNode = overflow_data.value().pTrailer;
      if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
        if (pOverflowTrailerNode) {
          auto pOverflowLeaderProcessor =
              pdfium::MakeUnique<CXFA_ContentLayoutProcessor>(
                  pOverflowTrailerNode, nullptr);
          pOverflowLeaderProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
          pTrailerLayoutItem =
              pOverflowLeaderProcessor->HasLayoutItem()
                  ? pOverflowLeaderProcessor->ExtractLayoutItem()
                  : nullptr;
        }

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

  if (!bTakeSpace ||
      *fContentCurRowY + childSize.height <=
          fAvailHeight + kXFALayoutPrecision ||
      (!bContainerHeightAutoSize &&
       m_fUsedSize + fAvailHeight + kXFALayoutPrecision >= fContainerHeight)) {
    if (!bTakeSpace || eRetValue == Result::kDone) {
      if (pProcessor->m_bUseInherited) {
        if (pTrailerLayoutItem)
          pProcessor->AddTrailerBeforeSplit(childSize.height,
                                            pTrailerLayoutItem, false);
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
          pProcessor->AddPendingNode(pOverflowLeaderNode, false);

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

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

      RetainPtr<CXFA_ContentLayoutItem> pChildLayoutItem =
          pProcessor->ExtractLayoutItem();
      if (ExistContainerKeep(pProcessor->GetFormNode(), false) &&
          pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
        m_ArrayKeepItems.push_back(pChildLayoutItem);
      } else {
        m_ArrayKeepItems.clear();
      }
      rgCurLineLayoutItems[uHAlign].push_back(pChildLayoutItem);
      *bAddedItemInRow = true;
      if (bTakeSpace) {
        *fContentCurRowAvailWidth -= childSize.width;
        *fContentCurRowHeight =
            std::max(*fContentCurRowHeight, childSize.height);
      }
      return Result::kDone;
    }

    if (eRetValue == Result::kPageFullBreak) {
      if (pProcessor->m_bUseInherited) {
        if (pTrailerLayoutItem) {
          pProcessor->AddTrailerBeforeSplit(childSize.height,
                                            pTrailerLayoutItem, false);
        }
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
          pProcessor->AddPendingNode(pOverflowLeaderNode, false);

        pProcessor->m_bUseInherited = 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;
  }

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

  *bForceEndPage = true;
  float fSplitPos = pProcessor->FindSplitPos(fAvailHeight - *fContentCurRowY);
  if (fSplitPos > kXFALayoutPrecision) {
    XFA_AttributeValue eLayout =
        pProcessor->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
    if (eLayout == XFA_AttributeValue::Tb && eRetValue == Result::kDone) {
      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 Result::kPageFullBreak;
    }

    if (m_pViewLayoutProcessor && !pProcessor->m_bUseInherited &&
        eRetValue != Result::kPageFullBreak) {
      m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
    }
    if (pTrailerLayoutItem && bIsAddTrailerHeight) {
      pProcessor->AddTrailerBeforeSplit(fSplitPos, pTrailerLayoutItem,
                                        bUseInherited);
    } else {
      pProcessor->SplitLayoutItem(fSplitPos);
    }

    if (bUseInherited) {
      pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                       pOverflowTrailerNode, pTrailerLayoutItem,
                                       pFormNode);
      m_bUseInherited = true;
    } else {
      CXFA_LayoutItem* firstChild = pProcessor->m_pLayoutItem->GetFirstChild();
      if (firstChild && !firstChild->GetNextSibling() &&
          firstChild->GetFormNode()->IsLayoutGeneratedNode()) {
        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
      } else if (pProcessor->JudgeLeaderOrTrailerForOccur(
                     pOverflowLeaderNode)) {
        pProcessor->AddPendingNode(pOverflowLeaderNode, false);
      }
    }

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

  if (*fContentCurRowY <= kXFALayoutPrecision) {
    childSize = pProcessor->GetCurrentComponentSize();
    if (pProcessor->m_pViewLayoutProcessor->GetNextAvailContentHeight(
            childSize.height)) {
      if (m_pViewLayoutProcessor) {
        if (!pFormNode && pLayoutContext)
          pFormNode = pLayoutContext->m_pOverflowProcessor->GetFormNode();

        m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
      }
      if (bUseInherited) {
        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
        m_bUseInherited = true;
      }
      return Result::kPageFullBreak;
    }

    rgCurLineLayoutItems[uHAlign].push_back(pProcessor->ExtractLayoutItem());
    *bAddedItemInRow = true;
    if (bTakeSpace) {
      *fContentCurRowAvailWidth -= childSize.width;
      *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height);
    }
    if (eRetValue == Result::kDone)
      *bForceEndPage = false;

    return eRetValue;
  }

  XFA_AttributeValue eLayout =
      pProcessor->GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
  if (pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None &&
      eLayout == XFA_AttributeValue::Tb) {
    if (m_pViewLayoutProcessor) {
      Optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
          m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
      if (overflow_data.has_value()) {
        pOverflowLeaderNode = overflow_data.value().pLeader;
        pOverflowTrailerNode = overflow_data.value().pTrailer;
      }
    }
    if (pTrailerLayoutItem)
      pProcessor->AddTrailerBeforeSplit(fSplitPos, pTrailerLayoutItem, false);
    if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode))
      pProcessor->AddPendingNode(pOverflowLeaderNode, false);

    return Result::kPageFullBreak;
  }

  if (eRetValue != Result::kDone)
    return Result::kPageFullBreak;

  if (!pFormNode && pLayoutContext)
    pFormNode = pLayoutContext->m_pOverflowProcessor->GetFormNode();
  if (m_pViewLayoutProcessor) {
    Optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
        m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
    if (overflow_data.has_value()) {
      pOverflowLeaderNode = overflow_data.value().pLeader;
      pOverflowTrailerNode = overflow_data.value().pTrailer;
    }
  }
  if (bUseInherited) {
    pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode,
                                     pTrailerLayoutItem, pFormNode);
    m_bUseInherited = true;
  }
  return Result::kPageFullBreak;
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleKeep(CXFA_Node* pBreakAfterNode,
                                        CXFA_Node** pCurActionNode) {
  if (m_bKeepBreakFinish)
    return {};
  return FindBreakNode(pBreakAfterNode, false, pCurActionNode);
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleBookendLeader(CXFA_Node* pParentContainer,
                                                 CXFA_Node** pCurActionNode) {
  for (CXFA_Node* pBookendNode = *pCurActionNode
                                     ? (*pCurActionNode)->GetNextSibling()
                                     : pParentContainer->GetFirstChild();
       pBookendNode; pBookendNode = pBookendNode->GetNextSibling()) {
    switch (pBookendNode->GetElementType()) {
      case XFA_Element::Bookend:
      case XFA_Element::Break:
        *pCurActionNode = pBookendNode;
        return Stage::kBookendLeader;
      default:
        break;
    }
  }
  return {};
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleBreakBefore(CXFA_Node* pChildContainer,
                                               CXFA_Node** pCurActionNode) {
  if (!*pCurActionNode)
    return {};

  CXFA_Node* pBreakBeforeNode = (*pCurActionNode)->GetNextSibling();
  if (!m_bKeepBreakFinish) {
    Optional<Stage> ret = FindBreakNode(pBreakBeforeNode, true, pCurActionNode);
    if (ret.has_value())
      return ret.value();
  }
  if (m_bIsProcessKeep)
    return ProcessKeepNodesForBreakBefore(pCurActionNode, pChildContainer);

  *pCurActionNode = pChildContainer;
  return Stage::kContainer;
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleBreakAfter(CXFA_Node* pChildContainer,
                                              CXFA_Node** pCurActionNode) {
  if (*pCurActionNode) {
    CXFA_Node* pBreakAfterNode = (*pCurActionNode)->GetNextSibling();
    return FindBreakNode(pBreakAfterNode, false, pCurActionNode);
  }

  CXFA_Node* pBreakAfterNode = pChildContainer->GetFirstChild();
  return HandleKeep(pBreakAfterNode, pCurActionNode);
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleCheckNextChildContainer(
    CXFA_Node* pParentContainer,
    CXFA_Node* pChildContainer,
    CXFA_Node** pCurActionNode) {
  CXFA_Node* pNextChildContainer =
      pChildContainer ? pChildContainer->GetNextContainerSibling()
                      : pParentContainer->GetFirstContainerChild();
  while (pNextChildContainer && pNextChildContainer->IsLayoutGeneratedNode()) {
    CXFA_Node* pSaveNode = pNextChildContainer;
    pNextChildContainer = pNextChildContainer->GetNextContainerSibling();
    if (pSaveNode->IsUnusedNode())
      DeleteLayoutGeneratedNode(pSaveNode);
  }
  if (!pNextChildContainer)
    return {};

  bool bLastKeep = false;
  Optional<Stage> ret = ProcessKeepNodesForCheckNext(
      pCurActionNode, &pNextChildContainer, &bLastKeep);
  if (ret.has_value())
    return ret.value();

  if (!m_bKeepBreakFinish && !bLastKeep) {
    ret = FindBreakNode(pNextChildContainer->GetFirstChild(), true,
                        pCurActionNode);
    if (ret.has_value())
      return ret.value();
  }
  *pCurActionNode = pNextChildContainer;
  return m_bIsProcessKeep ? Stage::kKeep : Stage::kContainer;
}

Optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleBookendTrailer(CXFA_Node* pParentContainer,
                                                  CXFA_Node** pCurActionNode) {
  for (CXFA_Node* pBookendNode = *pCurActionNode
                                     ? (*pCurActionNode)->GetNextSibling()
                                     : pParentContainer->GetFirstChild();
       pBookendNode; pBookendNode = pBookendNode->GetNextSibling()) {
    switch (pBookendNode->GetElementType()) {
      case XFA_Element::Bookend:
      case XFA_Element::Break:
        *pCurActionNode = pBookendNode;
        return Stage::kBookendTrailer;
      default:
        break;
    }
  }
  return {};
}

void CXFA_ContentLayoutProcessor::ProcessKeepNodesEnd() {
  m_bKeepBreakFinish = true;
  m_pKeepHeadNode = nullptr;
  m_pKeepTailNode = nullptr;
  m_bIsProcessKeep = false;
}

void CXFA_ContentLayoutProcessor::AdjustContainerSpecifiedSize(
    Context* pContext,
    CFX_SizeF* pSize,
    bool* pContainerWidthAutoSize,
    bool* pContainerHeightAutoSize) {
  if (pContext && pContext->m_fCurColumnWidth.has_value()) {
    pSize->width = pContext->m_fCurColumnWidth.value();
    *pContainerWidthAutoSize = false;
  }
  if (*pContainerHeightAutoSize)
    return;

  pSize->height -= m_fUsedSize;
  CXFA_Node* pParentNode = GetFormNode()->GetParent();
  bool bFocrTb = false;
  if (!pParentNode ||
      GetLayout(pParentNode, &bFocrTb) != XFA_AttributeValue::Row) {
    return;
  }

  CXFA_Node* pChildContainer = GetFormNode()->GetFirstContainerChild();
  if (!pChildContainer || !pChildContainer->GetNextContainerSibling())
    return;

  pSize->height = 0;
  *pContainerHeightAutoSize = true;
}

CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::FindLastContentLayoutItem(
    XFA_AttributeValue eFlowStrategy) {
  if (m_nCurChildNodeStage == Stage::kDone ||
      eFlowStrategy == XFA_AttributeValue::Tb) {
    return nullptr;
  }

  CXFA_ContentLayoutItem* pLastChild =
      ToContentLayoutItem(m_pLayoutItem->GetFirstChild());
  for (CXFA_LayoutItem* pNext = pLastChild; pNext;
       pNext = pNext->GetNextSibling()) {
    CXFA_ContentLayoutItem* pContentNext = pNext->AsContentLayoutItem();
    if (pContentNext && pContentNext->m_sPos.y != pLastChild->m_sPos.y)
      pLastChild = pContentNext;
  }
  return pLastChild;
}

CFX_SizeF CXFA_ContentLayoutProcessor::CalculateLayoutItemSize(
    const CXFA_ContentLayoutItem* pLastChild) {
  CFX_SizeF size;
  for (CXFA_LayoutItem* pChild = m_pLayoutItem->GetFirstChild();
       pChild != pLastChild; pChild = pChild->GetNextSibling()) {
    CXFA_ContentLayoutItem* pLayout = pChild->AsContentLayoutItem();
    if (!pLayout || !pLayout->GetFormNode()->PresenceRequiresSpace())
      continue;

    float fWidth = pLayout->m_sPos.x + pLayout->m_sSize.width;
    float fHeight = pLayout->m_sPos.y + pLayout->m_sSize.height;
    size.width = std::max(size.width, fWidth);
    size.height = std::max(size.height, fHeight);
  }
  return size;
}

CXFA_ContentLayoutProcessor::Context::Context() = default;

CXFA_ContentLayoutProcessor::Context::~Context() = default;
