Home | History | Annotate | Download | only in app
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include <algorithm>
      8 
      9 #include "xfa/src/foxitlib.h"
     10 #include "xfa/src/fxfa/src/common/xfa_common.h"
     11 #include "xfa_ffwidget.h"
     12 #include "xfa_ffdoc.h"
     13 #include "xfa_ffdocview.h"
     14 #include "xfa_ffpageview.h"
     15 #include "xfa_ffapp.h"
     16 #include "xfa_textlayout.h"
     17 #include "xfa_fwladapter.h"
     18 #include "xfa_fffield.h"
     19 #include "xfa_ffchoicelist.h"
     20 #include "xfa_ffcheckbutton.h"
     21 #include "xfa_ffwidgetacc.h"
     22 #include "xfa_fontmgr.h"
     23 static void XFA_FFDeleteCalcData(void* pData) {
     24   if (pData) {
     25     delete ((CXFA_CalcData*)pData);
     26   }
     27 }
     28 static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteCalcData = {
     29     XFA_FFDeleteCalcData, NULL};
     30 class CXFA_WidgetLayoutData {
     31  public:
     32   CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
     33   virtual ~CXFA_WidgetLayoutData() {}
     34   virtual void Release() { delete this; }
     35   FX_FLOAT m_fWidgetHeight;
     36 };
     37 class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
     38  public:
     39   CXFA_TextLayoutData() : m_pTextLayout(NULL), m_pTextProvider(NULL) {}
     40   ~CXFA_TextLayoutData() {
     41     if (m_pTextLayout) {
     42       delete m_pTextLayout;
     43     }
     44     m_pTextLayout = NULL;
     45     if (m_pTextProvider) {
     46       delete m_pTextProvider;
     47     }
     48     m_pTextProvider = NULL;
     49   }
     50   void LoadText(CXFA_WidgetAcc* pAcc) {
     51     if (m_pTextLayout)
     52       return;
     53 
     54     m_pTextProvider = new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Text);
     55     m_pTextLayout = new CXFA_TextLayout(m_pTextProvider);
     56   }
     57   CXFA_TextLayout* m_pTextLayout;
     58   CXFA_TextProvider* m_pTextProvider;
     59 };
     60 class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
     61  public:
     62   CXFA_ImageLayoutData()
     63       : m_pDIBitmap(NULL),
     64         m_bNamedImage(FALSE),
     65         m_iImageXDpi(0),
     66         m_iImageYDpi(0) {}
     67 
     68   ~CXFA_ImageLayoutData() {
     69     if (m_pDIBitmap && !m_bNamedImage) {
     70       delete m_pDIBitmap;
     71     }
     72     m_pDIBitmap = NULL;
     73   }
     74 
     75   FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
     76     if (m_pDIBitmap) {
     77       return TRUE;
     78     }
     79     CXFA_Value value = pAcc->GetFormValue();
     80     if (!value) {
     81       return FALSE;
     82     }
     83     CXFA_Image imageObj = value.GetImage();
     84     if (!imageObj) {
     85       return FALSE;
     86     }
     87     CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
     88     pAcc->SetImageImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
     89                                           m_iImageXDpi, m_iImageYDpi));
     90     return m_pDIBitmap != NULL;
     91   }
     92 
     93   CFX_DIBitmap* m_pDIBitmap;
     94   FX_BOOL m_bNamedImage;
     95   int32_t m_iImageXDpi;
     96   int32_t m_iImageYDpi;
     97 };
     98 class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
     99  public:
    100   CXFA_FieldLayoutData()
    101       : m_pCapTextLayout(NULL),
    102         m_pCapTextProvider(NULL),
    103         m_pTextOut(NULL),
    104         m_pFieldSplitArray(NULL) {}
    105   ~CXFA_FieldLayoutData() {
    106     if (m_pCapTextLayout) {
    107       delete m_pCapTextLayout;
    108     }
    109     m_pCapTextLayout = NULL;
    110     if (m_pCapTextProvider) {
    111       delete m_pCapTextProvider;
    112     }
    113     m_pCapTextProvider = NULL;
    114     if (m_pTextOut) {
    115       m_pTextOut->Release();
    116     }
    117     m_pTextOut = NULL;
    118     if (m_pFieldSplitArray) {
    119       m_pFieldSplitArray->RemoveAll();
    120       delete m_pFieldSplitArray;
    121       m_pFieldSplitArray = NULL;
    122     }
    123   }
    124   FX_BOOL LoadCaption(CXFA_WidgetAcc* pAcc) {
    125     if (m_pCapTextLayout) {
    126       return TRUE;
    127     }
    128     CXFA_Caption caption = pAcc->GetCaption();
    129     if (caption.IsExistInXML() &&
    130         caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
    131       m_pCapTextProvider =
    132           new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Caption);
    133       m_pCapTextLayout = new CXFA_TextLayout(m_pCapTextProvider);
    134       return TRUE;
    135     }
    136     return FALSE;
    137   }
    138   CXFA_TextLayout* m_pCapTextLayout;
    139   CXFA_TextProvider* m_pCapTextProvider;
    140   IFDE_TextOut* m_pTextOut;
    141   CFX_FloatArray* m_pFieldSplitArray;
    142 };
    143 class CXFA_TextEditData : public CXFA_FieldLayoutData {
    144  public:
    145 };
    146 class CXFA_ImageEditData : public CXFA_FieldLayoutData {
    147  public:
    148   CXFA_ImageEditData()
    149       : m_pDIBitmap(NULL),
    150         m_bNamedImage(FALSE),
    151         m_iImageXDpi(0),
    152         m_iImageYDpi(0) {}
    153 
    154   ~CXFA_ImageEditData() {
    155     if (m_pDIBitmap && !m_bNamedImage) {
    156       delete m_pDIBitmap;
    157     }
    158     m_pDIBitmap = NULL;
    159   }
    160   FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
    161     if (m_pDIBitmap) {
    162       return TRUE;
    163     }
    164     CXFA_Value value = pAcc->GetFormValue();
    165     if (!value) {
    166       return FALSE;
    167     }
    168     CXFA_Image imageObj = value.GetImage();
    169     CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
    170     pAcc->SetImageEditImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
    171                                               m_iImageXDpi, m_iImageYDpi));
    172     return m_pDIBitmap != NULL;
    173   }
    174   CFX_DIBitmap* m_pDIBitmap;
    175   FX_BOOL m_bNamedImage;
    176   int32_t m_iImageXDpi;
    177   int32_t m_iImageYDpi;
    178 };
    179 CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
    180     : CXFA_WidgetData(pNode),
    181       m_pDocView(pDocView),
    182       m_pLayoutData(NULL),
    183       m_nRecursionDepth(0) {}
    184 CXFA_WidgetAcc::~CXFA_WidgetAcc() {
    185   if (m_pLayoutData) {
    186     m_pLayoutData->Release();
    187     m_pLayoutData = NULL;
    188   }
    189 }
    190 FX_BOOL CXFA_WidgetAcc::GetName(CFX_WideString& wsName, int32_t iNameType) {
    191   if (iNameType == 0) {
    192     m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
    193     return !wsName.IsEmpty();
    194   }
    195   m_pNode->GetSOMExpression(wsName);
    196   if (iNameType == 2 && wsName.GetLength() >= 15) {
    197     CFX_WideStringC wsPre = FX_WSTRC(L"xfa[0].form[0].");
    198     if (wsPre == CFX_WideStringC(wsName, wsPre.GetLength())) {
    199       wsName.Delete(0, wsPre.GetLength());
    200     }
    201   }
    202   return TRUE;
    203 }
    204 CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
    205   return m_pNode->GetBindData();
    206 }
    207 FX_BOOL CXFA_WidgetAcc::ProcessValueChanged() {
    208   m_pDocView->AddValidateWidget(this);
    209   m_pDocView->AddCalculateWidgetAcc(this);
    210   m_pDocView->RunCalculateWidgets();
    211   m_pDocView->RunValidate();
    212   return TRUE;
    213 }
    214 void CXFA_WidgetAcc::ResetData() {
    215   CFX_WideString wsValue;
    216   XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
    217   switch (eUIType) {
    218     case XFA_ELEMENT_ImageEdit: {
    219       CXFA_Value imageValue = GetDefaultValue();
    220       CXFA_Image image = imageValue.GetImage();
    221       CFX_WideString wsContentType, wsHref;
    222       if (image) {
    223         image.GetContent(wsValue);
    224         image.GetContentType(wsContentType);
    225         image.GetHref(wsHref);
    226       }
    227       SetImageEdit(wsContentType, wsHref, wsValue);
    228     } break;
    229     case XFA_ELEMENT_ExclGroup: {
    230       CXFA_Node* pNextChild = m_pNode->GetNodeItem(
    231           XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
    232       while (pNextChild) {
    233         CXFA_Node* pChild = pNextChild;
    234         CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pChild->GetWidgetData();
    235         if (!pAcc) {
    236           continue;
    237         }
    238         CXFA_Value defValue(NULL);
    239         if (wsValue.IsEmpty() && (defValue = pAcc->GetDefaultValue())) {
    240           defValue.GetChildValueContent(wsValue);
    241           this->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
    242           pAcc->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
    243         } else {
    244           CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
    245           if (!pItems) {
    246             continue;
    247           }
    248           CFX_WideString itemText;
    249           if (pItems->CountChildren(XFA_ELEMENT_UNKNOWN) > 1) {
    250             itemText = pItems->GetChild(1, XFA_ELEMENT_UNKNOWN)->GetContent();
    251           }
    252           pAcc->SetValue(itemText, XFA_VALUEPICTURE_Raw);
    253         }
    254         pNextChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling,
    255                                          XFA_OBJECTTYPE_ContainerNode);
    256       }
    257     } break;
    258     case XFA_ELEMENT_ChoiceList:
    259       ClearAllSelections();
    260     default:
    261       if (CXFA_Value defValue = GetDefaultValue()) {
    262         defValue.GetChildValueContent(wsValue);
    263       }
    264       SetValue(wsValue, XFA_VALUEPICTURE_Raw);
    265       break;
    266   }
    267 }
    268 void CXFA_WidgetAcc::SetImageEdit(const CFX_WideStringC& wsContentType,
    269                                   const CFX_WideStringC& wsHref,
    270                                   const CFX_WideStringC& wsData) {
    271   CXFA_Image image = GetFormValue().GetImage();
    272   if (image) {
    273     image.SetContentType(wsContentType);
    274     image.SetHref(wsHref);
    275   }
    276   CFX_WideString wsFormatValue(wsData);
    277   this->GetFormatDataValue(wsData, wsFormatValue);
    278   m_pNode->SetContent(wsData, wsFormatValue, TRUE);
    279   CXFA_Node* pBind = GetDatasets();
    280   if (!pBind) {
    281     image.SetTransferEncoding(XFA_ATTRIBUTEENUM_Base64);
    282     return;
    283   }
    284   pBind->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
    285   CXFA_Node* pHrefNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
    286   if (pHrefNode) {
    287     pHrefNode->SetCData(XFA_ATTRIBUTE_Value, wsHref);
    288   } else {
    289     IFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
    290     FXSYS_assert(pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element);
    291     ((IFDE_XMLElement*)pXMLNode)->SetString(FX_WSTRC(L"href"), wsHref);
    292   }
    293 }
    294 
    295 CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup() {
    296   CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
    297   if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
    298     return NULL;
    299   }
    300   return (CXFA_WidgetAcc*)pExcl->GetWidgetData();
    301 }
    302 CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() {
    303   return m_pDocView;
    304 }
    305 CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
    306   return (CXFA_FFDoc*)m_pDocView->GetDoc();
    307 }
    308 CXFA_FFApp* CXFA_WidgetAcc::GetApp() {
    309   return GetDoc()->GetApp();
    310 }
    311 IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
    312   return GetApp()->GetAppProvider();
    313 }
    314 int32_t CXFA_WidgetAcc::ProcessEvent(int32_t iActivity,
    315                                      CXFA_EventParam* pEventParam) {
    316   if (this->GetClassID() == XFA_ELEMENT_Draw) {
    317     return XFA_EVENTERROR_NotExist;
    318   }
    319   int32_t iRet = XFA_EVENTERROR_NotExist;
    320   CXFA_NodeArray eventArray;
    321   int32_t iCounts =
    322       GetEventByActivity(iActivity, eventArray, pEventParam->m_bIsFormReady);
    323   for (int32_t i = 0; i < iCounts; i++) {
    324     CXFA_Event event(eventArray[i]);
    325     int32_t result = ProcessEvent(event, pEventParam);
    326     if (i == 0) {
    327       iRet = result;
    328     } else if (result == XFA_EVENTERROR_Sucess) {
    329       iRet = result;
    330     }
    331   }
    332   return iRet;
    333 }
    334 int32_t CXFA_WidgetAcc::ProcessEvent(CXFA_Event& event,
    335                                      CXFA_EventParam* pEventParam) {
    336   if (!event) {
    337     return XFA_EVENTERROR_NotExist;
    338   }
    339   switch (event.GetEventType()) {
    340     case XFA_ELEMENT_Execute:
    341       break;
    342     case XFA_ELEMENT_Script: {
    343       CXFA_Script script = event.GetScript();
    344       return ExecuteScript(script, pEventParam);
    345     } break;
    346     case XFA_ELEMENT_SignData:
    347       break;
    348     case XFA_ELEMENT_Submit: {
    349       CXFA_Submit submit = event.GetSubmit();
    350       return GetDoc()->GetDocProvider()->SubmitData(GetDoc(), submit);
    351     }
    352     default:
    353       break;
    354   }
    355   return XFA_EVENTERROR_NotExist;
    356 }
    357 int32_t CXFA_WidgetAcc::ProcessCalculate() {
    358   if (this->GetClassID() == XFA_ELEMENT_Draw) {
    359     return XFA_EVENTERROR_NotExist;
    360   }
    361   CXFA_Calculate calc = this->GetCalculate();
    362   if (!calc) {
    363     return XFA_EVENTERROR_NotExist;
    364   }
    365   if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    366     return XFA_EVENTERROR_Disabled;
    367   }
    368   CXFA_EventParam EventParam;
    369   EventParam.m_eType = XFA_EVENT_Calculate;
    370   CXFA_Script script = calc.GetScript();
    371   int32_t iRet = ExecuteScript(script, &EventParam);
    372   if (iRet == XFA_EVENTERROR_Sucess) {
    373     if (GetRawValue() != EventParam.m_wsResult) {
    374       FX_BOOL bNotify = GetDoc()->GetDocType() == XFA_DOCTYPE_Static;
    375       SetValue(EventParam.m_wsResult, XFA_VALUEPICTURE_Raw);
    376       UpdateUIDisplay();
    377       if (bNotify) {
    378         NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);
    379       }
    380       iRet = XFA_EVENTERROR_Sucess;
    381     }
    382   }
    383   return iRet;
    384 }
    385 void CXFA_WidgetAcc::ProcessScriptTestValidate(CXFA_Validate validate,
    386                                                int32_t iRet,
    387                                                FXJSE_HVALUE pRetValue,
    388                                                FX_BOOL bVersionFlag) {
    389   if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
    390     if (FXJSE_Value_IsBoolean(pRetValue) && !FXJSE_Value_ToBoolean(pRetValue)) {
    391       IXFA_AppProvider* pAppProvider = GetAppProvider();
    392       if (!pAppProvider) {
    393         return;
    394       }
    395       CFX_WideString wsTitle;
    396       pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
    397       CFX_WideString wsScriptMsg;
    398       validate.GetScriptMessageText(wsScriptMsg);
    399       int32_t eScriptTest = validate.GetScriptTest();
    400       if (eScriptTest == XFA_ATTRIBUTEENUM_Warning) {
    401         if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    402           return;
    403         }
    404         if (wsScriptMsg.IsEmpty()) {
    405           GetValidateMessage(pAppProvider, wsScriptMsg, FALSE, bVersionFlag);
    406         }
    407         if (bVersionFlag) {
    408           pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning,
    409                                XFA_MB_OK);
    410           return;
    411         }
    412         if (pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning,
    413                                  XFA_MB_YesNo) == XFA_IDYes) {
    414           this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
    415         }
    416       } else {
    417         if (wsScriptMsg.IsEmpty()) {
    418           GetValidateMessage(pAppProvider, wsScriptMsg, TRUE, bVersionFlag);
    419         }
    420         pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
    421       }
    422     }
    423   }
    424 }
    425 int32_t CXFA_WidgetAcc::ProcessFormatTestValidate(CXFA_Validate validate,
    426                                                   FX_BOOL bVersionFlag) {
    427   CFX_WideString wsRawValue = GetRawValue();
    428   if (!wsRawValue.IsEmpty()) {
    429     CFX_WideString wsPicture;
    430     validate.GetPicture(wsPicture);
    431     if (wsPicture.IsEmpty()) {
    432       return XFA_EVENTERROR_NotExist;
    433     }
    434     IFX_Locale* pLocale = GetLocal();
    435     if (!pLocale) {
    436       return XFA_EVENTERROR_NotExist;
    437     }
    438     CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
    439     if (!lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale)) {
    440       IXFA_AppProvider* pAppProvider = GetAppProvider();
    441       if (!pAppProvider) {
    442         return XFA_EVENTERROR_NotExist;
    443       }
    444       CFX_WideString wsFormatMsg;
    445       validate.GetFormatMessageText(wsFormatMsg);
    446       CFX_WideString wsTitle;
    447       pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
    448       int32_t eFormatTest = validate.GetFormatTest();
    449       if (eFormatTest == XFA_ATTRIBUTEENUM_Error) {
    450         if (wsFormatMsg.IsEmpty()) {
    451           GetValidateMessage(pAppProvider, wsFormatMsg, TRUE, bVersionFlag);
    452         }
    453         pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
    454         return XFA_EVENTERROR_Sucess;
    455       }
    456       if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    457         return XFA_EVENTERROR_NotExist;
    458       }
    459       if (wsFormatMsg.IsEmpty()) {
    460         GetValidateMessage(pAppProvider, wsFormatMsg, FALSE, bVersionFlag);
    461       }
    462       if (bVersionFlag) {
    463         pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
    464                              XFA_MB_OK);
    465         return XFA_EVENTERROR_Sucess;
    466       }
    467       if (pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
    468                                XFA_MB_YesNo) == XFA_IDYes) {
    469         this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
    470       }
    471       return XFA_EVENTERROR_Sucess;
    472     }
    473   }
    474   return XFA_EVENTERROR_NotExist;
    475 }
    476 int32_t CXFA_WidgetAcc::ProcessNullTestValidate(CXFA_Validate validate,
    477                                                 int32_t iFlags,
    478                                                 FX_BOOL bVersionFlag) {
    479   CFX_WideString wsValue;
    480   this->GetValue(wsValue, XFA_VALUEPICTURE_Raw);
    481   if (!wsValue.IsEmpty()) {
    482     return XFA_EVENTERROR_Sucess;
    483   }
    484   if (this->m_bIsNull && (this->m_bPreNull == this->m_bIsNull)) {
    485     return XFA_EVENTERROR_Sucess;
    486   }
    487   int32_t eNullTest = validate.GetNullTest();
    488   CFX_WideString wsNullMsg;
    489   validate.GetNullMessageText(wsNullMsg);
    490   if (iFlags & 0x01) {
    491     int32_t iRet = XFA_EVENTERROR_Sucess;
    492     if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
    493       iRet = XFA_EVENTERROR_Error;
    494     }
    495     if (!wsNullMsg.IsEmpty()) {
    496       if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
    497         m_pDocView->m_arrNullTestMsg.Add(wsNullMsg);
    498         return XFA_EVENTERROR_Error;
    499       }
    500       return XFA_EVENTERROR_Sucess;
    501     }
    502     return iRet;
    503   }
    504   if (wsNullMsg.IsEmpty() && bVersionFlag &&
    505       eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
    506     return XFA_EVENTERROR_Error;
    507   }
    508   IXFA_AppProvider* pAppProvider = GetAppProvider();
    509   if (!pAppProvider) {
    510     return XFA_EVENTERROR_NotExist;
    511   }
    512   CFX_WideString wsCaptionName;
    513   CFX_WideString wsTitle;
    514   pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
    515   switch (eNullTest) {
    516     case XFA_ATTRIBUTEENUM_Error: {
    517       if (wsNullMsg.IsEmpty()) {
    518         GetValidateCaptionName(wsCaptionName, bVersionFlag);
    519         CFX_WideString wsError;
    520         pAppProvider->LoadString(XFA_IDS_ValidateNullError, wsError);
    521         wsNullMsg.Format(wsError, (const FX_WCHAR*)wsCaptionName);
    522       }
    523       pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
    524       return XFA_EVENTERROR_Error;
    525     }
    526     case XFA_ATTRIBUTEENUM_Warning: {
    527       if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    528         return TRUE;
    529       }
    530       if (wsNullMsg.IsEmpty()) {
    531         GetValidateCaptionName(wsCaptionName, bVersionFlag);
    532         CFX_WideString wsWarning;
    533         pAppProvider->LoadString(XFA_IDS_ValidateNullWarning, wsWarning);
    534         wsNullMsg.Format(wsWarning, (const FX_WCHAR*)wsCaptionName,
    535                          (const FX_WCHAR*)wsCaptionName);
    536       }
    537       if (pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Warning,
    538                                XFA_MB_YesNo) == XFA_IDYes) {
    539         this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
    540       }
    541       return XFA_EVENTERROR_Error;
    542     }
    543     case XFA_ATTRIBUTEENUM_Disabled:
    544     default:
    545       break;
    546   }
    547   return XFA_EVENTERROR_Sucess;
    548 }
    549 void CXFA_WidgetAcc::GetValidateCaptionName(CFX_WideString& wsCaptionName,
    550                                             FX_BOOL bVersionFlag) {
    551   if (!bVersionFlag) {
    552     CXFA_Caption caption = GetCaption();
    553     if (caption) {
    554       CXFA_Value capValue = caption.GetValue();
    555       if (capValue) {
    556         CXFA_Text capText = capValue.GetText();
    557         if (capText) {
    558           capText.GetContent(wsCaptionName);
    559         }
    560       }
    561     }
    562   }
    563   if (wsCaptionName.IsEmpty()) {
    564     GetName(wsCaptionName);
    565   }
    566 }
    567 void CXFA_WidgetAcc::GetValidateMessage(IXFA_AppProvider* pAppProvider,
    568                                         CFX_WideString& wsMessage,
    569                                         FX_BOOL bError,
    570                                         FX_BOOL bVersionFlag) {
    571   CFX_WideString wsCaptionName;
    572   GetValidateCaptionName(wsCaptionName, bVersionFlag);
    573   CFX_WideString wsError;
    574   if (bVersionFlag) {
    575     pAppProvider->LoadString(XFA_IDS_ValidateFailed, wsError);
    576     wsMessage.Format(wsError, (const FX_WCHAR*)wsCaptionName);
    577     return;
    578   }
    579   if (bError) {
    580     pAppProvider->LoadString(XFA_IDS_ValidateError, wsError);
    581     wsMessage.Format(wsError, (const FX_WCHAR*)wsCaptionName);
    582     return;
    583   }
    584   CFX_WideString wsWarning;
    585   pAppProvider->LoadString(XFA_IDS_ValidateWarning, wsWarning);
    586   wsMessage.Format(wsWarning, (const FX_WCHAR*)wsCaptionName,
    587                    (const FX_WCHAR*)wsCaptionName);
    588 }
    589 int32_t CXFA_WidgetAcc::ProcessValidate(int32_t iFlags) {
    590   if (this->GetClassID() == XFA_ELEMENT_Draw) {
    591     return XFA_EVENTERROR_NotExist;
    592   }
    593   CXFA_Validate validate = this->GetValidate();
    594   if (!validate) {
    595     return XFA_EVENTERROR_NotExist;
    596   }
    597   FX_BOOL bInitDoc = ((CXFA_Node*)validate)->HasFlag(XFA_NODEFLAG_NeedsInitApp);
    598   FX_BOOL bStatus =
    599       m_pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
    600   int32_t iFormat = 0;
    601   FXJSE_HVALUE pRetValue = NULL;
    602   int32_t iRet = XFA_EVENTERROR_NotExist;
    603   CXFA_Script script = validate.GetScript();
    604   if (script) {
    605     CXFA_EventParam eParam;
    606     eParam.m_eType = XFA_EVENT_Validate;
    607     eParam.m_pTarget = this;
    608     iRet = ExecuteScript(
    609         script, &eParam,
    610         ((bInitDoc || bStatus) && this->GetRawValue().IsEmpty()) ? NULL
    611                                                                  : &pRetValue);
    612   }
    613   XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
    614   FX_BOOL bVersionFlag = FALSE;
    615   if (version < XFA_VERSION_208) {
    616     bVersionFlag = TRUE;
    617   }
    618   if (bInitDoc) {
    619     ((CXFA_Node*)validate)->SetFlag(XFA_NODEFLAG_NeedsInitApp, FALSE, FALSE);
    620   } else {
    621     iFormat = ProcessFormatTestValidate(validate, bVersionFlag);
    622     if (!bVersionFlag) {
    623       bVersionFlag = GetDoc()->GetXFADoc()->HasFlag(XFA_DOCFLAG_Scripting);
    624     }
    625     iRet |= ProcessNullTestValidate(validate, iFlags, bVersionFlag);
    626   }
    627   if (iFormat != XFA_EVENTERROR_Sucess) {
    628     ProcessScriptTestValidate(validate, iRet, pRetValue, bVersionFlag);
    629   }
    630   if (pRetValue) {
    631     FXJSE_Value_Release(pRetValue);
    632   }
    633   return iRet | iFormat;
    634 }
    635 int32_t CXFA_WidgetAcc::ExecuteScript(CXFA_Script script,
    636                                       CXFA_EventParam* pEventParam,
    637                                       FXJSE_HVALUE* pRetValue) {
    638   static const uint32_t MAX_RECURSION_DEPTH = 2;
    639   if (m_nRecursionDepth > MAX_RECURSION_DEPTH)
    640     return XFA_EVENTERROR_Sucess;
    641   FXSYS_assert(pEventParam);
    642   if (!script) {
    643     return XFA_EVENTERROR_NotExist;
    644   }
    645   if (script.GetRunAt() == XFA_ATTRIBUTEENUM_Server) {
    646     return XFA_EVENTERROR_Disabled;
    647   }
    648   CFX_WideString wsExpression;
    649   script.GetExpression(wsExpression);
    650   if (wsExpression.IsEmpty()) {
    651     return XFA_EVENTERROR_NotExist;
    652   }
    653   XFA_SCRIPTTYPE eScriptType = script.GetContentType();
    654   if (eScriptType == XFA_SCRIPTTYPE_Unkown) {
    655     return XFA_EVENTERROR_Sucess;
    656   }
    657   CXFA_FFDoc* pDoc = GetDoc();
    658   IXFA_ScriptContext* pContext = pDoc->GetXFADoc()->GetScriptContext();
    659   pContext->SetEventParam(pEventParam);
    660   pContext->SetRunAtType((XFA_ATTRIBUTEENUM)script.GetRunAt());
    661   CXFA_NodeArray refNodes;
    662   if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
    663       pEventParam->m_eType == XFA_EVENT_Calculate) {
    664     pContext->SetNodesOfRunScript(&refNodes);
    665   }
    666   FXJSE_HVALUE hRetValue = FXJSE_Value_Create(pContext->GetRuntime());
    667   ++m_nRecursionDepth;
    668   FX_BOOL bRet = pContext->RunScript((XFA_SCRIPTLANGTYPE)eScriptType,
    669                                      wsExpression, hRetValue, m_pNode);
    670   --m_nRecursionDepth;
    671   int32_t iRet = XFA_EVENTERROR_Error;
    672   if (bRet) {
    673     iRet = XFA_EVENTERROR_Sucess;
    674     if (pEventParam->m_eType == XFA_EVENT_Calculate ||
    675         pEventParam->m_eType == XFA_EVENT_InitCalculate) {
    676       if (!FXJSE_Value_IsUndefined(hRetValue)) {
    677         if (!FXJSE_Value_IsNull(hRetValue)) {
    678           CFX_ByteString bsString;
    679           FXJSE_Value_ToUTF8String(hRetValue, bsString);
    680           pEventParam->m_wsResult =
    681               CFX_WideString::FromUTF8(bsString, bsString.GetLength());
    682         }
    683         iRet = XFA_EVENTERROR_Sucess;
    684       } else {
    685         iRet = XFA_EVENTERROR_Error;
    686       }
    687       if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
    688         if ((iRet == XFA_EVENTERROR_Sucess) &&
    689             (GetRawValue() != pEventParam->m_wsResult)) {
    690           SetValue(pEventParam->m_wsResult, XFA_VALUEPICTURE_Raw);
    691           m_pDocView->AddValidateWidget(this);
    692         }
    693       }
    694       int32_t iRefs = refNodes.GetSize();
    695       for (int32_t r = 0; r < iRefs; r++) {
    696         CXFA_WidgetAcc* pRefAcc = (CXFA_WidgetAcc*)refNodes[r]->GetWidgetData();
    697         if (pRefAcc && pRefAcc == this) {
    698           continue;
    699         }
    700         CXFA_Node* pRefNode = refNodes[r];
    701         CXFA_CalcData* pGlobalData =
    702             (CXFA_CalcData*)pRefNode->GetUserData(XFA_CalcData);
    703         if (!pGlobalData) {
    704           pGlobalData = new CXFA_CalcData;
    705           pRefNode->SetUserData(XFA_CalcData, pGlobalData,
    706                                 &gs_XFADeleteCalcData);
    707         }
    708         if (pGlobalData->m_Globals.Find(this) < 0) {
    709           pGlobalData->m_Globals.Add(this);
    710         }
    711       }
    712     }
    713   }
    714   if (pRetValue) {
    715     *pRetValue = hRetValue;
    716   } else {
    717     FXJSE_Value_Release(hRetValue);
    718   }
    719   pContext->SetNodesOfRunScript(NULL);
    720   return iRet;
    721 }
    722 CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) {
    723   CXFA_LayoutItem* pLayout = nullptr;
    724   if (pWidget) {
    725     pLayout = pWidget->GetNext();
    726   } else {
    727     pLayout = m_pDocView->GetXFALayout()->GetLayoutItem(m_pNode);
    728   }
    729   return static_cast<CXFA_FFWidget*>(pLayout);
    730 }
    731 void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFWidget* pExcept) {
    732   CXFA_FFWidget* pWidget = NULL;
    733   while ((pWidget = this->GetNextWidget(pWidget)) != NULL) {
    734     if (pWidget == pExcept || !pWidget->IsLoaded() ||
    735         (GetUIType() != XFA_ELEMENT_CheckButton && pWidget->IsFocused())) {
    736       continue;
    737     }
    738     pWidget->UpdateFWLData();
    739     pWidget->AddInvalidateRect();
    740   }
    741 }
    742 void CXFA_WidgetAcc::NotifyEvent(FX_DWORD dwEvent,
    743                                  CXFA_FFWidget* pWidget,
    744                                  void* pParam,
    745                                  void* pAdditional) {
    746   IXFA_DocProvider* pDocProvider = GetDoc()->GetDocProvider();
    747   if (pWidget) {
    748     pDocProvider->WidgetEvent(pWidget, this, dwEvent, pParam, pAdditional);
    749   } else {
    750     pWidget = GetNextWidget(pWidget);
    751     if (pWidget == NULL) {
    752       pDocProvider->WidgetEvent(NULL, this, dwEvent, pParam, pAdditional);
    753       return;
    754     }
    755     while (pWidget) {
    756       pDocProvider->WidgetEvent(pWidget, this, dwEvent, pParam, pAdditional);
    757       pWidget = GetNextWidget(pWidget);
    758     }
    759   }
    760 }
    761 void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) {
    762   CXFA_Caption caption = this->GetCaption();
    763   if (!caption.IsExistInXML() ||
    764       caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    765     return;
    766   }
    767   LoadCaption();
    768   XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
    769   int32_t iCapPlacement = caption.GetPlacementType();
    770   FX_FLOAT fCapReserve = caption.GetReserve();
    771   FX_BOOL bVert = iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
    772                   iCapPlacement == XFA_ATTRIBUTEENUM_Bottom;
    773   FX_BOOL bReserveExit = fCapReserve > 0.01;
    774   CXFA_TextLayout* pCapTextLayout =
    775       ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout;
    776   if (pCapTextLayout) {
    777     if (!bVert && eUIType != XFA_ELEMENT_Button) {
    778       szCap.x = fCapReserve;
    779     }
    780     CFX_SizeF minSize;
    781     minSize.Set(0, 0);
    782     pCapTextLayout->CalcSize(minSize, szCap, szCap);
    783     if (bReserveExit) {
    784       bVert ? szCap.y = fCapReserve : szCap.x = fCapReserve;
    785     }
    786   } else {
    787     FX_FLOAT fFontSize = 10.0f;
    788     if (CXFA_Font font = caption.GetFont()) {
    789       fFontSize = font.GetFontSize();
    790     } else if (CXFA_Font widgetfont = GetFont()) {
    791       fFontSize = widgetfont.GetFontSize();
    792     }
    793     if (bVert) {
    794       szCap.y = fCapReserve > 0 ? fCapReserve : fFontSize;
    795     } else {
    796       szCap.x = fCapReserve > 0 ? fCapReserve : 0;
    797       szCap.y = fFontSize;
    798     }
    799   }
    800   if (CXFA_Margin mgCap = caption.GetMargin()) {
    801     FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
    802     mgCap.GetLeftInset(fLeftInset);
    803     mgCap.GetTopInset(fTopInset);
    804     mgCap.GetRightInset(fRightInset);
    805     mgCap.GetBottomInset(fBottomInset);
    806     if (bReserveExit) {
    807       bVert ? (szCap.x += fLeftInset + fRightInset)
    808             : (szCap.y += fTopInset + fBottomInset);
    809     } else {
    810       szCap.x += fLeftInset + fRightInset;
    811       szCap.y += fTopInset + fBottomInset;
    812     }
    813   }
    814 }
    815 FX_BOOL CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF& size) {
    816   CFX_SizeF szCap;
    817   szCap.Set(0, 0);
    818   CalcCaptionSize(szCap);
    819   CFX_RectF rtUIMargin;
    820   GetUIMargin(rtUIMargin);
    821   size.x += rtUIMargin.left + rtUIMargin.width;
    822   size.y += rtUIMargin.top + rtUIMargin.height;
    823   if (szCap.x > 0 && szCap.y > 0) {
    824     int32_t iCapPlacement = this->GetCaption().GetPlacementType();
    825     switch (iCapPlacement) {
    826       case XFA_ATTRIBUTEENUM_Left:
    827       case XFA_ATTRIBUTEENUM_Right:
    828       case XFA_ATTRIBUTEENUM_Inline: {
    829         size.x += szCap.x;
    830         size.y = std::max(size.y, szCap.y);
    831       } break;
    832       case XFA_ATTRIBUTEENUM_Top:
    833       case XFA_ATTRIBUTEENUM_Bottom: {
    834         size.y += szCap.y;
    835         size.x = std::max(size.x, szCap.x);
    836       }
    837       default:
    838         break;
    839     }
    840   }
    841   return CalculateWidgetAutoSize(size);
    842 }
    843 FX_BOOL CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
    844   CXFA_Margin mgWidget = this->GetMargin();
    845   if (mgWidget.IsExistInXML()) {
    846     FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
    847     mgWidget.GetLeftInset(fLeftInset);
    848     mgWidget.GetTopInset(fTopInset);
    849     mgWidget.GetRightInset(fRightInset);
    850     mgWidget.GetBottomInset(fBottomInset);
    851     size.x += fLeftInset + fRightInset;
    852     size.y += fTopInset + fBottomInset;
    853   }
    854   CXFA_Para para = this->GetPara();
    855   if (para.IsExistInXML()) {
    856     size.x += para.GetMarginLeft();
    857     size.x += para.GetTextIndent();
    858   }
    859   FX_FLOAT fVal = 0, fMin = 0, fMax = 0;
    860   if (this->GetWidth(fVal)) {
    861     size.x = fVal;
    862   } else {
    863     if (this->GetMinWidth(fMin)) {
    864       size.x = std::max(size.x, fMin);
    865     }
    866     if (this->GetMaxWidth(fMax) && fMax > 0) {
    867       size.x = std::min(size.x, fMax);
    868     }
    869   }
    870   fVal = 0, fMin = 0, fMax = 0;
    871   if (this->GetHeight(fVal)) {
    872     size.y = fVal;
    873   } else {
    874     if (this->GetMinHeight(fMin)) {
    875       size.y = std::max(size.y, fMin);
    876     }
    877     if (this->GetMaxHeight(fMax) && fMax > 0) {
    878       size.y = std::min(size.y, fMax);
    879     }
    880   }
    881   return TRUE;
    882 }
    883 void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) {
    884   FX_FLOAT fFontSize = GetFontSize();
    885   CFX_WideString wsText;
    886   this->GetValue(wsText, XFA_VALUEPICTURE_Display);
    887   if (wsText.IsEmpty()) {
    888     size.y += fFontSize;
    889     return;
    890   }
    891   FX_WCHAR wcEnter = '\n';
    892   FX_WCHAR wsLast = wsText.GetAt(wsText.GetLength() - 1);
    893   if (wsLast == wcEnter) {
    894     wsText = wsText + wcEnter;
    895   }
    896   if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
    897     ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut = IFDE_TextOut::Create();
    898     IFDE_TextOut* pTextOut = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut;
    899     pTextOut->SetFont(GetFDEFont());
    900     pTextOut->SetFontSize(fFontSize);
    901     pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
    902     pTextOut->SetLineSpace(GetLineHeight());
    903     FX_DWORD dwStyles = FDE_TTOSTYLE_LastLineHeight;
    904     if (GetUIType() == XFA_ELEMENT_TextEdit && IsMultiLine()) {
    905       dwStyles |= FDE_TTOSTYLE_LineWrap;
    906     }
    907     pTextOut->SetStyles(dwStyles);
    908   }
    909   ((CXFA_FieldLayoutData*)m_pLayoutData)
    910       ->m_pTextOut->CalcLogicSize(wsText, wsText.GetLength(), size);
    911 }
    912 FX_BOOL CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) {
    913   if (size.x > 0) {
    914     CFX_SizeF szOrz = size;
    915     CFX_SizeF szCap;
    916     szCap.Set(0, 0);
    917     CalcCaptionSize(szCap);
    918     FX_BOOL bCapExit = szCap.x > 0.01 && szCap.y > 0.01;
    919     int32_t iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
    920     if (bCapExit) {
    921       iCapPlacement = this->GetCaption().GetPlacementType();
    922       switch (iCapPlacement) {
    923         case XFA_ATTRIBUTEENUM_Left:
    924         case XFA_ATTRIBUTEENUM_Right:
    925         case XFA_ATTRIBUTEENUM_Inline: {
    926           size.x -= szCap.x;
    927         }
    928         default:
    929           break;
    930       }
    931     }
    932     CFX_RectF rtUIMargin;
    933     GetUIMargin(rtUIMargin);
    934     size.x -= rtUIMargin.left + rtUIMargin.width;
    935     CXFA_Margin mgWidget = this->GetMargin();
    936     if (mgWidget.IsExistInXML()) {
    937       FX_FLOAT fLeftInset, fRightInset;
    938       mgWidget.GetLeftInset(fLeftInset);
    939       mgWidget.GetRightInset(fRightInset);
    940       size.x -= fLeftInset + fRightInset;
    941     }
    942     CalculateTextContentSize(size);
    943     size.y += rtUIMargin.top + rtUIMargin.height;
    944     if (bCapExit) {
    945       switch (iCapPlacement) {
    946         case XFA_ATTRIBUTEENUM_Left:
    947         case XFA_ATTRIBUTEENUM_Right:
    948         case XFA_ATTRIBUTEENUM_Inline: {
    949           size.y = std::max(size.y, szCap.y);
    950         } break;
    951         case XFA_ATTRIBUTEENUM_Top:
    952         case XFA_ATTRIBUTEENUM_Bottom: {
    953           size.y += szCap.y;
    954         }
    955         default:
    956           break;
    957       }
    958     }
    959     size.x = szOrz.x;
    960     return CalculateWidgetAutoSize(size);
    961   }
    962   CalculateTextContentSize(size);
    963   return CalculateFieldAutoSize(size);
    964 }
    965 FX_BOOL CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) {
    966   FX_FLOAT fCheckSize = this->GetCheckButtonSize();
    967   size.x = size.y = fCheckSize;
    968   return CalculateFieldAutoSize(size);
    969 }
    970 FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
    971   CalcCaptionSize(size);
    972   return CalculateWidgetAutoSize(size);
    973 }
    974 FX_BOOL CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) {
    975   if (!GetImageImage()) {
    976     LoadImageImage();
    977   }
    978   size.Set(0, 0);
    979   if (CFX_DIBitmap* pBitmap = GetImageImage()) {
    980     CFX_RectF rtImage, rtFit;
    981     rtImage.Set(0, 0, 0, 0);
    982     rtFit.Set(0, 0, 0, 0);
    983     int32_t iImageXDpi = 0;
    984     int32_t iImageYDpi = 0;
    985     GetImageDpi(iImageXDpi, iImageYDpi);
    986     rtImage.width =
    987         XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
    988     rtImage.height =
    989         XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
    990     if (GetWidth(rtFit.width)) {
    991       GetWidthWithoutMargin(rtFit.width);
    992     } else {
    993       rtFit.width = rtImage.width;
    994     }
    995     if (GetHeight(rtFit.height)) {
    996       GetHeightWithoutMargin(rtFit.height);
    997     } else {
    998       rtFit.height = rtImage.height;
    999     }
   1000     size.x = rtFit.width;
   1001     size.y = rtFit.height;
   1002   }
   1003   return CalculateWidgetAutoSize(size);
   1004 }
   1005 FX_BOOL CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) {
   1006   if (!GetImageEditImage()) {
   1007     LoadImageEditImage();
   1008   }
   1009   size.Set(0, 0);
   1010   if (CFX_DIBitmap* pBitmap = GetImageEditImage()) {
   1011     CFX_RectF rtImage, rtFit;
   1012     rtImage.Set(0, 0, 0, 0);
   1013     rtFit.Set(0, 0, 0, 0);
   1014     int32_t iImageXDpi = 0;
   1015     int32_t iImageYDpi = 0;
   1016     GetImageEditDpi(iImageXDpi, iImageYDpi);
   1017     rtImage.width =
   1018         XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
   1019     rtImage.height =
   1020         XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
   1021     if (GetWidth(rtFit.width)) {
   1022       GetWidthWithoutMargin(rtFit.width);
   1023     } else {
   1024       rtFit.width = rtImage.width;
   1025     }
   1026     if (GetHeight(rtFit.height)) {
   1027       GetHeightWithoutMargin(rtFit.height);
   1028     } else {
   1029       rtFit.height = rtImage.height;
   1030     }
   1031     size.x = rtFit.width;
   1032     size.y = rtFit.height;
   1033   }
   1034   return CalculateFieldAutoSize(size);
   1035 }
   1036 FX_BOOL CXFA_WidgetAcc::LoadImageImage() {
   1037   InitLayoutData();
   1038   return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
   1039 }
   1040 FX_BOOL CXFA_WidgetAcc::LoadImageEditImage() {
   1041   InitLayoutData();
   1042   return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
   1043 }
   1044 void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
   1045   iImageXDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageXDpi;
   1046   iImageYDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageYDpi;
   1047 }
   1048 void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
   1049   iImageXDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageXDpi;
   1050   iImageYDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageYDpi;
   1051 }
   1052 FX_BOOL CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF& size) {
   1053   LoadText();
   1054   CXFA_TextLayout* pTextLayout =
   1055       ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
   1056   if (pTextLayout) {
   1057     size.x = pTextLayout->StartLayout(size.x);
   1058     size.y = pTextLayout->GetLayoutHeight();
   1059   }
   1060   return CalculateWidgetAutoSize(size);
   1061 }
   1062 void CXFA_WidgetAcc::LoadText() {
   1063   InitLayoutData();
   1064   ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
   1065 }
   1066 FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc) {
   1067   CXFA_Margin mgWidget = this->GetMargin();
   1068   if (mgWidget.IsExistInXML()) {
   1069     FX_FLOAT fLeftInset, fRightInset;
   1070     mgWidget.GetLeftInset(fLeftInset);
   1071     mgWidget.GetRightInset(fRightInset);
   1072     fWidthCalc += fLeftInset + fRightInset;
   1073   }
   1074   FX_FLOAT fMin = 0, fMax = 0;
   1075   if (this->GetMinWidth(fMin)) {
   1076     fWidthCalc = std::max(fWidthCalc, fMin);
   1077   }
   1078   if (this->GetMaxWidth(fMax) && fMax > 0) {
   1079     fWidthCalc = std::min(fWidthCalc, fMax);
   1080   }
   1081   return fWidthCalc;
   1082 }
   1083 FX_FLOAT CXFA_WidgetAcc::GetWidthWithoutMargin(FX_FLOAT fWidthCalc) {
   1084   CXFA_Margin mgWidget = this->GetMargin();
   1085   if (mgWidget.IsExistInXML()) {
   1086     FX_FLOAT fLeftInset, fRightInset;
   1087     mgWidget.GetLeftInset(fLeftInset);
   1088     mgWidget.GetRightInset(fRightInset);
   1089     fWidthCalc -= fLeftInset + fRightInset;
   1090   }
   1091   return fWidthCalc;
   1092 }
   1093 FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc) {
   1094   CXFA_Margin mgWidget = this->GetMargin();
   1095   if (mgWidget.IsExistInXML()) {
   1096     FX_FLOAT fTopInset, fBottomInset;
   1097     mgWidget.GetTopInset(fTopInset);
   1098     mgWidget.GetBottomInset(fBottomInset);
   1099     fHeightCalc += fTopInset + fBottomInset;
   1100   }
   1101   FX_FLOAT fMin = 0, fMax = 0;
   1102   if (this->GetMinHeight(fMin)) {
   1103     fHeightCalc = std::max(fHeightCalc, fMin);
   1104   }
   1105   if (this->GetMaxHeight(fMax) && fMax > 0) {
   1106     fHeightCalc = std::min(fHeightCalc, fMax);
   1107   }
   1108   return fHeightCalc;
   1109 }
   1110 FX_FLOAT CXFA_WidgetAcc::GetHeightWithoutMargin(FX_FLOAT fHeightCalc) {
   1111   CXFA_Margin mgWidget = this->GetMargin();
   1112   if (mgWidget.IsExistInXML()) {
   1113     FX_FLOAT fTopInset, fBottomInset;
   1114     mgWidget.GetTopInset(fTopInset);
   1115     mgWidget.GetBottomInset(fBottomInset);
   1116     fHeightCalc -= fTopInset + fBottomInset;
   1117   }
   1118   return fHeightCalc;
   1119 }
   1120 void CXFA_WidgetAcc::StartWidgetLayout(FX_FLOAT& fCalcWidth,
   1121                                        FX_FLOAT& fCalcHeight) {
   1122   InitLayoutData();
   1123   XFA_ELEMENT eUIType = GetUIType();
   1124   if (eUIType == XFA_ELEMENT_Text) {
   1125     m_pLayoutData->m_fWidgetHeight = -1;
   1126     GetHeight(m_pLayoutData->m_fWidgetHeight);
   1127     StartTextLayout(fCalcWidth, fCalcHeight);
   1128     return;
   1129   }
   1130   if (fCalcWidth > 0 && fCalcHeight > 0) {
   1131     return;
   1132   }
   1133   m_pLayoutData->m_fWidgetHeight = -1;
   1134   FX_FLOAT fWidth = 0;
   1135   if (fCalcWidth > 0 && fCalcHeight < 0) {
   1136     if (!GetHeight(fCalcHeight)) {
   1137       CalculateAccWidthAndHeight(eUIType, fCalcWidth, fCalcHeight);
   1138     }
   1139     m_pLayoutData->m_fWidgetHeight = fCalcHeight;
   1140     return;
   1141   }
   1142   if (fCalcWidth < 0 && fCalcHeight < 0) {
   1143     if (!GetWidth(fWidth) || !GetHeight(fCalcHeight)) {
   1144       CalculateAccWidthAndHeight(eUIType, fWidth, fCalcHeight);
   1145     }
   1146     fCalcWidth = fWidth;
   1147   }
   1148   m_pLayoutData->m_fWidgetHeight = fCalcHeight;
   1149 }
   1150 void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_ELEMENT eUIType,
   1151                                                 FX_FLOAT& fWidth,
   1152                                                 FX_FLOAT& fCalcHeight) {
   1153   CFX_SizeF sz;
   1154   sz.Set(fWidth, m_pLayoutData->m_fWidgetHeight);
   1155   switch (eUIType) {
   1156     case XFA_ELEMENT_Barcode:
   1157     case XFA_ELEMENT_ChoiceList:
   1158     case XFA_ELEMENT_Signature:
   1159       CalculateFieldAutoSize(sz);
   1160       break;
   1161     case XFA_ELEMENT_ImageEdit:
   1162       CalculateImageEditAutoSize(sz);
   1163       break;
   1164     case XFA_ELEMENT_Button:
   1165       CalculatePushButtonAutoSize(sz);
   1166       break;
   1167     case XFA_ELEMENT_CheckButton:
   1168       CalculateCheckButtonAutoSize(sz);
   1169       break;
   1170     case XFA_ELEMENT_DateTimeEdit:
   1171     case XFA_ELEMENT_NumericEdit:
   1172     case XFA_ELEMENT_PasswordEdit:
   1173     case XFA_ELEMENT_TextEdit:
   1174       CalculateTextEditAutoSize(sz);
   1175       break;
   1176     case XFA_ELEMENT_Image:
   1177       CalculateImageAutoSize(sz);
   1178       break;
   1179     case XFA_ELEMENT_Arc:
   1180     case XFA_ELEMENT_Line:
   1181     case XFA_ELEMENT_Rectangle:
   1182     case XFA_ELEMENT_Subform:
   1183     case XFA_ELEMENT_ExclGroup:
   1184       CalculateWidgetAutoSize(sz);
   1185       break;
   1186     default:
   1187       break;
   1188   }
   1189   fWidth = sz.x;
   1190   m_pLayoutData->m_fWidgetHeight = sz.y;
   1191   fCalcHeight = sz.y;
   1192 }
   1193 FX_BOOL CXFA_WidgetAcc::FindSplitPos(int32_t iBlockIndex,
   1194                                      FX_FLOAT& fCalcHeight) {
   1195   XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
   1196   if (eUIType == XFA_ELEMENT_Subform) {
   1197     return FALSE;
   1198   }
   1199   if (eUIType != XFA_ELEMENT_Text && eUIType != XFA_ELEMENT_TextEdit &&
   1200       eUIType != XFA_ELEMENT_NumericEdit &&
   1201       eUIType != XFA_ELEMENT_PasswordEdit) {
   1202     fCalcHeight = 0;
   1203     return TRUE;
   1204   }
   1205   FX_FLOAT fTopInset = 0;
   1206   FX_FLOAT fBottomInset = 0;
   1207   if (iBlockIndex == 0) {
   1208     CXFA_Margin mgWidget = this->GetMargin();
   1209     if (mgWidget.IsExistInXML()) {
   1210       mgWidget.GetTopInset(fTopInset);
   1211       mgWidget.GetBottomInset(fBottomInset);
   1212     }
   1213     CFX_RectF rtUIMargin;
   1214     this->GetUIMargin(rtUIMargin);
   1215     fTopInset += rtUIMargin.top;
   1216     fBottomInset += rtUIMargin.width;
   1217   }
   1218   if (eUIType == XFA_ELEMENT_Text) {
   1219     FX_FLOAT fHeight = fCalcHeight;
   1220     if (iBlockIndex == 0) {
   1221       fCalcHeight = fCalcHeight - fTopInset;
   1222       if (fCalcHeight < 0) {
   1223         fCalcHeight = 0;
   1224       }
   1225     }
   1226     CXFA_TextLayout* pTextLayout =
   1227         ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
   1228     pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
   1229                           m_pLayoutData->m_fWidgetHeight - fTopInset);
   1230     if (fCalcHeight != 0) {
   1231       if (iBlockIndex == 0) {
   1232         fCalcHeight = fCalcHeight + fTopInset;
   1233       }
   1234       if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
   1235         return FALSE;
   1236       }
   1237     }
   1238     return TRUE;
   1239   }
   1240   XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
   1241   FX_FLOAT fCapReserve = 0;
   1242   if (iBlockIndex == 0) {
   1243     CXFA_Caption caption = GetCaption();
   1244     if (caption.IsExistInXML() &&
   1245         caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
   1246       iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
   1247       fCapReserve = caption.GetReserve();
   1248     }
   1249     if (iCapPlacement == XFA_ATTRIBUTEENUM_Top &&
   1250         fCalcHeight < fCapReserve + fTopInset) {
   1251       fCalcHeight = 0;
   1252       return TRUE;
   1253     }
   1254     if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom &&
   1255         m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
   1256       fCalcHeight = 0;
   1257       return TRUE;
   1258     }
   1259     if (iCapPlacement != XFA_ATTRIBUTEENUM_Top) {
   1260       fCapReserve = 0;
   1261     }
   1262   }
   1263   int32_t iLinesCount = 0;
   1264   FX_FLOAT fHeight = m_pLayoutData->m_fWidgetHeight;
   1265   CFX_WideString wsText;
   1266   this->GetValue(wsText, XFA_VALUEPICTURE_Display);
   1267   if (wsText.IsEmpty()) {
   1268     iLinesCount = 1;
   1269   } else {
   1270     if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
   1271       FX_FLOAT fWidth = 0;
   1272       GetWidth(fWidth);
   1273       CalculateAccWidthAndHeight(eUIType, fWidth, fHeight);
   1274     }
   1275     iLinesCount =
   1276         ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut->GetTotalLines();
   1277   }
   1278   if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray) {
   1279     ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray =
   1280         new CFX_FloatArray;
   1281   }
   1282   CFX_FloatArray* pFieldArray =
   1283       ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray;
   1284   int32_t iFieldSplitCount = pFieldArray->GetSize();
   1285   for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
   1286     iLinesCount -= (int32_t)pFieldArray->GetAt(i + 1);
   1287     fHeight -= pFieldArray->GetAt(i + 2);
   1288   }
   1289   if (iLinesCount == 0) {
   1290     return FALSE;
   1291   }
   1292   FX_FLOAT fLineHeight = GetLineHeight();
   1293   FX_FLOAT fFontSize = GetFontSize();
   1294   FX_FLOAT fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
   1295   FX_FLOAT fSpaceAbove = 0;
   1296   FX_FLOAT fStartOffset = 0;
   1297   if (fHeight > 0.1f && iBlockIndex == 0) {
   1298     fStartOffset = fTopInset;
   1299     fHeight -= (fTopInset + fBottomInset);
   1300     if (CXFA_Para para = this->GetPara()) {
   1301       fSpaceAbove = para.GetSpaceAbove();
   1302       FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
   1303       fHeight -= (fSpaceAbove + fSpaceBelow);
   1304       switch (para.GetVerticalAlign()) {
   1305         case XFA_ATTRIBUTEENUM_Top:
   1306           fStartOffset += fSpaceAbove;
   1307           break;
   1308         case XFA_ATTRIBUTEENUM_Middle:
   1309           fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
   1310           break;
   1311         case XFA_ATTRIBUTEENUM_Bottom:
   1312           fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
   1313           break;
   1314       }
   1315     }
   1316     if (fStartOffset < 0.1f) {
   1317       fStartOffset = 0;
   1318     }
   1319   }
   1320   for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
   1321     fStartOffset = pFieldArray->GetAt(i * 3) - pFieldArray->GetAt(i * 3 + 2);
   1322     if (fStartOffset < 0.1f) {
   1323       fStartOffset = 0;
   1324     }
   1325   }
   1326   if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
   1327     pFieldArray->SetAt(0, fStartOffset);
   1328   } else {
   1329     pFieldArray->Add(fStartOffset);
   1330   }
   1331   XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
   1332   FX_BOOL bCanSplitNoContent = FALSE;
   1333   XFA_ATTRIBUTEENUM eLayoutMode;
   1334   this->GetNode()
   1335       ->GetNodeItem(XFA_NODEITEM_Parent)
   1336       ->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, TRUE);
   1337   if ((eLayoutMode == XFA_ATTRIBUTEENUM_Position ||
   1338        eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
   1339        eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
   1340        eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
   1341       version > XFA_VERSION_208) {
   1342     bCanSplitNoContent = TRUE;
   1343   }
   1344   if ((eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
   1345        eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
   1346        eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
   1347       version <= XFA_VERSION_208) {
   1348     if (fStartOffset < fCalcHeight) {
   1349       bCanSplitNoContent = TRUE;
   1350     } else {
   1351       fCalcHeight = 0;
   1352       return TRUE;
   1353     }
   1354   }
   1355   if (bCanSplitNoContent) {
   1356     if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
   1357       fCalcHeight = 0;
   1358       return TRUE;
   1359     }
   1360     if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
   1361       if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
   1362         pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
   1363         pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
   1364       } else {
   1365         pFieldArray->Add(0);
   1366         pFieldArray->Add(fCalcHeight);
   1367       }
   1368       return FALSE;
   1369     }
   1370     if (fCalcHeight - fStartOffset < fLineHeight) {
   1371       fCalcHeight = fStartOffset;
   1372       if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
   1373         pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
   1374         pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
   1375       } else {
   1376         pFieldArray->Add(0);
   1377         pFieldArray->Add(fCalcHeight);
   1378       }
   1379       return TRUE;
   1380     }
   1381     FX_FLOAT fTextNum =
   1382         fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
   1383     int32_t iLineNum =
   1384         (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
   1385     if (iLineNum >= iLinesCount) {
   1386       if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
   1387         if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
   1388           pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLinesCount);
   1389           pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
   1390         } else {
   1391           pFieldArray->Add((FX_FLOAT)iLinesCount);
   1392           pFieldArray->Add(fCalcHeight);
   1393         }
   1394         return FALSE;
   1395       }
   1396       if (fHeight - fStartOffset - fTextHeight < fFontSize) {
   1397         iLineNum -= 1;
   1398         if (iLineNum == 0) {
   1399           fCalcHeight = 0;
   1400           return TRUE;
   1401         }
   1402       } else {
   1403         iLineNum = (int32_t)(fTextNum / fLineHeight);
   1404       }
   1405     }
   1406     if (iLineNum > 0) {
   1407       FX_FLOAT fSplitHeight =
   1408           iLineNum * fLineHeight + fCapReserve + fStartOffset;
   1409       if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
   1410         pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLineNum);
   1411         pFieldArray->SetAt(iBlockIndex * 3 + 2, fSplitHeight);
   1412       } else {
   1413         pFieldArray->Add((FX_FLOAT)iLineNum);
   1414         pFieldArray->Add(fSplitHeight);
   1415       }
   1416       if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
   1417         return FALSE;
   1418       }
   1419       fCalcHeight = fSplitHeight;
   1420       return TRUE;
   1421     }
   1422   }
   1423   fCalcHeight = 0;
   1424   return TRUE;
   1425 }
   1426 void CXFA_WidgetAcc::InitLayoutData() {
   1427   if (m_pLayoutData) {
   1428     return;
   1429   }
   1430   switch (GetUIType()) {
   1431     case XFA_ELEMENT_Text:
   1432       m_pLayoutData = new CXFA_TextLayoutData;
   1433       return;
   1434     case XFA_ELEMENT_TextEdit:
   1435       m_pLayoutData = new CXFA_TextEditData;
   1436       return;
   1437     case XFA_ELEMENT_Image:
   1438       m_pLayoutData = new CXFA_ImageLayoutData;
   1439       return;
   1440     case XFA_ELEMENT_ImageEdit:
   1441       m_pLayoutData = new CXFA_ImageEditData;
   1442       return;
   1443     default:
   1444       break;
   1445   }
   1446   if (GetClassID() == XFA_ELEMENT_Field) {
   1447     m_pLayoutData = new CXFA_FieldLayoutData;
   1448   } else {
   1449     m_pLayoutData = new CXFA_WidgetLayoutData;
   1450   }
   1451 }
   1452 void CXFA_WidgetAcc::StartTextLayout(FX_FLOAT& fCalcWidth,
   1453                                      FX_FLOAT& fCalcHeight) {
   1454   LoadText();
   1455   CXFA_TextLayout* pTextLayout =
   1456       ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
   1457   FX_FLOAT fTextHeight = 0;
   1458   if (fCalcWidth > 0 && fCalcHeight > 0) {
   1459     FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
   1460     pTextLayout->StartLayout(fWidth);
   1461     fTextHeight = fCalcHeight;
   1462     fTextHeight = GetHeightWithoutMargin(fTextHeight);
   1463     pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
   1464     return;
   1465   }
   1466   if (fCalcWidth > 0 && fCalcHeight < 0) {
   1467     FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
   1468     pTextLayout->StartLayout(fWidth);
   1469   }
   1470   if (fCalcWidth < 0 && fCalcHeight < 0) {
   1471     FX_FLOAT fMaxWidth = -1;
   1472     FX_BOOL bRet = GetWidth(fMaxWidth);
   1473     if (bRet) {
   1474       FX_FLOAT fWidth = GetWidthWithoutMargin(fMaxWidth);
   1475       pTextLayout->StartLayout(fWidth);
   1476     } else {
   1477       FX_FLOAT fWidth = pTextLayout->StartLayout(fMaxWidth);
   1478       fMaxWidth = CalculateWidgetAutoWidth(fWidth);
   1479       fWidth = GetWidthWithoutMargin(fMaxWidth);
   1480       pTextLayout->StartLayout(fWidth);
   1481     }
   1482     fCalcWidth = fMaxWidth;
   1483   }
   1484   if (m_pLayoutData->m_fWidgetHeight < 0) {
   1485     m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
   1486     m_pLayoutData->m_fWidgetHeight =
   1487         CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
   1488   }
   1489   fTextHeight = m_pLayoutData->m_fWidgetHeight;
   1490   fTextHeight = GetHeightWithoutMargin(fTextHeight);
   1491   pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
   1492   fCalcHeight = m_pLayoutData->m_fWidgetHeight;
   1493 }
   1494 FX_BOOL CXFA_WidgetAcc::LoadCaption() {
   1495   InitLayoutData();
   1496   return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
   1497 }
   1498 CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
   1499   return m_pLayoutData
   1500              ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout
   1501              : NULL;
   1502 }
   1503 CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
   1504   return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout
   1505                        : NULL;
   1506 }
   1507 CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() {
   1508   return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap
   1509                        : NULL;
   1510 }
   1511 CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage() {
   1512   return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap
   1513                        : NULL;
   1514 }
   1515 void CXFA_WidgetAcc::SetImageImage(CFX_DIBitmap* newImage) {
   1516   if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap == newImage) {
   1517     return;
   1518   }
   1519   if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap &&
   1520       !((CXFA_ImageLayoutData*)m_pLayoutData)->m_bNamedImage) {
   1521     delete ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap;
   1522     ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = NULL;
   1523   }
   1524   ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = newImage;
   1525 }
   1526 void CXFA_WidgetAcc::SetImageEditImage(CFX_DIBitmap* newImage) {
   1527   if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap == newImage) {
   1528     return;
   1529   }
   1530   if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap &&
   1531       !((CXFA_ImageEditData*)m_pLayoutData)->m_bNamedImage) {
   1532     delete ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap;
   1533     ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = NULL;
   1534   }
   1535   ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = newImage;
   1536 }
   1537 CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() {
   1538   return m_pLayoutData;
   1539 }
   1540 IFX_Font* CXFA_WidgetAcc::GetFDEFont() {
   1541   CFX_WideStringC wsFontName = FX_WSTRC(L"Courier");
   1542   FX_DWORD dwFontStyle = 0;
   1543   if (CXFA_Font font = this->GetFont()) {
   1544     if (font.IsBold()) {
   1545       dwFontStyle |= FX_FONTSTYLE_Bold;
   1546     }
   1547     if (font.IsItalic()) {
   1548       dwFontStyle |= FX_FONTSTYLE_Italic;
   1549     }
   1550     font.GetTypeface(wsFontName);
   1551   }
   1552   CXFA_FFDoc* pDoc = GetDoc();
   1553   return pDoc->GetApp()->GetXFAFontMgr()->GetFont(pDoc, wsFontName,
   1554                                                   dwFontStyle);
   1555 }
   1556 FX_FLOAT CXFA_WidgetAcc::GetFontSize() {
   1557   FX_FLOAT fFontSize = 10.0f;
   1558   if (CXFA_Font font = this->GetFont()) {
   1559     fFontSize = font.GetFontSize();
   1560   }
   1561   return fFontSize < 0.1f ? 10.0f : fFontSize;
   1562 }
   1563 FX_FLOAT CXFA_WidgetAcc::GetLineHeight() {
   1564   FX_FLOAT fLineHeight = 0;
   1565   if (CXFA_Para para = this->GetPara()) {
   1566     fLineHeight = para.GetLineHeight();
   1567   }
   1568   if (fLineHeight < 1) {
   1569     fLineHeight = GetFontSize() * 1.2f;
   1570   }
   1571   return fLineHeight;
   1572 }
   1573 FX_ARGB CXFA_WidgetAcc::GetTextColor() {
   1574   if (CXFA_Font font = this->GetFont()) {
   1575     return font.GetColor();
   1576   }
   1577   return 0xFF000000;
   1578 }
   1579 CXFA_Node* CXFA_TextProvider::GetTextNode(FX_BOOL& bRichText) {
   1580   bRichText = FALSE;
   1581   if (m_pTextNode) {
   1582     if (m_pTextNode->GetClassID() == XFA_ELEMENT_ExData) {
   1583       CFX_WideString wsContentType;
   1584       m_pTextNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
   1585                                 FALSE);
   1586       if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
   1587         bRichText = TRUE;
   1588       }
   1589     }
   1590     return m_pTextNode;
   1591   }
   1592   if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
   1593     CXFA_Node* pElementNode = m_pWidgetAcc->GetNode();
   1594     CXFA_Node* pValueNode = pElementNode->GetChild(0, XFA_ELEMENT_Value);
   1595     if (!pValueNode) {
   1596       return NULL;
   1597     }
   1598     CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
   1599     if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
   1600       CFX_WideString wsContentType;
   1601       pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
   1602       if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
   1603         bRichText = TRUE;
   1604       }
   1605     }
   1606     return pChildNode;
   1607   } else if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
   1608     CXFA_Node* pBind = m_pWidgetAcc->GetDatasets();
   1609     IFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
   1610     FXSYS_assert(pXMLNode);
   1611     for (IFDE_XMLNode* pXMLChild =
   1612              pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
   1613          pXMLChild;
   1614          pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
   1615       if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
   1616         IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLChild;
   1617         if (XFA_RecognizeRichText(pElement)) {
   1618           bRichText = TRUE;
   1619         }
   1620       }
   1621     }
   1622     return pBind;
   1623   } else if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
   1624     CXFA_Node* pCaptionNode =
   1625         m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
   1626     if (pCaptionNode == NULL) {
   1627       return NULL;
   1628     }
   1629     CXFA_Node* pValueNode = pCaptionNode->GetChild(0, XFA_ELEMENT_Value);
   1630     if (pValueNode == NULL) {
   1631       return NULL;
   1632     }
   1633     CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
   1634     if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
   1635       CFX_WideString wsContentType;
   1636       pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
   1637       if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
   1638         bRichText = TRUE;
   1639       }
   1640     }
   1641     return pChildNode;
   1642   }
   1643   CXFA_Node* pItemNode =
   1644       m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Items);
   1645   if (pItemNode == NULL) {
   1646     return NULL;
   1647   }
   1648   CXFA_Node* pNode = pItemNode->GetNodeItem(XFA_NODEITEM_FirstChild);
   1649   while (pNode) {
   1650     CFX_WideStringC wsName;
   1651     pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
   1652     if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover &&
   1653         wsName == FX_WSTRC(L"rollover")) {
   1654       return pNode;
   1655     }
   1656     if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == FX_WSTRC(L"down")) {
   1657       return pNode;
   1658     }
   1659     pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
   1660   }
   1661   return NULL;
   1662 }
   1663 CXFA_Para CXFA_TextProvider::GetParaNode() {
   1664   if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
   1665     return m_pWidgetAcc->GetPara();
   1666   }
   1667   CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
   1668   return pNode->GetChild(0, XFA_ELEMENT_Para);
   1669 }
   1670 CXFA_Font CXFA_TextProvider::GetFontNode() {
   1671   if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
   1672     return m_pWidgetAcc->GetFont();
   1673   }
   1674   CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
   1675   pNode = pNode->GetChild(0, XFA_ELEMENT_Font);
   1676   if (pNode) {
   1677     return pNode;
   1678   }
   1679   return m_pWidgetAcc->GetFont();
   1680 }
   1681 FX_BOOL CXFA_TextProvider::IsCheckButtonAndAutoWidth() {
   1682   XFA_ELEMENT eType = m_pWidgetAcc->GetUIType();
   1683   if (eType == XFA_ELEMENT_CheckButton) {
   1684     FX_FLOAT fWidth = 0;
   1685     return !m_pWidgetAcc->GetWidth(fWidth);
   1686   }
   1687   return FALSE;
   1688 }
   1689 FX_BOOL CXFA_TextProvider::GetEmbbedObj(FX_BOOL bURI,
   1690                                         FX_BOOL bRaw,
   1691                                         const CFX_WideString& wsAttr,
   1692                                         CFX_WideString& wsValue) {
   1693   if (m_eType != XFA_TEXTPROVIDERTYPE_Text) {
   1694     return FALSE;
   1695   }
   1696   if (bURI) {
   1697     CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode();
   1698     CXFA_Node* pParent = pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent);
   1699     CXFA_Document* pDocument = pWidgetNode->GetDocument();
   1700     CXFA_Node* pIDNode = NULL;
   1701     CXFA_WidgetAcc* pEmbAcc = NULL;
   1702     if (pParent) {
   1703       pIDNode = pDocument->GetNodeByID(pParent, wsAttr);
   1704     }
   1705     if (!pIDNode) {
   1706       pIDNode = pDocument->GetNodeByID(
   1707           (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Form), wsAttr);
   1708     }
   1709     if (pIDNode) {
   1710       pEmbAcc = (CXFA_WidgetAcc*)pIDNode->GetWidgetData();
   1711     }
   1712     if (pEmbAcc) {
   1713       pEmbAcc->GetValue(wsValue, XFA_VALUEPICTURE_Display);
   1714       return TRUE;
   1715     }
   1716   }
   1717   return FALSE;
   1718 }
   1719