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