1 // Copyright 2016 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 "fpdfsdk/cpdfsdk_widget.h" 8 9 #include <memory> 10 #include <sstream> 11 12 #include "core/fpdfapi/parser/cpdf_array.h" 13 #include "core/fpdfapi/parser/cpdf_dictionary.h" 14 #include "core/fpdfapi/parser/cpdf_document.h" 15 #include "core/fpdfapi/parser/cpdf_reference.h" 16 #include "core/fpdfapi/parser/cpdf_stream.h" 17 #include "core/fpdfapi/parser/cpdf_string.h" 18 #include "core/fpdfdoc/cpdf_defaultappearance.h" 19 #include "core/fpdfdoc/cpdf_formcontrol.h" 20 #include "core/fpdfdoc/cpdf_formfield.h" 21 #include "core/fpdfdoc/cpdf_iconfit.h" 22 #include "core/fpdfdoc/cpdf_interform.h" 23 #include "core/fxge/cfx_graphstatedata.h" 24 #include "core/fxge/cfx_pathdata.h" 25 #include "core/fxge/cfx_renderdevice.h" 26 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" 27 #include "fpdfsdk/cpdfsdk_interform.h" 28 #include "fpdfsdk/cpdfsdk_pageview.h" 29 #include "fpdfsdk/formfiller/cba_fontmap.h" 30 #include "fpdfsdk/fsdk_actionhandler.h" 31 #include "fpdfsdk/fsdk_define.h" 32 #include "fpdfsdk/pwl/cpwl_appstream.h" 33 #include "fpdfsdk/pwl/cpwl_edit.h" 34 35 #ifdef PDF_ENABLE_XFA 36 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" 37 #include "xfa/fxfa/cxfa_eventparam.h" 38 #include "xfa/fxfa/cxfa_ffdocview.h" 39 #include "xfa/fxfa/cxfa_ffwidget.h" 40 #include "xfa/fxfa/cxfa_ffwidgethandler.h" 41 #include "xfa/fxfa/cxfa_widgetacc.h" 42 #include "xfa/fxfa/parser/cxfa_node.h" 43 #endif // PDF_ENABLE_XFA 44 45 namespace { 46 47 // Convert a FX_ARGB to a FX_COLORREF. 48 FX_COLORREF ARGBToColorRef(FX_ARGB argb) { 49 return (((static_cast<uint32_t>(argb) & 0x00FF0000) >> 16) | 50 (static_cast<uint32_t>(argb) & 0x0000FF00) | 51 ((static_cast<uint32_t>(argb) & 0x000000FF) << 16)); 52 } 53 54 } // namespace 55 56 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, 57 CPDFSDK_PageView* pPageView, 58 CPDFSDK_InterForm* pInterForm) 59 : CPDFSDK_BAAnnot(pAnnot, pPageView), 60 m_pInterForm(pInterForm), 61 m_nAppearanceAge(0), 62 m_nValueAge(0) 63 #ifdef PDF_ENABLE_XFA 64 , 65 m_hMixXFAWidget(nullptr), 66 m_pWidgetHandler(nullptr) 67 #endif // PDF_ENABLE_XFA 68 { 69 } 70 71 CPDFSDK_Widget::~CPDFSDK_Widget() {} 72 73 #ifdef PDF_ENABLE_XFA 74 CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const { 75 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 76 if (pContext->GetFormType() == FormType::kXFAForeground) { 77 if (!m_hMixXFAWidget) { 78 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) { 79 WideString sName; 80 if (GetFieldType() == FormFieldType::kRadioButton) { 81 sName = GetAnnotName(); 82 if (sName.IsEmpty()) 83 sName = GetName(); 84 } else { 85 sName = GetName(); 86 } 87 88 if (!sName.IsEmpty()) 89 m_hMixXFAWidget = pDocView->GetWidgetByName(sName, nullptr); 90 } 91 } 92 return m_hMixXFAWidget.Get(); 93 } 94 return nullptr; 95 } 96 97 CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget() { 98 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 99 if (pContext->GetFormType() != FormType::kXFAForeground) 100 return nullptr; 101 102 CXFA_FFDocView* pDocView = pContext->GetXFADocView(); 103 if (!pDocView) 104 return nullptr; 105 106 WideString sName = GetName(); 107 return !sName.IsEmpty() ? pDocView->GetWidgetByName(sName, nullptr) : nullptr; 108 } 109 110 CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const { 111 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 112 if (pContext->GetFormType() != FormType::kXFAForeground) 113 return nullptr; 114 115 if (!m_pWidgetHandler) { 116 CXFA_FFDocView* pDocView = pContext->GetXFADocView(); 117 if (pDocView) 118 m_pWidgetHandler = pDocView->GetWidgetHandler(); 119 } 120 return m_pWidgetHandler.Get(); 121 } 122 123 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) { 124 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; 125 126 switch (eXFAAAT) { 127 case PDFSDK_XFA_Click: 128 eEventType = XFA_EVENT_Click; 129 break; 130 case PDFSDK_XFA_Full: 131 eEventType = XFA_EVENT_Full; 132 break; 133 case PDFSDK_XFA_PreOpen: 134 eEventType = XFA_EVENT_PreOpen; 135 break; 136 case PDFSDK_XFA_PostOpen: 137 eEventType = XFA_EVENT_PostOpen; 138 break; 139 } 140 141 return eEventType; 142 } 143 144 static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT, 145 bool bWillCommit) { 146 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; 147 148 switch (eAAT) { 149 case CPDF_AAction::CursorEnter: 150 eEventType = XFA_EVENT_MouseEnter; 151 break; 152 case CPDF_AAction::CursorExit: 153 eEventType = XFA_EVENT_MouseExit; 154 break; 155 case CPDF_AAction::ButtonDown: 156 eEventType = XFA_EVENT_MouseDown; 157 break; 158 case CPDF_AAction::ButtonUp: 159 eEventType = XFA_EVENT_MouseUp; 160 break; 161 case CPDF_AAction::GetFocus: 162 eEventType = XFA_EVENT_Enter; 163 break; 164 case CPDF_AAction::LoseFocus: 165 eEventType = XFA_EVENT_Exit; 166 break; 167 case CPDF_AAction::PageOpen: 168 case CPDF_AAction::PageClose: 169 case CPDF_AAction::PageVisible: 170 case CPDF_AAction::PageInvisible: 171 break; 172 case CPDF_AAction::KeyStroke: 173 if (!bWillCommit) 174 eEventType = XFA_EVENT_Change; 175 break; 176 case CPDF_AAction::Validate: 177 eEventType = XFA_EVENT_Validate; 178 break; 179 case CPDF_AAction::OpenPage: 180 case CPDF_AAction::ClosePage: 181 case CPDF_AAction::Format: 182 case CPDF_AAction::Calculate: 183 case CPDF_AAction::CloseDocument: 184 case CPDF_AAction::SaveDocument: 185 case CPDF_AAction::DocumentSaved: 186 case CPDF_AAction::PrintDocument: 187 case CPDF_AAction::DocumentPrinted: 188 break; 189 case CPDF_AAction::NumberOfActions: 190 NOTREACHED(); 191 break; 192 } 193 194 return eEventType; 195 } 196 197 bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) { 198 CXFA_FFWidget* hWidget = GetMixXFAWidget(); 199 if (!hWidget) 200 return false; 201 202 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler(); 203 if (!pXFAWidgetHandler) 204 return false; 205 206 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); 207 208 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && 209 GetFieldType() == FormFieldType::kRadioButton) { 210 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { 211 if (pXFAWidgetHandler->HasEvent(hGroupWidget->GetNode()->GetWidgetAcc(), 212 eEventType)) { 213 return true; 214 } 215 } 216 } 217 218 return pXFAWidgetHandler->HasEvent(hWidget->GetNode()->GetWidgetAcc(), 219 eEventType); 220 } 221 222 bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, 223 PDFSDK_FieldAction& data, 224 CPDFSDK_PageView* pPageView) { 225 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 226 227 CXFA_FFWidget* hWidget = GetMixXFAWidget(); 228 if (!hWidget) 229 return false; 230 231 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); 232 if (eEventType == XFA_EVENT_Unknown) 233 return false; 234 235 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler(); 236 if (!pXFAWidgetHandler) 237 return false; 238 239 CXFA_EventParam param; 240 param.m_eType = eEventType; 241 param.m_wsChange = data.sChange; 242 param.m_iCommitKey = data.nCommitKey; 243 param.m_bShift = data.bShift; 244 param.m_iSelStart = data.nSelStart; 245 param.m_iSelEnd = data.nSelEnd; 246 param.m_wsFullText = data.sValue; 247 param.m_bKeyDown = data.bKeyDown; 248 param.m_bModifier = data.bModifier; 249 param.m_wsNewText = data.sValue; 250 if (data.nSelEnd > data.nSelStart) 251 param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart); 252 253 for (const auto& c : data.sChange) 254 param.m_wsNewText.Insert(data.nSelStart, c); 255 256 param.m_wsPrevText = data.sValue; 257 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && 258 GetFieldType() == FormFieldType::kRadioButton) { 259 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { 260 CXFA_WidgetAcc* pAcc = hGroupWidget->GetNode()->GetWidgetAcc(); 261 param.m_pTarget = pAcc; 262 if (pXFAWidgetHandler->ProcessEvent(pAcc, ¶m) != 263 XFA_EVENTERROR_Success) { 264 return false; 265 } 266 } 267 } 268 CXFA_WidgetAcc* pAcc = hWidget->GetNode()->GetWidgetAcc(); 269 param.m_pTarget = pAcc; 270 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 271 272 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) 273 pDocView->UpdateDocView(); 274 275 return nRet == XFA_EVENTERROR_Success; 276 } 277 278 void CPDFSDK_Widget::Synchronize(bool bSynchronizeElse) { 279 CXFA_FFWidget* hWidget = GetMixXFAWidget(); 280 if (!hWidget) 281 return; 282 283 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc(); 284 if (!pWidgetAcc) 285 return; 286 287 CPDF_FormField* pFormField = GetFormField(); 288 switch (GetFieldType()) { 289 case FormFieldType::kCheckBox: 290 case FormFieldType::kRadioButton: { 291 CPDF_FormControl* pFormCtrl = GetFormControl(); 292 XFA_CHECKSTATE eCheckState = 293 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off; 294 pWidgetAcc->SetCheckState(eCheckState, true); 295 break; 296 } 297 case FormFieldType::kTextField: 298 pWidgetAcc->SetValue(XFA_VALUEPICTURE_Edit, pFormField->GetValue()); 299 break; 300 case FormFieldType::kListBox: { 301 pWidgetAcc->ClearAllSelections(); 302 303 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { 304 int nIndex = pFormField->GetSelectedIndex(i); 305 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems(false)) 306 pWidgetAcc->SetItemState(nIndex, true, false, false, true); 307 } 308 break; 309 } 310 case FormFieldType::kComboBox: { 311 pWidgetAcc->ClearAllSelections(); 312 313 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { 314 int nIndex = pFormField->GetSelectedIndex(i); 315 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems(false)) 316 pWidgetAcc->SetItemState(nIndex, true, false, false, true); 317 } 318 pWidgetAcc->SetValue(XFA_VALUEPICTURE_Edit, pFormField->GetValue()); 319 break; 320 } 321 default: 322 break; 323 } 324 325 if (bSynchronizeElse) { 326 CPDFXFA_Context* context = m_pPageView->GetFormFillEnv()->GetXFAContext(); 327 context->GetXFADocView()->ProcessValueChanged(pWidgetAcc); 328 } 329 } 330 331 void CPDFSDK_Widget::SynchronizeXFAValue() { 332 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 333 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); 334 if (!pXFADocView) 335 return; 336 337 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 338 if (GetXFAWidgetHandler()) { 339 CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(), 340 GetFormControl()); 341 } 342 } 343 } 344 345 void CPDFSDK_Widget::SynchronizeXFAItems() { 346 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 347 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); 348 if (!pXFADocView) 349 return; 350 351 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 352 if (GetXFAWidgetHandler()) 353 SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr); 354 } 355 } 356 357 void CPDFSDK_Widget::SynchronizeXFAValue(CXFA_FFDocView* pXFADocView, 358 CXFA_FFWidget* hWidget, 359 CPDF_FormField* pFormField, 360 CPDF_FormControl* pFormControl) { 361 ASSERT(hWidget); 362 ASSERT(pFormControl); 363 364 switch (pFormField->GetFieldType()) { 365 case FormFieldType::kCheckBox: { 366 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 367 pFormField->CheckControl( 368 pFormField->GetControlIndex(pFormControl), 369 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); 370 } 371 break; 372 } 373 case FormFieldType::kRadioButton: { 374 // TODO(weili): Check whether we need to handle checkbox and radio 375 // button differently, otherwise, merge these two cases. 376 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 377 pFormField->CheckControl( 378 pFormField->GetControlIndex(pFormControl), 379 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); 380 } 381 break; 382 } 383 case FormFieldType::kTextField: { 384 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 385 pFormField->SetValue(pWidgetAcc->GetValue(XFA_VALUEPICTURE_Display), 386 true); 387 } 388 break; 389 } 390 case FormFieldType::kListBox: { 391 pFormField->ClearSelection(false); 392 393 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 394 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { 395 int nIndex = pWidgetAcc->GetSelectedItem(i); 396 397 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { 398 pFormField->SetItemSelection(nIndex, true, true); 399 } 400 } 401 } 402 break; 403 } 404 case FormFieldType::kComboBox: { 405 pFormField->ClearSelection(false); 406 407 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 408 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { 409 int nIndex = pWidgetAcc->GetSelectedItem(i); 410 411 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { 412 pFormField->SetItemSelection(nIndex, true, true); 413 } 414 } 415 pFormField->SetValue(pWidgetAcc->GetValue(XFA_VALUEPICTURE_Display), 416 true); 417 } 418 break; 419 } 420 default: 421 break; 422 } 423 } 424 425 void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView, 426 CXFA_FFWidget* hWidget, 427 CPDF_FormField* pFormField, 428 CPDF_FormControl* pFormControl) { 429 ASSERT(hWidget); 430 431 switch (pFormField->GetFieldType()) { 432 case FormFieldType::kListBox: { 433 pFormField->ClearSelection(false); 434 pFormField->ClearOptions(true); 435 436 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 437 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(false); i < sz; 438 i++) { 439 pFormField->InsertOption( 440 pWidgetAcc->GetChoiceListItem(i, false).value_or(L""), i, true); 441 } 442 } 443 break; 444 } 445 case FormFieldType::kComboBox: { 446 pFormField->ClearSelection(false); 447 pFormField->ClearOptions(false); 448 449 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 450 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(false); i < sz; 451 i++) { 452 pFormField->InsertOption( 453 pWidgetAcc->GetChoiceListItem(i, false).value_or(L""), i, false); 454 } 455 } 456 457 pFormField->SetValue(L"", true); 458 break; 459 } 460 default: 461 break; 462 } 463 } 464 #endif // PDF_ENABLE_XFA 465 466 bool CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode) { 467 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictFor("AP"); 468 if (!pAP) 469 return false; 470 471 // Choose the right sub-ap 472 const char* ap_entry = "N"; 473 if (mode == CPDF_Annot::Down) 474 ap_entry = "D"; 475 else if (mode == CPDF_Annot::Rollover) 476 ap_entry = "R"; 477 if (!pAP->KeyExist(ap_entry)) 478 ap_entry = "N"; 479 480 // Get the AP stream or subdirectory 481 CPDF_Object* psub = pAP->GetDirectObjectFor(ap_entry); 482 if (!psub) 483 return false; 484 485 FormFieldType fieldType = GetFieldType(); 486 switch (fieldType) { 487 case FormFieldType::kPushButton: 488 case FormFieldType::kComboBox: 489 case FormFieldType::kListBox: 490 case FormFieldType::kTextField: 491 case FormFieldType::kSignature: 492 return psub->IsStream(); 493 case FormFieldType::kCheckBox: 494 case FormFieldType::kRadioButton: 495 if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) { 496 return !!pSubDict->GetStreamFor(GetAppState()); 497 } 498 return false; 499 default: 500 return true; 501 } 502 } 503 504 FormFieldType CPDFSDK_Widget::GetFieldType() const { 505 CPDF_FormField* pField = GetFormField(); 506 return pField ? pField->GetFieldType() : FormFieldType::kUnknown; 507 } 508 509 bool CPDFSDK_Widget::IsAppearanceValid() { 510 #ifdef PDF_ENABLE_XFA 511 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext(); 512 FormType formType = pContext->GetFormType(); 513 if (formType == FormType::kXFAFull) 514 return true; 515 #endif // PDF_ENABLE_XFA 516 return CPDFSDK_BAAnnot::IsAppearanceValid(); 517 } 518 519 int CPDFSDK_Widget::GetLayoutOrder() const { 520 return 2; 521 } 522 523 int CPDFSDK_Widget::GetFieldFlags() const { 524 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm(); 525 CPDF_FormControl* pFormControl = 526 pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict()); 527 CPDF_FormField* pFormField = pFormControl->GetField(); 528 return pFormField->GetFieldFlags(); 529 } 530 531 bool CPDFSDK_Widget::IsSignatureWidget() const { 532 return GetFieldType() == FormFieldType::kSignature; 533 } 534 535 CPDF_FormField* CPDFSDK_Widget::GetFormField() const { 536 CPDF_FormControl* pControl = GetFormControl(); 537 return pControl ? pControl->GetField() : nullptr; 538 } 539 540 CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const { 541 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm(); 542 return pPDFInterForm->GetControlByDict(GetAnnotDict()); 543 } 544 545 CPDF_FormControl* CPDFSDK_Widget::GetFormControl( 546 CPDF_InterForm* pInterForm, 547 const CPDF_Dictionary* pAnnotDict) { 548 ASSERT(pAnnotDict); 549 return pInterForm->GetControlByDict(pAnnotDict); 550 } 551 552 int CPDFSDK_Widget::GetRotate() const { 553 CPDF_FormControl* pCtrl = GetFormControl(); 554 return pCtrl->GetRotation() % 360; 555 } 556 557 #ifdef PDF_ENABLE_XFA 558 WideString CPDFSDK_Widget::GetName() const { 559 CPDF_FormField* pFormField = GetFormField(); 560 return pFormField->GetFullName(); 561 } 562 #endif // PDF_ENABLE_XFA 563 564 bool CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const { 565 CPDF_FormControl* pFormCtrl = GetFormControl(); 566 int iColorType = 0; 567 color = ARGBToColorRef(pFormCtrl->GetBackgroundColor(iColorType)); 568 return iColorType != CFX_Color::kTransparent; 569 } 570 571 bool CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const { 572 CPDF_FormControl* pFormCtrl = GetFormControl(); 573 int iColorType = 0; 574 color = ARGBToColorRef(pFormCtrl->GetBorderColor(iColorType)); 575 return iColorType != CFX_Color::kTransparent; 576 } 577 578 bool CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const { 579 CPDF_FormControl* pFormCtrl = GetFormControl(); 580 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); 581 if (!da.HasColor()) 582 return false; 583 584 FX_ARGB argb; 585 int iColorType = CFX_Color::kTransparent; 586 da.GetColor(argb, iColorType); 587 color = ARGBToColorRef(argb); 588 return iColorType != CFX_Color::kTransparent; 589 } 590 591 float CPDFSDK_Widget::GetFontSize() const { 592 CPDF_FormControl* pFormCtrl = GetFormControl(); 593 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance(); 594 float fFontSize; 595 pDa.GetFont(&fFontSize); 596 return fFontSize; 597 } 598 599 int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const { 600 #ifdef PDF_ENABLE_XFA 601 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 602 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 603 if (nIndex < pWidgetAcc->CountSelectedItems()) 604 return pWidgetAcc->GetSelectedItem(nIndex); 605 } 606 } 607 #endif // PDF_ENABLE_XFA 608 CPDF_FormField* pFormField = GetFormField(); 609 return pFormField->GetSelectedIndex(nIndex); 610 } 611 612 #ifdef PDF_ENABLE_XFA 613 WideString CPDFSDK_Widget::GetValue(bool bDisplay) const { 614 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 615 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 616 return pWidgetAcc->GetValue(bDisplay ? XFA_VALUEPICTURE_Display 617 : XFA_VALUEPICTURE_Edit); 618 } 619 } 620 #else 621 WideString CPDFSDK_Widget::GetValue() const { 622 #endif // PDF_ENABLE_XFA 623 CPDF_FormField* pFormField = GetFormField(); 624 return pFormField->GetValue(); 625 } 626 627 WideString CPDFSDK_Widget::GetDefaultValue() const { 628 CPDF_FormField* pFormField = GetFormField(); 629 return pFormField->GetDefaultValue(); 630 } 631 632 WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const { 633 CPDF_FormField* pFormField = GetFormField(); 634 return pFormField->GetOptionLabel(nIndex); 635 } 636 637 int CPDFSDK_Widget::CountOptions() const { 638 CPDF_FormField* pFormField = GetFormField(); 639 return pFormField->CountOptions(); 640 } 641 642 bool CPDFSDK_Widget::IsOptionSelected(int nIndex) const { 643 #ifdef PDF_ENABLE_XFA 644 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 645 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) { 646 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems(false)) 647 return pWidgetAcc->GetItemState(nIndex); 648 649 return false; 650 } 651 } 652 #endif // PDF_ENABLE_XFA 653 CPDF_FormField* pFormField = GetFormField(); 654 return pFormField->IsItemSelected(nIndex); 655 } 656 657 int CPDFSDK_Widget::GetTopVisibleIndex() const { 658 CPDF_FormField* pFormField = GetFormField(); 659 return pFormField->GetTopVisibleIndex(); 660 } 661 662 bool CPDFSDK_Widget::IsChecked() const { 663 #ifdef PDF_ENABLE_XFA 664 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 665 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) 666 return pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On; 667 } 668 #endif // PDF_ENABLE_XFA 669 CPDF_FormControl* pFormCtrl = GetFormControl(); 670 return pFormCtrl->IsChecked(); 671 } 672 673 int CPDFSDK_Widget::GetAlignment() const { 674 CPDF_FormControl* pFormCtrl = GetFormControl(); 675 return pFormCtrl->GetControlAlignment(); 676 } 677 678 int CPDFSDK_Widget::GetMaxLen() const { 679 CPDF_FormField* pFormField = GetFormField(); 680 return pFormField->GetMaxLen(); 681 } 682 683 void CPDFSDK_Widget::SetCheck(bool bChecked, bool bNotify) { 684 CPDF_FormControl* pFormCtrl = GetFormControl(); 685 CPDF_FormField* pFormField = pFormCtrl->GetField(); 686 pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, 687 bNotify); 688 #ifdef PDF_ENABLE_XFA 689 if (!IsWidgetAppearanceValid(CPDF_Annot::Normal)) 690 ResetAppearance(true); 691 if (!bNotify) 692 Synchronize(true); 693 #endif // PDF_ENABLE_XFA 694 } 695 696 void CPDFSDK_Widget::SetValue(const WideString& sValue, bool bNotify) { 697 CPDF_FormField* pFormField = GetFormField(); 698 pFormField->SetValue(sValue, bNotify); 699 #ifdef PDF_ENABLE_XFA 700 if (!bNotify) 701 Synchronize(true); 702 #endif // PDF_ENABLE_XFA 703 } 704 705 void CPDFSDK_Widget::SetDefaultValue(const WideString& sValue) {} 706 void CPDFSDK_Widget::SetOptionSelection(int index, 707 bool bSelected, 708 bool bNotify) { 709 CPDF_FormField* pFormField = GetFormField(); 710 pFormField->SetItemSelection(index, bSelected, bNotify); 711 #ifdef PDF_ENABLE_XFA 712 if (!bNotify) 713 Synchronize(true); 714 #endif // PDF_ENABLE_XFA 715 } 716 717 void CPDFSDK_Widget::ClearSelection(bool bNotify) { 718 CPDF_FormField* pFormField = GetFormField(); 719 pFormField->ClearSelection(bNotify); 720 #ifdef PDF_ENABLE_XFA 721 if (!bNotify) 722 Synchronize(true); 723 #endif // PDF_ENABLE_XFA 724 } 725 726 void CPDFSDK_Widget::SetTopVisibleIndex(int index) {} 727 728 void CPDFSDK_Widget::SetAppModified() { 729 m_bAppModified = true; 730 } 731 732 void CPDFSDK_Widget::ClearAppModified() { 733 m_bAppModified = false; 734 } 735 736 bool CPDFSDK_Widget::IsAppModified() const { 737 return m_bAppModified; 738 } 739 740 #ifdef PDF_ENABLE_XFA 741 void CPDFSDK_Widget::ResetAppearance(bool bValueChanged) { 742 switch (GetFieldType()) { 743 case FormFieldType::kTextField: 744 case FormFieldType::kComboBox: { 745 bool bFormatted = false; 746 WideString sValue = OnFormat(bFormatted); 747 ResetAppearance(bFormatted ? &sValue : nullptr, true); 748 break; 749 } 750 default: 751 ResetAppearance(nullptr, false); 752 break; 753 } 754 } 755 #endif // PDF_ENABLE_XFA 756 757 void CPDFSDK_Widget::ResetAppearance(const WideString* sValue, 758 bool bValueChanged) { 759 SetAppModified(); 760 761 m_nAppearanceAge++; 762 if (bValueChanged) 763 m_nValueAge++; 764 765 CPWL_AppStream appStream(this, GetAPDict()); 766 switch (GetFieldType()) { 767 case FormFieldType::kPushButton: 768 appStream.SetAsPushButton(); 769 break; 770 case FormFieldType::kCheckBox: 771 appStream.SetAsCheckBox(); 772 break; 773 case FormFieldType::kRadioButton: 774 appStream.SetAsRadioButton(); 775 break; 776 case FormFieldType::kComboBox: 777 appStream.SetAsComboBox(sValue); 778 break; 779 case FormFieldType::kListBox: 780 appStream.SetAsListBox(); 781 break; 782 case FormFieldType::kTextField: 783 appStream.SetAsTextField(sValue); 784 break; 785 default: 786 break; 787 } 788 789 m_pAnnot->ClearCachedAP(); 790 } 791 792 WideString CPDFSDK_Widget::OnFormat(bool& bFormatted) { 793 CPDF_FormField* pFormField = GetFormField(); 794 ASSERT(pFormField); 795 return m_pInterForm->OnFormat(pFormField, bFormatted); 796 } 797 798 void CPDFSDK_Widget::ResetFieldAppearance(bool bValueChanged) { 799 CPDF_FormField* pFormField = GetFormField(); 800 ASSERT(pFormField); 801 m_pInterForm->ResetFieldAppearance(pFormField, nullptr, bValueChanged); 802 } 803 804 void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, 805 const CFX_Matrix& mtUser2Device, 806 CPDF_Annot::AppearanceMode mode, 807 const CPDF_RenderOptions* pOptions) { 808 FormFieldType fieldType = GetFieldType(); 809 810 if ((fieldType == FormFieldType::kCheckBox || 811 fieldType == FormFieldType::kRadioButton) && 812 mode == CPDF_Annot::Normal && 813 !IsWidgetAppearanceValid(CPDF_Annot::Normal)) { 814 CFX_PathData pathData; 815 816 CFX_FloatRect rcAnnot = GetRect(); 817 818 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right, 819 rcAnnot.top); 820 821 CFX_GraphStateData gsd; 822 gsd.m_LineWidth = 0.0f; 823 824 pDevice->DrawPath(&pathData, &mtUser2Device, &gsd, 0, 0xFFAAAAAA, 825 FXFILL_ALTERNATE); 826 } else { 827 CPDFSDK_BAAnnot::DrawAppearance(pDevice, mtUser2Device, mode, pOptions); 828 } 829 } 830 831 void CPDFSDK_Widget::UpdateField() { 832 CPDF_FormField* pFormField = GetFormField(); 833 ASSERT(pFormField); 834 m_pInterForm->UpdateField(pFormField); 835 } 836 837 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, 838 CPDFSDK_PageView* pPageView) { 839 FormFieldType fieldType = GetFieldType(); 840 if (!m_pInterForm->IsNeedHighLight(fieldType)) 841 return; 842 843 CFX_Matrix page2device; 844 pPageView->GetCurrentMatrix(page2device); 845 846 CFX_FloatRect rcDevice = GetRect(); 847 CFX_PointF tmp = 848 page2device.Transform(CFX_PointF(rcDevice.left, rcDevice.bottom)); 849 rcDevice.left = tmp.x; 850 rcDevice.bottom = tmp.y; 851 852 tmp = page2device.Transform(CFX_PointF(rcDevice.right, rcDevice.top)); 853 rcDevice.right = tmp.x; 854 rcDevice.top = tmp.y; 855 rcDevice.Normalize(); 856 857 FX_RECT rcDev = rcDevice.ToFxRect(); 858 pDevice->FillRect( 859 &rcDev, ArgbEncode(static_cast<int>(m_pInterForm->GetHighlightAlpha()), 860 m_pInterForm->GetHighlightColor(fieldType))); 861 } 862 863 CFX_FloatRect CPDFSDK_Widget::GetClientRect() const { 864 CFX_FloatRect rcWindow = GetRotatedRect(); 865 float fBorderWidth = (float)GetBorderWidth(); 866 switch (GetBorderStyle()) { 867 case BorderStyle::BEVELED: 868 case BorderStyle::INSET: 869 fBorderWidth *= 2.0f; 870 break; 871 default: 872 break; 873 } 874 return rcWindow.GetDeflated(fBorderWidth, fBorderWidth); 875 } 876 877 CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const { 878 CFX_FloatRect rectAnnot = GetRect(); 879 float fWidth = rectAnnot.right - rectAnnot.left; 880 float fHeight = rectAnnot.top - rectAnnot.bottom; 881 882 CPDF_FormControl* pControl = GetFormControl(); 883 CFX_FloatRect rcPDFWindow; 884 switch (abs(pControl->GetRotation() % 360)) { 885 case 0: 886 case 180: 887 default: 888 rcPDFWindow = CFX_FloatRect(0, 0, fWidth, fHeight); 889 break; 890 case 90: 891 case 270: 892 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth); 893 break; 894 } 895 896 return rcPDFWindow; 897 } 898 899 CFX_Matrix CPDFSDK_Widget::GetMatrix() const { 900 CFX_Matrix mt; 901 CPDF_FormControl* pControl = GetFormControl(); 902 CFX_FloatRect rcAnnot = GetRect(); 903 float fWidth = rcAnnot.right - rcAnnot.left; 904 float fHeight = rcAnnot.top - rcAnnot.bottom; 905 906 switch (abs(pControl->GetRotation() % 360)) { 907 default: 908 case 0: 909 break; 910 case 90: 911 mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0); 912 break; 913 case 180: 914 mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight); 915 break; 916 case 270: 917 mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight); 918 break; 919 } 920 921 return mt; 922 } 923 924 CFX_Color CPDFSDK_Widget::GetTextPWLColor() const { 925 CFX_Color crText = CFX_Color(CFX_Color::kGray, 0); 926 927 CPDF_FormControl* pFormCtrl = GetFormControl(); 928 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); 929 if (da.HasColor()) { 930 int32_t iColorType; 931 float fc[4]; 932 da.GetColor(iColorType, fc); 933 crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 934 } 935 936 return crText; 937 } 938 939 CFX_Color CPDFSDK_Widget::GetBorderPWLColor() const { 940 CFX_Color crBorder; 941 942 CPDF_FormControl* pFormCtrl = GetFormControl(); 943 int32_t iColorType; 944 float fc[4]; 945 pFormCtrl->GetOriginalBorderColor(iColorType, fc); 946 if (iColorType > 0) 947 crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 948 949 return crBorder; 950 } 951 952 CFX_Color CPDFSDK_Widget::GetFillPWLColor() const { 953 CFX_Color crFill; 954 955 CPDF_FormControl* pFormCtrl = GetFormControl(); 956 int32_t iColorType; 957 float fc[4]; 958 pFormCtrl->GetOriginalBackgroundColor(iColorType, fc); 959 if (iColorType > 0) 960 crFill = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 961 962 return crFill; 963 } 964 965 bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, 966 PDFSDK_FieldAction& data, 967 CPDFSDK_PageView* pPageView) { 968 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv(); 969 970 #ifdef PDF_ENABLE_XFA 971 CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext(); 972 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { 973 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit); 974 975 if (eEventType != XFA_EVENT_Unknown) { 976 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) { 977 CXFA_EventParam param; 978 param.m_eType = eEventType; 979 param.m_wsChange = data.sChange; 980 param.m_iCommitKey = data.nCommitKey; 981 param.m_bShift = data.bShift; 982 param.m_iSelStart = data.nSelStart; 983 param.m_iSelEnd = data.nSelEnd; 984 param.m_wsFullText = data.sValue; 985 param.m_bKeyDown = data.bKeyDown; 986 param.m_bModifier = data.bModifier; 987 param.m_wsNewText = data.sValue; 988 if (data.nSelEnd > data.nSelStart) 989 param.m_wsNewText.Delete(data.nSelStart, 990 data.nSelEnd - data.nSelStart); 991 for (int i = data.sChange.GetLength() - 1; i >= 0; i--) 992 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); 993 param.m_wsPrevText = data.sValue; 994 995 CXFA_WidgetAcc* pAcc = hWidget->GetNode()->GetWidgetAcc(); 996 param.m_pTarget = pAcc; 997 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 998 999 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) 1000 pDocView->UpdateDocView(); 1001 1002 if (nRet == XFA_EVENTERROR_Success) 1003 return true; 1004 } 1005 } 1006 } 1007 #endif // PDF_ENABLE_XFA 1008 1009 CPDF_Action action = GetAAction(type); 1010 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) { 1011 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHandler(); 1012 return pActionHandler->DoAction_Field(action, type, pFormFillEnv, 1013 GetFormField(), data); 1014 } 1015 return false; 1016 } 1017 1018 CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) { 1019 switch (eAAT) { 1020 case CPDF_AAction::CursorEnter: 1021 case CPDF_AAction::CursorExit: 1022 case CPDF_AAction::ButtonDown: 1023 case CPDF_AAction::ButtonUp: 1024 case CPDF_AAction::GetFocus: 1025 case CPDF_AAction::LoseFocus: 1026 case CPDF_AAction::PageOpen: 1027 case CPDF_AAction::PageClose: 1028 case CPDF_AAction::PageVisible: 1029 case CPDF_AAction::PageInvisible: 1030 return CPDFSDK_BAAnnot::GetAAction(eAAT); 1031 1032 case CPDF_AAction::KeyStroke: 1033 case CPDF_AAction::Format: 1034 case CPDF_AAction::Validate: 1035 case CPDF_AAction::Calculate: { 1036 CPDF_FormField* pField = GetFormField(); 1037 if (pField->GetAdditionalAction().GetDict()) 1038 return pField->GetAdditionalAction().GetAction(eAAT); 1039 return CPDFSDK_BAAnnot::GetAAction(eAAT); 1040 } 1041 default: 1042 break; 1043 } 1044 1045 return CPDF_Action(nullptr); 1046 } 1047 1048 WideString CPDFSDK_Widget::GetAlternateName() const { 1049 CPDF_FormField* pFormField = GetFormField(); 1050 return pFormField->GetAlternateName(); 1051 } 1052