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 "fpdfsdk/include/fsdk_baseform.h" 8 9 #include <memory> 10 11 #include "fpdfsdk/include/formfiller/FFL_FormFiller.h" 12 #include "fpdfsdk/include/fsdk_actionhandler.h" 13 #include "fpdfsdk/include/fsdk_baseannot.h" 14 #include "fpdfsdk/include/fsdk_define.h" 15 #include "fpdfsdk/include/fsdk_mgr.h" 16 #include "fpdfsdk/include/javascript/IJavaScript.h" 17 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h" 18 19 #ifdef PDF_ENABLE_XFA 20 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" 21 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" 22 #endif // PDF_ENABLE_XFA 23 24 #define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01) 25 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) 26 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) 27 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb)) 28 29 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, 30 CPDFSDK_PageView* pPageView, 31 CPDFSDK_InterForm* pInterForm) 32 : CPDFSDK_BAAnnot(pAnnot, pPageView), 33 m_pInterForm(pInterForm), 34 m_nAppAge(0), 35 m_nValueAge(0) 36 #ifdef PDF_ENABLE_XFA 37 , 38 m_hMixXFAWidget(NULL), 39 m_pWidgetHandler(NULL) 40 #endif // PDF_ENABLE_XFA 41 { 42 } 43 44 CPDFSDK_Widget::~CPDFSDK_Widget() {} 45 46 #ifdef PDF_ENABLE_XFA 47 IXFA_Widget* CPDFSDK_Widget::GetMixXFAWidget() const { 48 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 49 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 50 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) { 51 if (!m_hMixXFAWidget) { 52 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) { 53 CFX_WideString sName; 54 if (this->GetFieldType() == FIELDTYPE_RADIOBUTTON) { 55 sName = this->GetAnnotName(); 56 if (sName.IsEmpty()) 57 sName = GetName(); 58 } else 59 sName = GetName(); 60 61 if (!sName.IsEmpty()) 62 m_hMixXFAWidget = pDocView->GetWidgetByName(sName); 63 } 64 } 65 return m_hMixXFAWidget; 66 } 67 68 return NULL; 69 } 70 71 IXFA_Widget* CPDFSDK_Widget::GetGroupMixXFAWidget() { 72 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 73 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 74 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) { 75 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) { 76 CFX_WideString sName = GetName(); 77 if (!sName.IsEmpty()) 78 return pDocView->GetWidgetByName(sName); 79 } 80 } 81 82 return nullptr; 83 } 84 85 IXFA_WidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const { 86 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 87 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 88 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) { 89 if (!m_pWidgetHandler) { 90 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) { 91 m_pWidgetHandler = pDocView->GetWidgetHandler(); 92 } 93 } 94 return m_pWidgetHandler; 95 } 96 97 return NULL; 98 } 99 100 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) { 101 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; 102 103 switch (eXFAAAT) { 104 case PDFSDK_XFA_Click: 105 eEventType = XFA_EVENT_Click; 106 break; 107 case PDFSDK_XFA_Full: 108 eEventType = XFA_EVENT_Full; 109 break; 110 case PDFSDK_XFA_PreOpen: 111 eEventType = XFA_EVENT_PreOpen; 112 break; 113 case PDFSDK_XFA_PostOpen: 114 eEventType = XFA_EVENT_PostOpen; 115 break; 116 } 117 118 return eEventType; 119 } 120 121 static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT, 122 FX_BOOL bWillCommit) { 123 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; 124 125 switch (eAAT) { 126 case CPDF_AAction::CursorEnter: 127 eEventType = XFA_EVENT_MouseEnter; 128 break; 129 case CPDF_AAction::CursorExit: 130 eEventType = XFA_EVENT_MouseExit; 131 break; 132 case CPDF_AAction::ButtonDown: 133 eEventType = XFA_EVENT_MouseDown; 134 break; 135 case CPDF_AAction::ButtonUp: 136 eEventType = XFA_EVENT_MouseUp; 137 break; 138 case CPDF_AAction::GetFocus: 139 eEventType = XFA_EVENT_Enter; 140 break; 141 case CPDF_AAction::LoseFocus: 142 eEventType = XFA_EVENT_Exit; 143 break; 144 case CPDF_AAction::PageOpen: 145 break; 146 case CPDF_AAction::PageClose: 147 break; 148 case CPDF_AAction::PageVisible: 149 break; 150 case CPDF_AAction::PageInvisible: 151 break; 152 case CPDF_AAction::KeyStroke: 153 if (!bWillCommit) { 154 eEventType = XFA_EVENT_Change; 155 } 156 break; 157 case CPDF_AAction::Validate: 158 eEventType = XFA_EVENT_Validate; 159 break; 160 case CPDF_AAction::OpenPage: 161 case CPDF_AAction::ClosePage: 162 case CPDF_AAction::Format: 163 case CPDF_AAction::Calculate: 164 case CPDF_AAction::CloseDocument: 165 case CPDF_AAction::SaveDocument: 166 case CPDF_AAction::DocumentSaved: 167 case CPDF_AAction::PrintDocument: 168 case CPDF_AAction::DocumentPrinted: 169 break; 170 } 171 172 return eEventType; 173 } 174 175 FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) { 176 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 177 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 178 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); 179 180 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && 181 GetFieldType() == FIELDTYPE_RADIOBUTTON) { 182 if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) { 183 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget); 184 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType)) 185 return TRUE; 186 } 187 } 188 189 { 190 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget); 191 return pXFAWidgetHandler->HasEvent(pAcc, eEventType); 192 } 193 } 194 } 195 196 return FALSE; 197 } 198 199 FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, 200 PDFSDK_FieldAction& data, 201 CPDFSDK_PageView* pPageView) { 202 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 203 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 204 if (IXFA_Widget* hWidget = GetMixXFAWidget()) { 205 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); 206 207 if (eEventType != XFA_EVENT_Unknown) { 208 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 209 CXFA_EventParam param; 210 param.m_eType = eEventType; 211 param.m_wsChange = data.sChange; 212 param.m_iCommitKey = data.nCommitKey; 213 param.m_bShift = data.bShift; 214 param.m_iSelStart = data.nSelStart; 215 param.m_iSelEnd = data.nSelEnd; 216 param.m_wsFullText = data.sValue; 217 param.m_bKeyDown = data.bKeyDown; 218 param.m_bModifier = data.bModifier; 219 param.m_wsNewText = data.sValue; 220 if (data.nSelEnd > data.nSelStart) 221 param.m_wsNewText.Delete(data.nSelStart, 222 data.nSelEnd - data.nSelStart); 223 for (int i = 0; i < data.sChange.GetLength(); i++) 224 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); 225 param.m_wsPrevText = data.sValue; 226 227 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && 228 GetFieldType() == FIELDTYPE_RADIOBUTTON) { 229 if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) { 230 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget); 231 param.m_pTarget = pAcc; 232 pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 233 } 234 235 { 236 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget); 237 param.m_pTarget = pAcc; 238 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 239 return nRet == XFA_EVENTERROR_Sucess; 240 } 241 } else { 242 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget); 243 param.m_pTarget = pAcc; 244 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 245 return nRet == XFA_EVENTERROR_Sucess; 246 } 247 248 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) { 249 pDocView->UpdateDocView(); 250 } 251 } 252 } 253 } 254 255 return FALSE; 256 } 257 258 void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) { 259 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 260 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 261 CPDF_FormField* pFormField = GetFormField(); 262 ASSERT(pFormField != NULL); 263 264 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) { 265 switch (GetFieldType()) { 266 case FIELDTYPE_CHECKBOX: 267 case FIELDTYPE_RADIOBUTTON: { 268 CPDF_FormControl* pFormCtrl = GetFormControl(); 269 ASSERT(pFormCtrl != NULL); 270 271 XFA_CHECKSTATE eCheckState = 272 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off; 273 pWidgetAcc->SetCheckState(eCheckState); 274 } break; 275 case FIELDTYPE_TEXTFIELD: 276 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); 277 break; 278 case FIELDTYPE_LISTBOX: { 279 pWidgetAcc->ClearAllSelections(); 280 281 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; 282 i++) { 283 int nIndex = pFormField->GetSelectedIndex(i); 284 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) 285 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE); 286 } 287 } break; 288 case FIELDTYPE_COMBOBOX: { 289 pWidgetAcc->ClearAllSelections(); 290 291 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; 292 i++) { 293 int nIndex = pFormField->GetSelectedIndex(i); 294 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) 295 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE); 296 } 297 } 298 299 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); 300 break; 301 } 302 303 if (bSynchronizeElse) 304 pWidgetAcc->ProcessValueChanged(); 305 } 306 } 307 } 308 } 309 310 void CPDFSDK_Widget::SynchronizeXFAValue() { 311 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 312 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 313 IXFA_DocView* pXFADocView = pDoc->GetXFADocView(); 314 if (!pXFADocView) 315 return; 316 317 if (IXFA_Widget* hWidget = GetMixXFAWidget()) { 318 if (GetXFAWidgetHandler()) { 319 CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(), 320 GetFormControl()); 321 } 322 } 323 } 324 325 void CPDFSDK_Widget::SynchronizeXFAItems() { 326 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 327 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 328 IXFA_DocView* pXFADocView = pDoc->GetXFADocView(); 329 if (!pXFADocView) 330 return; 331 332 if (IXFA_Widget* hWidget = GetMixXFAWidget()) { 333 if (GetXFAWidgetHandler()) 334 SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr); 335 } 336 } 337 338 void CPDFSDK_Widget::SynchronizeXFAValue(IXFA_DocView* pXFADocView, 339 IXFA_Widget* hWidget, 340 CPDF_FormField* pFormField, 341 CPDF_FormControl* pFormControl) { 342 ASSERT(pXFADocView != NULL); 343 ASSERT(hWidget != NULL); 344 345 if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) { 346 ASSERT(pFormField != NULL); 347 ASSERT(pFormControl != NULL); 348 349 switch (pFormField->GetFieldType()) { 350 case FIELDTYPE_CHECKBOX: { 351 if (CXFA_WidgetAcc* pWidgetAcc = 352 pXFAWidgetHandler->GetDataAcc(hWidget)) { 353 FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On; 354 355 pFormField->CheckControl(pFormField->GetControlIndex(pFormControl), 356 bChecked, TRUE); 357 } 358 } break; 359 case FIELDTYPE_RADIOBUTTON: { 360 if (CXFA_WidgetAcc* pWidgetAcc = 361 pXFAWidgetHandler->GetDataAcc(hWidget)) { 362 FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On; 363 364 pFormField->CheckControl(pFormField->GetControlIndex(pFormControl), 365 bChecked, TRUE); 366 } 367 } break; 368 case FIELDTYPE_TEXTFIELD: { 369 if (CXFA_WidgetAcc* pWidgetAcc = 370 pXFAWidgetHandler->GetDataAcc(hWidget)) { 371 CFX_WideString sValue; 372 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); 373 pFormField->SetValue(sValue, TRUE); 374 } 375 } break; 376 case FIELDTYPE_LISTBOX: { 377 pFormField->ClearSelection(FALSE); 378 379 if (CXFA_WidgetAcc* pWidgetAcc = 380 pXFAWidgetHandler->GetDataAcc(hWidget)) { 381 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { 382 int nIndex = pWidgetAcc->GetSelectedItem(i); 383 384 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { 385 pFormField->SetItemSelection(nIndex, TRUE, TRUE); 386 } 387 } 388 } 389 } break; 390 case FIELDTYPE_COMBOBOX: { 391 pFormField->ClearSelection(FALSE); 392 393 if (CXFA_WidgetAcc* pWidgetAcc = 394 pXFAWidgetHandler->GetDataAcc(hWidget)) { 395 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { 396 int nIndex = pWidgetAcc->GetSelectedItem(i); 397 398 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { 399 pFormField->SetItemSelection(nIndex, TRUE, TRUE); 400 } 401 } 402 403 CFX_WideString sValue; 404 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); 405 pFormField->SetValue(sValue, TRUE); 406 } 407 } break; 408 } 409 } 410 } 411 412 void CPDFSDK_Widget::SynchronizeXFAItems(IXFA_DocView* pXFADocView, 413 IXFA_Widget* hWidget, 414 CPDF_FormField* pFormField, 415 CPDF_FormControl* pFormControl) { 416 ASSERT(pXFADocView != NULL); 417 ASSERT(hWidget != NULL); 418 419 if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) { 420 ASSERT(pFormField != NULL); 421 422 switch (pFormField->GetFieldType()) { 423 case FIELDTYPE_LISTBOX: { 424 pFormField->ClearSelection(FALSE); 425 pFormField->ClearOptions(TRUE); 426 427 if (CXFA_WidgetAcc* pWidgetAcc = 428 pXFAWidgetHandler->GetDataAcc(hWidget)) { 429 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; 430 i++) { 431 CFX_WideString swText; 432 pWidgetAcc->GetChoiceListItem(swText, i); 433 434 pFormField->InsertOption(swText, i, TRUE); 435 } 436 } 437 } break; 438 case FIELDTYPE_COMBOBOX: { 439 pFormField->ClearSelection(FALSE); 440 pFormField->ClearOptions(FALSE); 441 442 if (CXFA_WidgetAcc* pWidgetAcc = 443 pXFAWidgetHandler->GetDataAcc(hWidget)) { 444 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; 445 i++) { 446 CFX_WideString swText; 447 pWidgetAcc->GetChoiceListItem(swText, i); 448 449 pFormField->InsertOption(swText, i, FALSE); 450 } 451 } 452 453 pFormField->SetValue(L"", TRUE); 454 } break; 455 } 456 } 457 } 458 #endif // PDF_ENABLE_XFA 459 460 FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid( 461 CPDF_Annot::AppearanceMode mode) { 462 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP"); 463 if (!pAP) 464 return FALSE; 465 466 // Choose the right sub-ap 467 const FX_CHAR* ap_entry = "N"; 468 if (mode == CPDF_Annot::Down) 469 ap_entry = "D"; 470 else if (mode == CPDF_Annot::Rollover) 471 ap_entry = "R"; 472 if (!pAP->KeyExist(ap_entry)) 473 ap_entry = "N"; 474 475 // Get the AP stream or subdirectory 476 CPDF_Object* psub = pAP->GetElementValue(ap_entry); 477 if (!psub) 478 return FALSE; 479 480 int nFieldType = GetFieldType(); 481 switch (nFieldType) { 482 case FIELDTYPE_PUSHBUTTON: 483 case FIELDTYPE_COMBOBOX: 484 case FIELDTYPE_LISTBOX: 485 case FIELDTYPE_TEXTFIELD: 486 case FIELDTYPE_SIGNATURE: 487 return psub->IsStream(); 488 case FIELDTYPE_CHECKBOX: 489 case FIELDTYPE_RADIOBUTTON: 490 if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) { 491 return pSubDict->GetStream(GetAppState()) != NULL; 492 } 493 return FALSE; 494 } 495 return TRUE; 496 } 497 498 int CPDFSDK_Widget::GetFieldType() const { 499 return GetFormField()->GetFieldType(); 500 } 501 502 FX_BOOL CPDFSDK_Widget::IsAppearanceValid() { 503 #ifdef PDF_ENABLE_XFA 504 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); 505 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); 506 int nDocType = pDoc->GetDocType(); 507 if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA) 508 return TRUE; 509 #endif // PDF_ENABLE_XFA 510 return CPDFSDK_BAAnnot::IsAppearanceValid(); 511 } 512 513 int CPDFSDK_Widget::GetFieldFlags() const { 514 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm(); 515 CPDF_FormControl* pFormControl = 516 pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict()); 517 CPDF_FormField* pFormField = pFormControl->GetField(); 518 return pFormField->GetFieldFlags(); 519 } 520 521 CFX_ByteString CPDFSDK_Widget::GetSubType() const { 522 int nType = GetFieldType(); 523 524 if (nType == FIELDTYPE_SIGNATURE) 525 return BFFT_SIGNATURE; 526 return CPDFSDK_Annot::GetSubType(); 527 } 528 529 CPDF_FormField* CPDFSDK_Widget::GetFormField() const { 530 return GetFormControl()->GetField(); 531 } 532 533 CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const { 534 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm(); 535 return pPDFInterForm->GetControlByDict(GetAnnotDict()); 536 } 537 538 CPDF_FormControl* CPDFSDK_Widget::GetFormControl( 539 CPDF_InterForm* pInterForm, 540 const CPDF_Dictionary* pAnnotDict) { 541 ASSERT(pAnnotDict); 542 return pInterForm->GetControlByDict(pAnnotDict); 543 } 544 545 int CPDFSDK_Widget::GetRotate() const { 546 CPDF_FormControl* pCtrl = GetFormControl(); 547 return pCtrl->GetRotation() % 360; 548 } 549 550 #ifdef PDF_ENABLE_XFA 551 CFX_WideString CPDFSDK_Widget::GetName() const { 552 CPDF_FormField* pFormField = GetFormField(); 553 return pFormField->GetFullName(); 554 } 555 #endif // PDF_ENABLE_XFA 556 557 FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const { 558 CPDF_FormControl* pFormCtrl = GetFormControl(); 559 int iColorType = 0; 560 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType)); 561 562 return iColorType != COLORTYPE_TRANSPARENT; 563 } 564 565 FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const { 566 CPDF_FormControl* pFormCtrl = GetFormControl(); 567 int iColorType = 0; 568 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType)); 569 570 return iColorType != COLORTYPE_TRANSPARENT; 571 } 572 573 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const { 574 CPDF_FormControl* pFormCtrl = GetFormControl(); 575 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); 576 if (da.HasColor()) { 577 FX_ARGB argb; 578 int iColorType = COLORTYPE_TRANSPARENT; 579 da.GetColor(argb, iColorType); 580 color = FX_ARGBTOCOLORREF(argb); 581 582 return iColorType != COLORTYPE_TRANSPARENT; 583 } 584 585 return FALSE; 586 } 587 588 FX_FLOAT CPDFSDK_Widget::GetFontSize() const { 589 CPDF_FormControl* pFormCtrl = GetFormControl(); 590 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance(); 591 CFX_ByteString csFont = ""; 592 FX_FLOAT fFontSize = 0.0f; 593 pDa.GetFont(csFont, fFontSize); 594 595 return fFontSize; 596 } 597 598 int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const { 599 #ifdef PDF_ENABLE_XFA 600 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 601 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 602 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) { 603 if (nIndex < pWidgetAcc->CountSelectedItems()) 604 return pWidgetAcc->GetSelectedItem(nIndex); 605 } 606 } 607 } 608 #endif // PDF_ENABLE_XFA 609 CPDF_FormField* pFormField = GetFormField(); 610 return pFormField->GetSelectedIndex(nIndex); 611 } 612 613 #ifdef PDF_ENABLE_XFA 614 CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay) const { 615 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 616 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 617 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) { 618 CFX_WideString sValue; 619 pWidgetAcc->GetValue(sValue, bDisplay ? XFA_VALUEPICTURE_Display 620 : XFA_VALUEPICTURE_Edit); 621 return sValue; 622 } 623 } 624 } 625 #else 626 CFX_WideString CPDFSDK_Widget::GetValue() const { 627 #endif // PDF_ENABLE_XFA 628 CPDF_FormField* pFormField = GetFormField(); 629 return pFormField->GetValue(); 630 } 631 632 CFX_WideString CPDFSDK_Widget::GetDefaultValue() const { 633 CPDF_FormField* pFormField = GetFormField(); 634 return pFormField->GetDefaultValue(); 635 } 636 637 CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const { 638 CPDF_FormField* pFormField = GetFormField(); 639 return pFormField->GetOptionLabel(nIndex); 640 } 641 642 int CPDFSDK_Widget::CountOptions() const { 643 CPDF_FormField* pFormField = GetFormField(); 644 return pFormField->CountOptions(); 645 } 646 647 FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const { 648 #ifdef PDF_ENABLE_XFA 649 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 650 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 651 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) { 652 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) 653 return pWidgetAcc->GetItemState(nIndex); 654 655 return FALSE; 656 } 657 } 658 } 659 #endif // PDF_ENABLE_XFA 660 CPDF_FormField* pFormField = GetFormField(); 661 return pFormField->IsItemSelected(nIndex); 662 } 663 664 int CPDFSDK_Widget::GetTopVisibleIndex() const { 665 CPDF_FormField* pFormField = GetFormField(); 666 return pFormField->GetTopVisibleIndex(); 667 } 668 669 FX_BOOL CPDFSDK_Widget::IsChecked() const { 670 #ifdef PDF_ENABLE_XFA 671 if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) { 672 if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) { 673 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) { 674 FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On; 675 return bChecked; 676 } 677 } 678 } 679 #endif // PDF_ENABLE_XFA 680 CPDF_FormControl* pFormCtrl = GetFormControl(); 681 return pFormCtrl->IsChecked(); 682 } 683 684 int CPDFSDK_Widget::GetAlignment() const { 685 CPDF_FormControl* pFormCtrl = GetFormControl(); 686 return pFormCtrl->GetControlAlignment(); 687 } 688 689 int CPDFSDK_Widget::GetMaxLen() const { 690 CPDF_FormField* pFormField = GetFormField(); 691 return pFormField->GetMaxLen(); 692 } 693 694 void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify) { 695 CPDF_FormControl* pFormCtrl = GetFormControl(); 696 CPDF_FormField* pFormField = pFormCtrl->GetField(); 697 pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, 698 bNotify); 699 #ifdef PDF_ENABLE_XFA 700 if (!IsWidgetAppearanceValid(CPDF_Annot::Normal)) 701 ResetAppearance(TRUE); 702 if (!bNotify) 703 Synchronize(TRUE); 704 #endif // PDF_ENABLE_XFA 705 } 706 707 void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) { 708 CPDF_FormField* pFormField = GetFormField(); 709 pFormField->SetValue(sValue, bNotify); 710 #ifdef PDF_ENABLE_XFA 711 if (!bNotify) 712 Synchronize(TRUE); 713 #endif // PDF_ENABLE_XFA 714 } 715 716 void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {} 717 void CPDFSDK_Widget::SetOptionSelection(int index, 718 FX_BOOL bSelected, 719 FX_BOOL bNotify) { 720 CPDF_FormField* pFormField = GetFormField(); 721 pFormField->SetItemSelection(index, bSelected, bNotify); 722 #ifdef PDF_ENABLE_XFA 723 if (!bNotify) 724 Synchronize(TRUE); 725 #endif // PDF_ENABLE_XFA 726 } 727 728 void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) { 729 CPDF_FormField* pFormField = GetFormField(); 730 pFormField->ClearSelection(bNotify); 731 #ifdef PDF_ENABLE_XFA 732 if (!bNotify) 733 Synchronize(TRUE); 734 #endif // PDF_ENABLE_XFA 735 } 736 737 void CPDFSDK_Widget::SetTopVisibleIndex(int index) {} 738 739 void CPDFSDK_Widget::SetAppModified() { 740 m_bAppModified = TRUE; 741 } 742 743 void CPDFSDK_Widget::ClearAppModified() { 744 m_bAppModified = FALSE; 745 } 746 747 FX_BOOL CPDFSDK_Widget::IsAppModified() const { 748 return m_bAppModified; 749 } 750 751 #ifdef PDF_ENABLE_XFA 752 void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) { 753 switch (GetFieldType()) { 754 case FIELDTYPE_TEXTFIELD: 755 case FIELDTYPE_COMBOBOX: { 756 FX_BOOL bFormated = FALSE; 757 CFX_WideString sValue = this->OnFormat(bFormated); 758 if (bFormated) 759 this->ResetAppearance(sValue, TRUE); 760 else 761 this->ResetAppearance(NULL, TRUE); 762 } break; 763 default: 764 this->ResetAppearance(NULL, FALSE); 765 break; 766 } 767 } 768 #endif // PDF_ENABLE_XFA 769 770 void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue, 771 FX_BOOL bValueChanged) { 772 SetAppModified(); 773 774 m_nAppAge++; 775 if (m_nAppAge > 999999) 776 m_nAppAge = 0; 777 if (bValueChanged) 778 m_nValueAge++; 779 780 int nFieldType = GetFieldType(); 781 782 switch (nFieldType) { 783 case FIELDTYPE_PUSHBUTTON: 784 ResetAppearance_PushButton(); 785 break; 786 case FIELDTYPE_CHECKBOX: 787 ResetAppearance_CheckBox(); 788 break; 789 case FIELDTYPE_RADIOBUTTON: 790 ResetAppearance_RadioButton(); 791 break; 792 case FIELDTYPE_COMBOBOX: 793 ResetAppearance_ComboBox(sValue); 794 break; 795 case FIELDTYPE_LISTBOX: 796 ResetAppearance_ListBox(); 797 break; 798 case FIELDTYPE_TEXTFIELD: 799 ResetAppearance_TextField(sValue); 800 break; 801 } 802 803 m_pAnnot->ClearCachedAP(); 804 } 805 806 CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) { 807 CPDF_FormField* pFormField = GetFormField(); 808 ASSERT(pFormField); 809 return m_pInterForm->OnFormat(pFormField, bFormated); 810 } 811 812 void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) { 813 CPDF_FormField* pFormField = GetFormField(); 814 ASSERT(pFormField); 815 m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged); 816 } 817 818 void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, 819 const CFX_Matrix* pUser2Device, 820 CPDF_Annot::AppearanceMode mode, 821 const CPDF_RenderOptions* pOptions) { 822 int nFieldType = GetFieldType(); 823 824 if ((nFieldType == FIELDTYPE_CHECKBOX || 825 nFieldType == FIELDTYPE_RADIOBUTTON) && 826 mode == CPDF_Annot::Normal && 827 !IsWidgetAppearanceValid(CPDF_Annot::Normal)) { 828 CFX_PathData pathData; 829 830 CPDF_Rect rcAnnot = GetRect(); 831 832 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right, 833 rcAnnot.top); 834 835 CFX_GraphStateData gsd; 836 gsd.m_LineWidth = 0.0f; 837 838 pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA, 839 FXFILL_ALTERNATE); 840 } else { 841 CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions); 842 } 843 } 844 845 void CPDFSDK_Widget::UpdateField() { 846 CPDF_FormField* pFormField = GetFormField(); 847 ASSERT(pFormField); 848 m_pInterForm->UpdateField(pFormField); 849 } 850 851 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, 852 CPDFSDK_PageView* pPageView) { 853 int nFieldType = GetFieldType(); 854 if (m_pInterForm->IsNeedHighLight(nFieldType)) { 855 CPDF_Rect rc = GetRect(); 856 FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType); 857 uint8_t alpha = m_pInterForm->GetHighlightAlpha(); 858 859 CFX_FloatRect rcDevice; 860 ASSERT(m_pInterForm->GetDocument()); 861 CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv(); 862 if (!pEnv) 863 return; 864 CFX_Matrix page2device; 865 pPageView->GetCurrentMatrix(page2device); 866 page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), 867 rcDevice.left, rcDevice.bottom); 868 page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), 869 rcDevice.right, rcDevice.top); 870 871 rcDevice.Normalize(); 872 873 FX_ARGB argb = ArgbEncode((int)alpha, color); 874 FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right, 875 (int)rcDevice.bottom); 876 pDevice->FillRect(&rcDev, argb); 877 } 878 } 879 880 void CPDFSDK_Widget::ResetAppearance_PushButton() { 881 CPDF_FormControl* pControl = GetFormControl(); 882 CPDF_Rect rcWindow = GetRotatedRect(); 883 int32_t nLayout = 0; 884 switch (pControl->GetTextPosition()) { 885 case TEXTPOS_ICON: 886 nLayout = PPBL_ICON; 887 break; 888 case TEXTPOS_BELOW: 889 nLayout = PPBL_ICONTOPLABELBOTTOM; 890 break; 891 case TEXTPOS_ABOVE: 892 nLayout = PPBL_LABELTOPICONBOTTOM; 893 break; 894 case TEXTPOS_RIGHT: 895 nLayout = PPBL_ICONLEFTLABELRIGHT; 896 break; 897 case TEXTPOS_LEFT: 898 nLayout = PPBL_LABELLEFTICONRIGHT; 899 break; 900 case TEXTPOS_OVERLAID: 901 nLayout = PPBL_LABELOVERICON; 902 break; 903 default: 904 nLayout = PPBL_LABEL; 905 break; 906 } 907 908 CPWL_Color crBackground, crBorder; 909 910 int iColorType; 911 FX_FLOAT fc[4]; 912 913 pControl->GetOriginalBackgroundColor(iColorType, fc); 914 if (iColorType > 0) 915 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 916 917 pControl->GetOriginalBorderColor(iColorType, fc); 918 if (iColorType > 0) 919 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 920 921 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 922 int32_t nBorderStyle = 0; 923 CPWL_Dash dsBorder(3, 0, 0); 924 CPWL_Color crLeftTop, crRightBottom; 925 926 switch (GetBorderStyle()) { 927 case BBS_DASH: 928 nBorderStyle = PBS_DASH; 929 dsBorder = CPWL_Dash(3, 3, 0); 930 break; 931 case BBS_BEVELED: 932 nBorderStyle = PBS_BEVELED; 933 fBorderWidth *= 2; 934 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); 935 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); 936 break; 937 case BBS_INSET: 938 nBorderStyle = PBS_INSET; 939 fBorderWidth *= 2; 940 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5); 941 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75); 942 break; 943 case BBS_UNDERLINE: 944 nBorderStyle = PBS_UNDERLINED; 945 break; 946 default: 947 nBorderStyle = PBS_SOLID; 948 break; 949 } 950 951 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth); 952 953 CPWL_Color crText(COLORTYPE_GRAY, 0); 954 955 FX_FLOAT fFontSize = 12.0f; 956 CFX_ByteString csNameTag; 957 958 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance(); 959 if (da.HasColor()) { 960 da.GetColor(iColorType, fc); 961 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 962 } 963 964 if (da.HasFont()) 965 da.GetFont(csNameTag, fFontSize); 966 967 CFX_WideString csWCaption; 968 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption; 969 970 if (pControl->HasMKEntry("CA")) { 971 csNormalCaption = pControl->GetNormalCaption(); 972 } 973 if (pControl->HasMKEntry("RC")) { 974 csRolloverCaption = pControl->GetRolloverCaption(); 975 } 976 if (pControl->HasMKEntry("AC")) { 977 csDownCaption = pControl->GetDownCaption(); 978 } 979 980 CPDF_Stream* pNormalIcon = NULL; 981 CPDF_Stream* pRolloverIcon = NULL; 982 CPDF_Stream* pDownIcon = NULL; 983 984 if (pControl->HasMKEntry("I")) { 985 pNormalIcon = pControl->GetNormalIcon(); 986 } 987 if (pControl->HasMKEntry("RI")) { 988 pRolloverIcon = pControl->GetRolloverIcon(); 989 } 990 if (pControl->HasMKEntry("IX")) { 991 pDownIcon = pControl->GetDownIcon(); 992 } 993 994 if (pNormalIcon) { 995 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) { 996 if (pImageDict->GetString("Name").IsEmpty()) 997 pImageDict->SetAtString("Name", "ImgA"); 998 } 999 } 1000 1001 if (pRolloverIcon) { 1002 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) { 1003 if (pImageDict->GetString("Name").IsEmpty()) 1004 pImageDict->SetAtString("Name", "ImgB"); 1005 } 1006 } 1007 1008 if (pDownIcon) { 1009 if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) { 1010 if (pImageDict->GetString("Name").IsEmpty()) 1011 pImageDict->SetAtString("Name", "ImgC"); 1012 } 1013 } 1014 1015 CPDF_IconFit iconFit = pControl->GetIconFit(); 1016 1017 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument(); 1018 CPDFDoc_Environment* pEnv = pDoc->GetEnv(); 1019 1020 CBA_FontMap font_map(this, pEnv->GetSysHandler()); 1021 font_map.SetAPType("N"); 1022 1023 CFX_ByteString csAP = 1024 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 1025 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1026 crLeftTop, crRightBottom, nBorderStyle, 1027 dsBorder) + 1028 CPWL_Utils::GetPushButtonAppStream( 1029 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, 1030 pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout); 1031 1032 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP); 1033 if (pNormalIcon) 1034 AddImageToAppearance("N", pNormalIcon); 1035 1036 CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode(); 1037 if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) { 1038 if (csRolloverCaption.IsEmpty() && !pRolloverIcon) { 1039 csRolloverCaption = csNormalCaption; 1040 pRolloverIcon = pNormalIcon; 1041 } 1042 1043 font_map.SetAPType("R"); 1044 1045 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 1046 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1047 crLeftTop, crRightBottom, 1048 nBorderStyle, dsBorder) + 1049 CPWL_Utils::GetPushButtonAppStream( 1050 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, 1051 pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize, 1052 nLayout); 1053 1054 WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP); 1055 if (pRolloverIcon) 1056 AddImageToAppearance("R", pRolloverIcon); 1057 1058 if (csDownCaption.IsEmpty() && !pDownIcon) { 1059 csDownCaption = csNormalCaption; 1060 pDownIcon = pNormalIcon; 1061 } 1062 1063 switch (nBorderStyle) { 1064 case PBS_BEVELED: { 1065 CPWL_Color crTemp = crLeftTop; 1066 crLeftTop = crRightBottom; 1067 crRightBottom = crTemp; 1068 } break; 1069 case PBS_INSET: 1070 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0); 1071 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); 1072 break; 1073 } 1074 1075 font_map.SetAPType("D"); 1076 1077 csAP = CPWL_Utils::GetRectFillAppStream( 1078 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + 1079 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1080 crLeftTop, crRightBottom, 1081 nBorderStyle, dsBorder) + 1082 CPWL_Utils::GetPushButtonAppStream( 1083 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, 1084 pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout); 1085 1086 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP); 1087 if (pDownIcon) 1088 AddImageToAppearance("D", pDownIcon); 1089 } else { 1090 RemoveAppearance("D"); 1091 RemoveAppearance("R"); 1092 } 1093 } 1094 1095 void CPDFSDK_Widget::ResetAppearance_CheckBox() { 1096 CPDF_FormControl* pControl = GetFormControl(); 1097 CPWL_Color crBackground, crBorder, crText; 1098 int iColorType; 1099 FX_FLOAT fc[4]; 1100 1101 pControl->GetOriginalBackgroundColor(iColorType, fc); 1102 if (iColorType > 0) 1103 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1104 1105 pControl->GetOriginalBorderColor(iColorType, fc); 1106 if (iColorType > 0) 1107 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1108 1109 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 1110 int32_t nBorderStyle = 0; 1111 CPWL_Dash dsBorder(3, 0, 0); 1112 CPWL_Color crLeftTop, crRightBottom; 1113 1114 switch (GetBorderStyle()) { 1115 case BBS_DASH: 1116 nBorderStyle = PBS_DASH; 1117 dsBorder = CPWL_Dash(3, 3, 0); 1118 break; 1119 case BBS_BEVELED: 1120 nBorderStyle = PBS_BEVELED; 1121 fBorderWidth *= 2; 1122 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); 1123 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); 1124 break; 1125 case BBS_INSET: 1126 nBorderStyle = PBS_INSET; 1127 fBorderWidth *= 2; 1128 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5); 1129 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75); 1130 break; 1131 case BBS_UNDERLINE: 1132 nBorderStyle = PBS_UNDERLINED; 1133 break; 1134 default: 1135 nBorderStyle = PBS_SOLID; 1136 break; 1137 } 1138 1139 CPDF_Rect rcWindow = GetRotatedRect(); 1140 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth); 1141 1142 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance(); 1143 if (da.HasColor()) { 1144 da.GetColor(iColorType, fc); 1145 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1146 } 1147 1148 int32_t nStyle = 0; 1149 1150 CFX_WideString csWCaption = pControl->GetNormalCaption(); 1151 if (csWCaption.GetLength() > 0) { 1152 switch (csWCaption[0]) { 1153 case L'l': 1154 nStyle = PCS_CIRCLE; 1155 break; 1156 case L'8': 1157 nStyle = PCS_CROSS; 1158 break; 1159 case L'u': 1160 nStyle = PCS_DIAMOND; 1161 break; 1162 case L'n': 1163 nStyle = PCS_SQUARE; 1164 break; 1165 case L'H': 1166 nStyle = PCS_STAR; 1167 break; 1168 default: // L'4' 1169 nStyle = PCS_CHECK; 1170 break; 1171 } 1172 } else { 1173 nStyle = PCS_CHECK; 1174 } 1175 1176 CFX_ByteString csAP_N_ON = 1177 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 1178 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1179 crLeftTop, crRightBottom, nBorderStyle, 1180 dsBorder); 1181 1182 CFX_ByteString csAP_N_OFF = csAP_N_ON; 1183 1184 switch (nBorderStyle) { 1185 case PBS_BEVELED: { 1186 CPWL_Color crTemp = crLeftTop; 1187 crLeftTop = crRightBottom; 1188 crRightBottom = crTemp; 1189 } break; 1190 case PBS_INSET: 1191 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0); 1192 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); 1193 break; 1194 } 1195 1196 CFX_ByteString csAP_D_ON = 1197 CPWL_Utils::GetRectFillAppStream( 1198 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + 1199 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1200 crLeftTop, crRightBottom, nBorderStyle, 1201 dsBorder); 1202 1203 CFX_ByteString csAP_D_OFF = csAP_D_ON; 1204 1205 csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText); 1206 csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText); 1207 1208 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, 1209 pControl->GetCheckedAPState()); 1210 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off"); 1211 1212 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, 1213 pControl->GetCheckedAPState()); 1214 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off"); 1215 1216 CFX_ByteString csAS = GetAppState(); 1217 if (csAS.IsEmpty()) 1218 SetAppState("Off"); 1219 } 1220 1221 void CPDFSDK_Widget::ResetAppearance_RadioButton() { 1222 CPDF_FormControl* pControl = GetFormControl(); 1223 CPWL_Color crBackground, crBorder, crText; 1224 int iColorType; 1225 FX_FLOAT fc[4]; 1226 1227 pControl->GetOriginalBackgroundColor(iColorType, fc); 1228 if (iColorType > 0) 1229 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1230 1231 pControl->GetOriginalBorderColor(iColorType, fc); 1232 if (iColorType > 0) 1233 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1234 1235 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 1236 int32_t nBorderStyle = 0; 1237 CPWL_Dash dsBorder(3, 0, 0); 1238 CPWL_Color crLeftTop, crRightBottom; 1239 1240 switch (GetBorderStyle()) { 1241 case BBS_DASH: 1242 nBorderStyle = PBS_DASH; 1243 dsBorder = CPWL_Dash(3, 3, 0); 1244 break; 1245 case BBS_BEVELED: 1246 nBorderStyle = PBS_BEVELED; 1247 fBorderWidth *= 2; 1248 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); 1249 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); 1250 break; 1251 case BBS_INSET: 1252 nBorderStyle = PBS_INSET; 1253 fBorderWidth *= 2; 1254 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5); 1255 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75); 1256 break; 1257 case BBS_UNDERLINE: 1258 nBorderStyle = PBS_UNDERLINED; 1259 break; 1260 default: 1261 nBorderStyle = PBS_SOLID; 1262 break; 1263 } 1264 1265 CPDF_Rect rcWindow = GetRotatedRect(); 1266 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth); 1267 1268 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance(); 1269 if (da.HasColor()) { 1270 da.GetColor(iColorType, fc); 1271 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1272 } 1273 1274 int32_t nStyle = 0; 1275 1276 CFX_WideString csWCaption = pControl->GetNormalCaption(); 1277 if (csWCaption.GetLength() > 0) { 1278 switch (csWCaption[0]) { 1279 default: // L'l': 1280 nStyle = PCS_CIRCLE; 1281 break; 1282 case L'8': 1283 nStyle = PCS_CROSS; 1284 break; 1285 case L'u': 1286 nStyle = PCS_DIAMOND; 1287 break; 1288 case L'n': 1289 nStyle = PCS_SQUARE; 1290 break; 1291 case L'H': 1292 nStyle = PCS_STAR; 1293 break; 1294 case L'4': 1295 nStyle = PCS_CHECK; 1296 break; 1297 } 1298 } else { 1299 nStyle = PCS_CIRCLE; 1300 } 1301 1302 CFX_ByteString csAP_N_ON; 1303 1304 CPDF_Rect rcCenter = 1305 CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f); 1306 1307 if (nStyle == PCS_CIRCLE) { 1308 if (nBorderStyle == PBS_BEVELED) { 1309 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); 1310 crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f); 1311 } else if (nBorderStyle == PBS_INSET) { 1312 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f); 1313 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f); 1314 } 1315 1316 csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) + 1317 CPWL_Utils::GetCircleBorderAppStream( 1318 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom, 1319 nBorderStyle, dsBorder); 1320 } else { 1321 csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) + 1322 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1323 crLeftTop, crRightBottom, 1324 nBorderStyle, dsBorder); 1325 } 1326 1327 CFX_ByteString csAP_N_OFF = csAP_N_ON; 1328 1329 switch (nBorderStyle) { 1330 case PBS_BEVELED: { 1331 CPWL_Color crTemp = crLeftTop; 1332 crLeftTop = crRightBottom; 1333 crRightBottom = crTemp; 1334 } break; 1335 case PBS_INSET: 1336 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0); 1337 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); 1338 break; 1339 } 1340 1341 CFX_ByteString csAP_D_ON; 1342 1343 if (nStyle == PCS_CIRCLE) { 1344 CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f); 1345 if (nBorderStyle == PBS_BEVELED) { 1346 crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f); 1347 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); 1348 crBK = crBackground; 1349 } else if (nBorderStyle == PBS_INSET) { 1350 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0); 1351 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); 1352 } 1353 1354 csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) + 1355 CPWL_Utils::GetCircleBorderAppStream( 1356 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom, 1357 nBorderStyle, dsBorder); 1358 } else { 1359 csAP_D_ON = CPWL_Utils::GetRectFillAppStream( 1360 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + 1361 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1362 crLeftTop, crRightBottom, 1363 nBorderStyle, dsBorder); 1364 } 1365 1366 CFX_ByteString csAP_D_OFF = csAP_D_ON; 1367 1368 csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText); 1369 csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText); 1370 1371 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, 1372 pControl->GetCheckedAPState()); 1373 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off"); 1374 1375 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, 1376 pControl->GetCheckedAPState()); 1377 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off"); 1378 1379 CFX_ByteString csAS = GetAppState(); 1380 if (csAS.IsEmpty()) 1381 SetAppState("Off"); 1382 } 1383 1384 void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) { 1385 CPDF_FormControl* pControl = GetFormControl(); 1386 CPDF_FormField* pField = pControl->GetField(); 1387 CFX_ByteTextBuf sBody, sLines; 1388 1389 CPDF_Rect rcClient = GetClientRect(); 1390 CPDF_Rect rcButton = rcClient; 1391 rcButton.left = rcButton.right - 13; 1392 rcButton.Normalize(); 1393 1394 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) { 1395 pEdit->EnableRefresh(FALSE); 1396 1397 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument(); 1398 CPDFDoc_Environment* pEnv = pDoc->GetEnv(); 1399 CBA_FontMap font_map(this, pEnv->GetSysHandler()); 1400 pEdit->SetFontMap(&font_map); 1401 1402 CPDF_Rect rcEdit = rcClient; 1403 rcEdit.right = rcButton.left; 1404 rcEdit.Normalize(); 1405 1406 pEdit->SetPlateRect(rcEdit); 1407 pEdit->SetAlignmentV(1); 1408 1409 FX_FLOAT fFontSize = GetFontSize(); 1410 if (IsFloatZero(fFontSize)) 1411 pEdit->SetAutoFontSize(TRUE); 1412 else 1413 pEdit->SetFontSize(fFontSize); 1414 1415 pEdit->Initialize(); 1416 1417 if (sValue) { 1418 pEdit->SetText(sValue); 1419 } else { 1420 int32_t nCurSel = pField->GetSelectedIndex(0); 1421 1422 if (nCurSel < 0) 1423 pEdit->SetText(pField->GetValue().c_str()); 1424 else 1425 pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str()); 1426 } 1427 1428 CPDF_Rect rcContent = pEdit->GetContentRect(); 1429 1430 CFX_ByteString sEdit = 1431 CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f)); 1432 if (sEdit.GetLength() > 0) { 1433 sBody << "/Tx BMC\n" 1434 << "q\n"; 1435 if (rcContent.Width() > rcEdit.Width() || 1436 rcContent.Height() > rcEdit.Height()) { 1437 sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width() 1438 << " " << rcEdit.Height() << " re\nW\nn\n"; 1439 } 1440 1441 CPWL_Color crText = GetTextPWLColor(); 1442 sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit 1443 << "ET\n" 1444 << "Q\nEMC\n"; 1445 } 1446 1447 IFX_Edit::DelEdit(pEdit); 1448 } 1449 1450 sBody << CPWL_Utils::GetDropButtonAppStream(rcButton); 1451 1452 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + 1453 sLines.GetByteString() + sBody.GetByteString(); 1454 1455 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP); 1456 } 1457 1458 void CPDFSDK_Widget::ResetAppearance_ListBox() { 1459 CPDF_FormControl* pControl = GetFormControl(); 1460 CPDF_FormField* pField = pControl->GetField(); 1461 CPDF_Rect rcClient = GetClientRect(); 1462 CFX_ByteTextBuf sBody, sLines; 1463 1464 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) { 1465 pEdit->EnableRefresh(FALSE); 1466 1467 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument(); 1468 CPDFDoc_Environment* pEnv = pDoc->GetEnv(); 1469 1470 CBA_FontMap font_map(this, pEnv->GetSysHandler()); 1471 pEdit->SetFontMap(&font_map); 1472 1473 pEdit->SetPlateRect(CPDF_Rect(rcClient.left, 0.0f, rcClient.right, 0.0f)); 1474 1475 FX_FLOAT fFontSize = GetFontSize(); 1476 1477 if (IsFloatZero(fFontSize)) 1478 pEdit->SetFontSize(12.0f); 1479 else 1480 pEdit->SetFontSize(fFontSize); 1481 1482 pEdit->Initialize(); 1483 1484 CFX_ByteTextBuf sList; 1485 FX_FLOAT fy = rcClient.top; 1486 1487 int32_t nTop = pField->GetTopVisibleIndex(); 1488 int32_t nCount = pField->CountOptions(); 1489 int32_t nSelCount = pField->CountSelectedItems(); 1490 1491 for (int32_t i = nTop; i < nCount; i++) { 1492 FX_BOOL bSelected = FALSE; 1493 for (int32_t j = 0; j < nSelCount; j++) { 1494 if (pField->GetSelectedIndex(j) == i) { 1495 bSelected = TRUE; 1496 break; 1497 } 1498 } 1499 1500 pEdit->SetText(pField->GetOptionLabel(i).c_str()); 1501 1502 CPDF_Rect rcContent = pEdit->GetContentRect(); 1503 FX_FLOAT fItemHeight = rcContent.Height(); 1504 1505 if (bSelected) { 1506 CPDF_Rect rcItem = 1507 CPDF_Rect(rcClient.left, fy - fItemHeight, rcClient.right, fy); 1508 sList << "q\n" << CPWL_Utils::GetColorAppStream( 1509 CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 1510 113.0f / 255.0f), 1511 TRUE) 1512 << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() 1513 << " " << rcItem.Height() << " re f\n" 1514 << "Q\n"; 1515 1516 sList << "BT\n" << CPWL_Utils::GetColorAppStream( 1517 CPWL_Color(COLORTYPE_GRAY, 1), TRUE) 1518 << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy)) 1519 << "ET\n"; 1520 } else { 1521 CPWL_Color crText = GetTextPWLColor(); 1522 sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, TRUE) 1523 << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy)) 1524 << "ET\n"; 1525 } 1526 1527 fy -= fItemHeight; 1528 } 1529 1530 if (sList.GetSize() > 0) { 1531 sBody << "/Tx BMC\n" 1532 << "q\n" << rcClient.left << " " << rcClient.bottom << " " 1533 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n"; 1534 sBody << sList << "Q\nEMC\n"; 1535 } 1536 1537 IFX_Edit::DelEdit(pEdit); 1538 } 1539 1540 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + 1541 sLines.GetByteString() + sBody.GetByteString(); 1542 1543 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP); 1544 } 1545 1546 void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) { 1547 CPDF_FormControl* pControl = GetFormControl(); 1548 CPDF_FormField* pField = pControl->GetField(); 1549 CFX_ByteTextBuf sBody, sLines; 1550 1551 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) { 1552 pEdit->EnableRefresh(FALSE); 1553 1554 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument(); 1555 CPDFDoc_Environment* pEnv = pDoc->GetEnv(); 1556 1557 CBA_FontMap font_map(this, pEnv->GetSysHandler()); 1558 pEdit->SetFontMap(&font_map); 1559 1560 CPDF_Rect rcClient = GetClientRect(); 1561 pEdit->SetPlateRect(rcClient); 1562 pEdit->SetAlignmentH(pControl->GetControlAlignment()); 1563 1564 FX_DWORD dwFieldFlags = pField->GetFieldFlags(); 1565 FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1; 1566 1567 if (bMultiLine) { 1568 pEdit->SetMultiLine(TRUE); 1569 pEdit->SetAutoReturn(TRUE); 1570 } else { 1571 pEdit->SetAlignmentV(1); 1572 } 1573 1574 FX_WORD subWord = 0; 1575 if ((dwFieldFlags >> 13) & 1) { 1576 subWord = '*'; 1577 pEdit->SetPasswordChar(subWord); 1578 } 1579 1580 int nMaxLen = pField->GetMaxLen(); 1581 FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1; 1582 FX_FLOAT fFontSize = GetFontSize(); 1583 1584 #ifdef PDF_ENABLE_XFA 1585 CFX_WideString sValueTmp; 1586 if (!sValue && (NULL != this->GetMixXFAWidget())) { 1587 sValueTmp = GetValue(TRUE); 1588 sValue = sValueTmp; 1589 } 1590 #endif // PDF_ENABLE_XFA 1591 1592 if (nMaxLen > 0) { 1593 if (bCharArray) { 1594 pEdit->SetCharArray(nMaxLen); 1595 1596 if (IsFloatZero(fFontSize)) { 1597 fFontSize = CPWL_Edit::GetCharArrayAutoFontSize( 1598 font_map.GetPDFFont(0), rcClient, nMaxLen); 1599 } 1600 } else { 1601 if (sValue) 1602 nMaxLen = wcslen((const wchar_t*)sValue); 1603 pEdit->SetLimitChar(nMaxLen); 1604 } 1605 } 1606 1607 if (IsFloatZero(fFontSize)) 1608 pEdit->SetAutoFontSize(TRUE); 1609 else 1610 pEdit->SetFontSize(fFontSize); 1611 1612 pEdit->Initialize(); 1613 1614 if (sValue) 1615 pEdit->SetText(sValue); 1616 else 1617 pEdit->SetText(pField->GetValue().c_str()); 1618 1619 CPDF_Rect rcContent = pEdit->GetContentRect(); 1620 1621 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream( 1622 pEdit, CPDF_Point(0.0f, 0.0f), NULL, !bCharArray, subWord); 1623 1624 if (sEdit.GetLength() > 0) { 1625 sBody << "/Tx BMC\n" 1626 << "q\n"; 1627 if (rcContent.Width() > rcClient.Width() || 1628 rcContent.Height() > rcClient.Height()) { 1629 sBody << rcClient.left << " " << rcClient.bottom << " " 1630 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n"; 1631 } 1632 CPWL_Color crText = GetTextPWLColor(); 1633 sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit 1634 << "ET\n" 1635 << "Q\nEMC\n"; 1636 } 1637 1638 if (bCharArray) { 1639 switch (GetBorderStyle()) { 1640 case BBS_SOLID: { 1641 CFX_ByteString sColor = 1642 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE); 1643 if (sColor.GetLength() > 0) { 1644 sLines << "q\n" << GetBorderWidth() << " w\n" 1645 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE) 1646 << " 2 J 0 j\n"; 1647 1648 for (int32_t i = 1; i < nMaxLen; i++) { 1649 sLines << rcClient.left + 1650 ((rcClient.right - rcClient.left) / nMaxLen) * i 1651 << " " << rcClient.bottom << " m\n" 1652 << rcClient.left + 1653 ((rcClient.right - rcClient.left) / nMaxLen) * i 1654 << " " << rcClient.top << " l S\n"; 1655 } 1656 1657 sLines << "Q\n"; 1658 } 1659 } break; 1660 case BBS_DASH: { 1661 CFX_ByteString sColor = 1662 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE); 1663 if (sColor.GetLength() > 0) { 1664 CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0); 1665 1666 sLines << "q\n" << GetBorderWidth() << " w\n" 1667 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE) 1668 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] " 1669 << dsBorder.nPhase << " d\n"; 1670 1671 for (int32_t i = 1; i < nMaxLen; i++) { 1672 sLines << rcClient.left + 1673 ((rcClient.right - rcClient.left) / nMaxLen) * i 1674 << " " << rcClient.bottom << " m\n" 1675 << rcClient.left + 1676 ((rcClient.right - rcClient.left) / nMaxLen) * i 1677 << " " << rcClient.top << " l S\n"; 1678 } 1679 1680 sLines << "Q\n"; 1681 } 1682 } break; 1683 } 1684 } 1685 1686 IFX_Edit::DelEdit(pEdit); 1687 } 1688 1689 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + 1690 sLines.GetByteString() + sBody.GetByteString(); 1691 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP); 1692 } 1693 1694 CPDF_Rect CPDFSDK_Widget::GetClientRect() const { 1695 CPDF_Rect rcWindow = GetRotatedRect(); 1696 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 1697 switch (GetBorderStyle()) { 1698 case BBS_BEVELED: 1699 case BBS_INSET: 1700 fBorderWidth *= 2.0f; 1701 break; 1702 } 1703 1704 return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth); 1705 } 1706 1707 CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const { 1708 CPDF_Rect rectAnnot = GetRect(); 1709 FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left; 1710 FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom; 1711 1712 CPDF_FormControl* pControl = GetFormControl(); 1713 CPDF_Rect rcPDFWindow; 1714 switch (abs(pControl->GetRotation() % 360)) { 1715 case 0: 1716 case 180: 1717 default: 1718 rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight); 1719 break; 1720 case 90: 1721 case 270: 1722 rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth); 1723 break; 1724 } 1725 1726 return rcPDFWindow; 1727 } 1728 1729 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const { 1730 CPWL_Color crBackground = GetFillPWLColor(); 1731 if (crBackground.nColorType != COLORTYPE_TRANSPARENT) { 1732 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground); 1733 } 1734 return ""; 1735 } 1736 1737 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const { 1738 CPDF_Rect rcWindow = GetRotatedRect(); 1739 CPWL_Color crBorder = GetBorderPWLColor(); 1740 CPWL_Color crBackground = GetFillPWLColor(); 1741 CPWL_Color crLeftTop, crRightBottom; 1742 1743 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); 1744 int32_t nBorderStyle = 0; 1745 CPWL_Dash dsBorder(3, 0, 0); 1746 1747 switch (GetBorderStyle()) { 1748 case BBS_DASH: 1749 nBorderStyle = PBS_DASH; 1750 dsBorder = CPWL_Dash(3, 3, 0); 1751 break; 1752 case BBS_BEVELED: 1753 nBorderStyle = PBS_BEVELED; 1754 fBorderWidth *= 2; 1755 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); 1756 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); 1757 break; 1758 case BBS_INSET: 1759 nBorderStyle = PBS_INSET; 1760 fBorderWidth *= 2; 1761 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5); 1762 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75); 1763 break; 1764 case BBS_UNDERLINE: 1765 nBorderStyle = PBS_UNDERLINED; 1766 break; 1767 default: 1768 nBorderStyle = PBS_SOLID; 1769 break; 1770 } 1771 1772 return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, 1773 crLeftTop, crRightBottom, nBorderStyle, 1774 dsBorder); 1775 } 1776 1777 CFX_Matrix CPDFSDK_Widget::GetMatrix() const { 1778 CFX_Matrix mt; 1779 CPDF_FormControl* pControl = GetFormControl(); 1780 CPDF_Rect rcAnnot = GetRect(); 1781 FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left; 1782 FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom; 1783 1784 switch (abs(pControl->GetRotation() % 360)) { 1785 case 0: 1786 default: 1787 mt = CFX_Matrix(1, 0, 0, 1, 0, 0); 1788 break; 1789 case 90: 1790 mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0); 1791 break; 1792 case 180: 1793 mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight); 1794 break; 1795 case 270: 1796 mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight); 1797 break; 1798 } 1799 1800 return mt; 1801 } 1802 1803 CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const { 1804 CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0); 1805 1806 CPDF_FormControl* pFormCtrl = GetFormControl(); 1807 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); 1808 if (da.HasColor()) { 1809 int32_t iColorType; 1810 FX_FLOAT fc[4]; 1811 da.GetColor(iColorType, fc); 1812 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1813 } 1814 1815 return crText; 1816 } 1817 1818 CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const { 1819 CPWL_Color crBorder; 1820 1821 CPDF_FormControl* pFormCtrl = GetFormControl(); 1822 int32_t iColorType; 1823 FX_FLOAT fc[4]; 1824 pFormCtrl->GetOriginalBorderColor(iColorType, fc); 1825 if (iColorType > 0) 1826 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1827 1828 return crBorder; 1829 } 1830 1831 CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const { 1832 CPWL_Color crFill; 1833 1834 CPDF_FormControl* pFormCtrl = GetFormControl(); 1835 int32_t iColorType; 1836 FX_FLOAT fc[4]; 1837 pFormCtrl->GetOriginalBackgroundColor(iColorType, fc); 1838 if (iColorType > 0) 1839 crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); 1840 1841 return crFill; 1842 } 1843 1844 void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType, 1845 CPDF_Stream* pImage) { 1846 CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); 1847 ASSERT(pDoc); 1848 1849 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP"); 1850 CPDF_Stream* pStream = pAPDict->GetStream(sAPType); 1851 CPDF_Dictionary* pStreamDict = pStream->GetDict(); 1852 CFX_ByteString sImageAlias = "IMG"; 1853 1854 if (CPDF_Dictionary* pImageDict = pImage->GetDict()) { 1855 sImageAlias = pImageDict->GetString("Name"); 1856 if (sImageAlias.IsEmpty()) 1857 sImageAlias = "IMG"; 1858 } 1859 1860 CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources"); 1861 if (!pStreamResList) { 1862 pStreamResList = new CPDF_Dictionary(); 1863 pStreamDict->SetAt("Resources", pStreamResList); 1864 } 1865 1866 if (pStreamResList) { 1867 CPDF_Dictionary* pXObject = new CPDF_Dictionary; 1868 pXObject->SetAtReference(sImageAlias, pDoc, pImage); 1869 pStreamResList->SetAt("XObject", pXObject); 1870 } 1871 } 1872 1873 void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) { 1874 if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP")) { 1875 pAPDict->RemoveAt(sAPType); 1876 } 1877 } 1878 1879 FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, 1880 PDFSDK_FieldAction& data, 1881 CPDFSDK_PageView* pPageView) { 1882 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument(); 1883 CPDFDoc_Environment* pEnv = pDocument->GetEnv(); 1884 1885 #ifdef PDF_ENABLE_XFA 1886 CPDFXFA_Document* pDoc = pDocument->GetXFADocument(); 1887 if (IXFA_Widget* hWidget = GetMixXFAWidget()) { 1888 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit); 1889 1890 if (eEventType != XFA_EVENT_Unknown) { 1891 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) { 1892 CXFA_EventParam param; 1893 param.m_eType = eEventType; 1894 param.m_wsChange = data.sChange; 1895 param.m_iCommitKey = data.nCommitKey; 1896 param.m_bShift = data.bShift; 1897 param.m_iSelStart = data.nSelStart; 1898 param.m_iSelEnd = data.nSelEnd; 1899 param.m_wsFullText = data.sValue; 1900 param.m_bKeyDown = data.bKeyDown; 1901 param.m_bModifier = data.bModifier; 1902 param.m_wsNewText = data.sValue; 1903 if (data.nSelEnd > data.nSelStart) 1904 param.m_wsNewText.Delete(data.nSelStart, 1905 data.nSelEnd - data.nSelStart); 1906 for (int i = data.sChange.GetLength() - 1; i >= 0; i--) 1907 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); 1908 param.m_wsPrevText = data.sValue; 1909 1910 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget); 1911 param.m_pTarget = pAcc; 1912 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); 1913 1914 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) { 1915 pDocView->UpdateDocView(); 1916 } 1917 1918 if (nRet == XFA_EVENTERROR_Sucess) 1919 return TRUE; 1920 } 1921 } 1922 } 1923 #endif // PDF_ENABLE_XFA 1924 1925 CPDF_Action action = GetAAction(type); 1926 if (action && action.GetType() != CPDF_Action::Unknown) { 1927 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); 1928 return pActionHandler->DoAction_Field(action, type, pDocument, 1929 GetFormField(), data); 1930 } 1931 return FALSE; 1932 } 1933 1934 CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) { 1935 switch (eAAT) { 1936 case CPDF_AAction::CursorEnter: 1937 case CPDF_AAction::CursorExit: 1938 case CPDF_AAction::ButtonDown: 1939 case CPDF_AAction::ButtonUp: 1940 case CPDF_AAction::GetFocus: 1941 case CPDF_AAction::LoseFocus: 1942 case CPDF_AAction::PageOpen: 1943 case CPDF_AAction::PageClose: 1944 case CPDF_AAction::PageVisible: 1945 case CPDF_AAction::PageInvisible: 1946 return CPDFSDK_BAAnnot::GetAAction(eAAT); 1947 1948 case CPDF_AAction::KeyStroke: 1949 case CPDF_AAction::Format: 1950 case CPDF_AAction::Validate: 1951 case CPDF_AAction::Calculate: { 1952 CPDF_FormField* pField = GetFormField(); 1953 if (CPDF_AAction aa = pField->GetAdditionalAction()) 1954 return aa.GetAction(eAAT); 1955 return CPDFSDK_BAAnnot::GetAAction(eAAT); 1956 } 1957 default: 1958 break; 1959 } 1960 1961 return CPDF_Action(); 1962 } 1963 1964 CFX_WideString CPDFSDK_Widget::GetAlternateName() const { 1965 CPDF_FormField* pFormField = GetFormField(); 1966 return pFormField->GetAlternateName(); 1967 } 1968 1969 int32_t CPDFSDK_Widget::GetAppearanceAge() const { 1970 return m_nAppAge; 1971 } 1972 1973 int32_t CPDFSDK_Widget::GetValueAge() const { 1974 return m_nValueAge; 1975 } 1976 1977 FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) { 1978 CPDF_Annot* pAnnot = GetPDFAnnot(); 1979 CFX_FloatRect annotRect; 1980 pAnnot->GetRect(annotRect); 1981 if (annotRect.Contains(pageX, pageY)) { 1982 if (!IsVisible()) 1983 return FALSE; 1984 1985 int nFieldFlags = GetFieldFlags(); 1986 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) 1987 return FALSE; 1988 1989 return TRUE; 1990 } 1991 return FALSE; 1992 } 1993 1994 #ifdef PDF_ENABLE_XFA 1995 CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(IXFA_Widget* pAnnot, 1996 CPDFSDK_PageView* pPageView, 1997 CPDFSDK_InterForm* pInterForm) 1998 : CPDFSDK_Annot(pPageView), m_pInterForm(pInterForm), m_hXFAWidget(pAnnot) { 1999 } 2000 2001 FX_BOOL CPDFSDK_XFAWidget::IsXFAField() { 2002 return TRUE; 2003 } 2004 2005 CFX_ByteString CPDFSDK_XFAWidget::GetType() const { 2006 return FSDK_XFAWIDGET_TYPENAME; 2007 } 2008 2009 CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const { 2010 CPDFSDK_PageView* pPageView = GetPageView(); 2011 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument(); 2012 CPDFXFA_Document* pDoc = pDocument->GetXFADocument(); 2013 IXFA_DocView* pDocView = pDoc->GetXFADocView(); 2014 IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler(); 2015 2016 CFX_RectF rcBBox; 2017 pWidgetHandler->GetRect(GetXFAWidget(), rcBBox); 2018 2019 return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, 2020 rcBBox.top + rcBBox.height); 2021 } 2022 #endif // PDF_ENABLE_XFA 2023 2024 CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument) 2025 : m_pDocument(pDocument), 2026 m_pInterForm(NULL), 2027 #ifdef PDF_ENABLE_XFA 2028 m_bXfaCalculate(TRUE), 2029 m_bXfaValidationsEnabled(TRUE), 2030 #endif // PDF_ENABLE_XFA 2031 m_bCalculate(TRUE), 2032 m_bBusy(FALSE) { 2033 m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE); 2034 m_pInterForm->SetFormNotify(this); 2035 2036 for (int i = 0; i < kNumFieldTypes; ++i) 2037 m_bNeedHightlight[i] = FALSE; 2038 m_iHighlightAlpha = 0; 2039 } 2040 2041 CPDFSDK_InterForm::~CPDFSDK_InterForm() { 2042 delete m_pInterForm; 2043 m_pInterForm = nullptr; 2044 m_Map.clear(); 2045 #ifdef PDF_ENABLE_XFA 2046 m_XFAMap.RemoveAll(); 2047 #endif // PDF_ENABLE_XFA 2048 } 2049 2050 FX_BOOL CPDFSDK_InterForm::HighlightWidgets() { 2051 return FALSE; 2052 } 2053 2054 CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, 2055 FX_BOOL bNext) const { 2056 std::unique_ptr<CBA_AnnotIterator> pIterator( 2057 new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", "")); 2058 2059 if (bNext) { 2060 return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget); 2061 } 2062 return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget); 2063 } 2064 2065 CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const { 2066 if (!pControl || !m_pInterForm) 2067 return nullptr; 2068 2069 CPDFSDK_Widget* pWidget = nullptr; 2070 const auto it = m_Map.find(pControl); 2071 if (it != m_Map.end()) 2072 pWidget = it->second; 2073 2074 if (pWidget) 2075 return pWidget; 2076 2077 CPDF_Dictionary* pControlDict = pControl->GetWidget(); 2078 CPDF_Document* pDocument = m_pDocument->GetPDFDocument(); 2079 CPDFSDK_PageView* pPage = nullptr; 2080 2081 if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P")) { 2082 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum()); 2083 if (nPageIndex >= 0) { 2084 pPage = m_pDocument->GetPageView(nPageIndex); 2085 } 2086 } 2087 2088 if (!pPage) { 2089 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict); 2090 if (nPageIndex >= 0) { 2091 pPage = m_pDocument->GetPageView(nPageIndex); 2092 } 2093 } 2094 2095 if (!pPage) 2096 return nullptr; 2097 return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict); 2098 } 2099 2100 void CPDFSDK_InterForm::GetWidgets( 2101 const CFX_WideString& sFieldName, 2102 std::vector<CPDFSDK_Widget*>* widgets) const { 2103 for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) { 2104 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName); 2105 ASSERT(pFormField); 2106 GetWidgets(pFormField, widgets); 2107 } 2108 } 2109 2110 void CPDFSDK_InterForm::GetWidgets( 2111 CPDF_FormField* pField, 2112 std::vector<CPDFSDK_Widget*>* widgets) const { 2113 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { 2114 CPDF_FormControl* pFormCtrl = pField->GetControl(i); 2115 ASSERT(pFormCtrl); 2116 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl); 2117 if (pWidget) 2118 widgets->push_back(pWidget); 2119 } 2120 } 2121 2122 int CPDFSDK_InterForm::GetPageIndexByAnnotDict( 2123 CPDF_Document* pDocument, 2124 CPDF_Dictionary* pAnnotDict) const { 2125 ASSERT(pAnnotDict); 2126 2127 for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) { 2128 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) { 2129 if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots")) { 2130 for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) { 2131 CPDF_Object* pDict = pAnnots->GetElementValue(j); 2132 if (pAnnotDict == pDict) { 2133 return i; 2134 } 2135 } 2136 } 2137 } 2138 } 2139 2140 return -1; 2141 } 2142 2143 void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, 2144 CPDFSDK_Widget* pWidget) { 2145 m_Map[pControl] = pWidget; 2146 } 2147 2148 void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) { 2149 m_Map.erase(pControl); 2150 } 2151 2152 void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) { 2153 m_bCalculate = bEnabled; 2154 } 2155 2156 FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const { 2157 return m_bCalculate; 2158 } 2159 2160 #ifdef PDF_ENABLE_XFA 2161 void CPDFSDK_InterForm::AddXFAMap(IXFA_Widget* hWidget, 2162 CPDFSDK_XFAWidget* pWidget) { 2163 m_XFAMap.SetAt(hWidget, pWidget); 2164 } 2165 2166 void CPDFSDK_InterForm::RemoveXFAMap(IXFA_Widget* hWidget) { 2167 m_XFAMap.RemoveKey(hWidget); 2168 } 2169 2170 CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(IXFA_Widget* hWidget) { 2171 CPDFSDK_XFAWidget* pWidget = NULL; 2172 m_XFAMap.Lookup(hWidget, pWidget); 2173 2174 return pWidget; 2175 } 2176 2177 void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) { 2178 m_bXfaCalculate = bEnabled; 2179 } 2180 FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const { 2181 return m_bXfaCalculate; 2182 } 2183 2184 FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() { 2185 return m_bXfaValidationsEnabled; 2186 } 2187 void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) { 2188 m_bXfaValidationsEnabled = bEnabled; 2189 } 2190 #endif // PDF_ENABLE_XFA 2191 2192 void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) { 2193 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2194 ASSERT(pEnv); 2195 if (!pEnv->IsJSInitiated()) 2196 return; 2197 2198 if (m_bBusy) 2199 return; 2200 2201 m_bBusy = TRUE; 2202 2203 if (IsCalculateEnabled()) { 2204 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); 2205 pRuntime->SetReaderDocument(m_pDocument); 2206 2207 int nSize = m_pInterForm->CountFieldsInCalculationOrder(); 2208 for (int i = 0; i < nSize; i++) { 2209 if (CPDF_FormField* pField = 2210 m_pInterForm->GetFieldInCalculationOrder(i)) { 2211 int nType = pField->GetFieldType(); 2212 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) { 2213 CPDF_AAction aAction = pField->GetAdditionalAction(); 2214 if (aAction && aAction.ActionExist(CPDF_AAction::Calculate)) { 2215 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate); 2216 if (action) { 2217 CFX_WideString csJS = action.GetJavaScript(); 2218 if (!csJS.IsEmpty()) { 2219 IJS_Context* pContext = pRuntime->NewContext(); 2220 CFX_WideString sOldValue = pField->GetValue(); 2221 CFX_WideString sValue = sOldValue; 2222 FX_BOOL bRC = TRUE; 2223 pContext->OnField_Calculate(pFormField, pField, sValue, bRC); 2224 2225 CFX_WideString sInfo; 2226 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo); 2227 pRuntime->ReleaseContext(pContext); 2228 2229 if (bRet) { 2230 if (bRC) { 2231 if (sValue.Compare(sOldValue) != 0) 2232 pField->SetValue(sValue, TRUE); 2233 } 2234 } 2235 } 2236 } 2237 } 2238 } 2239 } 2240 } 2241 } 2242 2243 m_bBusy = FALSE; 2244 } 2245 2246 CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, 2247 FX_BOOL& bFormated) { 2248 CFX_WideString sValue = pFormField->GetValue(); 2249 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2250 ASSERT(pEnv); 2251 if (!pEnv->IsJSInitiated()) { 2252 bFormated = FALSE; 2253 return sValue; 2254 } 2255 2256 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); 2257 pRuntime->SetReaderDocument(m_pDocument); 2258 2259 if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) { 2260 if (pFormField->CountSelectedItems() > 0) { 2261 int index = pFormField->GetSelectedIndex(0); 2262 if (index >= 0) 2263 sValue = pFormField->GetOptionLabel(index); 2264 } 2265 } 2266 2267 bFormated = FALSE; 2268 2269 CPDF_AAction aAction = pFormField->GetAdditionalAction(); 2270 if (aAction && aAction.ActionExist(CPDF_AAction::Format)) { 2271 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format); 2272 if (action) { 2273 CFX_WideString script = action.GetJavaScript(); 2274 if (!script.IsEmpty()) { 2275 CFX_WideString Value = sValue; 2276 2277 IJS_Context* pContext = pRuntime->NewContext(); 2278 pContext->OnField_Format(pFormField, Value, TRUE); 2279 2280 CFX_WideString sInfo; 2281 FX_BOOL bRet = pContext->RunScript(script, &sInfo); 2282 pRuntime->ReleaseContext(pContext); 2283 2284 if (bRet) { 2285 sValue = Value; 2286 bFormated = TRUE; 2287 } 2288 } 2289 } 2290 } 2291 2292 return sValue; 2293 } 2294 2295 void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, 2296 const FX_WCHAR* sValue, 2297 FX_BOOL bValueChanged) { 2298 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { 2299 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); 2300 ASSERT(pFormCtrl); 2301 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) 2302 pWidget->ResetAppearance(sValue, bValueChanged); 2303 } 2304 } 2305 2306 void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) { 2307 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { 2308 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); 2309 ASSERT(pFormCtrl); 2310 2311 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) { 2312 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2313 CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller(); 2314 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); 2315 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, FALSE); 2316 FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget); 2317 2318 pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right, 2319 rcBBox.bottom); 2320 } 2321 } 2322 } 2323 2324 void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, 2325 CFX_WideString& csValue, 2326 FX_BOOL& bRC) { 2327 CPDF_AAction aAction = pFormField->GetAdditionalAction(); 2328 if (aAction && aAction.ActionExist(CPDF_AAction::KeyStroke)) { 2329 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke); 2330 if (action) { 2331 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2332 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); 2333 PDFSDK_FieldAction fa; 2334 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); 2335 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); 2336 fa.sValue = csValue; 2337 2338 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke, 2339 m_pDocument, pFormField, fa); 2340 bRC = fa.bRC; 2341 } 2342 } 2343 } 2344 2345 void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, 2346 CFX_WideString& csValue, 2347 FX_BOOL& bRC) { 2348 CPDF_AAction aAction = pFormField->GetAdditionalAction(); 2349 if (aAction && aAction.ActionExist(CPDF_AAction::Validate)) { 2350 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate); 2351 if (action) { 2352 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2353 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); 2354 PDFSDK_FieldAction fa; 2355 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); 2356 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); 2357 fa.sValue = csValue; 2358 2359 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, 2360 m_pDocument, pFormField, fa); 2361 bRC = fa.bRC; 2362 } 2363 } 2364 } 2365 2366 FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) { 2367 ASSERT(action); 2368 2369 CPDF_ActionFields af = action.GetWidgets(); 2370 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); 2371 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); 2372 2373 FX_BOOL bHide = action.GetHideStatus(); 2374 FX_BOOL bChanged = FALSE; 2375 2376 for (CPDF_FormField* pField : fields) { 2377 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { 2378 CPDF_FormControl* pControl = pField->GetControl(i); 2379 ASSERT(pControl); 2380 2381 if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) { 2382 int nFlags = pWidget->GetFlags(); 2383 nFlags &= ~ANNOTFLAG_INVISIBLE; 2384 nFlags &= ~ANNOTFLAG_NOVIEW; 2385 if (bHide) 2386 nFlags |= ANNOTFLAG_HIDDEN; 2387 else 2388 nFlags &= ~ANNOTFLAG_HIDDEN; 2389 pWidget->SetFlags(nFlags); 2390 pWidget->GetPageView()->UpdateView(pWidget); 2391 bChanged = TRUE; 2392 } 2393 } 2394 } 2395 2396 return bChanged; 2397 } 2398 2399 FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) { 2400 CFX_WideString sDestination = action.GetFilePath(); 2401 if (sDestination.IsEmpty()) 2402 return FALSE; 2403 2404 CPDF_Dictionary* pActionDict = action.GetDict(); 2405 if (pActionDict->KeyExist("Fields")) { 2406 CPDF_ActionFields af = action.GetWidgets(); 2407 FX_DWORD dwFlags = action.GetFlags(); 2408 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); 2409 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); 2410 if (!fields.empty()) { 2411 bool bIncludeOrExclude = !(dwFlags & 0x01); 2412 if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude)) 2413 return FALSE; 2414 2415 return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE); 2416 } 2417 } 2418 if (m_pInterForm->CheckRequiredFields(nullptr, true)) 2419 return FALSE; 2420 2421 return SubmitForm(sDestination, FALSE); 2422 } 2423 2424 FX_BOOL CPDFSDK_InterForm::SubmitFields( 2425 const CFX_WideString& csDestination, 2426 const std::vector<CPDF_FormField*>& fields, 2427 FX_BOOL bIncludeOrExclude, 2428 FX_BOOL bUrlEncoded) { 2429 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2430 2431 CFX_ByteTextBuf textBuf; 2432 ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf); 2433 2434 uint8_t* pBuffer = textBuf.GetBuffer(); 2435 FX_STRSIZE nBufSize = textBuf.GetLength(); 2436 2437 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize)) 2438 return FALSE; 2439 2440 pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str()); 2441 return TRUE; 2442 } 2443 2444 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, 2445 CFX_WideString csTxtFile) { 2446 return TRUE; 2447 } 2448 2449 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, 2450 FX_STRSIZE& nBufSize) { 2451 CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize); 2452 if (pFDF) { 2453 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF"); 2454 if (!pMainDict) 2455 return FALSE; 2456 2457 // Get fields 2458 CPDF_Array* pFields = pMainDict->GetArray("Fields"); 2459 if (!pFields) 2460 return FALSE; 2461 2462 CFX_ByteTextBuf fdfEncodedData; 2463 2464 for (FX_DWORD i = 0; i < pFields->GetCount(); i++) { 2465 CPDF_Dictionary* pField = pFields->GetDict(i); 2466 if (!pField) 2467 continue; 2468 CFX_WideString name; 2469 name = pField->GetUnicodeText("T"); 2470 CFX_ByteString name_b = CFX_ByteString::FromUnicode(name); 2471 CFX_ByteString csBValue = pField->GetString("V"); 2472 CFX_WideString csWValue = PDF_DecodeText(csBValue); 2473 CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue); 2474 2475 fdfEncodedData = fdfEncodedData << name_b.GetBuffer(name_b.GetLength()); 2476 name_b.ReleaseBuffer(); 2477 fdfEncodedData = fdfEncodedData << "="; 2478 fdfEncodedData = fdfEncodedData 2479 << csValue_b.GetBuffer(csValue_b.GetLength()); 2480 csValue_b.ReleaseBuffer(); 2481 if (i != pFields->GetCount() - 1) 2482 fdfEncodedData = fdfEncodedData << "&"; 2483 } 2484 2485 nBufSize = fdfEncodedData.GetLength(); 2486 pBuf = FX_Alloc(uint8_t, nBufSize); 2487 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize); 2488 } 2489 return TRUE; 2490 } 2491 2492 FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf( 2493 const std::vector<CPDF_FormField*>& fields, 2494 FX_BOOL bIncludeOrExclude, 2495 CFX_ByteTextBuf& textBuf) { 2496 std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF( 2497 m_pDocument->GetPath(), fields, bIncludeOrExclude)); 2498 return pFDF ? pFDF->WriteBuf(textBuf) : FALSE; 2499 } 2500 2501 #ifdef PDF_ENABLE_XFA 2502 void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField, 2503 FX_BOOL bSynchronizeElse) { 2504 ASSERT(pFormField != NULL); 2505 2506 int x = 0; 2507 if (m_FieldSynchronizeMap.Lookup(pFormField, x)) 2508 return; 2509 2510 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { 2511 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); 2512 ASSERT(pFormCtrl != NULL); 2513 2514 ASSERT(m_pInterForm != NULL); 2515 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) { 2516 pWidget->Synchronize(bSynchronizeElse); 2517 } 2518 } 2519 } 2520 #endif // PDF_ENABLE_XFA 2521 2522 CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName( 2523 const CFX_WideString& sFileExt) { 2524 CFX_WideString sFileName; 2525 return L""; 2526 } 2527 2528 FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, 2529 FX_BOOL bUrlEncoded) { 2530 if (sDestination.IsEmpty()) 2531 return FALSE; 2532 2533 if (!m_pDocument || !m_pInterForm) 2534 return FALSE; 2535 2536 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 2537 CFX_WideString wsPDFFilePath = m_pDocument->GetPath(); 2538 CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath); 2539 if (!pFDFDoc) 2540 return FALSE; 2541 2542 CFX_ByteTextBuf FdfBuffer; 2543 FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer); 2544 delete pFDFDoc; 2545 if (!bRet) 2546 return FALSE; 2547 2548 uint8_t* pBuffer = FdfBuffer.GetBuffer(); 2549 FX_STRSIZE nBufSize = FdfBuffer.GetLength(); 2550 2551 if (bUrlEncoded) { 2552 if (!FDFToURLEncodedData(pBuffer, nBufSize)) 2553 return FALSE; 2554 } 2555 2556 pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str()); 2557 2558 if (bUrlEncoded) { 2559 FX_Free(pBuffer); 2560 pBuffer = NULL; 2561 } 2562 2563 return TRUE; 2564 } 2565 2566 FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) { 2567 CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath()); 2568 if (!pFDF) 2569 return FALSE; 2570 2571 FX_BOOL bRet = pFDF->WriteBuf(textBuf); 2572 delete pFDF; 2573 2574 return bRet; 2575 } 2576 2577 FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) { 2578 ASSERT(action); 2579 2580 CPDF_Dictionary* pActionDict = action.GetDict(); 2581 if (!pActionDict->KeyExist("Fields")) 2582 return m_pInterForm->ResetForm(true); 2583 2584 CPDF_ActionFields af = action.GetWidgets(); 2585 FX_DWORD dwFlags = action.GetFlags(); 2586 2587 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); 2588 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); 2589 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true); 2590 } 2591 2592 FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) { 2593 return FALSE; 2594 } 2595 2596 std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects( 2597 const std::vector<CPDF_Object*>& objects) const { 2598 std::vector<CPDF_FormField*> fields; 2599 for (CPDF_Object* pObject : objects) { 2600 if (pObject && pObject->IsString()) { 2601 CFX_WideString csName = pObject->GetUnicodeText(); 2602 CPDF_FormField* pField = m_pInterForm->GetField(0, csName); 2603 if (pField) 2604 fields.push_back(pField); 2605 } 2606 } 2607 return fields; 2608 } 2609 2610 int CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField, 2611 CFX_WideString& csValue) { 2612 CPDF_FormField* pFormField = (CPDF_FormField*)pField; 2613 int nType = pFormField->GetFieldType(); 2614 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) { 2615 FX_BOOL bRC = TRUE; 2616 OnKeyStrokeCommit(pFormField, csValue, bRC); 2617 if (bRC) { 2618 OnValidate(pFormField, csValue, bRC); 2619 return bRC ? 1 : -1; 2620 } 2621 return -1; 2622 } 2623 return 0; 2624 } 2625 2626 int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField) { 2627 CPDF_FormField* pFormField = (CPDF_FormField*)pField; 2628 #ifdef PDF_ENABLE_XFA 2629 SynchronizeField(pFormField, FALSE); 2630 #endif // PDF_ENABLE_XFA 2631 int nType = pFormField->GetFieldType(); 2632 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) { 2633 OnCalculate(pFormField); 2634 FX_BOOL bFormated = FALSE; 2635 CFX_WideString sValue = OnFormat(pFormField, bFormated); 2636 if (bFormated) 2637 ResetFieldAppearance(pFormField, sValue.c_str(), TRUE); 2638 else 2639 ResetFieldAppearance(pFormField, NULL, TRUE); 2640 UpdateField(pFormField); 2641 } 2642 return 0; 2643 } 2644 2645 int CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField, 2646 CFX_WideString& csValue) { 2647 CPDF_FormField* pFormField = (CPDF_FormField*)pField; 2648 if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX) 2649 return 0; 2650 2651 FX_BOOL bRC = TRUE; 2652 OnKeyStrokeCommit(pFormField, csValue, bRC); 2653 if (!bRC) 2654 return -1; 2655 2656 OnValidate(pFormField, csValue, bRC); 2657 if (!bRC) 2658 return -1; 2659 2660 return 1; 2661 } 2662 2663 int CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField) { 2664 CPDF_FormField* pFormField = (CPDF_FormField*)pField; 2665 if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX) { 2666 OnCalculate(pFormField); 2667 ResetFieldAppearance(pFormField, NULL, TRUE); 2668 UpdateField(pFormField); 2669 } 2670 return 0; 2671 } 2672 2673 int CPDFSDK_InterForm::AfterCheckedStatusChange( 2674 const CPDF_FormField* pField, 2675 const CFX_ByteArray& statusArray) { 2676 CPDF_FormField* pFormField = (CPDF_FormField*)pField; 2677 int nType = pFormField->GetFieldType(); 2678 if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) { 2679 OnCalculate(pFormField); 2680 UpdateField(pFormField); 2681 } 2682 return 0; 2683 } 2684 2685 int CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm) { 2686 return 0; 2687 } 2688 2689 int CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm) { 2690 OnCalculate(nullptr); 2691 return 0; 2692 } 2693 2694 int CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm) { 2695 return 0; 2696 } 2697 2698 int CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm) { 2699 OnCalculate(nullptr); 2700 return 0; 2701 } 2702 2703 FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) { 2704 if (nFieldType < 1 || nFieldType > kNumFieldTypes) 2705 return FALSE; 2706 return m_bNeedHightlight[nFieldType - 1]; 2707 } 2708 2709 void CPDFSDK_InterForm::RemoveAllHighLight() { 2710 for (int i = 0; i < kNumFieldTypes; ++i) 2711 m_bNeedHightlight[i] = FALSE; 2712 } 2713 2714 void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) { 2715 if (nFieldType < 0 || nFieldType > kNumFieldTypes) 2716 return; 2717 switch (nFieldType) { 2718 case 0: { 2719 for (int i = 0; i < kNumFieldTypes; ++i) { 2720 m_aHighlightColor[i] = clr; 2721 m_bNeedHightlight[i] = TRUE; 2722 } 2723 break; 2724 } 2725 default: { 2726 m_aHighlightColor[nFieldType - 1] = clr; 2727 m_bNeedHightlight[nFieldType - 1] = TRUE; 2728 break; 2729 } 2730 } 2731 } 2732 2733 FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) { 2734 if (nFieldType < 0 || nFieldType > kNumFieldTypes) 2735 return FXSYS_RGB(255, 255, 255); 2736 if (nFieldType == 0) 2737 return m_aHighlightColor[0]; 2738 return m_aHighlightColor[nFieldType - 1]; 2739 } 2740 2741 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, 2742 const CFX_ByteString& sType, 2743 const CFX_ByteString& sSubType) 2744 : m_pPageView(pPageView), 2745 m_sType(sType), 2746 m_sSubType(sSubType), 2747 m_nTabs(BAI_STRUCTURE) { 2748 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); 2749 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs"); 2750 2751 if (sTabs == "R") { 2752 m_nTabs = BAI_ROW; 2753 } else if (sTabs == "C") { 2754 m_nTabs = BAI_COLUMN; 2755 } else { 2756 m_nTabs = BAI_STRUCTURE; 2757 } 2758 2759 GenerateResults(); 2760 } 2761 2762 CBA_AnnotIterator::~CBA_AnnotIterator() { 2763 m_Annots.RemoveAll(); 2764 } 2765 2766 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { 2767 if (m_Annots.GetSize() > 0) 2768 return m_Annots[0]; 2769 2770 return NULL; 2771 } 2772 2773 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { 2774 if (m_Annots.GetSize() > 0) 2775 return m_Annots[m_Annots.GetSize() - 1]; 2776 2777 return NULL; 2778 } 2779 2780 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { 2781 for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) { 2782 if (m_Annots[i] == pAnnot) 2783 return (i + 1 < sz) ? m_Annots[i + 1] : m_Annots[0]; 2784 } 2785 return NULL; 2786 } 2787 2788 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { 2789 for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) { 2790 if (m_Annots[i] == pAnnot) 2791 return (i - 1 >= 0) ? m_Annots[i - 1] : m_Annots[sz - 1]; 2792 } 2793 return NULL; 2794 } 2795 2796 int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) { 2797 ASSERT(p1); 2798 ASSERT(p2); 2799 2800 CPDF_Rect rcAnnot1 = GetAnnotRect(p1); 2801 CPDF_Rect rcAnnot2 = GetAnnotRect(p2); 2802 2803 if (rcAnnot1.left < rcAnnot2.left) 2804 return -1; 2805 if (rcAnnot1.left > rcAnnot2.left) 2806 return 1; 2807 return 0; 2808 } 2809 2810 int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) { 2811 ASSERT(p1); 2812 ASSERT(p2); 2813 2814 CPDF_Rect rcAnnot1 = GetAnnotRect(p1); 2815 CPDF_Rect rcAnnot2 = GetAnnotRect(p2); 2816 2817 if (rcAnnot1.top < rcAnnot2.top) 2818 return -1; 2819 if (rcAnnot1.top > rcAnnot2.top) 2820 return 1; 2821 return 0; 2822 } 2823 2824 void CBA_AnnotIterator::GenerateResults() { 2825 switch (m_nTabs) { 2826 case BAI_STRUCTURE: { 2827 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { 2828 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); 2829 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) 2830 m_Annots.Add(pAnnot); 2831 } 2832 break; 2833 } 2834 case BAI_ROW: { 2835 CPDFSDK_SortAnnots sa; 2836 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { 2837 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); 2838 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) 2839 sa.Add(pAnnot); 2840 } 2841 2842 if (sa.GetSize() > 0) 2843 sa.Sort(CBA_AnnotIterator::CompareByLeft); 2844 2845 while (sa.GetSize() > 0) { 2846 int nLeftTopIndex = -1; 2847 FX_FLOAT fTop = 0.0f; 2848 2849 for (int i = sa.GetSize() - 1; i >= 0; i--) { 2850 CPDFSDK_Annot* pAnnot = sa.GetAt(i); 2851 ASSERT(pAnnot); 2852 2853 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); 2854 2855 if (rcAnnot.top > fTop) { 2856 nLeftTopIndex = i; 2857 fTop = rcAnnot.top; 2858 } 2859 } 2860 2861 if (nLeftTopIndex >= 0) { 2862 CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex); 2863 ASSERT(pLeftTopAnnot); 2864 2865 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); 2866 2867 m_Annots.Add(pLeftTopAnnot); 2868 sa.RemoveAt(nLeftTopIndex); 2869 2870 CFX_ArrayTemplate<int> aSelect; 2871 2872 for (int i = 0, sz = sa.GetSize(); i < sz; ++i) { 2873 CPDFSDK_Annot* pAnnot = sa.GetAt(i); 2874 ASSERT(pAnnot); 2875 2876 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); 2877 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; 2878 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) 2879 aSelect.Add(i); 2880 } 2881 2882 for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i) 2883 m_Annots.Add(sa[aSelect[i]]); 2884 2885 for (int i = aSelect.GetSize() - 1; i >= 0; --i) 2886 sa.RemoveAt(aSelect[i]); 2887 2888 aSelect.RemoveAll(); 2889 } 2890 } 2891 sa.RemoveAll(); 2892 break; 2893 } 2894 case BAI_COLUMN: { 2895 CPDFSDK_SortAnnots sa; 2896 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { 2897 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); 2898 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) 2899 sa.Add(pAnnot); 2900 } 2901 2902 if (sa.GetSize() > 0) 2903 sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE); 2904 2905 while (sa.GetSize() > 0) { 2906 int nLeftTopIndex = -1; 2907 FX_FLOAT fLeft = -1.0f; 2908 2909 for (int i = sa.GetSize() - 1; i >= 0; --i) { 2910 CPDFSDK_Annot* pAnnot = sa.GetAt(i); 2911 ASSERT(pAnnot); 2912 2913 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); 2914 2915 if (fLeft < 0) { 2916 nLeftTopIndex = 0; 2917 fLeft = rcAnnot.left; 2918 } else if (rcAnnot.left < fLeft) { 2919 nLeftTopIndex = i; 2920 fLeft = rcAnnot.left; 2921 } 2922 } 2923 2924 if (nLeftTopIndex >= 0) { 2925 CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex); 2926 ASSERT(pLeftTopAnnot); 2927 2928 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); 2929 2930 m_Annots.Add(pLeftTopAnnot); 2931 sa.RemoveAt(nLeftTopIndex); 2932 2933 CFX_ArrayTemplate<int> aSelect; 2934 for (int i = 0, sz = sa.GetSize(); i < sz; ++i) { 2935 CPDFSDK_Annot* pAnnot = sa.GetAt(i); 2936 ASSERT(pAnnot); 2937 2938 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); 2939 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; 2940 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) 2941 aSelect.Add(i); 2942 } 2943 2944 for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i) 2945 m_Annots.Add(sa[aSelect[i]]); 2946 2947 for (int i = aSelect.GetSize() - 1; i >= 0; --i) 2948 sa.RemoveAt(aSelect[i]); 2949 2950 aSelect.RemoveAll(); 2951 } 2952 } 2953 sa.RemoveAll(); 2954 break; 2955 } 2956 } 2957 } 2958 2959 CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot) { 2960 CPDF_Rect rcAnnot; 2961 pAnnot->GetPDFAnnot()->GetRect(rcAnnot); 2962 return rcAnnot; 2963 } 2964