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"
23static void XFA_FFDeleteCalcData(void* pData) {
24  if (pData) {
25    delete ((CXFA_CalcData*)pData);
26  }
27}
28static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteCalcData = {
29    XFA_FFDeleteCalcData, NULL};
30class 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};
37class 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};
60class 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};
98class 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};
143class CXFA_TextEditData : public CXFA_FieldLayoutData {
144 public:
145};
146class 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};
179CXFA_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) {}
184CXFA_WidgetAcc::~CXFA_WidgetAcc() {
185  if (m_pLayoutData) {
186    m_pLayoutData->Release();
187    m_pLayoutData = NULL;
188  }
189}
190FX_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}
204CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
205  return m_pNode->GetBindData();
206}
207FX_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}
214void 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}
268void 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
295CXFA_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}
302CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() {
303  return m_pDocView;
304}
305CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
306  return (CXFA_FFDoc*)m_pDocView->GetDoc();
307}
308CXFA_FFApp* CXFA_WidgetAcc::GetApp() {
309  return GetDoc()->GetApp();
310}
311IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
312  return GetApp()->GetAppProvider();
313}
314int32_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}
334int32_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}
357int32_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}
385void 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}
425int32_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}
476int32_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}
549void 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}
567void 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}
589int32_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}
635int32_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}
722CXFA_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}
731void 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}
742void 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}
761void 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}
815FX_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}
843FX_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}
883void 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}
912FX_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}
965FX_BOOL CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) {
966  FX_FLOAT fCheckSize = this->GetCheckButtonSize();
967  size.x = size.y = fCheckSize;
968  return CalculateFieldAutoSize(size);
969}
970FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
971  CalcCaptionSize(size);
972  return CalculateWidgetAutoSize(size);
973}
974FX_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}
1005FX_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}
1036FX_BOOL CXFA_WidgetAcc::LoadImageImage() {
1037  InitLayoutData();
1038  return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
1039}
1040FX_BOOL CXFA_WidgetAcc::LoadImageEditImage() {
1041  InitLayoutData();
1042  return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
1043}
1044void 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}
1048void 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}
1052FX_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}
1062void CXFA_WidgetAcc::LoadText() {
1063  InitLayoutData();
1064  ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
1065}
1066FX_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}
1083FX_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}
1093FX_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}
1110FX_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}
1120void 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}
1150void 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}
1193FX_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}
1426void 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}
1452void 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}
1494FX_BOOL CXFA_WidgetAcc::LoadCaption() {
1495  InitLayoutData();
1496  return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
1497}
1498CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
1499  return m_pLayoutData
1500             ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout
1501             : NULL;
1502}
1503CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
1504  return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout
1505                       : NULL;
1506}
1507CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() {
1508  return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap
1509                       : NULL;
1510}
1511CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage() {
1512  return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap
1513                       : NULL;
1514}
1515void 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}
1526void 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}
1537CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() {
1538  return m_pLayoutData;
1539}
1540IFX_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}
1556FX_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}
1563FX_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}
1573FX_ARGB CXFA_WidgetAcc::GetTextColor() {
1574  if (CXFA_Font font = this->GetFont()) {
1575    return font.GetColor();
1576  }
1577  return 0xFF000000;
1578}
1579CXFA_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}
1663CXFA_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}
1670CXFA_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}
1681FX_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}
1689FX_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