// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/cxfa_widgetacc.h"

#include <algorithm>
#include <vector>

#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "fxjs/cfxjse_engine.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_textout.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_localevalue.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_utils.h"

class CXFA_WidgetLayoutData {
 public:
  CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
  virtual ~CXFA_WidgetLayoutData() {}

  float m_fWidgetHeight;
};

namespace {

class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_TextLayoutData() {}
  ~CXFA_TextLayoutData() override {}

  CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
  CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }

  void LoadText(CXFA_WidgetAcc* pAcc) {
    if (m_pTextLayout)
      return;

    m_pTextProvider =
        pdfium::MakeUnique<CXFA_TextProvider>(pAcc, XFA_TEXTPROVIDERTYPE_Text);
    m_pTextLayout = pdfium::MakeUnique<CXFA_TextLayout>(m_pTextProvider.get());
  }

 private:
  std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
  std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
};

class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_ImageLayoutData()
      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}

  ~CXFA_ImageLayoutData() override {}

  bool LoadImageData(CXFA_WidgetAcc* pAcc) {
    if (m_pDIBitmap)
      return true;

    CXFA_ValueData valueData = pAcc->GetFormValueData();
    if (!valueData.HasValidNode())
      return false;

    CXFA_ImageData imageData = valueData.GetImageData();
    if (!imageData.HasValidNode())
      return false;

    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
    pAcc->SetImageImage(XFA_LoadImageData(pFFDoc, &imageData, m_bNamedImage,
                                          m_iImageXDpi, m_iImageYDpi));
    return !!m_pDIBitmap;
  }

  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
  bool m_bNamedImage;
  int32_t m_iImageXDpi;
  int32_t m_iImageYDpi;
};

class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_FieldLayoutData() {}
  ~CXFA_FieldLayoutData() override {}

  bool LoadCaption(CXFA_WidgetAcc* pAcc) {
    if (m_pCapTextLayout)
      return true;
    CXFA_CaptionData captionData = pAcc->GetCaptionData();
    if (!captionData.HasValidNode() ||
        captionData.GetPresence() == XFA_ATTRIBUTEENUM_Hidden) {
      return false;
    }

    m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
        pAcc, XFA_TEXTPROVIDERTYPE_Caption);
    m_pCapTextLayout =
        pdfium::MakeUnique<CXFA_TextLayout>(m_pCapTextProvider.get());
    return true;
  }

  std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
  std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
  std::unique_ptr<CFDE_TextOut> m_pTextOut;
  std::vector<float> m_FieldSplitArray;
};

class CXFA_TextEditData : public CXFA_FieldLayoutData {
 public:
};

class CXFA_ImageEditData : public CXFA_FieldLayoutData {
 public:
  CXFA_ImageEditData()
      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}

  ~CXFA_ImageEditData() override {}

  bool LoadImageData(CXFA_WidgetAcc* pAcc) {
    if (m_pDIBitmap)
      return true;

    CXFA_ValueData valueData = pAcc->GetFormValueData();
    if (!valueData.HasValidNode())
      return false;

    CXFA_ImageData imageData = valueData.GetImageData();
    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
    pAcc->SetImageEditImage(XFA_LoadImageData(pFFDoc, &imageData, m_bNamedImage,
                                              m_iImageXDpi, m_iImageYDpi));
    return !!m_pDIBitmap;
  }

  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
  bool m_bNamedImage;
  int32_t m_iImageXDpi;
  int32_t m_iImageYDpi;
};

}  // namespace

CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
    : CXFA_WidgetData(pNode), m_pDocView(pDocView), m_nRecursionDepth(0) {}

CXFA_WidgetAcc::~CXFA_WidgetAcc() {}

CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
  return m_pNode->GetBindData();
}

bool CXFA_WidgetAcc::ProcessValueChanged() {
  m_pDocView->AddValidateWidget(this);
  m_pDocView->AddCalculateWidgetAcc(this);
  m_pDocView->RunCalculateWidgets();
  m_pDocView->RunValidate();
  return true;
}

void CXFA_WidgetAcc::ResetData() {
  WideString wsValue;
  XFA_Element eUIType = GetUIType();
  switch (eUIType) {
    case XFA_Element::ImageEdit: {
      CXFA_ValueData imageValueData = GetDefaultValueData();
      CXFA_ImageData imageData = imageValueData.GetImageData();
      WideString wsContentType, wsHref;
      if (imageData.HasValidNode()) {
        wsValue = imageData.GetContent();
        wsContentType = imageData.GetContentType();
        wsHref = imageData.GetHref();
      }
      SetImageEdit(wsContentType, wsHref, wsValue);
      break;
    }
    case XFA_Element::ExclGroup: {
      CXFA_Node* pNextChild = m_pNode->GetNodeItem(
          XFA_NODEITEM_FirstChild, XFA_ObjectType::ContainerNode);
      while (pNextChild) {
        CXFA_Node* pChild = pNextChild;
        CXFA_WidgetAcc* pAcc =
            static_cast<CXFA_WidgetAcc*>(pChild->GetWidgetData());
        if (!pAcc)
          continue;

        bool done = false;
        if (wsValue.IsEmpty()) {
          CXFA_ValueData defValueData = pAcc->GetDefaultValueData();
          if (defValueData.HasValidNode()) {
            wsValue = defValueData.GetChildValueContent();
            SetValue(wsValue, XFA_VALUEPICTURE_Raw);
            pAcc->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
            done = true;
          }
        }
        if (!done) {
          CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items, false);
          if (!pItems)
            continue;

          WideString itemText;
          if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
            itemText = pItems->GetChild(1, XFA_Element::Unknown, false)
                           ->JSNode()
                           ->GetContent(false);
          }

          pAcc->SetValue(itemText, XFA_VALUEPICTURE_Raw);
        }
        pNextChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling,
                                         XFA_ObjectType::ContainerNode);
      }
      break;
    }
    case XFA_Element::ChoiceList:
      ClearAllSelections();
    default: {
      CXFA_ValueData defValueData = GetDefaultValueData();
      if (defValueData.HasValidNode())
        wsValue = defValueData.GetChildValueContent();

      SetValue(wsValue, XFA_VALUEPICTURE_Raw);
      break;
    }
  }
}

void CXFA_WidgetAcc::SetImageEdit(const WideString& wsContentType,
                                  const WideString& wsHref,
                                  const WideString& wsData) {
  CXFA_ImageData imageData = GetFormValueData().GetImageData();
  if (imageData.HasValidNode()) {
    imageData.SetContentType(WideString(wsContentType));
    imageData.SetHref(wsHref);
  }

  WideString wsFormatValue(wsData);
  GetFormatDataValue(wsData, wsFormatValue);
  m_pNode->JSNode()->SetContent(wsData, wsFormatValue, true, false, true);

  CXFA_Node* pBind = GetDatasets();
  if (!pBind) {
    imageData.SetTransferEncoding(XFA_ATTRIBUTEENUM_Base64);
    return;
  }
  pBind->JSNode()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
                            false);
  CXFA_Node* pHrefNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
  if (pHrefNode) {
    pHrefNode->JSNode()->SetCData(XFA_Attribute::Value, wsHref, false, false);
  } else {
    CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
    ASSERT(pXMLNode && pXMLNode->GetType() == FX_XMLNODE_Element);
    static_cast<CFX_XMLElement*>(pXMLNode)->SetString(L"href", wsHref);
  }
}

CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup() {
  CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
    return nullptr;
  return static_cast<CXFA_WidgetAcc*>(pExcl->GetWidgetData());
}

CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
  return m_pDocView->GetDoc();
}

IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
  return GetDoc()->GetApp()->GetAppProvider();
}

int32_t CXFA_WidgetAcc::ProcessEvent(int32_t iActivity,
                                     CXFA_EventParam* pEventParam) {
  if (GetElementType() == XFA_Element::Draw)
    return XFA_EVENTERROR_NotExist;

  std::vector<CXFA_Node*> eventArray =
      GetEventByActivity(iActivity, pEventParam->m_bIsFormReady);
  bool first = true;
  int32_t iRet = XFA_EVENTERROR_NotExist;
  for (CXFA_Node* pNode : eventArray) {
    int32_t result = ProcessEvent(CXFA_EventData(pNode), pEventParam);
    if (first || result == XFA_EVENTERROR_Success)
      iRet = result;
    first = false;
  }
  return iRet;
}

int32_t CXFA_WidgetAcc::ProcessEvent(const CXFA_EventData& eventData,
                                     CXFA_EventParam* pEventParam) {
  if (!eventData.HasValidNode())
    return XFA_EVENTERROR_NotExist;

  switch (eventData.GetEventType()) {
    case XFA_Element::Execute:
      break;
    case XFA_Element::Script:
      return ExecuteScript(eventData.GetScriptData(), pEventParam);
    case XFA_Element::SignData:
      break;
    case XFA_Element::Submit:
      return GetDoc()->GetDocEnvironment()->SubmitData(
          GetDoc(), eventData.GetSubmitData());
    default:
      break;
  }
  return XFA_EVENTERROR_NotExist;
}

int32_t CXFA_WidgetAcc::ProcessCalculate() {
  if (GetElementType() == XFA_Element::Draw)
    return XFA_EVENTERROR_NotExist;

  CXFA_CalculateData calcData = GetCalculateData();
  if (!calcData.HasValidNode())
    return XFA_EVENTERROR_NotExist;
  if (GetNode()->IsUserInteractive())
    return XFA_EVENTERROR_Disabled;

  CXFA_EventParam EventParam;
  EventParam.m_eType = XFA_EVENT_Calculate;
  int32_t iRet = ExecuteScript(calcData.GetScriptData(), &EventParam);
  if (iRet != XFA_EVENTERROR_Success)
    return iRet;

  if (GetRawValue() != EventParam.m_wsResult) {
    SetValue(EventParam.m_wsResult, XFA_VALUEPICTURE_Raw);
    UpdateUIDisplay();
  }
  return XFA_EVENTERROR_Success;
}

void CXFA_WidgetAcc::ProcessScriptTestValidate(CXFA_ValidateData validateData,
                                               int32_t iRet,
                                               bool bRetValue,
                                               bool bVersionFlag) {
  if (iRet != XFA_EVENTERROR_Success)
    return;
  if (bRetValue)
    return;

  IXFA_AppProvider* pAppProvider = GetAppProvider();
  if (!pAppProvider)
    return;

  WideString wsTitle = pAppProvider->GetAppTitle();
  WideString wsScriptMsg = validateData.GetScriptMessageText();
  if (validateData.GetScriptTest() == XFA_ATTRIBUTEENUM_Warning) {
    if (GetNode()->IsUserInteractive())
      return;
    if (wsScriptMsg.IsEmpty())
      wsScriptMsg = GetValidateMessage(false, bVersionFlag);

    if (bVersionFlag) {
      pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_OK);
      return;
    }
    if (pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning,
                             XFA_MB_YesNo) == XFA_IDYes) {
      GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false);
    }
    return;
  }

  if (wsScriptMsg.IsEmpty())
    wsScriptMsg = GetValidateMessage(true, bVersionFlag);
  pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
}

int32_t CXFA_WidgetAcc::ProcessFormatTestValidate(
    CXFA_ValidateData validateData,
    bool bVersionFlag) {
  WideString wsRawValue = GetRawValue();
  if (!wsRawValue.IsEmpty()) {
    WideString wsPicture = validateData.GetPicture();
    if (wsPicture.IsEmpty())
      return XFA_EVENTERROR_NotExist;

    IFX_Locale* pLocale = GetLocal();
    if (!pLocale)
      return XFA_EVENTERROR_NotExist;

    CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
    if (!lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale,
                               nullptr)) {
      IXFA_AppProvider* pAppProvider = GetAppProvider();
      if (!pAppProvider)
        return XFA_EVENTERROR_NotExist;

      WideString wsFormatMsg = validateData.GetFormatMessageText();
      WideString wsTitle = pAppProvider->GetAppTitle();
      if (validateData.GetFormatTest() == XFA_ATTRIBUTEENUM_Error) {
        if (wsFormatMsg.IsEmpty())
          wsFormatMsg = GetValidateMessage(true, bVersionFlag);
        pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
        return XFA_EVENTERROR_Success;
      }
      if (GetNode()->IsUserInteractive())
        return XFA_EVENTERROR_NotExist;
      if (wsFormatMsg.IsEmpty())
        wsFormatMsg = GetValidateMessage(false, bVersionFlag);

      if (bVersionFlag) {
        pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
                             XFA_MB_OK);
        return XFA_EVENTERROR_Success;
      }
      if (pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
                               XFA_MB_YesNo) == XFA_IDYes) {
        GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false);
      }
      return XFA_EVENTERROR_Success;
    }
  }
  return XFA_EVENTERROR_NotExist;
}

int32_t CXFA_WidgetAcc::ProcessNullTestValidate(CXFA_ValidateData validateData,
                                                int32_t iFlags,
                                                bool bVersionFlag) {
  WideString wsValue;
  GetValue(wsValue, XFA_VALUEPICTURE_Raw);
  if (!wsValue.IsEmpty())
    return XFA_EVENTERROR_Success;
  if (m_bIsNull && (m_bPreNull == m_bIsNull))
    return XFA_EVENTERROR_Success;

  XFA_ATTRIBUTEENUM eNullTest = validateData.GetNullTest();
  WideString wsNullMsg = validateData.GetNullMessageText();
  if (iFlags & 0x01) {
    int32_t iRet = XFA_EVENTERROR_Success;
    if (eNullTest != XFA_ATTRIBUTEENUM_Disabled)
      iRet = XFA_EVENTERROR_Error;

    if (!wsNullMsg.IsEmpty()) {
      if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
        m_pDocView->m_arrNullTestMsg.push_back(wsNullMsg);
        return XFA_EVENTERROR_Error;
      }
      return XFA_EVENTERROR_Success;
    }
    return iRet;
  }
  if (wsNullMsg.IsEmpty() && bVersionFlag &&
      eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
    return XFA_EVENTERROR_Error;
  }
  IXFA_AppProvider* pAppProvider = GetAppProvider();
  if (!pAppProvider)
    return XFA_EVENTERROR_NotExist;

  WideString wsCaptionName;
  WideString wsTitle = pAppProvider->GetAppTitle();
  switch (eNullTest) {
    case XFA_ATTRIBUTEENUM_Error: {
      if (wsNullMsg.IsEmpty()) {
        wsCaptionName = GetValidateCaptionName(bVersionFlag);
        wsNullMsg =
            WideString::Format(L"%s cannot be blank.", wsCaptionName.c_str());
      }
      pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
      return XFA_EVENTERROR_Error;
    }
    case XFA_ATTRIBUTEENUM_Warning: {
      if (GetNode()->IsUserInteractive())
        return true;

      if (wsNullMsg.IsEmpty()) {
        wsCaptionName = GetValidateCaptionName(bVersionFlag);
        wsNullMsg = WideString::Format(
            L"%s cannot be blank. To ignore validations for %s, click Ignore.",
            wsCaptionName.c_str(), wsCaptionName.c_str());
      }
      if (pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Warning,
                               XFA_MB_YesNo) == XFA_IDYes) {
        GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false);
      }
      return XFA_EVENTERROR_Error;
    }
    case XFA_ATTRIBUTEENUM_Disabled:
    default:
      break;
  }
  return XFA_EVENTERROR_Success;
}

WideString CXFA_WidgetAcc::GetValidateCaptionName(bool bVersionFlag) {
  WideString wsCaptionName;

  if (!bVersionFlag) {
    CXFA_CaptionData captionData = GetCaptionData();
    if (captionData.HasValidNode()) {
      CXFA_ValueData capValue = captionData.GetValueData();
      if (capValue.HasValidNode()) {
        CXFA_TextData captionTextData = capValue.GetTextData();
        if (captionTextData.HasValidNode())
          wsCaptionName = captionTextData.GetContent();
      }
    }
  }
  if (!wsCaptionName.IsEmpty())
    return wsCaptionName;
  return m_pNode->JSNode()->GetCData(XFA_Attribute::Name);
}

WideString CXFA_WidgetAcc::GetValidateMessage(bool bError, bool bVersionFlag) {
  WideString wsCaptionName = GetValidateCaptionName(bVersionFlag);
  if (bVersionFlag)
    return WideString::Format(L"%s validation failed", wsCaptionName.c_str());
  if (bError) {
    return WideString::Format(L"The value you entered for %s is invalid.",
                              wsCaptionName.c_str());
  }
  return WideString::Format(
      L"The value you entered for %s is invalid. To ignore "
      L"validations for %s, click Ignore.",
      wsCaptionName.c_str(), wsCaptionName.c_str());
}

int32_t CXFA_WidgetAcc::ProcessValidate(int32_t iFlags) {
  if (GetElementType() == XFA_Element::Draw)
    return XFA_EVENTERROR_NotExist;

  CXFA_ValidateData validateData = GetValidateData(false);
  if (!validateData.HasValidNode())
    return XFA_EVENTERROR_NotExist;

  bool bInitDoc = validateData.GetNode()->NeedsInitApp();
  bool bStatus = m_pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
  int32_t iFormat = 0;
  int32_t iRet = XFA_EVENTERROR_NotExist;
  CXFA_ScriptData scriptData = validateData.GetScriptData();
  bool bRet = false;
  bool hasBoolResult = (bInitDoc || bStatus) && GetRawValue().IsEmpty();
  if (scriptData.HasValidNode()) {
    CXFA_EventParam eParam;
    eParam.m_eType = XFA_EVENT_Validate;
    eParam.m_pTarget = this;
    std::tie(iRet, bRet) = ExecuteBoolScript(scriptData, &eParam);
  }

  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
  bool bVersionFlag = false;
  if (version < XFA_VERSION_208)
    bVersionFlag = true;

  if (bInitDoc) {
    validateData.GetNode()->ClearFlag(XFA_NodeFlag_NeedsInitApp);
  } else {
    iFormat = ProcessFormatTestValidate(validateData, bVersionFlag);
    if (!bVersionFlag)
      bVersionFlag = GetDoc()->GetXFADoc()->HasFlag(XFA_DOCFLAG_Scripting);

    iRet |= ProcessNullTestValidate(validateData, iFlags, bVersionFlag);
  }

  if (iFormat != XFA_EVENTERROR_Success && hasBoolResult)
    ProcessScriptTestValidate(validateData, iRet, bRet, bVersionFlag);

  return iRet | iFormat;
}

int32_t CXFA_WidgetAcc::ExecuteScript(const CXFA_ScriptData& scriptData,
                                      CXFA_EventParam* pEventParam) {
  bool bRet;
  int32_t iRet;
  std::tie(iRet, bRet) = ExecuteBoolScript(scriptData, pEventParam);
  return iRet;
}

std::pair<int32_t, bool> CXFA_WidgetAcc::ExecuteBoolScript(
    CXFA_ScriptData scriptData,
    CXFA_EventParam* pEventParam) {
  static const uint32_t MAX_RECURSION_DEPTH = 2;
  if (m_nRecursionDepth > MAX_RECURSION_DEPTH)
    return {XFA_EVENTERROR_Success, false};

  ASSERT(pEventParam);
  if (!scriptData.HasValidNode())
    return {XFA_EVENTERROR_NotExist, false};
  if (scriptData.GetRunAt() == XFA_ATTRIBUTEENUM_Server)
    return {XFA_EVENTERROR_Disabled, false};

  WideString wsExpression = scriptData.GetExpression();
  if (wsExpression.IsEmpty())
    return {XFA_EVENTERROR_NotExist, false};

  CXFA_ScriptData::Type eScriptType = scriptData.GetContentType();
  if (eScriptType == CXFA_ScriptData::Type::Unknown)
    return {XFA_EVENTERROR_Success, false};

  CXFA_FFDoc* pDoc = GetDoc();
  CFXJSE_Engine* pContext = pDoc->GetXFADoc()->GetScriptContext();
  pContext->SetEventParam(*pEventParam);
  pContext->SetRunAtType(scriptData.GetRunAt());

  std::vector<CXFA_Node*> refNodes;
  if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
      pEventParam->m_eType == XFA_EVENT_Calculate) {
    pContext->SetNodesOfRunScript(&refNodes);
  }

  auto pTmpRetValue = pdfium::MakeUnique<CFXJSE_Value>(pContext->GetRuntime());
  ++m_nRecursionDepth;
  bool bRet = pContext->RunScript(eScriptType, wsExpression.AsStringView(),
                                  pTmpRetValue.get(), m_pNode);
  --m_nRecursionDepth;
  int32_t iRet = XFA_EVENTERROR_Error;
  if (bRet) {
    iRet = XFA_EVENTERROR_Success;
    if (pEventParam->m_eType == XFA_EVENT_Calculate ||
        pEventParam->m_eType == XFA_EVENT_InitCalculate) {
      if (!pTmpRetValue->IsUndefined()) {
        if (!pTmpRetValue->IsNull())
          pEventParam->m_wsResult = pTmpRetValue->ToWideString();

        iRet = XFA_EVENTERROR_Success;
      } else {
        iRet = XFA_EVENTERROR_Error;
      }
      if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
        if ((iRet == XFA_EVENTERROR_Success) &&
            (GetRawValue() != pEventParam->m_wsResult)) {
          SetValue(pEventParam->m_wsResult, XFA_VALUEPICTURE_Raw);
          m_pDocView->AddValidateWidget(this);
        }
      }
      for (CXFA_Node* pRefNode : refNodes) {
        if (static_cast<CXFA_WidgetAcc*>(pRefNode->GetWidgetData()) == this)
          continue;

        CXFA_CalcData* pGlobalData = pRefNode->JSNode()->GetCalcData();
        if (!pGlobalData) {
          pRefNode->JSNode()->SetCalcData(pdfium::MakeUnique<CXFA_CalcData>());
          pGlobalData = pRefNode->JSNode()->GetCalcData();
        }
        if (!pdfium::ContainsValue(pGlobalData->m_Globals, this))
          pGlobalData->m_Globals.push_back(this);
      }
    }
  }
  pContext->SetNodesOfRunScript(nullptr);

  return {iRet, pTmpRetValue->IsBoolean() ? pTmpRetValue->ToBoolean() : false};
}

CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) {
  CXFA_LayoutItem* pLayout = nullptr;
  if (pWidget)
    pLayout = pWidget->GetNext();
  else
    pLayout = m_pDocView->GetXFALayout()->GetLayoutItem(m_pNode);

  return static_cast<CXFA_FFWidget*>(pLayout);
}

void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFWidget* pExcept) {
  CXFA_FFWidget* pWidget = nullptr;
  while ((pWidget = GetNextWidget(pWidget)) != nullptr) {
    if (pWidget == pExcept || !pWidget->IsLoaded() ||
        (GetUIType() != XFA_Element::CheckButton && pWidget->IsFocused())) {
      continue;
    }
    pWidget->UpdateFWLData();
    pWidget->AddInvalidateRect();
  }
}

void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) {
  CXFA_CaptionData captionData = GetCaptionData();
  if (!captionData.HasValidNode() ||
      captionData.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }

  LoadCaption();
  XFA_Element eUIType = GetUIType();
  int32_t iCapPlacement = captionData.GetPlacementType();
  float fCapReserve = captionData.GetReserve();
  const bool bVert = iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
                     iCapPlacement == XFA_ATTRIBUTEENUM_Bottom;
  const bool bReserveExit = fCapReserve > 0.01;
  CXFA_TextLayout* pCapTextLayout =
      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
          ->m_pCapTextLayout.get();
  if (pCapTextLayout) {
    if (!bVert && eUIType != XFA_Element::Button)
      szCap.width = fCapReserve;

    CFX_SizeF minSize;
    szCap = pCapTextLayout->CalcSize(minSize, szCap);
    if (bReserveExit)
      bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve;
  } else {
    float fFontSize = 10.0f;
    CXFA_FontData fontData = captionData.GetFontData();
    if (fontData.HasValidNode()) {
      fFontSize = fontData.GetFontSize();
    } else {
      CXFA_FontData widgetfontData = GetFontData(false);
      if (widgetfontData.HasValidNode())
        fFontSize = widgetfontData.GetFontSize();
    }

    if (bVert) {
      szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize;
    } else {
      szCap.width = fCapReserve > 0 ? fCapReserve : 0;
      szCap.height = fFontSize;
    }
  }

  CXFA_MarginData captionMarginData = captionData.GetMarginData();
  if (captionMarginData.HasValidNode()) {
    float fLeftInset = captionMarginData.GetLeftInset();
    float fTopInset = captionMarginData.GetTopInset();
    float fRightInset = captionMarginData.GetRightInset();
    float fBottomInset = captionMarginData.GetBottomInset();
    if (bReserveExit) {
      bVert ? (szCap.width += fLeftInset + fRightInset)
            : (szCap.height += fTopInset + fBottomInset);
    } else {
      szCap.width += fLeftInset + fRightInset;
      szCap.height += fTopInset + fBottomInset;
    }
  }
}

bool CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF& size) {
  CFX_SizeF szCap;
  CalcCaptionSize(szCap);
  CFX_RectF rtUIMargin = GetUIMargin();
  size.width += rtUIMargin.left + rtUIMargin.width;
  size.height += rtUIMargin.top + rtUIMargin.height;
  if (szCap.width > 0 && szCap.height > 0) {
    int32_t iCapPlacement = GetCaptionData().GetPlacementType();
    switch (iCapPlacement) {
      case XFA_ATTRIBUTEENUM_Left:
      case XFA_ATTRIBUTEENUM_Right:
      case XFA_ATTRIBUTEENUM_Inline: {
        size.width += szCap.width;
        size.height = std::max(size.height, szCap.height);
      } break;
      case XFA_ATTRIBUTEENUM_Top:
      case XFA_ATTRIBUTEENUM_Bottom: {
        size.height += szCap.height;
        size.width = std::max(size.width, szCap.width);
      }
      default:
        break;
    }
  }
  return CalculateWidgetAutoSize(size);
}

bool CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
  CXFA_MarginData marginData = GetMarginData();
  if (marginData.HasValidNode()) {
    size.width += marginData.GetLeftInset() + marginData.GetRightInset();
    size.height += marginData.GetTopInset() + marginData.GetBottomInset();
  }

  CXFA_ParaData paraData = GetParaData();
  if (paraData.HasValidNode())
    size.width += paraData.GetMarginLeft() + paraData.GetTextIndent();

  pdfium::Optional<float> width = TryWidth();
  if (width) {
    size.width = *width;
  } else {
    pdfium::Optional<float> min = TryMinWidth();
    if (min)
      size.width = std::max(size.width, *min);

    pdfium::Optional<float> max = TryMaxWidth();
    if (max && *max > 0)
      size.width = std::min(size.width, *max);
  }

  pdfium::Optional<float> height = TryHeight();
  if (height) {
    size.height = *height;
  } else {
    pdfium::Optional<float> min = TryMinHeight();
    if (min)
      size.height = std::max(size.height, *min);

    pdfium::Optional<float> max = TryMaxHeight();
    if (max && *max > 0)
      size.height = std::min(size.height, *max);
  }
  return true;
}

void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) {
  float fFontSize = GetFontSize();
  WideString wsText;
  GetValue(wsText, XFA_VALUEPICTURE_Display);
  if (wsText.IsEmpty()) {
    size.height += fFontSize;
    return;
  }

  wchar_t wcEnter = '\n';
  wchar_t wsLast = wsText[wsText.GetLength() - 1];
  if (wsLast == wcEnter)
    wsText = wsText + wcEnter;

  CXFA_FieldLayoutData* layoutData =
      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
  if (!layoutData->m_pTextOut) {
    layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
    CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
    pTextOut->SetFont(GetFDEFont());
    pTextOut->SetFontSize(fFontSize);
    pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
    pTextOut->SetLineSpace(GetLineHeight());

    FDE_TextStyle dwStyles;
    dwStyles.last_line_height_ = true;
    if (GetUIType() == XFA_Element::TextEdit && IsMultiLine())
      dwStyles.line_wrap_ = true;

    pTextOut->SetStyles(dwStyles);
  }
  layoutData->m_pTextOut->CalcLogicSize(wsText, size);
}

bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) {
  if (size.width > 0) {
    CFX_SizeF szOrz = size;
    CFX_SizeF szCap;
    CalcCaptionSize(szCap);
    bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
    int32_t iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
    if (bCapExit) {
      iCapPlacement = GetCaptionData().GetPlacementType();
      switch (iCapPlacement) {
        case XFA_ATTRIBUTEENUM_Left:
        case XFA_ATTRIBUTEENUM_Right:
        case XFA_ATTRIBUTEENUM_Inline: {
          size.width -= szCap.width;
        }
        default:
          break;
      }
    }
    CFX_RectF rtUIMargin = GetUIMargin();
    size.width -= rtUIMargin.left + rtUIMargin.width;
    CXFA_MarginData marginData = GetMarginData();
    if (marginData.HasValidNode())
      size.width -= marginData.GetLeftInset() + marginData.GetRightInset();

    CalculateTextContentSize(size);
    size.height += rtUIMargin.top + rtUIMargin.height;
    if (bCapExit) {
      switch (iCapPlacement) {
        case XFA_ATTRIBUTEENUM_Left:
        case XFA_ATTRIBUTEENUM_Right:
        case XFA_ATTRIBUTEENUM_Inline: {
          size.height = std::max(size.height, szCap.height);
        } break;
        case XFA_ATTRIBUTEENUM_Top:
        case XFA_ATTRIBUTEENUM_Bottom: {
          size.height += szCap.height;
        }
        default:
          break;
      }
    }
    size.width = szOrz.width;
    return CalculateWidgetAutoSize(size);
  }
  CalculateTextContentSize(size);
  return CalculateFieldAutoSize(size);
}

bool CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) {
  float fCheckSize = GetCheckButtonSize();
  size = CFX_SizeF(fCheckSize, fCheckSize);
  return CalculateFieldAutoSize(size);
}

bool CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
  CalcCaptionSize(size);
  return CalculateWidgetAutoSize(size);
}

CFX_SizeF CXFA_WidgetAcc::CalculateImageSize(float img_width,
                                             float img_height,
                                             float dpi_x,
                                             float dpi_y) {
  CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi_x),
                    XFA_UnitPx2Pt(img_height, dpi_y));

  CFX_RectF rtFit;
  pdfium::Optional<float> width = TryWidth();
  if (width) {
    rtFit.width = *width;
    GetWidthWithoutMargin(rtFit.width);
  } else {
    rtFit.width = rtImage.width;
  }

  pdfium::Optional<float> height = TryHeight();
  if (height) {
    rtFit.height = *height;
    GetHeightWithoutMargin(rtFit.height);
  } else {
    rtFit.height = rtImage.height;
  }

  return rtFit.Size();
}

bool CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) {
  if (!GetImageImage())
    LoadImageImage();

  size.clear();
  RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
  if (!pBitmap)
    return CalculateWidgetAutoSize(size);

  int32_t iImageXDpi = 0;
  int32_t iImageYDpi = 0;
  GetImageDpi(iImageXDpi, iImageYDpi);

  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
                            iImageXDpi, iImageYDpi);
  return CalculateWidgetAutoSize(size);
}

bool CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) {
  if (!GetImageEditImage())
    LoadImageEditImage();

  size.clear();
  RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
  if (!pBitmap)
    return CalculateFieldAutoSize(size);

  int32_t iImageXDpi = 0;
  int32_t iImageYDpi = 0;
  GetImageEditDpi(iImageXDpi, iImageYDpi);

  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
                            iImageXDpi, iImageYDpi);
  return CalculateFieldAutoSize(size);
}

bool CXFA_WidgetAcc::LoadImageImage() {
  InitLayoutData();
  return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
      ->LoadImageData(this);
}

bool CXFA_WidgetAcc::LoadImageEditImage() {
  InitLayoutData();
  return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
      ->LoadImageData(this);
}

void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
  CXFA_ImageLayoutData* pData =
      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
  iImageXDpi = pData->m_iImageXDpi;
  iImageYDpi = pData->m_iImageYDpi;
}

void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
  CXFA_ImageEditData* pData =
      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
  iImageXDpi = pData->m_iImageXDpi;
  iImageYDpi = pData->m_iImageYDpi;
}

bool CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF& size) {
  LoadText();
  CXFA_TextLayout* pTextLayout =
      static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
  if (pTextLayout) {
    size.width = pTextLayout->StartLayout(size.width);
    size.height = pTextLayout->GetLayoutHeight();
  }
  return CalculateWidgetAutoSize(size);
}

void CXFA_WidgetAcc::LoadText() {
  InitLayoutData();
  static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(this);
}

float CXFA_WidgetAcc::CalculateWidgetAutoWidth(float fWidthCalc) {
  CXFA_MarginData marginData = GetMarginData();
  if (marginData.HasValidNode())
    fWidthCalc += marginData.GetLeftInset() + marginData.GetRightInset();

  pdfium::Optional<float> min = TryMinWidth();
  if (min)
    fWidthCalc = std::max(fWidthCalc, *min);

  pdfium::Optional<float> max = TryMaxWidth();
  if (max && *max > 0)
    fWidthCalc = std::min(fWidthCalc, *max);

  return fWidthCalc;
}

float CXFA_WidgetAcc::GetWidthWithoutMargin(float fWidthCalc) {
  CXFA_MarginData marginData = GetMarginData();
  if (marginData.HasValidNode())
    fWidthCalc -= marginData.GetLeftInset() + marginData.GetRightInset();
  return fWidthCalc;
}

float CXFA_WidgetAcc::CalculateWidgetAutoHeight(float fHeightCalc) {
  CXFA_MarginData marginData = GetMarginData();
  if (marginData.HasValidNode())
    fHeightCalc += marginData.GetTopInset() + marginData.GetBottomInset();

  pdfium::Optional<float> min = TryMinHeight();
  if (min)
    fHeightCalc = std::max(fHeightCalc, *min);

  pdfium::Optional<float> max = TryMaxHeight();
  if (max && *max > 0)
    fHeightCalc = std::min(fHeightCalc, *max);

  return fHeightCalc;
}

float CXFA_WidgetAcc::GetHeightWithoutMargin(float fHeightCalc) {
  CXFA_MarginData marginData = GetMarginData();
  if (marginData.HasValidNode())
    fHeightCalc -= marginData.GetTopInset() + marginData.GetBottomInset();
  return fHeightCalc;
}

void CXFA_WidgetAcc::StartWidgetLayout(float& fCalcWidth, float& fCalcHeight) {
  InitLayoutData();
  XFA_Element eUIType = GetUIType();
  if (eUIType == XFA_Element::Text) {
    m_pLayoutData->m_fWidgetHeight = TryHeight().value_or(-1);
    StartTextLayout(fCalcWidth, fCalcHeight);
    return;
  }
  if (fCalcWidth > 0 && fCalcHeight > 0)
    return;

  m_pLayoutData->m_fWidgetHeight = -1;
  float fWidth = 0;
  if (fCalcWidth > 0 && fCalcHeight < 0) {
    pdfium::Optional<float> height = TryHeight();
    if (height)
      fCalcHeight = *height;
    else
      CalculateAccWidthAndHeight(eUIType, fCalcWidth, fCalcHeight);

    m_pLayoutData->m_fWidgetHeight = fCalcHeight;
    return;
  }
  if (fCalcWidth < 0 && fCalcHeight < 0) {
    pdfium::Optional<float> height;
    pdfium::Optional<float> width = TryWidth();
    if (width) {
      fWidth = *width;

      height = TryHeight();
      if (height)
        fCalcHeight = *height;
    }
    if (!width || !height)
      CalculateAccWidthAndHeight(eUIType, fWidth, fCalcHeight);

    fCalcWidth = fWidth;
  }
  m_pLayoutData->m_fWidgetHeight = fCalcHeight;
}

void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_Element eUIType,
                                                float& fWidth,
                                                float& fCalcHeight) {
  CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
  switch (eUIType) {
    case XFA_Element::Barcode:
    case XFA_Element::ChoiceList:
    case XFA_Element::Signature:
      CalculateFieldAutoSize(sz);
      break;
    case XFA_Element::ImageEdit:
      CalculateImageEditAutoSize(sz);
      break;
    case XFA_Element::Button:
      CalculatePushButtonAutoSize(sz);
      break;
    case XFA_Element::CheckButton:
      CalculateCheckButtonAutoSize(sz);
      break;
    case XFA_Element::DateTimeEdit:
    case XFA_Element::NumericEdit:
    case XFA_Element::PasswordEdit:
    case XFA_Element::TextEdit:
      CalculateTextEditAutoSize(sz);
      break;
    case XFA_Element::Image:
      CalculateImageAutoSize(sz);
      break;
    case XFA_Element::Arc:
    case XFA_Element::Line:
    case XFA_Element::Rectangle:
    case XFA_Element::Subform:
    case XFA_Element::ExclGroup:
      CalculateWidgetAutoSize(sz);
      break;
    default:
      break;
  }
  fWidth = sz.width;
  m_pLayoutData->m_fWidgetHeight = sz.height;
  fCalcHeight = sz.height;
}

bool CXFA_WidgetAcc::FindSplitPos(int32_t iBlockIndex, float& fCalcHeight) {
  XFA_Element eUIType = GetUIType();
  if (eUIType == XFA_Element::Subform)
    return false;

  if (eUIType != XFA_Element::Text && eUIType != XFA_Element::TextEdit &&
      eUIType != XFA_Element::NumericEdit &&
      eUIType != XFA_Element::PasswordEdit) {
    fCalcHeight = 0;
    return true;
  }

  float fTopInset = 0;
  float fBottomInset = 0;
  if (iBlockIndex == 0) {
    CXFA_MarginData marginData = GetMarginData();
    if (marginData.HasValidNode()) {
      fTopInset = marginData.GetTopInset();
      fBottomInset = marginData.GetBottomInset();
    }

    CFX_RectF rtUIMargin = GetUIMargin();
    fTopInset += rtUIMargin.top;
    fBottomInset += rtUIMargin.width;
  }
  if (eUIType == XFA_Element::Text) {
    float fHeight = fCalcHeight;
    if (iBlockIndex == 0) {
      fCalcHeight = fCalcHeight - fTopInset;
      if (fCalcHeight < 0)
        fCalcHeight = 0;
    }

    CXFA_TextLayout* pTextLayout =
        static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
    fCalcHeight =
        pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
                              m_pLayoutData->m_fWidgetHeight - fTopInset);
    if (fCalcHeight != 0) {
      if (iBlockIndex == 0)
        fCalcHeight = fCalcHeight + fTopInset;
      if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
        return false;
    }
    return true;
  }
  XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
  float fCapReserve = 0;
  if (iBlockIndex == 0) {
    CXFA_CaptionData captionData = GetCaptionData();
    if (captionData.HasValidNode() &&
        captionData.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
      iCapPlacement = (XFA_ATTRIBUTEENUM)captionData.GetPlacementType();
      fCapReserve = captionData.GetReserve();
    }
    if (iCapPlacement == XFA_ATTRIBUTEENUM_Top &&
        fCalcHeight < fCapReserve + fTopInset) {
      fCalcHeight = 0;
      return true;
    }
    if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom &&
        m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
      fCalcHeight = 0;
      return true;
    }
    if (iCapPlacement != XFA_ATTRIBUTEENUM_Top)
      fCapReserve = 0;
  }
  CXFA_FieldLayoutData* pFieldData =
      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
  int32_t iLinesCount = 0;
  float fHeight = m_pLayoutData->m_fWidgetHeight;
  WideString wsText;
  GetValue(wsText, XFA_VALUEPICTURE_Display);
  if (wsText.IsEmpty()) {
    iLinesCount = 1;
  } else {
    if (!pFieldData->m_pTextOut) {
      // TODO(dsinclair): Inline fWidth when the 2nd param of
      // CalculateAccWidthAndHeight isn't a ref-param.
      float fWidth = TryWidth().value_or(0);
      CalculateAccWidthAndHeight(eUIType, fWidth, fHeight);
    }
    iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
  }
  std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
  int32_t iFieldSplitCount = pdfium::CollectionSize<int32_t>(*pFieldArray);
  for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
    iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
    fHeight -= (*pFieldArray)[i + 2];
  }
  if (iLinesCount == 0)
    return false;

  float fLineHeight = GetLineHeight();
  float fFontSize = GetFontSize();
  float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
  float fSpaceAbove = 0;
  float fStartOffset = 0;
  if (fHeight > 0.1f && iBlockIndex == 0) {
    fStartOffset = fTopInset;
    fHeight -= (fTopInset + fBottomInset);
    CXFA_ParaData paraData = GetParaData();
    if (paraData.HasValidNode()) {
      fSpaceAbove = paraData.GetSpaceAbove();
      float fSpaceBelow = paraData.GetSpaceBelow();
      fHeight -= (fSpaceAbove + fSpaceBelow);
      switch (paraData.GetVerticalAlign()) {
        case XFA_ATTRIBUTEENUM_Top:
          fStartOffset += fSpaceAbove;
          break;
        case XFA_ATTRIBUTEENUM_Middle:
          fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
          break;
        case XFA_ATTRIBUTEENUM_Bottom:
          fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
          break;
        default:
          NOTREACHED();
          break;
      }
    }
    if (fStartOffset < 0.1f)
      fStartOffset = 0;
  }
  for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
    fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
    if (fStartOffset < 0.1f)
      fStartOffset = 0;
  }
  if (iFieldSplitCount / 3 == (iBlockIndex + 1))
    (*pFieldArray)[0] = fStartOffset;
  else
    pFieldArray->push_back(fStartOffset);

  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
  bool bCanSplitNoContent = false;
  XFA_ATTRIBUTEENUM eLayoutMode = GetNode()
                                      ->GetNodeItem(XFA_NODEITEM_Parent)
                                      ->JSNode()
                                      ->GetEnum(XFA_Attribute::Layout);
  if ((eLayoutMode == XFA_ATTRIBUTEENUM_Position ||
       eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
       eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
       eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
      version > XFA_VERSION_208) {
    bCanSplitNoContent = true;
  }
  if ((eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
       eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
       eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
      version <= XFA_VERSION_208) {
    if (fStartOffset < fCalcHeight) {
      bCanSplitNoContent = true;
    } else {
      fCalcHeight = 0;
      return true;
    }
  }
  if (bCanSplitNoContent) {
    if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
      fCalcHeight = 0;
      return true;
    }
    if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
      } else {
        pFieldArray->push_back(0);
        pFieldArray->push_back(fCalcHeight);
      }
      return false;
    }
    if (fCalcHeight - fStartOffset < fLineHeight) {
      fCalcHeight = fStartOffset;
      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
      } else {
        pFieldArray->push_back(0);
        pFieldArray->push_back(fCalcHeight);
      }
      return true;
    }
    float fTextNum =
        fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
    int32_t iLineNum =
        (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
    if (iLineNum >= iLinesCount) {
      if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
        if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
          (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLinesCount;
          (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
        } else {
          pFieldArray->push_back((float)iLinesCount);
          pFieldArray->push_back(fCalcHeight);
        }
        return false;
      }
      if (fHeight - fStartOffset - fTextHeight < fFontSize) {
        iLineNum -= 1;
        if (iLineNum == 0) {
          fCalcHeight = 0;
          return true;
        }
      } else {
        iLineNum = (int32_t)(fTextNum / fLineHeight);
      }
    }
    if (iLineNum > 0) {
      float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
        (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLineNum;
        (*pFieldArray)[iBlockIndex * 3 + 2] = fSplitHeight;
      } else {
        pFieldArray->push_back((float)iLineNum);
        pFieldArray->push_back(fSplitHeight);
      }
      if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
        return false;

      fCalcHeight = fSplitHeight;
      return true;
    }
  }
  fCalcHeight = 0;
  return true;
}

void CXFA_WidgetAcc::InitLayoutData() {
  if (m_pLayoutData)
    return;

  switch (GetUIType()) {
    case XFA_Element::Text:
      m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
      return;
    case XFA_Element::TextEdit:
      m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
      return;
    case XFA_Element::Image:
      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
      return;
    case XFA_Element::ImageEdit:
      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
      return;
    default:
      break;
  }
  if (GetElementType() == XFA_Element::Field) {
    m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
    return;
  }
  m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
}

void CXFA_WidgetAcc::StartTextLayout(float& fCalcWidth, float& fCalcHeight) {
  LoadText();
  CXFA_TextLayout* pTextLayout =
      static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
  float fTextHeight = 0;
  if (fCalcWidth > 0 && fCalcHeight > 0) {
    float fWidth = GetWidthWithoutMargin(fCalcWidth);
    pTextLayout->StartLayout(fWidth);
    fTextHeight = fCalcHeight;
    fTextHeight = GetHeightWithoutMargin(fTextHeight);
    pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
    return;
  }
  if (fCalcWidth > 0 && fCalcHeight < 0) {
    float fWidth = GetWidthWithoutMargin(fCalcWidth);
    pTextLayout->StartLayout(fWidth);
  }

  if (fCalcWidth < 0 && fCalcHeight < 0) {
    pdfium::Optional<float> width = TryWidth();
    if (width) {
      pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
      fCalcWidth = *width;
    } else {
      float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
      pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
      fCalcWidth = fMaxWidth;
    }
  }

  if (m_pLayoutData->m_fWidgetHeight < 0) {
    m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
    m_pLayoutData->m_fWidgetHeight =
        CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
  }
  fTextHeight = m_pLayoutData->m_fWidgetHeight;
  fTextHeight = GetHeightWithoutMargin(fTextHeight);
  pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
  fCalcHeight = m_pLayoutData->m_fWidgetHeight;
}

bool CXFA_WidgetAcc::LoadCaption() {
  InitLayoutData();
  return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
      ->LoadCaption(this);
}

CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
  return m_pLayoutData
             ? static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
                   ->m_pCapTextLayout.get()
             : nullptr;
}

CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
  return m_pLayoutData
             ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())
                   ->GetTextLayout()
             : nullptr;
}

RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageImage() {
  return m_pLayoutData
             ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
                   ->m_pDIBitmap
             : nullptr;
}

RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageEditImage() {
  return m_pLayoutData
             ? static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
                   ->m_pDIBitmap
             : nullptr;
}

void CXFA_WidgetAcc::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
  CXFA_ImageLayoutData* pData =
      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
  if (pData->m_pDIBitmap != newImage)
    pData->m_pDIBitmap = newImage;
}

void CXFA_WidgetAcc::SetImageEditImage(
    const RetainPtr<CFX_DIBitmap>& newImage) {
  CXFA_ImageEditData* pData =
      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
  if (pData->m_pDIBitmap != newImage)
    pData->m_pDIBitmap = newImage;
}

RetainPtr<CFGAS_GEFont> CXFA_WidgetAcc::GetFDEFont() {
  WideString wsFontName = L"Courier";
  uint32_t dwFontStyle = 0;
  CXFA_FontData fontData = GetFontData(false);
  if (fontData.HasValidNode()) {
    if (fontData.IsBold())
      dwFontStyle |= FXFONT_BOLD;
    if (fontData.IsItalic())
      dwFontStyle |= FXFONT_ITALIC;

    wsFontName = fontData.GetTypeface();
  }

  auto* pDoc = GetDoc();
  return pDoc->GetApp()->GetXFAFontMgr()->GetFont(
      pDoc, wsFontName.AsStringView(), dwFontStyle);
}

float CXFA_WidgetAcc::GetFontSize() {
  CXFA_FontData fontData = GetFontData(false);
  float fFontSize = fontData.HasValidNode() ? fontData.GetFontSize() : 10.0f;
  return fFontSize < 0.1f ? 10.0f : fFontSize;
}

float CXFA_WidgetAcc::GetLineHeight() {
  float fLineHeight = 0;
  CXFA_ParaData paraData = GetParaData();
  if (paraData.HasValidNode())
    fLineHeight = paraData.GetLineHeight();
  if (fLineHeight < 1)
    fLineHeight = GetFontSize() * 1.2f;
  return fLineHeight;
}

FX_ARGB CXFA_WidgetAcc::GetTextColor() {
  CXFA_FontData fontData = GetFontData(false);
  return fontData.HasValidNode() ? fontData.GetColor() : 0xFF000000;
}
