• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
XFA_FFDeleteCalcData(void * pData)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:
CXFA_WidgetLayoutData()32   CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
~CXFA_WidgetLayoutData()33   virtual ~CXFA_WidgetLayoutData() {}
Release()34   virtual void Release() { delete this; }
35   FX_FLOAT m_fWidgetHeight;
36 };
37 class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
38  public:
CXFA_TextLayoutData()39   CXFA_TextLayoutData() : m_pTextLayout(NULL), m_pTextProvider(NULL) {}
~CXFA_TextLayoutData()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   }
LoadText(CXFA_WidgetAcc * pAcc)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:
CXFA_ImageLayoutData()62   CXFA_ImageLayoutData()
63       : m_pDIBitmap(NULL),
64         m_bNamedImage(FALSE),
65         m_iImageXDpi(0),
66         m_iImageYDpi(0) {}
67 
~CXFA_ImageLayoutData()68   ~CXFA_ImageLayoutData() {
69     if (m_pDIBitmap && !m_bNamedImage) {
70       delete m_pDIBitmap;
71     }
72     m_pDIBitmap = NULL;
73   }
74 
LoadImageData(CXFA_WidgetAcc * pAcc)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:
CXFA_FieldLayoutData()100   CXFA_FieldLayoutData()
101       : m_pCapTextLayout(NULL),
102         m_pCapTextProvider(NULL),
103         m_pTextOut(NULL),
104         m_pFieldSplitArray(NULL) {}
~CXFA_FieldLayoutData()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   }
LoadCaption(CXFA_WidgetAcc * pAcc)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:
CXFA_ImageEditData()148   CXFA_ImageEditData()
149       : m_pDIBitmap(NULL),
150         m_bNamedImage(FALSE),
151         m_iImageXDpi(0),
152         m_iImageYDpi(0) {}
153 
~CXFA_ImageEditData()154   ~CXFA_ImageEditData() {
155     if (m_pDIBitmap && !m_bNamedImage) {
156       delete m_pDIBitmap;
157     }
158     m_pDIBitmap = NULL;
159   }
LoadImageData(CXFA_WidgetAcc * pAcc)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 };
CXFA_WidgetAcc(CXFA_FFDocView * pDocView,CXFA_Node * pNode)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) {}
~CXFA_WidgetAcc()184 CXFA_WidgetAcc::~CXFA_WidgetAcc() {
185   if (m_pLayoutData) {
186     m_pLayoutData->Release();
187     m_pLayoutData = NULL;
188   }
189 }
GetName(CFX_WideString & wsName,int32_t iNameType)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 }
GetDatasets()204 CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
205   return m_pNode->GetBindData();
206 }
ProcessValueChanged()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 }
ResetData()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 }
SetImageEdit(const CFX_WideStringC & wsContentType,const CFX_WideStringC & wsHref,const CFX_WideStringC & wsData)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 
GetExclGroup()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 }
GetDocView()302 CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() {
303   return m_pDocView;
304 }
GetDoc()305 CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
306   return (CXFA_FFDoc*)m_pDocView->GetDoc();
307 }
GetApp()308 CXFA_FFApp* CXFA_WidgetAcc::GetApp() {
309   return GetDoc()->GetApp();
310 }
GetAppProvider()311 IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
312   return GetApp()->GetAppProvider();
313 }
ProcessEvent(int32_t iActivity,CXFA_EventParam * pEventParam)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 }
ProcessEvent(CXFA_Event & event,CXFA_EventParam * pEventParam)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 }
ProcessCalculate()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 }
ProcessScriptTestValidate(CXFA_Validate validate,int32_t iRet,FXJSE_HVALUE pRetValue,FX_BOOL bVersionFlag)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 }
ProcessFormatTestValidate(CXFA_Validate validate,FX_BOOL bVersionFlag)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 }
ProcessNullTestValidate(CXFA_Validate validate,int32_t iFlags,FX_BOOL bVersionFlag)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 }
GetValidateCaptionName(CFX_WideString & wsCaptionName,FX_BOOL bVersionFlag)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 }
GetValidateMessage(IXFA_AppProvider * pAppProvider,CFX_WideString & wsMessage,FX_BOOL bError,FX_BOOL bVersionFlag)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 }
ProcessValidate(int32_t iFlags)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 }
ExecuteScript(CXFA_Script script,CXFA_EventParam * pEventParam,FXJSE_HVALUE * pRetValue)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 }
GetNextWidget(CXFA_FFWidget * pWidget)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 }
UpdateUIDisplay(CXFA_FFWidget * pExcept)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 }
NotifyEvent(FX_DWORD dwEvent,CXFA_FFWidget * pWidget,void * pParam,void * pAdditional)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 }
CalcCaptionSize(CFX_SizeF & szCap)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 }
CalculateFieldAutoSize(CFX_SizeF & size)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 }
CalculateWidgetAutoSize(CFX_SizeF & size)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 }
CalculateTextContentSize(CFX_SizeF & size)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 }
CalculateTextEditAutoSize(CFX_SizeF & size)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 }
CalculateCheckButtonAutoSize(CFX_SizeF & size)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 }
CalculatePushButtonAutoSize(CFX_SizeF & size)970 FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
971   CalcCaptionSize(size);
972   return CalculateWidgetAutoSize(size);
973 }
CalculateImageAutoSize(CFX_SizeF & size)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 }
CalculateImageEditAutoSize(CFX_SizeF & size)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 }
LoadImageImage()1036 FX_BOOL CXFA_WidgetAcc::LoadImageImage() {
1037   InitLayoutData();
1038   return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
1039 }
LoadImageEditImage()1040 FX_BOOL CXFA_WidgetAcc::LoadImageEditImage() {
1041   InitLayoutData();
1042   return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
1043 }
GetImageDpi(int32_t & iImageXDpi,int32_t & iImageYDpi)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 }
GetImageEditDpi(int32_t & iImageXDpi,int32_t & iImageYDpi)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 }
CalculateTextAutoSize(CFX_SizeF & size)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 }
LoadText()1062 void CXFA_WidgetAcc::LoadText() {
1063   InitLayoutData();
1064   ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
1065 }
CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc)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 }
GetWidthWithoutMargin(FX_FLOAT fWidthCalc)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 }
CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc)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 }
GetHeightWithoutMargin(FX_FLOAT fHeightCalc)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 }
StartWidgetLayout(FX_FLOAT & fCalcWidth,FX_FLOAT & fCalcHeight)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 }
CalculateAccWidthAndHeight(XFA_ELEMENT eUIType,FX_FLOAT & fWidth,FX_FLOAT & fCalcHeight)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 }
FindSplitPos(int32_t iBlockIndex,FX_FLOAT & fCalcHeight)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 }
InitLayoutData()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 }
StartTextLayout(FX_FLOAT & fCalcWidth,FX_FLOAT & fCalcHeight)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 }
LoadCaption()1494 FX_BOOL CXFA_WidgetAcc::LoadCaption() {
1495   InitLayoutData();
1496   return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
1497 }
GetCaptionTextLayout()1498 CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
1499   return m_pLayoutData
1500              ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout
1501              : NULL;
1502 }
GetTextLayout()1503 CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
1504   return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout
1505                        : NULL;
1506 }
GetImageImage()1507 CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() {
1508   return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap
1509                        : NULL;
1510 }
GetImageEditImage()1511 CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage() {
1512   return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap
1513                        : NULL;
1514 }
SetImageImage(CFX_DIBitmap * newImage)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 }
SetImageEditImage(CFX_DIBitmap * newImage)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 }
GetWidgetLayoutData()1537 CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() {
1538   return m_pLayoutData;
1539 }
GetFDEFont()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 }
GetFontSize()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 }
GetLineHeight()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 }
GetTextColor()1573 FX_ARGB CXFA_WidgetAcc::GetTextColor() {
1574   if (CXFA_Font font = this->GetFont()) {
1575     return font.GetColor();
1576   }
1577   return 0xFF000000;
1578 }
GetTextNode(FX_BOOL & bRichText)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 }
GetParaNode()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 }
GetFontNode()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 }
IsCheckButtonAndAutoWidth()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 }
GetEmbbedObj(FX_BOOL bURI,FX_BOOL bRaw,const CFX_WideString & wsAttr,CFX_WideString & wsValue)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