// Copyright 2014 The PDFium Authors
// 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 <array>
#include <utility>
#include <vector>

#include "core/fxcrt/check.h"
#include "core/fxcrt/containers/adapters.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/stl_util.h"
#include "fxjs/gc/container_trace.h"
#include "fxjs/xfa/cjx_object.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 {

using NextPosRow = std::array<uint8_t, 9>;
constexpr std::array<const NextPosRow, 4> kNextPosTable = {{
    {{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}},
}};

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->s_size_.width;
      }
      if (*pHeight < -kXFALayoutPrecision) {
        *pHeight = pLayoutItem->s_size_.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) {
    std::optional<CXFA_Measurement> wValue =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::W, false);
    if (wValue.has_value() && wValue->GetValue() > kXFALayoutPrecision) {
      containerSize.width = wValue->ToUnit(XFA_Unit::Pt);
      *bContainerWidthAutoSize = false;
    }

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

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

    std::optional<CXFA_Measurement> maxH =
        pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxH, false);
    if (maxH.has_value() && 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) {
      std::optional<CXFA_Measurement> leftInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::LeftInset, false);
      if (leftInset.has_value()) {
        componentSize.width += leftInset->ToUnit(XFA_Unit::Pt);
      }

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

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

      std::optional<CXFA_Measurement> bottomInset =
          pMarginNode->JSObject()->TryMeasure(XFA_Attribute::BottomInset,
                                              false);
      if (bottomInset.has_value()) {
        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(CXFA_ContentLayoutItem* pLayoutRow,
                           const std::vector<float>& rgSpecifiedColumnWidths,
                           XFA_AttributeValue eLayout) {
  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  const CFX_SizeF containerSize = CalculateContainerSpecifiedSize(
      pLayoutRow->GetFormNode(), &bContainerWidthAutoSize,
      &bContainerHeightAutoSize);

  CXFA_Margin* pMargin =
      pLayoutRow->GetFormNode()->GetFirstChildByClass<CXFA_Margin>(
          XFA_Element::Margin);
  const CFX_FloatRect inset = GetMarginInset(pMargin);

  const float fContentWidthLimit =
      bContainerWidthAutoSize ? FLT_MAX
                              : containerSize.width - inset.left - inset.right;
  const float fContentCurrentHeight =
      pLayoutRow->s_size_.height - inset.top - inset.bottom;

  float fContentCalculatedWidth = 0;
  float fContentCalculatedHeight = 0;
  float fCurrentColX = 0;
  size_t nCurrentColIdx = 0;
  bool bMetWholeRowCell = false;

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

    const int32_t nOriginalColSpan =
        pLayoutChild->GetFormNode()->JSObject()->GetInteger(
            XFA_Attribute::ColSpan);

    size_t nColSpan;
    if (nOriginalColSpan > 0) {
      nColSpan = static_cast<size_t>(nOriginalColSpan);
    } else if (nOriginalColSpan == -1) {
      nColSpan = rgSpecifiedColumnWidths.size();
    } else {
      continue;
    }

    CHECK(nCurrentColIdx <= rgSpecifiedColumnWidths.size());
    const size_t remaining = rgSpecifiedColumnWidths.size() - nCurrentColIdx;
    nColSpan = std::min(nColSpan, remaining);

    float fColSpanWidth = 0;
    for (size_t i = 0; i < nColSpan; i++) {
      fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];
    }

    if (nOriginalColSpan == -1 ||
        nColSpan != static_cast<size_t>(nOriginalColSpan)) {
      fColSpanWidth = bMetWholeRowCell ? 0
                                       : std::max(fColSpanWidth,
                                                  pLayoutChild->s_size_.height);
    }
    if (nOriginalColSpan == -1) {
      bMetWholeRowCell = true;
    }

    pLayoutChild->s_pos_ = CFX_PointF(fCurrentColX, 0);
    pLayoutChild->s_size_.width = fColSpanWidth;
    if (!pLayoutChild->GetFormNode()->PresenceRequiresSpace()) {
      continue;
    }

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

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

      UpdateWidgetSize(pLayoutChild, &pLayoutChild->s_size_.width,
                       &fContentCalculatedHeight);
      float fOldChildHeight = pLayoutChild->s_size_.height;
      pLayoutChild->s_size_.height = fContentCalculatedHeight;
      CXFA_Para* pParaNode =
          pLayoutChild->GetFormNode()->GetFirstChildByClass<CXFA_Para>(
              XFA_Element::Para);
      if (!pParaNode || !pLayoutChild->GetFirstChild()) {
        continue;
      }

      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) {
        continue;
      }

      for (CXFA_LayoutItem* pInnerIter = pLayoutChild->GetFirstChild();
           pInnerIter; pInnerIter = pInnerIter->GetNextSibling()) {
        CXFA_ContentLayoutItem* pInnerChild = pInnerIter->AsContentLayoutItem();
        if (pInnerChild) {
          pInnerChild->s_pos_.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->s_pos_.x = fContentCalculatedWidth -
                               pLayoutChild->s_pos_.x -
                               pLayoutChild->s_size_.width;
    }
  }
  pLayoutRow->s_size_ = CalculateContainerComponentSizeFromContentSize(
      pLayoutRow->GetFormNode(), bContainerWidthAutoSize,
      fContentCalculatedWidth, bContainerHeightAutoSize,
      fContentCalculatedHeight, containerSize);
}

XFA_AttributeValue GetLayout(CXFA_Node* pFormNode, bool* bRootForceTb) {
  *bRootForceTb = false;
  std::optional<XFA_AttributeValue> layoutMode =
      pFormNode->JSObject()->TryEnum(XFA_Attribute::Layout, false);
  if (layoutMode.has_value()) {
    return layoutMode.value();
  }

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

    std::optional<XFA_AttributeValue> previous =
        pKeep->JSObject()->TryEnum(eKeepType, false);
    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;
  }

  std::optional<XFA_AttributeValue> next =
      pKeep->JSObject()->TryEnum(eKeepType, false);
  if (next == XFA_AttributeValue::ContentArea ||
      next == XFA_AttributeValue::PageArea) {
    return true;
  }
  return false;
}

std::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakBeforeNode(
    CXFA_Node* pContainerNode,
    CXFA_Node** pCurActionNode) {
  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
       pBreakNode = pBreakNode->GetNextSibling()) {
    switch (pBreakNode->GetElementType()) {
      case XFA_Element::BreakBefore:
        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakBefore;
      case XFA_Element::Break:
        if (pBreakNode->JSObject()->GetEnum(XFA_Attribute::Before) ==
            XFA_AttributeValue::Auto) {
          break;
        }
        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakBefore;
      default:
        break;
    }
  }
  return std::nullopt;
}

std::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakAfterNode(
    CXFA_Node* pContainerNode,
    CXFA_Node** pCurActionNode) {
  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
       pBreakNode = pBreakNode->GetNextSibling()) {
    switch (pBreakNode->GetElementType()) {
      case XFA_Element::BreakAfter:
        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakAfter;
      case XFA_Element::Break:
        if (pBreakNode->JSObject()->GetEnum(XFA_Attribute::After) ==
            XFA_AttributeValue::Auto) {
          break;
        }
        *pCurActionNode = pBreakNode;
        return CXFA_ContentLayoutProcessor::Stage::kBreakAfter;
      default:
        break;
    }
  }
  return std::nullopt;
}

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()) {
    CXFA_ContentLayoutItem* pCurLayoutItem =
        ToContentLayoutItem(pNode->JSObject()->GetLayoutItem());
    while (pCurLayoutItem) {
      CXFA_ContentLayoutItem* pNextLayoutItem = pCurLayoutItem->GetNext();
      pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
      pCurLayoutItem = 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->s_size_.height -
                               kXFALayoutPrecision) {
    return false;
  }

  switch (pFormNode->GetIntact()) {
    case XFA_AttributeValue::None: {
      bool bAnyChanged = false;
      CXFA_Document* document = pFormNode->GetDocument();
      CXFA_FFNotify* pNotify = document->GetNotify();
      float fCurTopMargin = 0;
      float 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;
        {
          std::optional<float> fRelSplitPos = pFormNode->FindSplitPos(
              pNotify->GetFFDoc()->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->s_pos_.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;
  }
  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 = kNextPosTable[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(
    FXGC_Heap* pHeap,
    CXFA_Node* pNode,
    CXFA_ViewLayoutProcessor* pViewLayoutProcessor)
    : heap_(pHeap),
      form_node_(pNode),
      view_layout_processor_(pViewLayoutProcessor) {
  DCHECK(GetFormNode());
  DCHECK(GetFormNode()->IsContainerNode() ||
         GetFormNode()->GetElementType() == XFA_Element::Form);
  old_layout_item_ =
      ToContentLayoutItem(GetFormNode()->JSObject()->GetLayoutItem());
}

CXFA_ContentLayoutProcessor::~CXFA_ContentLayoutProcessor() = default;

void CXFA_ContentLayoutProcessor::Trace(cppgc::Visitor* visitor) const {
  visitor->Trace(form_node_);
  visitor->Trace(cur_child_node_);
  visitor->Trace(keep_head_node_);
  visitor->Trace(keep_tail_node_);
  visitor->Trace(layout_item_);
  visitor->Trace(old_layout_item_);
  visitor->Trace(view_layout_processor_);
  visitor->Trace(cur_child_preprocessor_);
  ContainerTrace(visitor, array_keep_items_);
  ContainerTrace(visitor, pending_nodes_);
  ContainerTrace(visitor, pending_nodes_count_);
}

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

  if (old_layout_item_) {
    CXFA_ContentLayoutItem* pLayoutItem = old_layout_item_;
    old_layout_item_ = old_layout_item_->GetNext();
    return pLayoutItem;
  }
  CXFA_FFNotify* pNotify = pFormNode->GetDocument()->GetNotify();
  auto* pNewLayoutItem = cppgc::MakeGarbageCollected<CXFA_ContentLayoutItem>(
      GetHeap()->GetAllocationHandle(), pFormNode,
      pNotify->OnCreateContentLayoutItem(pFormNode));

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

float CXFA_ContentLayoutProcessor::FindSplitPos(float fProposedSplitPos) {
  DCHECK(layout_item_);
  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(layout_item_.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);
  }

  CXFA_ContentLayoutItem* pSecondLayoutItem = nullptr;
  if (cur_child_preprocessor_ &&
      cur_child_preprocessor_->GetFormNode() == pLayoutItem->GetFormNode()) {
    pSecondLayoutItem = cur_child_preprocessor_->CreateContentLayoutItem(
        pLayoutItem->GetFormNode());
  } else {
    pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->GetFormNode());
  }
  pSecondLayoutItem->s_pos_.x = pLayoutItem->s_pos_.x;
  pSecondLayoutItem->s_size_.width = pLayoutItem->s_size_.width;
  pSecondLayoutItem->s_pos_.y = 0;
  pSecondLayoutItem->s_size_.height = pLayoutItem->s_size_.height - fSplitPos;
  pLayoutItem->s_size_.height -= pSecondLayoutItem->s_size_.height;
  if (pLayoutItem->GetFirstChild()) {
    pSecondLayoutItem->s_size_.height += fCurTopMargin;
  }

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

        pContentItem->s_size_.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<CXFA_ContentLayoutItem*> children;
  while (auto* pFirst = ToContentLayoutItem(pLayoutItem->GetFirstChild())) {
    children.push_back(pFirst);
    pLayoutItem->RemoveChild(children.back());
  }

  float lHeightForKeep = 0;
  float fAddMarginHeight = 0;
  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
  for (CXFA_ContentLayoutItem* pChildItem : children) {
    if (fSplitPos <= fCurTopMargin + pChildItem->s_pos_.y + fCurBottomMargin +
                         kXFALayoutPrecision) {
      if (!ExistContainerKeep(pChildItem->GetFormNode(), true)) {
        pChildItem->s_pos_.y -= fSplitPos - fCurBottomMargin;
        pChildItem->s_pos_.y += lHeightForKeep;
        pChildItem->s_pos_.y += fAddMarginHeight;
        pSecondLayoutItem->AppendLastChild(pChildItem);
        continue;
      }
      if (lHeightForKeep < kXFALayoutPrecision) {
        for (CXFA_ContentLayoutItem* pPreItem : keepLayoutItems) {
          pLayoutItem->RemoveChild(pPreItem);
          pPreItem->s_pos_.y -= fSplitPos;
          if (pPreItem->s_pos_.y < 0) {
            pPreItem->s_pos_.y = 0;
          }
          if (pPreItem->s_pos_.y + pPreItem->s_size_.height > lHeightForKeep) {
            pPreItem->s_pos_.y = lHeightForKeep;
            lHeightForKeep += pPreItem->s_size_.height;
            pSecondLayoutItem->s_size_.height += pPreItem->s_size_.height;
            if (pSecondParent) {
              pSecondParent->s_size_.height += pPreItem->s_size_.height;
            }
          }
          pSecondLayoutItem->AppendLastChild(pPreItem);
        }
      }
      pChildItem->s_pos_.y -= fSplitPos;
      pChildItem->s_pos_.y += lHeightForKeep;
      pChildItem->s_pos_.y += fAddMarginHeight;
      pSecondLayoutItem->AppendLastChild(pChildItem);
      continue;
    }
    if (fSplitPos + kXFALayoutPrecision >= fCurTopMargin + fCurBottomMargin +
                                               pChildItem->s_pos_.y +
                                               pChildItem->s_size_.height) {
      pLayoutItem->AppendLastChild(pChildItem);
      if (ExistContainerKeep(pChildItem->GetFormNode(), false)) {
        keepLayoutItems.push_back(pChildItem);
      } else {
        keepLayoutItems.clear();
      }
      continue;
    }

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

void CXFA_ContentLayoutProcessor::SplitLayoutItem(float fSplitPos) {
  DCHECK(layout_item_);
  SplitLayoutItem(layout_item_.Get(), nullptr, fSplitPos);
}

CXFA_ContentLayoutItem* CXFA_ContentLayoutProcessor::ExtractLayoutItem() {
  CXFA_ContentLayoutItem* pLayoutItem = layout_item_;
  if (pLayoutItem) {
    layout_item_ = ToContentLayoutItem(pLayoutItem->GetNextSibling());
    pLayoutItem->RemoveSelfIfParented();
  }
  if (cur_child_node_stage_ != Stage::kDone || !old_layout_item_) {
    return pLayoutItem;
  }

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

  while (old_layout_item_) {
    CXFA_ContentLayoutItem* pToDeleteItem = old_layout_item_;
    old_layout_item_ = pToDeleteItem->GetNext();
    if (pToDeleteItem == pLayoutItem) {
      break;
    }
    pNotify->OnLayoutItemRemoving(pDocLayout, pToDeleteItem);
    pToDeleteItem->RemoveSelfIfParented();
  }
  return pLayoutItem;
}

void CXFA_ContentLayoutProcessor::GotoNextContainerNodeSimple() {
  std::tie(cur_child_node_stage_, cur_child_node_) = GotoNextContainerNode(
      cur_child_node_stage_, GetFormNode(), cur_child_node_);
}

std::pair<CXFA_ContentLayoutProcessor::Stage, CXFA_Node*>
CXFA_ContentLayoutProcessor::GotoNextContainerNode(Stage nCurStage,
                                                   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;
  }

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

    case Stage::kNone:
      pCurActionNode = nullptr;
      [[fallthrough]];

    case Stage::kBookendLeader:
      ret = HandleBookendLeader(pParentContainer, &pCurActionNode);
      if (ret.has_value()) {
        return {ret.value(), pCurActionNode};
      }
      pCurActionNode = nullptr;
      [[fallthrough]];

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

    case Stage::kContainer:
      pCurActionNode = nullptr;
      [[fallthrough]];

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

    case Stage::kBookendTrailer:
      ret = HandleBookendTrailer(pParentContainer, &pCurActionNode);
      if (ret.has_value()) {
        return {ret.value(), pCurActionNode};
      }
      [[fallthrough]];

    default:
      return {Stage::kDone, nullptr};
  }

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

  pCurActionNode = nullptr;
  ret = HandleBookendTrailer(pParentContainer, &pCurActionNode);
  if (ret.has_value()) {
    return {ret.value(), pCurActionNode};
  }

  return {Stage::kDone, nullptr};
}

std::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 (!is_process_keep_ && !keep_break_finish_) {
      keep_head_node_ = *pNextContainer;
      is_process_keep_ = true;
    }
    return std::nullopt;
  }

  if (!is_process_keep_ || !keep_head_node_) {
    if (keep_break_finish_) {
      *pLastKeepNode = true;
    }
    keep_break_finish_ = false;
    return std::nullopt;
  }

  keep_tail_node_ = *pNextContainer;
  if (keep_break_finish_) {
    *pNextContainer = keep_head_node_;
    ProcessKeepNodesEnd();
    return std::nullopt;
  }

  std::optional<Stage> ret =
      FindBreakBeforeNode((*pNextContainer)->GetFirstChild(), pCurActionNode);
  if (!ret.has_value()) {
    *pNextContainer = keep_head_node_;
    ProcessKeepNodesEnd();
    return std::nullopt;
  }

  return ret;
}

std::optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::ProcessKeepNodesForBreakBefore(
    CXFA_Node** pCurActionNode,
    CXFA_Node* pContainerNode) {
  if (keep_tail_node_ == pContainerNode) {
    *pCurActionNode = keep_head_node_;
    ProcessKeepNodesEnd();
    return Stage::kContainer;
  }

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

void CXFA_ContentLayoutProcessor::DoLayoutPageArea(
    CXFA_ViewLayoutItem* pPageAreaLayoutItem) {
  CXFA_Node* pFormNode = pPageAreaLayoutItem->GetFormNode();
  CXFA_Node* pCurChildNode = nullptr;
  CXFA_LayoutItem* pBeforeItem = nullptr;
  Stage nCurChildNodeStage = Stage::kNone;
  while (true) {
    std::tie(nCurChildNodeStage, pCurChildNode) =
        GotoNextContainerNode(nCurChildNodeStage, pFormNode, pCurChildNode);
    if (!pCurChildNode) {
      break;
    }

    if (nCurChildNodeStage != Stage::kContainer ||
        pCurChildNode->GetElementType() == XFA_Element::Variables) {
      continue;
    }

    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
        GetHeap()->GetAllocationHandle(), GetHeap(), pCurChildNode, nullptr);
    pProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
    if (!pProcessor->HasLayoutItem()) {
      continue;
    }

    pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos(
        pCurChildNode, pProcessor->GetCurrentComponentSize()));

    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
    if (!pBeforeItem) {
      pPageAreaLayoutItem->AppendFirstChild(pProcessItem);
    } else {
      pPageAreaLayoutItem->InsertAfter(pProcessItem, pBeforeItem);
    }

    pBeforeItem = pProcessItem;
  }

  pBeforeItem = nullptr;
  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->GetFirstChild();
  while (pLayoutItem) {
    if (!pLayoutItem->IsContentLayoutItem() ||
        pLayoutItem->GetFormNode()->GetElementType() != XFA_Element::Draw) {
      pLayoutItem = 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;
    pLayoutItem = pNextLayoutItem;
  }
}

void CXFA_ContentLayoutProcessor::DoLayoutPositionedContainer(
    Context* context) {
  if (layout_item_) {
    return;
  }

  layout_item_ = 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 (!cur_child_node_) {
    GotoNextContainerNodeSimple();
  }

  int32_t iColIndex = 0;
  for (; cur_child_node_; GotoNextContainerNodeSimple()) {
    if (cur_child_node_stage_ != Stage::kContainer) {
      continue;
    }
    if (cur_child_node_->GetElementType() == XFA_Element::Variables) {
      continue;
    }

    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
        GetHeap()->GetAllocationHandle(), GetHeap(), cur_child_node_,
        view_layout_processor_);

    if (context && context->prg_specified_column_widths_) {
      int32_t iColSpan =
          cur_child_node_->JSObject()->GetInteger(XFA_Attribute::ColSpan);
      if (iColSpan <= fxcrt::CollectionSize<int32_t>(
                          *context->prg_specified_column_widths_) -
                          iColIndex) {
        context->cur_column_width_ = 0.0f;
        if (iColSpan == -1) {
          iColSpan = fxcrt::CollectionSize<int32_t>(
              *context->prg_specified_column_widths_);
        }
        for (int32_t i = 0; iColIndex + i < iColSpan; ++i) {
          context->cur_column_width_.value() +=
              (*context->prg_specified_column_widths_)[iColIndex + i];
        }
        if (context->cur_column_width_.value() == 0) {
          context->cur_column_width_.reset();
        }

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

    pProcessor->DoLayoutInternal(false, FLT_MAX, FLT_MAX, context);
    if (!pProcessor->HasLayoutItem()) {
      continue;
    }

    CFX_SizeF size = pProcessor->GetCurrentComponentSize();
    bool bChangeParentSize = false;
    if (cur_child_node_->PresenceRequiresSpace()) {
      bChangeParentSize = true;
    }

    CFX_PointF absolutePos;
    if (!bIgnoreXY) {
      absolutePos = CalculatePositionedContainerPos(cur_child_node_, size);
    }

    pProcessor->SetCurrentComponentPos(absolutePos);
    if (bContainerWidthAutoSize) {
      float fChildSuppliedWidth = absolutePos.x + size.width;
      if (bChangeParentSize) {
        fContentCalculatedWidth =
            std::max(fContentCalculatedWidth, fChildSuppliedWidth);
      } else {
        if (fHiddenContentCalculatedWidth < fChildSuppliedWidth &&
            cur_child_node_->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 &&
            cur_child_node_->GetElementType() != XFA_Element::Subform) {
          fHiddenContentCalculatedHeight = fChildSuppliedHeight;
        }
      }
    }
    layout_item_->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 (layout_item_) {
    return;
  }
  if (!pLayoutNode) {
    pLayoutNode = GetFormNode();
  }

  DCHECK(!cur_child_node_);

  layout_item_ = 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.TrimFront(L' ');
      if (width.IsEmpty()) {
        continue;
      }

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

  int32_t iSpecifiedColumnCount =
      fxcrt::CollectionSize<int32_t>(rg_specified_column_widths_);
  Context layoutContext;
  layoutContext.prg_specified_column_widths_ = &rg_specified_column_widths_;
  Context* pLayoutContext =
      iSpecifiedColumnCount > 0 ? &layoutContext : nullptr;
  if (!cur_child_node_) {
    GotoNextContainerNodeSimple();
  }

  for (; cur_child_node_; GotoNextContainerNodeSimple()) {
    layoutContext.cur_column_width_.reset();
    if (cur_child_node_stage_ != Stage::kContainer) {
      continue;
    }

    auto* pProcessor = cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
        GetHeap()->GetAllocationHandle(), GetHeap(), cur_child_node_,
        view_layout_processor_);

    pProcessor->DoLayoutInternal(false, FLT_MAX, FLT_MAX, pLayoutContext);
    if (!pProcessor->HasLayoutItem()) {
      continue;
    }

    layout_item_->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 = layout_item_->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->s_size_.width);
      }
    }

    iRowCount = fxcrt::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->s_size_.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 -
              fxcrt::CollectionSize<int32_t>(rg_specified_column_widths_);
          for (int32_t j = 0; j < c; j++) {
            rg_specified_column_widths_.push_back(0);
          }
        }
        if (rg_specified_column_widths_[iColCount] < kXFALayoutPrecision) {
          bAutoCol = true;
        }
        if (bAutoCol &&
            rg_specified_column_widths_[iColCount] < rgRowItemsWidth[i]) {
          rg_specified_column_widths_[iColCount] = rgRowItemsWidth[i];
        }
      }

      if (!bMoreColumns) {
        continue;
      }

      float fFinalColumnWidth = 0.0f;
      if (fxcrt::IndexInBounds(rg_specified_column_widths_, iColCount)) {
        fFinalColumnWidth = rg_specified_column_widths_[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 = layout_item_->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    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, rg_specified_column_widths_,
                              eSubformLayout);
      }
    }

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

    if (bContainerWidthAutoSize) {
      float fChildSuppliedWidth =
          pLayoutChild->s_pos_.x + pLayoutChild->s_size_.width;
      if (fContentWidthLimit < FLT_MAX &&
          fContentWidthLimit > fChildSuppliedWidth) {
        fChildSuppliedWidth = fContentWidthLimit;
      }
      fContentCalculatedWidth =
          std::max(fContentCalculatedWidth, fChildSuppliedWidth);
    }
    fCurrentRowY += pLayoutChild->s_size_.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->s_size_.width;
  XFA_AttributeValue eLayout =
      GetFormNode()->JSObject()->GetEnum(XFA_Attribute::Layout);
  return eLayout == XFA_AttributeValue::Tb || width_limit_ <= fWidth;
}

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

  if (!layout_item_) {
    layout_item_ = CreateContentLayoutItem(GetFormNode());
    layout_item_->s_size_.clear();
  }

  float fTotalHeight = 0;
  for (const auto& item : pdfium::Reversed(array_keep_items_)) {
    AddLeaderAfterSplit(item);
    fTotalHeight += item->s_size_.height;
  }
  array_keep_items_.clear();

  return fTotalHeight;
}

bool CXFA_ContentLayoutProcessor::ProcessKeepForSplit(
    CXFA_ContentLayoutProcessor* pChildProcessor,
    Result eRetValue,
    ContentLayoutItemVector& rgCurLineLayoutItem,
    float* fContentCurRowAvailWidth,
    float* fContentCurRowHeight,
    float* fContentCurRowY,
    bool* bAddedItemInRow,
    bool* bForceEndPage,
    Result* result) {
  if (!pChildProcessor) {
    return false;
  }

  if (cur_child_node_->GetIntact() == XFA_AttributeValue::None &&
      pChildProcessor->has_avail_height_) {
    return false;
  }

  if (!ExistContainerKeep(cur_child_node_, true)) {
    return false;
  }

  CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize();
  std::vector<CXFA_ContentLayoutItem*> keepLayoutItems;
  if (JudgePutNextPage(layout_item_.Get(), childSize.height,
                       &keepLayoutItems)) {
    array_keep_items_.clear();
    for (CXFA_ContentLayoutItem* item : keepLayoutItems) {
      layout_item_->RemoveChild(item);
      *fContentCurRowY -= item->s_size_.height;
      array_keep_items_.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<CXFA_ContentLayoutItem*>* pKeepItems) {
  if (!pParentLayoutItem) {
    return false;
  }

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

    if (ExistContainerKeep(pChildLayoutItem->GetFormNode(), false)) {
      pKeepItems->push_back(pChildLayoutItem);
      fItemsHeight += pChildLayoutItem->s_size_.height;
    } else {
      pKeepItems->clear();
      fItemsHeight = 0;
    }
  }
  fItemsHeight += fChildHeight;
  return view_layout_processor_->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::kUnusedNode);
  }
}

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

  if (pFormNode->GetElementType() == XFA_Element::Overflow ||
      pFormNode->GetElementType() == XFA_Element::Break) {
    pFormNode = pFormNode->GetParent();
  }
  if (pLeaderNode && pFormNode) {
    pFormNode->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* context,
    bool bRootForceTb) {
  has_avail_height_ = true;
  if (cur_child_preprocessor_) {
    cur_child_preprocessor_->pre_process_rs_ = Result::kDone;
  }

  bool bContainerWidthAutoSize = true;
  bool bContainerHeightAutoSize = true;
  CFX_SizeF container_size = CalculateContainerSpecifiedSize(
      GetFormNode(), &bContainerWidthAutoSize, &bContainerHeightAutoSize);
  AdjustContainerSpecifiedSize(context, &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) {
    has_avail_height_ = false;
  }

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

  fContentCurRowY += InsertKeepLayoutItems();
  if (cur_child_node_stage_ == Stage::kNone) {
    GotoNextContainerNodeSimple();
  }

  fContentCurRowY += InsertPendingItems(GetFormNode());
  if (cur_child_preprocessor_ && cur_child_node_stage_ == Stage::kContainer) {
    if (ExistContainerKeep(cur_child_preprocessor_->GetFormNode(), false)) {
      keep_head_node_ = cur_child_node_;
      is_process_keep_ = true;
      cur_child_node_stage_ = Stage::kKeep;
    }
  }

  bool bForceEndPage = false;
  bool bBreakDone = false;
  bool bIsManualBreak = false;
  while (cur_child_node_stage_ != Stage::kDone) {
    float fContentCurRowHeight = 0;
    float fContentCurRowAvailWidth = fContentWidthLimit;
    width_limit_ = fContentCurRowAvailWidth;
    std::array<ContentLayoutItemVector, 3> rgCurLineLayoutItems;
    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() && cur_child_preprocessor_ &&
            cur_child_preprocessor_->GetFormNode() ==
                pLayoutNext->GetFormNode()) {
          if (cur_child_preprocessor_->layout_item_ &&
              cur_child_preprocessor_->layout_item_ != pLayoutNext) {
            pLayoutNext->InsertAfter(
                cur_child_preprocessor_->layout_item_.Get());
          }
          cur_child_preprocessor_->layout_item_ = 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->s_size_.height > fContentCurRowHeight) {
            fContentCurRowHeight = pLayoutNext->s_size_.height;
          }
          fContentCurRowAvailWidth -= pLayoutNext->s_size_.width;
        }
      }

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

    while (cur_child_node_) {
      CXFA_ContentLayoutProcessor* pProcessor = nullptr;
      bool bAddedItemInRow = false;
      fContentCurRowY += InsertPendingItems(GetFormNode());
      switch (cur_child_node_stage_) {
        case Stage::kKeep:
        case Stage::kNone:
          break;
        case Stage::kBreakBefore: {
          if (layout_item_) {
            for (auto& item : array_keep_items_) {
              layout_item_->RemoveChild(item);
              calculated_size.height -= item->s_size_.height;
            }
          }

          if (!bUseBreakControl || !view_layout_processor_) {
            break;
          }

          std::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
              view_layout_processor_->ProcessBreakBefore(cur_child_node_);
          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 &&
                !layout_item_) {
              AddPendingNode(pTrailerNode, true);
            } else {
              auto* pTempProcessor =
                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                      GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
                      nullptr);

              InsertFlowedItem(
                  pTempProcessor, bContainerWidthAutoSize,
                  bContainerHeightAutoSize, container_size.height,
                  eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                  FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, context, false);
            }
          }
          GotoNextContainerNodeSimple();
          bForceEndPage = true;
          bIsManualBreak = true;
          goto SuspendAndCreateNewRow;
        }
        case Stage::kBreakAfter: {
          if (!bUseBreakControl || !view_layout_processor_) {
            break;
          }

          std::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
              view_layout_processor_->ProcessBreakAfter(cur_child_node_);
          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 =
                cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                    GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
                    nullptr);

            InsertFlowedItem(pTempProcessor, bContainerWidthAutoSize,
                             bContainerHeightAutoSize, container_size.height,
                             eFlowStrategy, &uCurHAlignState,
                             rgCurLineLayoutItems, false, FLT_MAX, FLT_MAX,
                             fContentWidthLimit, &fContentCurRowY,
                             &fContentCurRowAvailWidth, &fContentCurRowHeight,
                             &bAddedItemInRow, &bForceEndPage, context, false);
          }
          if (!bCreatePage) {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
              CalculateRowChildPosition(
                  rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize,
                  bContainerWidthAutoSize, &calculated_size.width,
                  &calculated_size.height, &fContentCurRowY,
                  fContentCurRowHeight, fContentWidthLimit, false);
              rgCurLineLayoutItems.front().clear();
              auto* pTempProcessor =
                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                      GetHeap()->GetAllocationHandle(), GetHeap(), pLeaderNode,
                      nullptr);
              InsertFlowedItem(
                  pTempProcessor, bContainerWidthAutoSize,
                  bContainerHeightAutoSize, container_size.height,
                  eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, false,
                  FLT_MAX, FLT_MAX, fContentWidthLimit, &fContentCurRowY,
                  &fContentCurRowAvailWidth, &fContentCurRowHeight,
                  &bAddedItemInRow, &bForceEndPage, context, false);
            }
          } else {
            if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
              AddPendingNode(pLeaderNode, true);
            }
          }

          GotoNextContainerNodeSimple();
          if (bCreatePage) {
            bForceEndPage = true;
            bIsManualBreak = true;
            if (cur_child_node_stage_ == Stage::kDone) {
              bBreakDone = true;
            }
          }
          goto SuspendAndCreateNewRow;
        }
        case Stage::kBookendLeader: {
          if (cur_child_preprocessor_) {
            pProcessor = cur_child_preprocessor_.Get();
            cur_child_preprocessor_ = nullptr;
          } else if (view_layout_processor_) {
            CXFA_Node* pLeaderNode =
                view_layout_processor_->ProcessBookendLeader(cur_child_node_);
            if (pLeaderNode) {
              pProcessor =
                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                      GetHeap()->GetAllocationHandle(), GetHeap(), pLeaderNode,
                      view_layout_processor_);
            }
          }

          if (pProcessor) {
            if (InsertFlowedItem(
                    pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, container_size.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, context,
                    false) != Result::kDone) {
              goto SuspendAndCreateNewRow;
            }
            pProcessor = nullptr;
          }
          break;
        }
        case Stage::kBookendTrailer: {
          if (cur_child_preprocessor_) {
            pProcessor = cur_child_preprocessor_;
            cur_child_preprocessor_.Clear();
          } else if (view_layout_processor_) {
            CXFA_Node* pTrailerNode =
                view_layout_processor_->ProcessBookendTrailer(cur_child_node_);
            if (pTrailerNode) {
              pProcessor =
                  cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                      GetHeap()->GetAllocationHandle(), GetHeap(), pTrailerNode,
                      view_layout_processor_);
            }
          }
          if (pProcessor) {
            if (InsertFlowedItem(
                    pProcessor, bContainerWidthAutoSize,
                    bContainerHeightAutoSize, container_size.height,
                    eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems,
                    bUseBreakControl, fAvailHeight, fRealHeight,
                    fContentWidthLimit, &fContentCurRowY,
                    &fContentCurRowAvailWidth, &fContentCurRowHeight,
                    &bAddedItemInRow, &bForceEndPage, context,
                    false) != Result::kDone) {
              goto SuspendAndCreateNewRow;
            }
            pProcessor = nullptr;
          }
          break;
        }
        case Stage::kContainer: {
          DCHECK(cur_child_node_->IsContainerNode());
          if (cur_child_node_->GetElementType() == XFA_Element::Variables) {
            break;
          }
          if (fContentCurRowY >= fHeightLimit + kXFALayoutPrecision &&
              cur_child_node_->PresenceRequiresSpace()) {
            bForceEndPage = true;
            goto SuspendAndCreateNewRow;
          }
          if (!cur_child_node_->IsContainerNode()) {
            break;
          }

          bool bNewRow = false;
          if (cur_child_preprocessor_) {
            pProcessor = cur_child_preprocessor_;
            cur_child_preprocessor_.Clear();
            bNewRow = true;
          } else {
            pProcessor =
                cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                    GetHeap()->GetAllocationHandle(), GetHeap(),
                    cur_child_node_, view_layout_processor_);
          }

          pProcessor->InsertPendingItems(cur_child_node_);
          Result rs = InsertFlowedItem(
              pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize,
              container_size.height, eFlowStrategy, &uCurHAlignState,
              rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight,
              fContentWidthLimit, &fContentCurRowY, &fContentCurRowAvailWidth,
              &fContentCurRowHeight, &bAddedItemInRow, &bForceEndPage, context,
              bNewRow);
          switch (rs) {
            case Result::kManualBreak:
              bIsManualBreak = true;
              [[fallthrough]];
            case Result::kPageFullBreak:
              bForceEndPage = true;
              [[fallthrough]];
            case Result::kRowFullBreak:
              goto SuspendAndCreateNewRow;
            case Result::kDone:
              fContentCurRowY +=
                  pProcessor->InsertPendingItems(cur_child_node_);
              pProcessor = nullptr;
              break;
          }
          break;
        }
        case Stage::kDone:
          break;
      }
      GotoNextContainerNodeSimple();
      if (bAddedItemInRow && eFlowStrategy == XFA_AttributeValue::Tb) {
        break;
      }
      continue;
    SuspendAndCreateNewRow:
      if (pProcessor) {
        cur_child_preprocessor_ = pProcessor;
        pProcessor = nullptr;
      }
      break;
    }

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

  bool bRetValue =
      cur_child_node_stage_ == Stage::kDone && pending_nodes_.empty();
  if (bBreakDone) {
    bRetValue = false;
  }

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

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

    SetCurrentComponentSize(container_size);
    if (bForceEndPage) {
      used_size_ = 0;
    } else {
      used_size_ += layout_item_->s_size_.height;
    }
  }

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

bool CXFA_ContentLayoutProcessor::CalculateRowChildPosition(
    std::array<ContentLayoutItemVector, 3>& rgCurLineLayoutItems,
    XFA_AttributeValue eFlowStrategy,
    bool bContainerHeightAutoSize,
    bool bContainerWidthAutoSize,
    float* fContentCalculatedWidth,
    float* fContentCalculatedHeight,
    float* fContentCurRowY,
    float fContentCurRowHeight,
    float fContentWidthLimit,
    bool bRootForceTb) {
  std::array<int32_t, 3> nGroupLengths = {};
  std::array<float, 3> fGroupWidths = {};
  int32_t nTotalLength = 0;
  for (int32_t i = 0; i < 3; i++) {
    nGroupLengths[i] = fxcrt::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]->s_size_.width;
      }
    }
  }
  if (!nTotalLength) {
    if (bContainerHeightAutoSize) {
      *fContentCalculatedHeight =
          std::min(*fContentCalculatedHeight, *fContentCurRowY);
    }
    return false;
  }
  if (!layout_item_) {
    layout_item_ = 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]->s_pos_ = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[0][j]->GetFormNode(),
            rgCurLineLayoutItems[0][j]->s_size_);
      } else {
        rgCurLineLayoutItems[0][j]->s_pos_ =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[0][j]
                ->GetFormNode()
                ->PresenceRequiresSpace()) {
          fCurPos += rgCurLineLayoutItems[0][j]->s_size_.width;
        }
      }
      layout_item_->AppendLastChild(rgCurLineLayoutItems[0][j]);
      last_row_width_ = 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]->s_pos_ = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[1][j]->GetFormNode(),
            rgCurLineLayoutItems[1][j]->s_size_);
      } else {
        rgCurLineLayoutItems[1][j]->s_pos_ =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[1][j]
                ->GetFormNode()
                ->PresenceRequiresSpace()) {
          fCurPos += rgCurLineLayoutItems[1][j]->s_size_.width;
        }
      }
      layout_item_->AppendLastChild(rgCurLineLayoutItems[1][j]);
      last_row_width_ = fCurPos;
    }
    fCurPos = fContentWidthLimit - fGroupWidths[2];
    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
      if (bRootForceTb) {
        rgCurLineLayoutItems[2][j]->s_pos_ = CalculatePositionedContainerPos(
            rgCurLineLayoutItems[2][j]->GetFormNode(),
            rgCurLineLayoutItems[2][j]->s_size_);
      } else {
        rgCurLineLayoutItems[2][j]->s_pos_ =
            CFX_PointF(fCurPos, *fContentCurRowY);
        if (rgCurLineLayoutItems[2][j]
                ->GetFormNode()
                ->PresenceRequiresSpace()) {
          fCurPos += rgCurLineLayoutItems[2][j]->s_size_.width;
        }
      }
      layout_item_->AppendLastChild(rgCurLineLayoutItems[2][j]);
      last_row_width_ = 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]->s_size_.width;
      }

      rgCurLineLayoutItems[0][j]->s_pos_ =
          CFX_PointF(fCurPos, *fContentCurRowY);
      layout_item_->AppendLastChild(rgCurLineLayoutItems[0][j]);
      last_row_width_ = 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]->s_size_.width;
      }

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

      rgCurLineLayoutItems[2][j]->s_pos_ =
          CFX_PointF(fCurPos, *fContentCurRowY);
      layout_item_->AppendLastChild(rgCurLineLayoutItems[2][j]);
      last_row_width_ = fCurPos;
    }
  }
  last_row_y_ = *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 (layout_item_) {
    return;
  }

  DCHECK(!cur_child_node_);
  layout_item_ = CreateContentLayoutItem(GetFormNode());
  if (!layout_item_) {
    return;
  }

  CXFA_Document* document = GetFormNode()->GetDocument();
  CXFA_FFNotify* pNotify = document->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* context) {
  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, context,
                                         bRootForceTb);
        case XFA_AttributeValue::Position:
        case XFA_AttributeValue::Row:
        case XFA_AttributeValue::Rl_row:
        default:
          DoLayoutPositionedContainer(context);
          cur_child_node_stage_ = Stage::kDone;
          return Result::kDone;
        case XFA_AttributeValue::Table:
          DoLayoutTableContainer(pLayoutNode);
          cur_child_node_stage_ = Stage::kDone;
          return Result::kDone;
      }
    }
    case XFA_Element::Draw:
    case XFA_Element::Field:
      DoLayoutField();
      cur_child_node_stage_ = Stage::kDone;
      return Result::kDone;
    case XFA_Element::ContentArea:
    default:
      return Result::kDone;
  }
}

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

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

void CXFA_ContentLayoutProcessor::SetCurrentComponentSize(
    const CFX_SizeF& size) {
  layout_item_->s_size_ = 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 = pending_nodes_count_[pTemplate];
  if (iCount >= iMax) {
    return false;
  }

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

void CXFA_ContentLayoutProcessor::UpdatePendingItemLayout(
    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, rg_specified_column_widths_, eLayout);
      break;
    default:
      break;
  }
}

void CXFA_ContentLayoutProcessor::AddTrailerBeforeSplit(
    float fSplitPos,
    CXFA_ContentLayoutItem* pTrailerLayoutItem,
    bool bUseInherited) {
  if (!pTrailerLayoutItem) {
    return;
  }

  float fHeight = pTrailerLayoutItem->s_size_.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)) {
    pTrailerLayoutItem->s_pos_.y = last_row_y_;
    pTrailerLayoutItem->s_pos_.x = last_row_width_;
    layout_item_->s_size_.width += pTrailerLayoutItem->s_size_.width;
    layout_item_->AppendLastChild(pTrailerLayoutItem);
    return;
  }

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

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

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

void CXFA_ContentLayoutProcessor::AddLeaderAfterSplit(
    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->s_size_.height;
  for (CXFA_LayoutItem* pIter = layout_item_->GetFirstChild(); pIter;
       pIter = pIter->GetNextSibling()) {
    CXFA_ContentLayoutItem* pContentItem = pIter->AsContentLayoutItem();
    if (!pContentItem) {
      continue;
    }

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

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

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

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

  if (!layout_item_) {
    layout_item_ = CreateContentLayoutItem(pCurChildNode);
    layout_item_->s_size_.clear();
  }

  while (!pending_nodes_.empty()) {
    auto* pPendingProcessor =
        cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
            GetHeap()->GetAllocationHandle(), GetHeap(), pending_nodes_.front(),
            nullptr);
    pending_nodes_.pop_front();
    pPendingProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
    CXFA_ContentLayoutItem* pPendingLayoutItem = nullptr;
    if (pPendingProcessor->HasLayoutItem()) {
      pPendingLayoutItem = pPendingProcessor->ExtractLayoutItem();
    }
    if (pPendingLayoutItem) {
      AddLeaderAfterSplit(pPendingLayoutItem);
      if (break_pending_) {
        fTotalHeight += pPendingLayoutItem->s_size_.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::array<ContentLayoutItemVector, 3>& rgCurLineLayoutItems,
    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(
      cur_child_node_->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 (view_layout_processor_) {
    CXFA_Node* pOverflowNode =
        view_layout_processor_->QueryOverflow(GetFormNode());
    if (pOverflowNode) {
      layoutContext.overflow_node_ = pOverflowNode;
      layoutContext.overflow_processor_ = this;
      pLayoutContext = &layoutContext;
    }
  }

  Result eRetValue = Result::kDone;
  if (!bNewRow || pProcessor->pre_process_rs_ == Result::kDone) {
    eRetValue = pProcessor->DoLayoutInternal(
        bTakeSpace && bUseBreakControl,
        bUseRealHeight ? fRealHeight - *fContentCurRowY : FLT_MAX,
        bIsTransHeight ? fRealHeight - *fContentCurRowY : FLT_MAX,
        pLayoutContext);
    pProcessor->pre_process_rs_ = eRetValue;
  } else {
    eRetValue = pProcessor->pre_process_rs_;
    pProcessor->pre_process_rs_ = 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;
  CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr;
  bool bIsAddTrailerHeight = false;
  if (view_layout_processor_ &&
      pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
    pFormNode =
        view_layout_processor_->QueryOverflow(pProcessor->GetFormNode());
    if (!pFormNode && pLayoutContext && pLayoutContext->overflow_processor_) {
      pFormNode = pLayoutContext->overflow_node_;
      bUseInherited = true;
    }
    std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
        view_layout_processor_->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 =
              cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
                  GetHeap()->GetAllocationHandle(), GetHeap(),
                  pOverflowTrailerNode, nullptr);
          pOverflowLeaderProcessor->DoLayout(false, FLT_MAX, FLT_MAX);
          pTrailerLayoutItem =
              pOverflowLeaderProcessor->HasLayoutItem()
                  ? pOverflowLeaderProcessor->ExtractLayoutItem()
                  : nullptr;
        }

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

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

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

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

      CXFA_ContentLayoutItem* pChildLayoutItem =
          pProcessor->ExtractLayoutItem();
      if (ExistContainerKeep(pProcessor->GetFormNode(), false) &&
          pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None) {
        if (pChildLayoutItem) {
          array_keep_items_.push_back(pChildLayoutItem);
        }
      } else {
        array_keep_items_.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->use_inherited_) {
        if (pTrailerLayoutItem) {
          pProcessor->AddTrailerBeforeSplit(childSize.height,
                                            pTrailerLayoutItem, false);
        }
        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
          pProcessor->AddPendingNode(pOverflowLeaderNode, false);
        }

        pProcessor->use_inherited_ = false;
      } else {
        if (bIsAddTrailerHeight) {
          childSize.height -= pTrailerLayoutItem->s_size_.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 (view_layout_processor_ && !pProcessor->use_inherited_ &&
        eRetValue != Result::kPageFullBreak) {
      view_layout_processor_->ProcessOverflow(pFormNode, true);
    }
    if (pTrailerLayoutItem && bIsAddTrailerHeight) {
      pProcessor->AddTrailerBeforeSplit(fSplitPos, pTrailerLayoutItem,
                                        bUseInherited);
    } else {
      pProcessor->SplitLayoutItem(fSplitPos);
    }

    if (bUseInherited) {
      pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                       pOverflowTrailerNode, pTrailerLayoutItem,
                                       pFormNode);
      use_inherited_ = true;
    } else {
      CXFA_LayoutItem* firstChild = pProcessor->layout_item_->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->layout_item_->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->view_layout_processor_->GetNextAvailContentHeight(
            childSize.height)) {
      if (view_layout_processor_) {
        if (!pFormNode && pLayoutContext) {
          pFormNode = pLayoutContext->overflow_processor_->GetFormNode();
        }

        view_layout_processor_->ProcessOverflow(pFormNode, true);
      }
      if (bUseInherited) {
        pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
                                         pOverflowTrailerNode,
                                         pTrailerLayoutItem, pFormNode);
        use_inherited_ = 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 (view_layout_processor_) {
      std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
          view_layout_processor_->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->overflow_processor_->GetFormNode();
  }
  if (view_layout_processor_) {
    std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
        view_layout_processor_->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);
    use_inherited_ = true;
  }
  return Result::kPageFullBreak;
}

std::optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleKeep(CXFA_Node* pBreakAfterNode,
                                        CXFA_Node** pCurActionNode) {
  if (keep_break_finish_) {
    return std::nullopt;
  }
  return FindBreakAfterNode(pBreakAfterNode, pCurActionNode);
}

std::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 std::nullopt;
}

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

  CXFA_Node* pBreakBeforeNode = (*pCurActionNode)->GetNextSibling();
  if (!keep_break_finish_) {
    std::optional<Stage> ret =
        FindBreakBeforeNode(pBreakBeforeNode, pCurActionNode);
    if (ret.has_value()) {
      return ret.value();
    }
  }
  if (is_process_keep_) {
    return ProcessKeepNodesForBreakBefore(pCurActionNode, pChildContainer);
  }

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

std::optional<CXFA_ContentLayoutProcessor::Stage>
CXFA_ContentLayoutProcessor::HandleBreakAfter(CXFA_Node* pChildContainer,
                                              CXFA_Node** pCurActionNode) {
  if (*pCurActionNode) {
    CXFA_Node* pBreakAfterNode = (*pCurActionNode)->GetNextSibling();
    return FindBreakAfterNode(pBreakAfterNode, pCurActionNode);
  }

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

std::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 std::nullopt;
  }

  bool bLastKeep = false;
  std::optional<Stage> ret = ProcessKeepNodesForCheckNext(
      pCurActionNode, &pNextChildContainer, &bLastKeep);
  if (ret.has_value()) {
    return ret.value();
  }

  if (!keep_break_finish_ && !bLastKeep) {
    ret = FindBreakBeforeNode(pNextChildContainer->GetFirstChild(),
                              pCurActionNode);
    if (ret.has_value()) {
      return ret.value();
    }
  }
  *pCurActionNode = pNextChildContainer;
  return is_process_keep_ ? Stage::kKeep : Stage::kContainer;
}

std::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 std::nullopt;
}

void CXFA_ContentLayoutProcessor::ProcessKeepNodesEnd() {
  keep_break_finish_ = true;
  keep_head_node_ = nullptr;
  keep_tail_node_ = nullptr;
  is_process_keep_ = false;
}

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

  pSize->height -= used_size_;
  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 (cur_child_node_stage_ == Stage::kDone ||
      eFlowStrategy == XFA_AttributeValue::Tb) {
    return nullptr;
  }

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

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

    float fWidth = pLayout->s_pos_.x + pLayout->s_size_.width;
    float fHeight = pLayout->s_pos_.y + pLayout->s_size_.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;
