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 "public/fpdf_formfill.h" 8 9 #include <memory> 10 #include <vector> 11 12 #include "core/fpdfapi/page/cpdf_page.h" 13 #include "core/fpdfapi/parser/cpdf_document.h" 14 #include "core/fpdfapi/render/cpdf_renderoptions.h" 15 #include "core/fpdfdoc/cpdf_formcontrol.h" 16 #include "core/fpdfdoc/cpdf_formfield.h" 17 #include "core/fpdfdoc/cpdf_interform.h" 18 #include "core/fpdfdoc/cpdf_occontext.h" 19 #include "core/fxge/cfx_defaultrenderdevice.h" 20 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" 21 #include "fpdfsdk/cpdfsdk_interform.h" 22 #include "fpdfsdk/cpdfsdk_pageview.h" 23 #include "fpdfsdk/fsdk_actionhandler.h" 24 #include "fpdfsdk/fsdk_define.h" 25 #include "public/fpdfview.h" 26 #include "third_party/base/ptr_util.h" 27 #include "third_party/base/stl_util.h" 28 29 #ifdef PDF_ENABLE_XFA 30 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" 31 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" 32 #include "xfa/fxfa/cxfa_ffdocview.h" 33 #include "xfa/fxfa/cxfa_ffpageview.h" 34 #include "xfa/fxfa/cxfa_ffwidget.h" 35 36 static_assert(static_cast<int>(FormType::kNone) == FORMTYPE_NONE, 37 "None form types must match"); 38 static_assert(static_cast<int>(FormType::kAcroForm) == FORMTYPE_ACRO_FORM, 39 "AcroForm form types must match"); 40 static_assert(static_cast<int>(FormType::kXFAFull) == FORMTYPE_XFA_FULL, 41 "XFA full form types must match"); 42 static_assert(static_cast<int>(FormType::kXFAForeground) == 43 FORMTYPE_XFA_FOREGROUND, 44 "XFA foreground form types must match"); 45 #endif // PDF_ENABLE_XFA 46 47 static_assert(static_cast<int>(FormFieldType::kUnknown) == 48 FPDF_FORMFIELD_UNKNOWN, 49 "Unknown form field types must match"); 50 static_assert(static_cast<int>(FormFieldType::kPushButton) == 51 FPDF_FORMFIELD_PUSHBUTTON, 52 "PushButton form field types must match"); 53 static_assert(static_cast<int>(FormFieldType::kCheckBox) == 54 FPDF_FORMFIELD_CHECKBOX, 55 "CheckBox form field types must match"); 56 static_assert(static_cast<int>(FormFieldType::kRadioButton) == 57 FPDF_FORMFIELD_RADIOBUTTON, 58 "RadioButton form field types must match"); 59 static_assert(static_cast<int>(FormFieldType::kComboBox) == 60 FPDF_FORMFIELD_COMBOBOX, 61 "ComboBox form field types must match"); 62 static_assert(static_cast<int>(FormFieldType::kListBox) == 63 FPDF_FORMFIELD_LISTBOX, 64 "ListBox form field types must match"); 65 static_assert(static_cast<int>(FormFieldType::kTextField) == 66 FPDF_FORMFIELD_TEXTFIELD, 67 "TextField form field types must match"); 68 static_assert(static_cast<int>(FormFieldType::kSignature) == 69 FPDF_FORMFIELD_SIGNATURE, 70 "Signature form field types must match"); 71 #ifdef PDF_ENABLE_XFA 72 static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA, 73 "XFA form field types must match"); 74 static_assert(static_cast<int>(FormFieldType::kXFA_CheckBox) == 75 FPDF_FORMFIELD_XFA_CHECKBOX, 76 "XFA CheckBox form field types must match"); 77 static_assert(static_cast<int>(FormFieldType::kXFA_ComboBox) == 78 FPDF_FORMFIELD_XFA_COMBOBOX, 79 "XFA ComboBox form field types must match"); 80 static_assert(static_cast<int>(FormFieldType::kXFA_ImageField) == 81 FPDF_FORMFIELD_XFA_IMAGEFIELD, 82 "XFA ImageField form field types must match"); 83 static_assert(static_cast<int>(FormFieldType::kXFA_ListBox) == 84 FPDF_FORMFIELD_XFA_LISTBOX, 85 "XFA ListBox form field types must match"); 86 static_assert(static_cast<int>(FormFieldType::kXFA_PushButton) == 87 FPDF_FORMFIELD_XFA_PUSHBUTTON, 88 "XFA PushButton form field types must match"); 89 static_assert(static_cast<int>(FormFieldType::kXFA_Signature) == 90 FPDF_FORMFIELD_XFA_SIGNATURE, 91 "XFA Signature form field types must match"); 92 static_assert(static_cast<int>(FormFieldType::kXFA_TextField) == 93 FPDF_FORMFIELD_XFA_TEXTFIELD, 94 "XFA TextField form field types must match"); 95 #endif // PDF_ENABLE_XFA 96 static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT, 97 "Number of form field types must match"); 98 99 namespace { 100 101 CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment( 102 FPDF_FORMHANDLE handle) { 103 return static_cast<CPDFSDK_FormFillEnvironment*>(handle); 104 } 105 106 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) { 107 CPDFSDK_FormFillEnvironment* pFormFillEnv = 108 HandleToCPDFSDKEnvironment(hHandle); 109 return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr; 110 } 111 112 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle, 113 FPDF_PAGE page) { 114 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 115 if (!pPage) 116 return nullptr; 117 118 CPDFSDK_FormFillEnvironment* pFormFillEnv = 119 HandleToCPDFSDKEnvironment(hHandle); 120 return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr; 121 } 122 123 #ifdef PDF_ENABLE_XFA 124 std::vector<ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) { 125 return static_cast<std::vector<ByteString>*>(handle); 126 } 127 128 FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<ByteString>* strings) { 129 return static_cast<FPDF_STRINGHANDLE>(strings); 130 } 131 #endif // PDF_ENABLE_XFA 132 133 void FFLCommon(FPDF_FORMHANDLE hHandle, 134 FPDF_BITMAP bitmap, 135 FPDF_RECORDER recorder, 136 FPDF_PAGE page, 137 int start_x, 138 int start_y, 139 int size_x, 140 int size_y, 141 int rotate, 142 int flags) { 143 if (!hHandle) 144 return; 145 146 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 147 if (!pPage) 148 return; 149 150 #ifdef PDF_ENABLE_XFA 151 CPDFXFA_Context* pContext = pPage->GetContext(); 152 if (!pContext) 153 return; 154 CPDF_Document* pPDFDoc = pContext->GetPDFDoc(); 155 if (!pPDFDoc) 156 return; 157 CPDFSDK_FormFillEnvironment* pFormFillEnv = 158 HandleToCPDFSDKEnvironment(hHandle); 159 if (!pFormFillEnv) 160 return; 161 #endif // PDF_ENABLE_XFA 162 163 CFX_Matrix matrix = 164 pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); 165 FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y); 166 167 auto pDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>(); 168 #ifdef _SKIA_SUPPORT_ 169 pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder)); 170 #endif 171 RetainPtr<CFX_DIBitmap> holder(CFXBitmapFromFPDFBitmap(bitmap)); 172 pDevice->Attach(holder, false, nullptr, false); 173 { 174 CFX_RenderDevice::StateRestorer restorer(pDevice.get()); 175 pDevice->SetClip_Rect(clip); 176 177 CPDF_RenderOptions options; 178 uint32_t option_flags = options.GetFlags(); 179 if (flags & FPDF_LCD_TEXT) 180 option_flags |= RENDER_CLEARTYPE; 181 else 182 option_flags &= ~RENDER_CLEARTYPE; 183 options.SetFlags(option_flags); 184 185 // Grayscale output 186 if (flags & FPDF_GRAYSCALE) 187 options.SetColorMode(CPDF_RenderOptions::kGray); 188 189 options.SetDrawAnnots(flags & FPDF_ANNOT); 190 191 #ifdef PDF_ENABLE_XFA 192 options.SetOCContext( 193 pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View)); 194 if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true)) 195 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip); 196 #else // PDF_ENABLE_XFA 197 options.SetOCContext(pdfium::MakeRetain<CPDF_OCContext>( 198 pPage->m_pDocument.Get(), CPDF_OCContext::View)); 199 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage)) 200 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options); 201 #endif // PDF_ENABLE_XFA 202 } 203 #ifdef _SKIA_SUPPORT_PATHS_ 204 pDevice->Flush(true); 205 holder->UnPreMultiply(); 206 #endif 207 } 208 209 } // namespace 210 211 FPDF_EXPORT int FPDF_CALLCONV 212 FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, 213 FPDF_PAGE page, 214 double page_x, 215 double page_y) { 216 if (!hHandle) 217 return -1; 218 CPDF_Page* pPage = CPDFPageFromFPDFPage(page); 219 if (pPage) { 220 CPDF_InterForm interform(pPage->m_pDocument.Get()); 221 CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint( 222 pPage, 223 CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)), 224 nullptr); 225 if (!pFormCtrl) 226 return -1; 227 CPDF_FormField* pFormField = pFormCtrl->GetField(); 228 return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1; 229 } 230 231 #ifdef PDF_ENABLE_XFA 232 CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page); 233 if (!pXFAPage) 234 return -1; 235 236 CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView(); 237 if (!pPageView) 238 return -1; 239 240 CXFA_FFDocView* pDocView = pPageView->GetDocView(); 241 if (!pDocView) 242 return -1; 243 244 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler(); 245 if (!pWidgetHandler) 246 return -1; 247 248 std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator( 249 pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, 250 XFA_WidgetStatus_Viewable)); 251 if (!pWidgetIterator) 252 return -1; 253 254 CXFA_FFWidget* pXFAAnnot; 255 while ((pXFAAnnot = pWidgetIterator->MoveToNext()) != nullptr) { 256 CFX_RectF rcBBox = pXFAAnnot->GetBBox(0); 257 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, 258 rcBBox.top + rcBBox.height); 259 rcWidget.Inflate(1.0f, 1.0f); 260 if (rcWidget.Contains(CFX_PointF(static_cast<float>(page_x), 261 static_cast<float>(page_y)))) { 262 return static_cast<int>(pXFAAnnot->GetFormFieldType()); 263 } 264 } 265 #endif // PDF_ENABLE_XFA 266 return -1; 267 } 268 269 FPDF_EXPORT int FPDF_CALLCONV 270 FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle, 271 FPDF_PAGE page, 272 double page_x, 273 double page_y) { 274 if (!hHandle) 275 return -1; 276 CPDF_Page* pPage = CPDFPageFromFPDFPage(page); 277 if (!pPage) 278 return -1; 279 CPDF_InterForm interform(pPage->m_pDocument.Get()); 280 int z_order = -1; 281 (void)interform.GetControlAtPoint( 282 pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)), 283 &z_order); 284 return z_order; 285 } 286 287 FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV 288 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document, 289 FPDF_FORMFILLINFO* formInfo) { 290 #ifdef PDF_ENABLE_XFA 291 const int kRequiredVersion = 2; 292 #else // PDF_ENABLE_XFA 293 const int kRequiredVersion = 1; 294 #endif // PDF_ENABLE_XFA 295 if (!formInfo || formInfo->version != kRequiredVersion) 296 return nullptr; 297 298 UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document); 299 if (!pDocument) 300 return nullptr; 301 302 #ifdef PDF_ENABLE_XFA 303 // If the CPDFXFA_Context has a FormFillEnvironment already then we've done 304 // this and can just return the old Env. Otherwise, we'll end up setting a new 305 // environment into the XFADocument and, that could get weird. 306 if (pDocument->GetFormFillEnv()) 307 return pDocument->GetFormFillEnv(); 308 #endif 309 310 auto pFormFillEnv = 311 pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(pDocument, formInfo); 312 313 #ifdef PDF_ENABLE_XFA 314 pDocument->SetFormFillEnv(pFormFillEnv.get()); 315 #endif // PDF_ENABLE_XFA 316 317 return pFormFillEnv.release(); // Caller takes ownership. 318 } 319 320 FPDF_EXPORT void FPDF_CALLCONV 321 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) { 322 CPDFSDK_FormFillEnvironment* pFormFillEnv = 323 HandleToCPDFSDKEnvironment(hHandle); 324 if (!pFormFillEnv) 325 return; 326 327 #ifdef PDF_ENABLE_XFA 328 // Reset the focused annotations and remove the SDK document from the 329 // XFA document. 330 pFormFillEnv->ClearAllFocusedAnnots(); 331 // If the document was closed first, it's possible the XFA document 332 // is now a nullptr. 333 if (pFormFillEnv->GetXFAContext()) 334 pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr); 335 #endif // PDF_ENABLE_XFA 336 delete pFormFillEnv; 337 } 338 339 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, 340 FPDF_PAGE page, 341 int modifier, 342 double page_x, 343 double page_y) { 344 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 345 if (!pPageView) 346 return false; 347 return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier); 348 } 349 350 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnFocus(FPDF_FORMHANDLE hHandle, 351 FPDF_PAGE page, 352 int modifier, 353 double page_x, 354 double page_y) { 355 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 356 if (!pPageView) 357 return false; 358 return pPageView->OnFocus(CFX_PointF(page_x, page_y), modifier); 359 } 360 361 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, 362 FPDF_PAGE page, 363 int modifier, 364 double page_x, 365 double page_y) { 366 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 367 if (!pPageView) 368 return false; 369 return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier); 370 } 371 372 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, 373 FPDF_PAGE page, 374 int modifier, 375 double page_x, 376 double page_y) { 377 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 378 if (!pPageView) 379 return false; 380 return pPageView->OnLButtonUp(CFX_PointF(page_x, page_y), modifier); 381 } 382 383 #ifdef PDF_ENABLE_XFA 384 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, 385 FPDF_PAGE page, 386 int modifier, 387 double page_x, 388 double page_y) { 389 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 390 if (!pPageView) 391 return false; 392 return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier); 393 } 394 395 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, 396 FPDF_PAGE page, 397 int modifier, 398 double page_x, 399 double page_y) { 400 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 401 if (!pPageView) 402 return false; 403 return pPageView->OnRButtonUp(CFX_PointF(page_x, page_y), modifier); 404 } 405 #endif // PDF_ENABLE_XFA 406 407 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, 408 FPDF_PAGE page, 409 int nKeyCode, 410 int modifier) { 411 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 412 if (!pPageView) 413 return false; 414 return pPageView->OnKeyDown(nKeyCode, modifier); 415 } 416 417 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, 418 FPDF_PAGE page, 419 int nKeyCode, 420 int modifier) { 421 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 422 if (!pPageView) 423 return false; 424 return pPageView->OnKeyUp(nKeyCode, modifier); 425 } 426 427 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, 428 FPDF_PAGE page, 429 int nChar, 430 int modifier) { 431 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 432 if (!pPageView) 433 return false; 434 return pPageView->OnChar(nChar, modifier); 435 } 436 437 FPDF_EXPORT unsigned long FPDF_CALLCONV 438 FORM_GetSelectedText(FPDF_FORMHANDLE hHandle, 439 FPDF_PAGE page, 440 void* buffer, 441 unsigned long buflen) { 442 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 443 if (!pPageView) 444 return 0; 445 446 WideString wide_str_form_text = pPageView->GetSelectedText(); 447 ByteString encoded_form_text = wide_str_form_text.UTF16LE_Encode(); 448 unsigned long form_text_len = encoded_form_text.GetLength(); 449 450 if (buffer && buflen >= form_text_len) 451 memcpy(buffer, encoded_form_text.c_str(), form_text_len); 452 453 return form_text_len; 454 } 455 456 FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle, 457 FPDF_PAGE page, 458 FPDF_WIDESTRING wsText) { 459 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 460 if (!pPageView) 461 return; 462 463 size_t len = WideString::WStringLength(wsText); 464 WideString wide_str_text = WideString::FromUTF16LE(wsText, len); 465 466 pPageView->ReplaceSelection(wide_str_text); 467 } 468 469 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV 470 FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) { 471 CPDFSDK_FormFillEnvironment* pFormFillEnv = 472 HandleToCPDFSDKEnvironment(hHandle); 473 if (!pFormFillEnv) 474 return false; 475 return pFormFillEnv->KillFocusAnnot(0); 476 } 477 478 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, 479 FPDF_BITMAP bitmap, 480 FPDF_PAGE page, 481 int start_x, 482 int start_y, 483 int size_x, 484 int size_y, 485 int rotate, 486 int flags) { 487 FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y, 488 rotate, flags); 489 } 490 491 #ifdef _SKIA_SUPPORT_ 492 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLRecord(FPDF_FORMHANDLE hHandle, 493 FPDF_RECORDER recorder, 494 FPDF_PAGE page, 495 int start_x, 496 int start_y, 497 int size_x, 498 int size_y, 499 int rotate, 500 int flags) { 501 FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y, 502 rotate, flags); 503 } 504 #endif 505 506 #ifdef PDF_ENABLE_XFA 507 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Undo(FPDF_DOCUMENT document, 508 FPDF_WIDGET hWidget) { 509 if (!hWidget || !document) 510 return; 511 512 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 513 if (!pContext->ContainsXFAForm()) 514 return; 515 516 static_cast<CXFA_FFWidget*>(hWidget)->Undo(); 517 } 518 519 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Redo(FPDF_DOCUMENT document, 520 FPDF_WIDGET hWidget) { 521 if (!hWidget || !document) 522 return; 523 524 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 525 if (!pContext->ContainsXFAForm()) 526 return; 527 528 static_cast<CXFA_FFWidget*>(hWidget)->Redo(); 529 } 530 531 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_SelectAll(FPDF_DOCUMENT document, 532 FPDF_WIDGET hWidget) { 533 if (!hWidget || !document) 534 return; 535 536 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 537 if (!pContext->ContainsXFAForm()) 538 return; 539 540 static_cast<CXFA_FFWidget*>(hWidget)->SelectAll(); 541 } 542 543 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Copy(FPDF_DOCUMENT document, 544 FPDF_WIDGET hWidget, 545 FPDF_WIDESTRING wsText, 546 FPDF_DWORD* size) { 547 if (!hWidget || !document) 548 return; 549 550 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 551 if (!pContext->ContainsXFAForm()) 552 return; 553 554 WideString wsCpText = 555 static_cast<CXFA_FFWidget*>(hWidget)->Copy().value_or(WideString()); 556 557 ByteString bsCpText = wsCpText.UTF16LE_Encode(); 558 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short); 559 if (!wsText) { 560 *size = len; 561 return; 562 } 563 564 uint32_t real_size = len < *size ? len : *size; 565 if (real_size > 0) { 566 memcpy((void*)wsText, 567 bsCpText.GetBuffer(real_size * sizeof(unsigned short)), 568 real_size * sizeof(unsigned short)); 569 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short)); 570 } 571 *size = real_size; 572 } 573 574 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Cut(FPDF_DOCUMENT document, 575 FPDF_WIDGET hWidget, 576 FPDF_WIDESTRING wsText, 577 FPDF_DWORD* size) { 578 if (!hWidget || !document) 579 return; 580 581 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 582 if (!pContext->ContainsXFAForm()) 583 return; 584 585 WideString wsCpText = 586 static_cast<CXFA_FFWidget*>(hWidget)->Cut().value_or(WideString()); 587 588 ByteString bsCpText = wsCpText.UTF16LE_Encode(); 589 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short); 590 if (!wsText) { 591 *size = len; 592 return; 593 } 594 595 uint32_t real_size = len < *size ? len : *size; 596 if (real_size > 0) { 597 memcpy((void*)wsText, 598 bsCpText.GetBuffer(real_size * sizeof(unsigned short)), 599 real_size * sizeof(unsigned short)); 600 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short)); 601 } 602 *size = real_size; 603 } 604 605 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Paste(FPDF_DOCUMENT document, 606 FPDF_WIDGET hWidget, 607 FPDF_WIDESTRING wsText, 608 FPDF_DWORD size) { 609 if (!hWidget || !document) 610 return; 611 612 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 613 if (!pContext->ContainsXFAForm()) 614 return; 615 616 WideString wstr = WideString::FromUTF16LE(wsText, size); 617 static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr); 618 } 619 620 FPDF_EXPORT void FPDF_CALLCONV 621 FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document, 622 FPDF_WIDGET hWidget, 623 float x, 624 float y, 625 FPDF_BYTESTRING bsText) { 626 if (!hWidget || !document) 627 return; 628 629 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 630 if (!pContext->ContainsXFAForm()) 631 return; 632 633 CFX_PointF ptPopup; 634 ptPopup.x = x; 635 ptPopup.y = y; 636 ByteStringView bs(bsText); 637 static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs); 638 } 639 640 FPDF_EXPORT void FPDF_CALLCONV 641 FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document, 642 FPDF_WIDGET hWidget, 643 float x, 644 float y, 645 FPDF_STRINGHANDLE* stringHandle) { 646 if (!hWidget || !document) 647 return; 648 649 auto* pContext = static_cast<CPDFXFA_Context*>(document); 650 if (!pContext->ContainsXFAForm()) 651 return; 652 653 CFX_PointF ptPopup; 654 ptPopup.x = x; 655 ptPopup.y = y; 656 auto sSuggestWords = pdfium::MakeUnique<std::vector<ByteString>>(); 657 static_cast<CXFA_FFWidget*>(hWidget)->GetSuggestWords(ptPopup, 658 sSuggestWords.get()); 659 660 // Caller takes ownership. 661 *stringHandle = ToFPDFStringHandle(sSuggestWords.release()); 662 } 663 664 FPDF_EXPORT int FPDF_CALLCONV 665 FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) { 666 std::vector<ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle); 667 return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1; 668 } 669 670 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV 671 FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle, 672 int index, 673 FPDF_BYTESTRING bsText, 674 FPDF_DWORD* size) { 675 if (!sHandle || !size) 676 return false; 677 678 int count = FPDF_StringHandleCounts(sHandle); 679 if (index < 0 || index >= count) 680 return false; 681 682 std::vector<ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle); 683 uint32_t len = (*sSuggestWords)[index].GetLength(); 684 if (!bsText) { 685 *size = len; 686 return true; 687 } 688 689 uint32_t real_size = len < *size ? len : *size; 690 if (real_size > 0) 691 memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size); 692 *size = real_size; 693 return true; 694 } 695 696 FPDF_EXPORT void FPDF_CALLCONV 697 FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) { 698 delete FromFPDFStringHandle(stringHandle); 699 } 700 701 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV 702 FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle, 703 FPDF_BYTESTRING bsText, 704 FPDF_DWORD size) { 705 if (!stringHandle || !bsText || size == 0) 706 return false; 707 708 FromFPDFStringHandle(stringHandle)->push_back(ByteString(bsText, size)); 709 return true; 710 } 711 #endif // PDF_ENABLE_XFA 712 713 FPDF_EXPORT void FPDF_CALLCONV 714 FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, 715 int fieldType, 716 unsigned long color) { 717 CPDFSDK_InterForm* interForm = FormHandleToInterForm(hHandle); 718 if (!interForm) 719 return; 720 721 Optional<FormFieldType> cast_input = IntToFormFieldType(fieldType); 722 if (!cast_input) 723 return; 724 725 if (cast_input.value() == FormFieldType::kUnknown) { 726 interForm->SetAllHighlightColors(color); 727 } else { 728 interForm->SetHighlightColor(color, cast_input.value()); 729 } 730 } 731 732 FPDF_EXPORT void FPDF_CALLCONV 733 FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) { 734 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 735 pInterForm->SetHighlightAlpha(alpha); 736 } 737 738 FPDF_EXPORT void FPDF_CALLCONV 739 FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) { 740 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 741 pInterForm->RemoveAllHighLights(); 742 } 743 744 FPDF_EXPORT void FPDF_CALLCONV FORM_OnAfterLoadPage(FPDF_PAGE page, 745 FPDF_FORMHANDLE hHandle) { 746 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page)) 747 pPageView->SetValid(true); 748 } 749 750 FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page, 751 FPDF_FORMHANDLE hHandle) { 752 CPDFSDK_FormFillEnvironment* pFormFillEnv = 753 HandleToCPDFSDKEnvironment(hHandle); 754 if (!pFormFillEnv) 755 return; 756 757 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 758 if (!pPage) 759 return; 760 761 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false); 762 if (pPageView) { 763 pPageView->SetValid(false); 764 // RemovePageView() takes care of the delete for us. 765 pFormFillEnv->RemovePageView(pPage); 766 } 767 } 768 769 FPDF_EXPORT void FPDF_CALLCONV 770 FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) { 771 CPDFSDK_FormFillEnvironment* pFormFillEnv = 772 HandleToCPDFSDKEnvironment(hHandle); 773 if (pFormFillEnv && pFormFillEnv->IsJSInitiated()) 774 pFormFillEnv->ProcJavascriptFun(); 775 } 776 777 FPDF_EXPORT void FPDF_CALLCONV 778 FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) { 779 CPDFSDK_FormFillEnvironment* pFormFillEnv = 780 HandleToCPDFSDKEnvironment(hHandle); 781 if (pFormFillEnv && pFormFillEnv->IsJSInitiated()) 782 pFormFillEnv->ProcOpenAction(); 783 } 784 785 FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, 786 int aaType) { 787 CPDFSDK_FormFillEnvironment* pFormFillEnv = 788 HandleToCPDFSDKEnvironment(hHandle); 789 if (!pFormFillEnv) 790 return; 791 792 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument(); 793 const CPDF_Dictionary* pDict = pDoc->GetRoot(); 794 if (!pDict) 795 return; 796 797 CPDF_AAction aa(pDict->GetDictFor("AA")); 798 auto type = static_cast<CPDF_AAction::AActionType>(aaType); 799 if (aa.ActionExist(type)) { 800 CPDF_Action action = aa.GetAction(type); 801 CPDFSDK_ActionHandler* pActionHandler = 802 HandleToCPDFSDKEnvironment(hHandle)->GetActionHandler(); 803 pActionHandler->DoAction_Document(action, type, pFormFillEnv); 804 } 805 } 806 807 FPDF_EXPORT void FPDF_CALLCONV FORM_DoPageAAction(FPDF_PAGE page, 808 FPDF_FORMHANDLE hHandle, 809 int aaType) { 810 CPDFSDK_FormFillEnvironment* pFormFillEnv = 811 HandleToCPDFSDKEnvironment(hHandle); 812 if (!pFormFillEnv) 813 return; 814 815 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 816 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page); 817 if (!pPDFPage) 818 return; 819 820 if (!pFormFillEnv->GetPageView(pPage, false)) 821 return; 822 823 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHandler(); 824 CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict.Get(); 825 CPDF_AAction aa(pPageDict->GetDictFor("AA")); 826 CPDF_AAction::AActionType type = aaType == FPDFPAGE_AACTION_OPEN 827 ? CPDF_AAction::OpenPage 828 : CPDF_AAction::ClosePage; 829 if (aa.ActionExist(type)) { 830 CPDF_Action action = aa.GetAction(type); 831 pActionHandler->DoAction_Page(action, type, pFormFillEnv); 832 } 833 } 834