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 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: 45 CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {} 46 virtual ~CXFA_WidgetLayoutData() {} 47 48 FX_FLOAT m_fWidgetHeight; 49 }; 50 51 class CXFA_TextLayoutData : public CXFA_WidgetLayoutData { 52 public: 53 CXFA_TextLayoutData() {} 54 ~CXFA_TextLayoutData() override {} 55 56 CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); } 57 CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); } 58 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: 75 CXFA_ImageLayoutData() 76 : m_pDIBitmap(nullptr), 77 m_bNamedImage(false), 78 m_iImageXDpi(0), 79 m_iImageYDpi(0) {} 80 81 ~CXFA_ImageLayoutData() override { 82 if (m_pDIBitmap && !m_bNamedImage) 83 delete m_pDIBitmap; 84 } 85 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: 112 CXFA_FieldLayoutData() {} 113 ~CXFA_FieldLayoutData() override {} 114 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: 140 CXFA_ImageEditData() 141 : m_pDIBitmap(nullptr), 142 m_bNamedImage(false), 143 m_iImageXDpi(0), 144 m_iImageYDpi(0) {} 145 146 ~CXFA_ImageEditData() override { 147 if (m_pDIBitmap && !m_bNamedImage) 148 delete m_pDIBitmap; 149 } 150 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 172 CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode) 173 : CXFA_WidgetData(pNode), 174 m_pDocView(pDocView), 175 m_nRecursionDepth(0) {} 176 177 CXFA_WidgetAcc::~CXFA_WidgetAcc() {} 178 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 } 193 CXFA_Node* CXFA_WidgetAcc::GetDatasets() { 194 return m_pNode->GetBindData(); 195 } 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 } 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 } 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 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 } 292 CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() { 293 return m_pDocView; 294 } 295 CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() { 296 return m_pDocView->GetDoc(); 297 } 298 CXFA_FFApp* CXFA_WidgetAcc::GetApp() { 299 return GetDoc()->GetApp(); 300 } 301 IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() { 302 return GetApp()->GetAppProvider(); 303 } 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 } 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 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 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 } 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 } 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 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 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 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 } 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 } 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 } 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 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 } 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 } 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 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 } 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 } 916 bool CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) { 917 FX_FLOAT fCheckSize = GetCheckButtonSize(); 918 size = CFX_SizeF(fCheckSize, fCheckSize); 919 return CalculateFieldAutoSize(size); 920 } 921 bool CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) { 922 CalcCaptionSize(size); 923 return CalculateWidgetAutoSize(size); 924 } 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 } 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 } 984 bool CXFA_WidgetAcc::LoadImageImage() { 985 InitLayoutData(); 986 return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get()) 987 ->LoadImageData(this); 988 } 989 bool CXFA_WidgetAcc::LoadImageEditImage() { 990 InitLayoutData(); 991 return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get()) 992 ->LoadImageData(this); 993 } 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 } 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 } 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 } 1016 void CXFA_WidgetAcc::LoadText() { 1017 InitLayoutData(); 1018 static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(this); 1019 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 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 } 1439 bool CXFA_WidgetAcc::LoadCaption() { 1440 InitLayoutData(); 1441 return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get()) 1442 ->LoadCaption(this); 1443 } 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 } 1450 CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() { 1451 return m_pLayoutData 1452 ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get()) 1453 ->GetTextLayout() 1454 : nullptr; 1455 } 1456 CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() { 1457 return m_pLayoutData 1458 ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get()) 1459 ->m_pDIBitmap 1460 : nullptr; 1461 } 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 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 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 1493 CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() { 1494 return m_pLayoutData.get(); 1495 } 1496 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 } 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 } 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 } 1529 FX_ARGB CXFA_WidgetAcc::GetTextColor() { 1530 if (CXFA_Font font = GetFont()) { 1531 return font.GetColor(); 1532 } 1533 return 0xFF000000; 1534 } 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 } 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 } 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 } 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 } 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