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

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

#include "xfa/fxfa/app/xfa_ffwidgetacc.h"

#include <algorithm>

#include "xfa/fde/tto/fde_textout.h"
#include "xfa/fde/xml/fde_xml_imp.h"
#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
#include "xfa/fxfa/app/xfa_ffchoicelist.h"
#include "xfa/fxfa/app/xfa_fffield.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/fxfa/include/xfa_ffapp.h"
#include "xfa/fxfa/include/xfa_ffdoc.h"
#include "xfa/fxfa/include/xfa_ffdocview.h"
#include "xfa/fxfa/include/xfa_ffpageview.h"
#include "xfa/fxfa/include/xfa_ffwidget.h"
#include "xfa/fxfa/include/xfa_fontmgr.h"
#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
#include "xfa/fxfa/parser/xfa_localevalue.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_script_imp.h"

static void XFA_FFDeleteCalcData(void* pData) {
  if (pData) {
    delete ((CXFA_CalcData*)pData);
  }
}
static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteCalcData = {
    XFA_FFDeleteCalcData, NULL};
class CXFA_WidgetLayoutData {
 public:
  CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
  virtual ~CXFA_WidgetLayoutData() {}
  virtual void Release() { delete this; }
  FX_FLOAT m_fWidgetHeight;
};
class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_TextLayoutData() : m_pTextLayout(NULL), m_pTextProvider(NULL) {}
  ~CXFA_TextLayoutData() {
    if (m_pTextLayout) {
      delete m_pTextLayout;
    }
    m_pTextLayout = NULL;
    if (m_pTextProvider) {
      delete m_pTextProvider;
    }
    m_pTextProvider = NULL;
  }
  void LoadText(CXFA_WidgetAcc* pAcc) {
    if (m_pTextLayout)
      return;

    m_pTextProvider = new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Text);
    m_pTextLayout = new CXFA_TextLayout(m_pTextProvider);
  }
  CXFA_TextLayout* m_pTextLayout;
  CXFA_TextProvider* m_pTextProvider;
};
class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_ImageLayoutData()
      : m_pDIBitmap(NULL),
        m_bNamedImage(FALSE),
        m_iImageXDpi(0),
        m_iImageYDpi(0) {}

  ~CXFA_ImageLayoutData() {
    if (m_pDIBitmap && !m_bNamedImage) {
      delete m_pDIBitmap;
    }
    m_pDIBitmap = NULL;
  }

  FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
    if (m_pDIBitmap) {
      return TRUE;
    }
    CXFA_Value value = pAcc->GetFormValue();
    if (!value) {
      return FALSE;
    }
    CXFA_Image imageObj = value.GetImage();
    if (!imageObj) {
      return FALSE;
    }
    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
    pAcc->SetImageImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
                                          m_iImageXDpi, m_iImageYDpi));
    return m_pDIBitmap != NULL;
  }

  CFX_DIBitmap* m_pDIBitmap;
  FX_BOOL m_bNamedImage;
  int32_t m_iImageXDpi;
  int32_t m_iImageYDpi;
};
class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
 public:
  CXFA_FieldLayoutData()
      : m_pCapTextLayout(NULL),
        m_pCapTextProvider(NULL),
        m_pTextOut(NULL),
        m_pFieldSplitArray(NULL) {}
  ~CXFA_FieldLayoutData() {
    if (m_pCapTextLayout) {
      delete m_pCapTextLayout;
    }
    m_pCapTextLayout = NULL;
    if (m_pCapTextProvider) {
      delete m_pCapTextProvider;
    }
    m_pCapTextProvider = NULL;
    if (m_pTextOut) {
      m_pTextOut->Release();
    }
    m_pTextOut = NULL;
    if (m_pFieldSplitArray) {
      m_pFieldSplitArray->RemoveAll();
      delete m_pFieldSplitArray;
      m_pFieldSplitArray = NULL;
    }
  }
  FX_BOOL LoadCaption(CXFA_WidgetAcc* pAcc) {
    if (m_pCapTextLayout) {
      return TRUE;
    }
    CXFA_Caption caption = pAcc->GetCaption();
    if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
      m_pCapTextProvider =
          new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Caption);
      m_pCapTextLayout = new CXFA_TextLayout(m_pCapTextProvider);
      return TRUE;
    }
    return FALSE;
  }
  CXFA_TextLayout* m_pCapTextLayout;
  CXFA_TextProvider* m_pCapTextProvider;
  CFDE_TextOut* m_pTextOut;
  CFX_FloatArray* m_pFieldSplitArray;
};
class CXFA_TextEditData : public CXFA_FieldLayoutData {
 public:
};
class CXFA_ImageEditData : public CXFA_FieldLayoutData {
 public:
  CXFA_ImageEditData()
      : m_pDIBitmap(NULL),
        m_bNamedImage(FALSE),
        m_iImageXDpi(0),
        m_iImageYDpi(0) {}

  ~CXFA_ImageEditData() {
    if (m_pDIBitmap && !m_bNamedImage) {
      delete m_pDIBitmap;
    }
    m_pDIBitmap = NULL;
  }
  FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
    if (m_pDIBitmap) {
      return TRUE;
    }
    CXFA_Value value = pAcc->GetFormValue();
    if (!value) {
      return FALSE;
    }
    CXFA_Image imageObj = value.GetImage();
    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
    pAcc->SetImageEditImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
                                              m_iImageXDpi, m_iImageYDpi));
    return m_pDIBitmap != NULL;
  }
  CFX_DIBitmap* m_pDIBitmap;
  FX_BOOL m_bNamedImage;
  int32_t m_iImageXDpi;
  int32_t m_iImageYDpi;
};
CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
    : CXFA_WidgetData(pNode),
      m_pDocView(pDocView),
      m_pLayoutData(NULL),
      m_nRecursionDepth(0) {}
CXFA_WidgetAcc::~CXFA_WidgetAcc() {
  if (m_pLayoutData) {
    m_pLayoutData->Release();
    m_pLayoutData = NULL;
  }
}
FX_BOOL CXFA_WidgetAcc::GetName(CFX_WideString& wsName, int32_t iNameType) {
  if (iNameType == 0) {
    m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
    return !wsName.IsEmpty();
  }
  m_pNode->GetSOMExpression(wsName);
  if (iNameType == 2 && wsName.GetLength() >= 15) {
    CFX_WideStringC wsPre = FX_WSTRC(L"xfa[0].form[0].");
    if (wsPre == CFX_WideStringC(wsName.c_str(), wsPre.GetLength())) {
      wsName.Delete(0, wsPre.GetLength());
    }
  }
  return TRUE;
}
CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
  return m_pNode->GetBindData();
}
FX_BOOL CXFA_WidgetAcc::ProcessValueChanged() {
  m_pDocView->AddValidateWidget(this);
  m_pDocView->AddCalculateWidgetAcc(this);
  m_pDocView->RunCalculateWidgets();
  m_pDocView->RunValidate();
  return TRUE;
}
void CXFA_WidgetAcc::ResetData() {
  CFX_WideString wsValue;
  XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
  switch (eUIType) {
    case XFA_ELEMENT_ImageEdit: {
      CXFA_Value imageValue = GetDefaultValue();
      CXFA_Image image = imageValue.GetImage();
      CFX_WideString wsContentType, wsHref;
      if (image) {
        image.GetContent(wsValue);
        image.GetContentType(wsContentType);
        image.GetHref(wsHref);
      }
      SetImageEdit(wsContentType.AsStringC(), wsHref.AsStringC(),
                   wsValue.AsStringC());
    } 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 = (CXFA_WidgetAcc*)pChild->GetWidgetData();
        if (!pAcc) {
          continue;
        }
        CXFA_Value defValue(NULL);
        if (wsValue.IsEmpty() && (defValue = pAcc->GetDefaultValue())) {
          defValue.GetChildValueContent(wsValue);
          SetValue(wsValue, XFA_VALUEPICTURE_Raw);
          pAcc->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
        } else {
          CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
          if (!pItems) {
            continue;
          }
          CFX_WideString itemText;
          if (pItems->CountChildren(XFA_ELEMENT_UNKNOWN) > 1) {
            itemText = pItems->GetChild(1, XFA_ELEMENT_UNKNOWN)->GetContent();
          }
          pAcc->SetValue(itemText, XFA_VALUEPICTURE_Raw);
        }
        pNextChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling,
                                         XFA_OBJECTTYPE_ContainerNode);
      }
    } break;
    case XFA_ELEMENT_ChoiceList:
      ClearAllSelections();
    default:
      if (CXFA_Value defValue = GetDefaultValue()) {
        defValue.GetChildValueContent(wsValue);
      }
      SetValue(wsValue, XFA_VALUEPICTURE_Raw);
      break;
  }
}
void CXFA_WidgetAcc::SetImageEdit(const CFX_WideStringC& wsContentType,
                                  const CFX_WideStringC& wsHref,
                                  const CFX_WideStringC& wsData) {
  CXFA_Image image = GetFormValue().GetImage();
  if (image) {
    image.SetContentType(wsContentType);
    image.SetHref(wsHref);
  }
  CFX_WideString wsFormatValue(wsData);
  GetFormatDataValue(wsData, wsFormatValue);
  m_pNode->SetContent(wsData, wsFormatValue, TRUE);
  CXFA_Node* pBind = GetDatasets();
  if (!pBind) {
    image.SetTransferEncoding(XFA_ATTRIBUTEENUM_Base64);
    return;
  }
  pBind->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
  CXFA_Node* pHrefNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
  if (pHrefNode) {
    pHrefNode->SetCData(XFA_ATTRIBUTE_Value, wsHref);
  } else {
    CFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
    ASSERT(pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element);
    static_cast<CFDE_XMLElement*>(pXMLNode)
        ->SetString(FX_WSTRC(L"href"), wsHref);
  }
}

CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup() {
  CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
    return NULL;
  }
  return (CXFA_WidgetAcc*)pExcl->GetWidgetData();
}
CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() {
  return m_pDocView;
}
CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
  return (CXFA_FFDoc*)m_pDocView->GetDoc();
}
CXFA_FFApp* CXFA_WidgetAcc::GetApp() {
  return GetDoc()->GetApp();
}
IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
  return GetApp()->GetAppProvider();
}
int32_t CXFA_WidgetAcc::ProcessEvent(int32_t iActivity,
                                     CXFA_EventParam* pEventParam) {
  if (GetClassID() == XFA_ELEMENT_Draw) {
    return XFA_EVENTERROR_NotExist;
  }
  int32_t iRet = XFA_EVENTERROR_NotExist;
  CXFA_NodeArray eventArray;
  int32_t iCounts =
      GetEventByActivity(iActivity, eventArray, pEventParam->m_bIsFormReady);
  for (int32_t i = 0; i < iCounts; i++) {
    CXFA_Event event(eventArray[i]);
    int32_t result = ProcessEvent(event, pEventParam);
    if (i == 0) {
      iRet = result;
    } else if (result == XFA_EVENTERROR_Success) {
      iRet = result;
    }
  }
  return iRet;
}
int32_t CXFA_WidgetAcc::ProcessEvent(CXFA_Event& event,
                                     CXFA_EventParam* pEventParam) {
  if (!event) {
    return XFA_EVENTERROR_NotExist;
  }
  switch (event.GetEventType()) {
    case XFA_ELEMENT_Execute:
      break;
    case XFA_ELEMENT_Script: {
      CXFA_Script script = event.GetScript();
      return ExecuteScript(script, pEventParam);
    } break;
    case XFA_ELEMENT_SignData:
      break;
    case XFA_ELEMENT_Submit: {
      CXFA_Submit submit = event.GetSubmit();
      return GetDoc()->GetDocProvider()->SubmitData(GetDoc(), submit);
    }
    default:
      break;
  }
  return XFA_EVENTERROR_NotExist;
}

int32_t CXFA_WidgetAcc::ProcessCalculate() {
  if (GetClassID() == XFA_ELEMENT_Draw) {
    return XFA_EVENTERROR_NotExist;
  }
  CXFA_Calculate calc = GetCalculate();
  if (!calc) {
    return XFA_EVENTERROR_NotExist;
  }
  if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    return XFA_EVENTERROR_Disabled;
  }
  CXFA_EventParam EventParam;
  EventParam.m_eType = XFA_EVENT_Calculate;
  CXFA_Script script = calc.GetScript();
  int32_t iRet = ExecuteScript(script, &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_Validate validate,
                                               int32_t iRet,
                                               FXJSE_HVALUE pRetValue,
                                               FX_BOOL bVersionFlag) {
  if (iRet == XFA_EVENTERROR_Success && pRetValue) {
    if (FXJSE_Value_IsBoolean(pRetValue) && !FXJSE_Value_ToBoolean(pRetValue)) {
      IXFA_AppProvider* pAppProvider = GetAppProvider();
      if (!pAppProvider) {
        return;
      }
      CFX_WideString wsTitle;
      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
      CFX_WideString wsScriptMsg;
      validate.GetScriptMessageText(wsScriptMsg);
      int32_t eScriptTest = validate.GetScriptTest();
      if (eScriptTest == XFA_ATTRIBUTEENUM_Warning) {
        if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
          return;
        }
        if (wsScriptMsg.IsEmpty()) {
          GetValidateMessage(pAppProvider, wsScriptMsg, FALSE, bVersionFlag);
        }
        if (bVersionFlag) {
          pAppProvider->MsgBox(wsScriptMsg.AsStringC(), wsTitle.AsStringC(),
                               XFA_MBICON_Warning, XFA_MB_OK);
          return;
        }
        if (pAppProvider->MsgBox(wsScriptMsg.AsStringC(), wsTitle.AsStringC(),
                                 XFA_MBICON_Warning,
                                 XFA_MB_YesNo) == XFA_IDYes) {
          GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, false);
        }
      } else {
        if (wsScriptMsg.IsEmpty()) {
          GetValidateMessage(pAppProvider, wsScriptMsg, TRUE, bVersionFlag);
        }
        pAppProvider->MsgBox(wsScriptMsg.AsStringC(), wsTitle.AsStringC(),
                             XFA_MBICON_Error, XFA_MB_OK);
      }
    }
  }
}
int32_t CXFA_WidgetAcc::ProcessFormatTestValidate(CXFA_Validate validate,
                                                  FX_BOOL bVersionFlag) {
  CFX_WideString wsRawValue = GetRawValue();
  if (!wsRawValue.IsEmpty()) {
    CFX_WideString wsPicture;
    validate.GetPicture(wsPicture);
    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)) {
      IXFA_AppProvider* pAppProvider = GetAppProvider();
      if (!pAppProvider) {
        return XFA_EVENTERROR_NotExist;
      }
      CFX_WideString wsFormatMsg;
      validate.GetFormatMessageText(wsFormatMsg);
      CFX_WideString wsTitle;
      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
      int32_t eFormatTest = validate.GetFormatTest();
      if (eFormatTest == XFA_ATTRIBUTEENUM_Error) {
        if (wsFormatMsg.IsEmpty()) {
          GetValidateMessage(pAppProvider, wsFormatMsg, TRUE, bVersionFlag);
        }
        pAppProvider->MsgBox(wsFormatMsg.AsStringC(), wsTitle.AsStringC(),
                             XFA_MBICON_Error, XFA_MB_OK);
        return XFA_EVENTERROR_Success;
      }
      if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
        return XFA_EVENTERROR_NotExist;
      }
      if (wsFormatMsg.IsEmpty()) {
        GetValidateMessage(pAppProvider, wsFormatMsg, FALSE, bVersionFlag);
      }
      if (bVersionFlag) {
        pAppProvider->MsgBox(wsFormatMsg.AsStringC(), wsTitle.AsStringC(),
                             XFA_MBICON_Warning, XFA_MB_OK);
        return XFA_EVENTERROR_Success;
      }
      if (pAppProvider->MsgBox(wsFormatMsg.AsStringC(), wsTitle.AsStringC(),
                               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_Validate validate,
                                                int32_t iFlags,
                                                FX_BOOL bVersionFlag) {
  CFX_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;
  }
  int32_t eNullTest = validate.GetNullTest();
  CFX_WideString wsNullMsg;
  validate.GetNullMessageText(wsNullMsg);
  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.Add(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;
  }
  CFX_WideString wsCaptionName;
  CFX_WideString wsTitle;
  pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
  switch (eNullTest) {
    case XFA_ATTRIBUTEENUM_Error: {
      if (wsNullMsg.IsEmpty()) {
        GetValidateCaptionName(wsCaptionName, bVersionFlag);
        CFX_WideString wsError;
        pAppProvider->LoadString(XFA_IDS_ValidateNullError, wsError);
        wsNullMsg.Format(wsError.c_str(), wsCaptionName.c_str());
      }
      pAppProvider->MsgBox(wsNullMsg.AsStringC(), wsTitle.AsStringC(),
                           XFA_MBICON_Status, XFA_MB_OK);
      return XFA_EVENTERROR_Error;
    }
    case XFA_ATTRIBUTEENUM_Warning: {
      if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
        return TRUE;
      }
      if (wsNullMsg.IsEmpty()) {
        GetValidateCaptionName(wsCaptionName, bVersionFlag);
        CFX_WideString wsWarning;
        pAppProvider->LoadString(XFA_IDS_ValidateNullWarning, wsWarning);
        wsNullMsg.Format(wsWarning.c_str(), wsCaptionName.c_str(),
                         wsCaptionName.c_str());
      }
      if (pAppProvider->MsgBox(wsNullMsg.AsStringC(), wsTitle.AsStringC(),
                               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;
}
void CXFA_WidgetAcc::GetValidateCaptionName(CFX_WideString& wsCaptionName,
                                            FX_BOOL bVersionFlag) {
  if (!bVersionFlag) {
    CXFA_Caption caption = GetCaption();
    if (caption) {
      CXFA_Value capValue = caption.GetValue();
      if (capValue) {
        CXFA_Text capText = capValue.GetText();
        if (capText) {
          capText.GetContent(wsCaptionName);
        }
      }
    }
  }
  if (wsCaptionName.IsEmpty()) {
    GetName(wsCaptionName);
  }
}
void CXFA_WidgetAcc::GetValidateMessage(IXFA_AppProvider* pAppProvider,
                                        CFX_WideString& wsMessage,
                                        FX_BOOL bError,
                                        FX_BOOL bVersionFlag) {
  CFX_WideString wsCaptionName;
  GetValidateCaptionName(wsCaptionName, bVersionFlag);
  CFX_WideString wsError;
  if (bVersionFlag) {
    pAppProvider->LoadString(XFA_IDS_ValidateFailed, wsError);
    wsMessage.Format(wsError.c_str(), wsCaptionName.c_str());
    return;
  }
  if (bError) {
    pAppProvider->LoadString(XFA_IDS_ValidateError, wsError);
    wsMessage.Format(wsError.c_str(), wsCaptionName.c_str());
    return;
  }
  CFX_WideString wsWarning;
  pAppProvider->LoadString(XFA_IDS_ValidateWarning, wsWarning);
  wsMessage.Format(wsWarning.c_str(), wsCaptionName.c_str(),
                   wsCaptionName.c_str());
}
int32_t CXFA_WidgetAcc::ProcessValidate(int32_t iFlags) {
  if (GetClassID() == XFA_ELEMENT_Draw) {
    return XFA_EVENTERROR_NotExist;
  }
  CXFA_Validate validate = GetValidate();
  if (!validate) {
    return XFA_EVENTERROR_NotExist;
  }
  FX_BOOL bInitDoc = validate.GetNode()->HasFlag(XFA_NODEFLAG_NeedsInitApp);
  FX_BOOL bStatus =
      m_pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
  int32_t iFormat = 0;
  FXJSE_HVALUE pRetValue = NULL;
  int32_t iRet = XFA_EVENTERROR_NotExist;
  CXFA_Script script = validate.GetScript();
  if (script) {
    CXFA_EventParam eParam;
    eParam.m_eType = XFA_EVENT_Validate;
    eParam.m_pTarget = this;
    iRet = ExecuteScript(script, &eParam,
                         ((bInitDoc || bStatus) && GetRawValue().IsEmpty())
                             ? nullptr
                             : &pRetValue);
  }
  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
  FX_BOOL bVersionFlag = FALSE;
  if (version < XFA_VERSION_208) {
    bVersionFlag = TRUE;
  }
  if (bInitDoc) {
    validate.GetNode()->ClearFlag(XFA_NODEFLAG_NeedsInitApp);
  } else {
    iFormat = ProcessFormatTestValidate(validate, bVersionFlag);
    if (!bVersionFlag) {
      bVersionFlag = GetDoc()->GetXFADoc()->HasFlag(XFA_DOCFLAG_Scripting);
    }
    iRet |= ProcessNullTestValidate(validate, iFlags, bVersionFlag);
  }
  if (iFormat != XFA_EVENTERROR_Success) {
    ProcessScriptTestValidate(validate, iRet, pRetValue, bVersionFlag);
  }
  if (pRetValue) {
    FXJSE_Value_Release(pRetValue);
  }
  return iRet | iFormat;
}
int32_t CXFA_WidgetAcc::ExecuteScript(CXFA_Script script,
                                      CXFA_EventParam* pEventParam,
                                      FXJSE_HVALUE* pRetValue) {
  static const uint32_t MAX_RECURSION_DEPTH = 2;
  if (m_nRecursionDepth > MAX_RECURSION_DEPTH)
    return XFA_EVENTERROR_Success;
  ASSERT(pEventParam);
  if (!script) {
    return XFA_EVENTERROR_NotExist;
  }
  if (script.GetRunAt() == XFA_ATTRIBUTEENUM_Server) {
    return XFA_EVENTERROR_Disabled;
  }
  CFX_WideString wsExpression;
  script.GetExpression(wsExpression);
  if (wsExpression.IsEmpty()) {
    return XFA_EVENTERROR_NotExist;
  }
  XFA_SCRIPTTYPE eScriptType = script.GetContentType();
  if (eScriptType == XFA_SCRIPTTYPE_Unkown) {
    return XFA_EVENTERROR_Success;
  }
  CXFA_FFDoc* pDoc = GetDoc();
  CXFA_ScriptContext* pContext = pDoc->GetXFADoc()->GetScriptContext();
  pContext->SetEventParam(*pEventParam);
  pContext->SetRunAtType((XFA_ATTRIBUTEENUM)script.GetRunAt());
  CXFA_NodeArray refNodes;
  if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
      pEventParam->m_eType == XFA_EVENT_Calculate) {
    pContext->SetNodesOfRunScript(&refNodes);
  }
  FXJSE_HVALUE hRetValue = FXJSE_Value_Create(pContext->GetRuntime());
  ++m_nRecursionDepth;
  FX_BOOL bRet =
      pContext->RunScript((XFA_SCRIPTLANGTYPE)eScriptType,
                          wsExpression.AsStringC(), hRetValue, 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 (!FXJSE_Value_IsUndefined(hRetValue)) {
        if (!FXJSE_Value_IsNull(hRetValue)) {
          CFX_ByteString bsString;
          FXJSE_Value_ToUTF8String(hRetValue, bsString);
          pEventParam->m_wsResult =
              CFX_WideString::FromUTF8(bsString.AsStringC());
        }
        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);
        }
      }
      int32_t iRefs = refNodes.GetSize();
      for (int32_t r = 0; r < iRefs; r++) {
        CXFA_WidgetAcc* pRefAcc = (CXFA_WidgetAcc*)refNodes[r]->GetWidgetData();
        if (pRefAcc && pRefAcc == this) {
          continue;
        }
        CXFA_Node* pRefNode = refNodes[r];
        CXFA_CalcData* pGlobalData =
            (CXFA_CalcData*)pRefNode->GetUserData(XFA_CalcData);
        if (!pGlobalData) {
          pGlobalData = new CXFA_CalcData;
          pRefNode->SetUserData(XFA_CalcData, pGlobalData,
                                &gs_XFADeleteCalcData);
        }
        if (pGlobalData->m_Globals.Find(this) < 0) {
          pGlobalData->m_Globals.Add(this);
        }
      }
    }
  }
  if (pRetValue) {
    *pRetValue = hRetValue;
  } else {
    FXJSE_Value_Release(hRetValue);
  }
  pContext->SetNodesOfRunScript(NULL);
  return iRet;
}
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 = NULL;
  while ((pWidget = GetNextWidget(pWidget))) {
    if (pWidget == pExcept || !pWidget->IsLoaded() ||
        (GetUIType() != XFA_ELEMENT_CheckButton && pWidget->IsFocused())) {
      continue;
    }
    pWidget->UpdateFWLData();
    pWidget->AddInvalidateRect();
  }
}

void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) {
  CXFA_Caption caption = GetCaption();
  if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }
  LoadCaption();
  XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
  int32_t iCapPlacement = caption.GetPlacementType();
  FX_FLOAT fCapReserve = caption.GetReserve();
  const bool bVert = iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
                     iCapPlacement == XFA_ATTRIBUTEENUM_Bottom;
  const bool bReserveExit = fCapReserve > 0.01;
  CXFA_TextLayout* pCapTextLayout =
      ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout;
  if (pCapTextLayout) {
    if (!bVert && eUIType != XFA_ELEMENT_Button) {
      szCap.x = fCapReserve;
    }
    CFX_SizeF minSize;
    pCapTextLayout->CalcSize(minSize, szCap, szCap);
    if (bReserveExit) {
      bVert ? szCap.y = fCapReserve : szCap.x = fCapReserve;
    }
  } else {
    FX_FLOAT fFontSize = 10.0f;
    if (CXFA_Font font = caption.GetFont()) {
      fFontSize = font.GetFontSize();
    } else if (CXFA_Font widgetfont = GetFont()) {
      fFontSize = widgetfont.GetFontSize();
    }
    if (bVert) {
      szCap.y = fCapReserve > 0 ? fCapReserve : fFontSize;
    } else {
      szCap.x = fCapReserve > 0 ? fCapReserve : 0;
      szCap.y = fFontSize;
    }
  }
  if (CXFA_Margin mgCap = caption.GetMargin()) {
    FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
    mgCap.GetLeftInset(fLeftInset);
    mgCap.GetTopInset(fTopInset);
    mgCap.GetRightInset(fRightInset);
    mgCap.GetBottomInset(fBottomInset);
    if (bReserveExit) {
      bVert ? (szCap.x += fLeftInset + fRightInset)
            : (szCap.y += fTopInset + fBottomInset);
    } else {
      szCap.x += fLeftInset + fRightInset;
      szCap.y += fTopInset + fBottomInset;
    }
  }
}
FX_BOOL CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF& size) {
  CFX_SizeF szCap;
  CalcCaptionSize(szCap);
  CFX_RectF rtUIMargin;
  GetUIMargin(rtUIMargin);
  size.x += rtUIMargin.left + rtUIMargin.width;
  size.y += rtUIMargin.top + rtUIMargin.height;
  if (szCap.x > 0 && szCap.y > 0) {
    int32_t iCapPlacement = GetCaption().GetPlacementType();
    switch (iCapPlacement) {
      case XFA_ATTRIBUTEENUM_Left:
      case XFA_ATTRIBUTEENUM_Right:
      case XFA_ATTRIBUTEENUM_Inline: {
        size.x += szCap.x;
        size.y = std::max(size.y, szCap.y);
      } break;
      case XFA_ATTRIBUTEENUM_Top:
      case XFA_ATTRIBUTEENUM_Bottom: {
        size.y += szCap.y;
        size.x = std::max(size.x, szCap.x);
      }
      default:
        break;
    }
  }
  return CalculateWidgetAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
  CXFA_Margin mgWidget = GetMargin();
  if (mgWidget) {
    FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
    mgWidget.GetLeftInset(fLeftInset);
    mgWidget.GetTopInset(fTopInset);
    mgWidget.GetRightInset(fRightInset);
    mgWidget.GetBottomInset(fBottomInset);
    size.x += fLeftInset + fRightInset;
    size.y += fTopInset + fBottomInset;
  }
  CXFA_Para para = GetPara();
  if (para) {
    size.x += para.GetMarginLeft();
    size.x += para.GetTextIndent();
  }
  FX_FLOAT fVal = 0, fMin = 0, fMax = 0;
  if (GetWidth(fVal)) {
    size.x = fVal;
  } else {
    if (GetMinWidth(fMin)) {
      size.x = std::max(size.x, fMin);
    }
    if (GetMaxWidth(fMax) && fMax > 0) {
      size.x = std::min(size.x, fMax);
    }
  }
  fVal = 0, fMin = 0, fMax = 0;
  if (GetHeight(fVal)) {
    size.y = fVal;
  } else {
    if (GetMinHeight(fMin)) {
      size.y = std::max(size.y, fMin);
    }
    if (GetMaxHeight(fMax) && fMax > 0) {
      size.y = std::min(size.y, fMax);
    }
  }
  return TRUE;
}
void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) {
  FX_FLOAT fFontSize = GetFontSize();
  CFX_WideString wsText;
  GetValue(wsText, XFA_VALUEPICTURE_Display);
  if (wsText.IsEmpty()) {
    size.y += fFontSize;
    return;
  }
  FX_WCHAR wcEnter = '\n';
  FX_WCHAR wsLast = wsText.GetAt(wsText.GetLength() - 1);
  if (wsLast == wcEnter) {
    wsText = wsText + wcEnter;
  }

  CXFA_FieldLayoutData* layoutData =
      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData);
  if (!layoutData->m_pTextOut) {
    layoutData->m_pTextOut = new CFDE_TextOut;
    CFDE_TextOut* pTextOut = layoutData->m_pTextOut;
    pTextOut->SetFont(GetFDEFont());
    pTextOut->SetFontSize(fFontSize);
    pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
    pTextOut->SetLineSpace(GetLineHeight());
    uint32_t dwStyles = FDE_TTOSTYLE_LastLineHeight;
    if (GetUIType() == XFA_ELEMENT_TextEdit && IsMultiLine()) {
      dwStyles |= FDE_TTOSTYLE_LineWrap;
    }
    pTextOut->SetStyles(dwStyles);
  }
  layoutData->m_pTextOut->CalcLogicSize(wsText.c_str(), wsText.GetLength(),
                                        size);
}
FX_BOOL CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) {
  if (size.x > 0) {
    CFX_SizeF szOrz = size;
    CFX_SizeF szCap;
    CalcCaptionSize(szCap);
    FX_BOOL bCapExit = szCap.x > 0.01 && szCap.y > 0.01;
    int32_t iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
    if (bCapExit) {
      iCapPlacement = GetCaption().GetPlacementType();
      switch (iCapPlacement) {
        case XFA_ATTRIBUTEENUM_Left:
        case XFA_ATTRIBUTEENUM_Right:
        case XFA_ATTRIBUTEENUM_Inline: {
          size.x -= szCap.x;
        }
        default:
          break;
      }
    }
    CFX_RectF rtUIMargin;
    GetUIMargin(rtUIMargin);
    size.x -= rtUIMargin.left + rtUIMargin.width;
    CXFA_Margin mgWidget = GetMargin();
    if (mgWidget) {
      FX_FLOAT fLeftInset, fRightInset;
      mgWidget.GetLeftInset(fLeftInset);
      mgWidget.GetRightInset(fRightInset);
      size.x -= fLeftInset + fRightInset;
    }
    CalculateTextContentSize(size);
    size.y += rtUIMargin.top + rtUIMargin.height;
    if (bCapExit) {
      switch (iCapPlacement) {
        case XFA_ATTRIBUTEENUM_Left:
        case XFA_ATTRIBUTEENUM_Right:
        case XFA_ATTRIBUTEENUM_Inline: {
          size.y = std::max(size.y, szCap.y);
        } break;
        case XFA_ATTRIBUTEENUM_Top:
        case XFA_ATTRIBUTEENUM_Bottom: {
          size.y += szCap.y;
        }
        default:
          break;
      }
    }
    size.x = szOrz.x;
    return CalculateWidgetAutoSize(size);
  }
  CalculateTextContentSize(size);
  return CalculateFieldAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) {
  FX_FLOAT fCheckSize = GetCheckButtonSize();
  size.x = size.y = fCheckSize;
  return CalculateFieldAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
  CalcCaptionSize(size);
  return CalculateWidgetAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) {
  if (!GetImageImage()) {
    LoadImageImage();
  }
  size.clear();
  if (CFX_DIBitmap* pBitmap = GetImageImage()) {
    CFX_RectF rtImage, rtFit;
    rtImage.Set(0, 0, 0, 0);
    rtFit.Set(0, 0, 0, 0);
    int32_t iImageXDpi = 0;
    int32_t iImageYDpi = 0;
    GetImageDpi(iImageXDpi, iImageYDpi);
    rtImage.width =
        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
    rtImage.height =
        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
    if (GetWidth(rtFit.width)) {
      GetWidthWithoutMargin(rtFit.width);
    } else {
      rtFit.width = rtImage.width;
    }
    if (GetHeight(rtFit.height)) {
      GetHeightWithoutMargin(rtFit.height);
    } else {
      rtFit.height = rtImage.height;
    }
    size.x = rtFit.width;
    size.y = rtFit.height;
  }
  return CalculateWidgetAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) {
  if (!GetImageEditImage()) {
    LoadImageEditImage();
  }
  size.clear();
  if (CFX_DIBitmap* pBitmap = GetImageEditImage()) {
    CFX_RectF rtImage, rtFit;
    rtImage.Set(0, 0, 0, 0);
    rtFit.Set(0, 0, 0, 0);
    int32_t iImageXDpi = 0;
    int32_t iImageYDpi = 0;
    GetImageEditDpi(iImageXDpi, iImageYDpi);
    rtImage.width =
        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
    rtImage.height =
        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
    if (GetWidth(rtFit.width)) {
      GetWidthWithoutMargin(rtFit.width);
    } else {
      rtFit.width = rtImage.width;
    }
    if (GetHeight(rtFit.height)) {
      GetHeightWithoutMargin(rtFit.height);
    } else {
      rtFit.height = rtImage.height;
    }
    size.x = rtFit.width;
    size.y = rtFit.height;
  }
  return CalculateFieldAutoSize(size);
}
FX_BOOL CXFA_WidgetAcc::LoadImageImage() {
  InitLayoutData();
  return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
}
FX_BOOL CXFA_WidgetAcc::LoadImageEditImage() {
  InitLayoutData();
  return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
}
void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
  iImageXDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageXDpi;
  iImageYDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageYDpi;
}
void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
  iImageXDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageXDpi;
  iImageYDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageYDpi;
}
FX_BOOL CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF& size) {
  LoadText();
  CXFA_TextLayout* pTextLayout =
      ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
  if (pTextLayout) {
    size.x = pTextLayout->StartLayout(size.x);
    size.y = pTextLayout->GetLayoutHeight();
  }
  return CalculateWidgetAutoSize(size);
}
void CXFA_WidgetAcc::LoadText() {
  InitLayoutData();
  ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
}
FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc) {
  CXFA_Margin mgWidget = GetMargin();
  if (mgWidget) {
    FX_FLOAT fLeftInset, fRightInset;
    mgWidget.GetLeftInset(fLeftInset);
    mgWidget.GetRightInset(fRightInset);
    fWidthCalc += fLeftInset + fRightInset;
  }
  FX_FLOAT fMin = 0, fMax = 0;
  if (GetMinWidth(fMin)) {
    fWidthCalc = std::max(fWidthCalc, fMin);
  }
  if (GetMaxWidth(fMax) && fMax > 0) {
    fWidthCalc = std::min(fWidthCalc, fMax);
  }
  return fWidthCalc;
}
FX_FLOAT CXFA_WidgetAcc::GetWidthWithoutMargin(FX_FLOAT fWidthCalc) {
  CXFA_Margin mgWidget = GetMargin();
  if (mgWidget) {
    FX_FLOAT fLeftInset, fRightInset;
    mgWidget.GetLeftInset(fLeftInset);
    mgWidget.GetRightInset(fRightInset);
    fWidthCalc -= fLeftInset + fRightInset;
  }
  return fWidthCalc;
}
FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc) {
  CXFA_Margin mgWidget = GetMargin();
  if (mgWidget) {
    FX_FLOAT fTopInset, fBottomInset;
    mgWidget.GetTopInset(fTopInset);
    mgWidget.GetBottomInset(fBottomInset);
    fHeightCalc += fTopInset + fBottomInset;
  }
  FX_FLOAT fMin = 0, fMax = 0;
  if (GetMinHeight(fMin)) {
    fHeightCalc = std::max(fHeightCalc, fMin);
  }
  if (GetMaxHeight(fMax) && fMax > 0) {
    fHeightCalc = std::min(fHeightCalc, fMax);
  }
  return fHeightCalc;
}
FX_FLOAT CXFA_WidgetAcc::GetHeightWithoutMargin(FX_FLOAT fHeightCalc) {
  CXFA_Margin mgWidget = GetMargin();
  if (mgWidget) {
    FX_FLOAT fTopInset, fBottomInset;
    mgWidget.GetTopInset(fTopInset);
    mgWidget.GetBottomInset(fBottomInset);
    fHeightCalc -= fTopInset + fBottomInset;
  }
  return fHeightCalc;
}
void CXFA_WidgetAcc::StartWidgetLayout(FX_FLOAT& fCalcWidth,
                                       FX_FLOAT& fCalcHeight) {
  InitLayoutData();
  XFA_ELEMENT eUIType = GetUIType();
  if (eUIType == XFA_ELEMENT_Text) {
    m_pLayoutData->m_fWidgetHeight = -1;
    GetHeight(m_pLayoutData->m_fWidgetHeight);
    StartTextLayout(fCalcWidth, fCalcHeight);
    return;
  }
  if (fCalcWidth > 0 && fCalcHeight > 0) {
    return;
  }
  m_pLayoutData->m_fWidgetHeight = -1;
  FX_FLOAT fWidth = 0;
  if (fCalcWidth > 0 && fCalcHeight < 0) {
    if (!GetHeight(fCalcHeight)) {
      CalculateAccWidthAndHeight(eUIType, fCalcWidth, fCalcHeight);
    }
    m_pLayoutData->m_fWidgetHeight = fCalcHeight;
    return;
  }
  if (fCalcWidth < 0 && fCalcHeight < 0) {
    if (!GetWidth(fWidth) || !GetHeight(fCalcHeight)) {
      CalculateAccWidthAndHeight(eUIType, fWidth, fCalcHeight);
    }
    fCalcWidth = fWidth;
  }
  m_pLayoutData->m_fWidgetHeight = fCalcHeight;
}
void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_ELEMENT eUIType,
                                                FX_FLOAT& fWidth,
                                                FX_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.x;
  m_pLayoutData->m_fWidgetHeight = sz.y;
  fCalcHeight = sz.y;
}
FX_BOOL CXFA_WidgetAcc::FindSplitPos(int32_t iBlockIndex,
                                     FX_FLOAT& fCalcHeight) {
  XFA_ELEMENT eUIType = (XFA_ELEMENT)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;
  }
  FX_FLOAT fTopInset = 0;
  FX_FLOAT fBottomInset = 0;
  if (iBlockIndex == 0) {
    CXFA_Margin mgWidget = GetMargin();
    if (mgWidget) {
      mgWidget.GetTopInset(fTopInset);
      mgWidget.GetBottomInset(fBottomInset);
    }
    CFX_RectF rtUIMargin;
    GetUIMargin(rtUIMargin);
    fTopInset += rtUIMargin.top;
    fBottomInset += rtUIMargin.width;
  }
  if (eUIType == XFA_ELEMENT_Text) {
    FX_FLOAT fHeight = fCalcHeight;
    if (iBlockIndex == 0) {
      fCalcHeight = fCalcHeight - fTopInset;
      if (fCalcHeight < 0) {
        fCalcHeight = 0;
      }
    }
    CXFA_TextLayout* pTextLayout =
        ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
    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;
  FX_FLOAT fCapReserve = 0;
  if (iBlockIndex == 0) {
    CXFA_Caption caption = GetCaption();
    if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
      iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
      fCapReserve = caption.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;
    }
  }
  int32_t iLinesCount = 0;
  FX_FLOAT fHeight = m_pLayoutData->m_fWidgetHeight;
  CFX_WideString wsText;
  GetValue(wsText, XFA_VALUEPICTURE_Display);
  if (wsText.IsEmpty()) {
    iLinesCount = 1;
  } else {
    if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
      FX_FLOAT fWidth = 0;
      GetWidth(fWidth);
      CalculateAccWidthAndHeight(eUIType, fWidth, fHeight);
    }
    iLinesCount =
        ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut->GetTotalLines();
  }
  if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray) {
    ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray =
        new CFX_FloatArray;
  }
  CFX_FloatArray* pFieldArray =
      ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray;
  int32_t iFieldSplitCount = pFieldArray->GetSize();
  for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
    iLinesCount -= (int32_t)pFieldArray->GetAt(i + 1);
    fHeight -= pFieldArray->GetAt(i + 2);
  }
  if (iLinesCount == 0) {
    return FALSE;
  }
  FX_FLOAT fLineHeight = GetLineHeight();
  FX_FLOAT fFontSize = GetFontSize();
  FX_FLOAT fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
  FX_FLOAT fSpaceAbove = 0;
  FX_FLOAT fStartOffset = 0;
  if (fHeight > 0.1f && iBlockIndex == 0) {
    fStartOffset = fTopInset;
    fHeight -= (fTopInset + fBottomInset);
    if (CXFA_Para para = GetPara()) {
      fSpaceAbove = para.GetSpaceAbove();
      FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
      fHeight -= (fSpaceAbove + fSpaceBelow);
      switch (para.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;
      }
    }
    if (fStartOffset < 0.1f) {
      fStartOffset = 0;
    }
  }
  for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
    fStartOffset = pFieldArray->GetAt(i * 3) - pFieldArray->GetAt(i * 3 + 2);
    if (fStartOffset < 0.1f) {
      fStartOffset = 0;
    }
  }
  if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
    pFieldArray->SetAt(0, fStartOffset);
  } else {
    pFieldArray->Add(fStartOffset);
  }
  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
  FX_BOOL bCanSplitNoContent = FALSE;
  XFA_ATTRIBUTEENUM eLayoutMode;
  GetNode()
      ->GetNodeItem(XFA_NODEITEM_Parent)
      ->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, TRUE);
  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->SetAt(iBlockIndex * 3 + 1, 0);
        pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
      } else {
        pFieldArray->Add(0);
        pFieldArray->Add(fCalcHeight);
      }
      return FALSE;
    }
    if (fCalcHeight - fStartOffset < fLineHeight) {
      fCalcHeight = fStartOffset;
      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
        pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
        pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
      } else {
        pFieldArray->Add(0);
        pFieldArray->Add(fCalcHeight);
      }
      return TRUE;
    }
    FX_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->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLinesCount);
          pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
        } else {
          pFieldArray->Add((FX_FLOAT)iLinesCount);
          pFieldArray->Add(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) {
      FX_FLOAT fSplitHeight =
          iLineNum * fLineHeight + fCapReserve + fStartOffset;
      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
        pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLineNum);
        pFieldArray->SetAt(iBlockIndex * 3 + 2, fSplitHeight);
      } else {
        pFieldArray->Add((FX_FLOAT)iLineNum);
        pFieldArray->Add(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 = new CXFA_TextLayoutData;
      return;
    case XFA_ELEMENT_TextEdit:
      m_pLayoutData = new CXFA_TextEditData;
      return;
    case XFA_ELEMENT_Image:
      m_pLayoutData = new CXFA_ImageLayoutData;
      return;
    case XFA_ELEMENT_ImageEdit:
      m_pLayoutData = new CXFA_ImageEditData;
      return;
    default:
      break;
  }
  if (GetClassID() == XFA_ELEMENT_Field) {
    m_pLayoutData = new CXFA_FieldLayoutData;
  } else {
    m_pLayoutData = new CXFA_WidgetLayoutData;
  }
}
void CXFA_WidgetAcc::StartTextLayout(FX_FLOAT& fCalcWidth,
                                     FX_FLOAT& fCalcHeight) {
  LoadText();
  CXFA_TextLayout* pTextLayout =
      ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
  FX_FLOAT fTextHeight = 0;
  if (fCalcWidth > 0 && fCalcHeight > 0) {
    FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
    pTextLayout->StartLayout(fWidth);
    fTextHeight = fCalcHeight;
    fTextHeight = GetHeightWithoutMargin(fTextHeight);
    pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
    return;
  }
  if (fCalcWidth > 0 && fCalcHeight < 0) {
    FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
    pTextLayout->StartLayout(fWidth);
  }
  if (fCalcWidth < 0 && fCalcHeight < 0) {
    FX_FLOAT fMaxWidth = -1;
    FX_BOOL bRet = GetWidth(fMaxWidth);
    if (bRet) {
      FX_FLOAT fWidth = GetWidthWithoutMargin(fMaxWidth);
      pTextLayout->StartLayout(fWidth);
    } else {
      FX_FLOAT fWidth = pTextLayout->StartLayout(fMaxWidth);
      fMaxWidth = CalculateWidgetAutoWidth(fWidth);
      fWidth = GetWidthWithoutMargin(fMaxWidth);
      pTextLayout->StartLayout(fWidth);
    }
    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;
}
FX_BOOL CXFA_WidgetAcc::LoadCaption() {
  InitLayoutData();
  return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
}
CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
  return m_pLayoutData
             ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout
             : NULL;
}
CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
  return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout
                       : NULL;
}
CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() {
  return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap
                       : NULL;
}
CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage() {
  return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap
                       : NULL;
}
void CXFA_WidgetAcc::SetImageImage(CFX_DIBitmap* newImage) {
  if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap == newImage) {
    return;
  }
  if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap &&
      !((CXFA_ImageLayoutData*)m_pLayoutData)->m_bNamedImage) {
    delete ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap;
    ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = NULL;
  }
  ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = newImage;
}
void CXFA_WidgetAcc::SetImageEditImage(CFX_DIBitmap* newImage) {
  if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap == newImage) {
    return;
  }
  if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap &&
      !((CXFA_ImageEditData*)m_pLayoutData)->m_bNamedImage) {
    delete ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap;
    ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = NULL;
  }
  ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = newImage;
}
CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() {
  return m_pLayoutData;
}
IFX_Font* CXFA_WidgetAcc::GetFDEFont() {
  CFX_WideStringC wsFontName = FX_WSTRC(L"Courier");
  uint32_t dwFontStyle = 0;
  if (CXFA_Font font = GetFont()) {
    if (font.IsBold()) {
      dwFontStyle |= FX_FONTSTYLE_Bold;
    }
    if (font.IsItalic()) {
      dwFontStyle |= FX_FONTSTYLE_Italic;
    }
    font.GetTypeface(wsFontName);
  }
  CXFA_FFDoc* pDoc = GetDoc();
  return pDoc->GetApp()->GetXFAFontMgr()->GetFont(pDoc, wsFontName,
                                                  dwFontStyle);
}
FX_FLOAT CXFA_WidgetAcc::GetFontSize() {
  FX_FLOAT fFontSize = 10.0f;
  if (CXFA_Font font = GetFont()) {
    fFontSize = font.GetFontSize();
  }
  return fFontSize < 0.1f ? 10.0f : fFontSize;
}
FX_FLOAT CXFA_WidgetAcc::GetLineHeight() {
  FX_FLOAT fLineHeight = 0;
  if (CXFA_Para para = GetPara()) {
    fLineHeight = para.GetLineHeight();
  }
  if (fLineHeight < 1) {
    fLineHeight = GetFontSize() * 1.2f;
  }
  return fLineHeight;
}
FX_ARGB CXFA_WidgetAcc::GetTextColor() {
  if (CXFA_Font font = GetFont()) {
    return font.GetColor();
  }
  return 0xFF000000;
}
CXFA_Node* CXFA_TextProvider::GetTextNode(FX_BOOL& bRichText) {
  bRichText = FALSE;
  if (m_pTextNode) {
    if (m_pTextNode->GetClassID() == XFA_ELEMENT_ExData) {
      CFX_WideString wsContentType;
      m_pTextNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
                                FALSE);
      if (wsContentType == FX_WSTRC(L"text/html")) {
        bRichText = TRUE;
      }
    }
    return m_pTextNode;
  }
  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
    CXFA_Node* pElementNode = m_pWidgetAcc->GetNode();
    CXFA_Node* pValueNode = pElementNode->GetChild(0, XFA_ELEMENT_Value);
    if (!pValueNode) {
      return NULL;
    }
    CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
      CFX_WideString wsContentType;
      pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
      if (wsContentType == FX_WSTRC(L"text/html")) {
        bRichText = TRUE;
      }
    }
    return pChildNode;
  } else if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
    CXFA_Node* pBind = m_pWidgetAcc->GetDatasets();
    CFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
    ASSERT(pXMLNode);
    for (CFDE_XMLNode* pXMLChild =
             pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
         pXMLChild;
         pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
        CFDE_XMLElement* pElement = static_cast<CFDE_XMLElement*>(pXMLChild);
        if (XFA_RecognizeRichText(pElement)) {
          bRichText = TRUE;
        }
      }
    }
    return pBind;
  } else if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
    CXFA_Node* pCaptionNode =
        m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
    if (pCaptionNode == NULL) {
      return NULL;
    }
    CXFA_Node* pValueNode = pCaptionNode->GetChild(0, XFA_ELEMENT_Value);
    if (pValueNode == NULL) {
      return NULL;
    }
    CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
      CFX_WideString wsContentType;
      pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
      if (wsContentType == FX_WSTRC(L"text/html")) {
        bRichText = TRUE;
      }
    }
    return pChildNode;
  }
  CXFA_Node* pItemNode =
      m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Items);
  if (pItemNode == NULL) {
    return NULL;
  }
  CXFA_Node* pNode = pItemNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pNode) {
    CFX_WideStringC wsName;
    pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
    if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover &&
        wsName == FX_WSTRC(L"rollover")) {
      return pNode;
    }
    if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == FX_WSTRC(L"down")) {
      return pNode;
    }
    pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return NULL;
}
CXFA_Para CXFA_TextProvider::GetParaNode() {
  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
    return m_pWidgetAcc->GetPara();
  }
  CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
  return CXFA_Para(pNode->GetChild(0, XFA_ELEMENT_Para));
}
CXFA_Font CXFA_TextProvider::GetFontNode() {
  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
    return m_pWidgetAcc->GetFont();
  }
  CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
  pNode = pNode->GetChild(0, XFA_ELEMENT_Font);
  if (pNode) {
    return CXFA_Font(pNode);
  }
  return m_pWidgetAcc->GetFont();
}
FX_BOOL CXFA_TextProvider::IsCheckButtonAndAutoWidth() {
  XFA_ELEMENT eType = m_pWidgetAcc->GetUIType();
  if (eType == XFA_ELEMENT_CheckButton) {
    FX_FLOAT fWidth = 0;
    return !m_pWidgetAcc->GetWidth(fWidth);
  }
  return FALSE;
}
FX_BOOL CXFA_TextProvider::GetEmbbedObj(FX_BOOL bURI,
                                        FX_BOOL bRaw,
                                        const CFX_WideString& wsAttr,
                                        CFX_WideString& wsValue) {
  if (m_eType != XFA_TEXTPROVIDERTYPE_Text) {
    return FALSE;
  }
  if (bURI) {
    CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode();
    CXFA_Node* pParent = pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent);
    CXFA_Document* pDocument = pWidgetNode->GetDocument();
    CXFA_Node* pIDNode = NULL;
    CXFA_WidgetAcc* pEmbAcc = NULL;
    if (pParent) {
      pIDNode = pDocument->GetNodeByID(pParent, wsAttr.AsStringC());
    }
    if (!pIDNode) {
      pIDNode = pDocument->GetNodeByID(
          ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Form)),
          wsAttr.AsStringC());
    }
    if (pIDNode) {
      pEmbAcc = (CXFA_WidgetAcc*)pIDNode->GetWidgetData();
    }
    if (pEmbAcc) {
      pEmbAcc->GetValue(wsValue, XFA_VALUEPICTURE_Display);
      return TRUE;
    }
  }
  return FALSE;
}
