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_fxgedevice.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/xfa_ffdocview.h" 33 #include "xfa/fxfa/xfa_ffpageview.h" 34 #include "xfa/fxfa/xfa_ffwidget.h" 35 #endif // PDF_ENABLE_XFA 36 37 namespace { 38 39 CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment( 40 FPDF_FORMHANDLE handle) { 41 return static_cast<CPDFSDK_FormFillEnvironment*>(handle); 42 } 43 44 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) { 45 CPDFSDK_FormFillEnvironment* pFormFillEnv = 46 HandleToCPDFSDKEnvironment(hHandle); 47 return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr; 48 } 49 50 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle, 51 FPDF_PAGE page) { 52 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 53 if (!pPage) 54 return nullptr; 55 56 CPDFSDK_FormFillEnvironment* pFormFillEnv = 57 HandleToCPDFSDKEnvironment(hHandle); 58 return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr; 59 } 60 61 #ifdef PDF_ENABLE_XFA 62 std::vector<CFX_ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) { 63 return reinterpret_cast<std::vector<CFX_ByteString>*>(handle); 64 } 65 66 FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<CFX_ByteString>* strings) { 67 return reinterpret_cast<FPDF_STRINGHANDLE>(strings); 68 } 69 #endif // PDF_ENABLE_XFA 70 71 void FFLCommon(FPDF_FORMHANDLE hHandle, 72 FPDF_BITMAP bitmap, 73 FPDF_RECORDER recorder, 74 FPDF_PAGE page, 75 int start_x, 76 int start_y, 77 int size_x, 78 int size_y, 79 int rotate, 80 int flags) { 81 if (!hHandle) 82 return; 83 84 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 85 if (!pPage) 86 return; 87 88 #ifdef PDF_ENABLE_XFA 89 CPDFXFA_Context* pContext = pPage->GetContext(); 90 if (!pContext) 91 return; 92 CPDF_Document* pPDFDoc = pContext->GetPDFDoc(); 93 if (!pPDFDoc) 94 return; 95 CPDFSDK_FormFillEnvironment* pFormFillEnv = 96 HandleToCPDFSDKEnvironment(hHandle); 97 if (!pFormFillEnv) 98 return; 99 #endif // PDF_ENABLE_XFA 100 101 CFX_Matrix matrix = 102 pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); 103 FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y); 104 105 std::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice); 106 #ifdef _SKIA_SUPPORT_ 107 pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder)); 108 #endif 109 pDevice->Attach(CFXBitmapFromFPDFBitmap(bitmap), false, nullptr, false); 110 pDevice->SaveState(); 111 pDevice->SetClip_Rect(clip); 112 113 CPDF_RenderOptions options; 114 if (flags & FPDF_LCD_TEXT) 115 options.m_Flags |= RENDER_CLEARTYPE; 116 else 117 options.m_Flags &= ~RENDER_CLEARTYPE; 118 119 // Grayscale output 120 if (flags & FPDF_GRAYSCALE) { 121 options.m_ColorMode = RENDER_COLOR_GRAY; 122 options.m_ForeColor = 0; 123 options.m_BackColor = 0xffffff; 124 } 125 options.m_AddFlags = flags >> 8; 126 options.m_bDrawAnnots = flags & FPDF_ANNOT; 127 128 #ifdef PDF_ENABLE_XFA 129 options.m_pOCContext = 130 pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View); 131 if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true)) 132 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip); 133 #else // PDF_ENABLE_XFA 134 options.m_pOCContext = pdfium::MakeRetain<CPDF_OCContext>( 135 pPage->m_pDocument, CPDF_OCContext::View); 136 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage)) 137 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options); 138 #endif // PDF_ENABLE_XFA 139 140 pDevice->RestoreState(false); 141 #ifdef _SKIA_SUPPORT_PATHS_ 142 pDevice->Flush(); 143 CFXBitmapFromFPDFBitmap(bitmap)->UnPreMultiply(); 144 #endif 145 } 146 147 } // namespace 148 149 DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, 150 FPDF_PAGE page, 151 double page_x, 152 double page_y) { 153 if (!hHandle) 154 return -1; 155 CPDF_Page* pPage = CPDFPageFromFPDFPage(page); 156 if (pPage) { 157 CPDF_InterForm interform(pPage->m_pDocument); 158 CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint( 159 pPage, CFX_PointF(static_cast<FX_FLOAT>(page_x), 160 static_cast<FX_FLOAT>(page_y)), 161 nullptr); 162 if (!pFormCtrl) 163 return -1; 164 CPDF_FormField* pFormField = pFormCtrl->GetField(); 165 return pFormField ? pFormField->GetFieldType() : -1; 166 } 167 168 #ifdef PDF_ENABLE_XFA 169 CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page); 170 if (!pXFAPage) 171 return -1; 172 173 CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView(); 174 if (!pPageView) 175 return -1; 176 177 CXFA_FFDocView* pDocView = pPageView->GetDocView(); 178 if (!pDocView) 179 return -1; 180 181 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler(); 182 if (!pWidgetHandler) 183 return -1; 184 185 std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator( 186 pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, 187 XFA_WidgetStatus_Viewable)); 188 if (!pWidgetIterator) 189 return -1; 190 191 CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext(); 192 while (pXFAAnnot) { 193 CFX_RectF rcBBox = pXFAAnnot->GetBBox(0); 194 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, 195 rcBBox.top + rcBBox.height); 196 rcWidget.left -= 1.0f; 197 rcWidget.right += 1.0f; 198 rcWidget.bottom -= 1.0f; 199 rcWidget.top += 1.0f; 200 201 if (rcWidget.Contains(CFX_PointF(static_cast<FX_FLOAT>(page_x), 202 static_cast<FX_FLOAT>(page_y)))) { 203 return FPDF_FORMFIELD_XFA; 204 } 205 pXFAAnnot = pWidgetIterator->MoveToNext(); 206 } 207 #endif // PDF_ENABLE_XFA 208 return -1; 209 } 210 211 DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, 212 FPDF_PAGE page, 213 double page_x, 214 double page_y) { 215 return FPDFPage_HasFormFieldAtPoint(hHandle, page, page_x, page_y); 216 } 217 218 DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle, 219 FPDF_PAGE page, 220 double page_x, 221 double page_y) { 222 if (!hHandle) 223 return -1; 224 CPDF_Page* pPage = CPDFPageFromFPDFPage(page); 225 if (!pPage) 226 return -1; 227 CPDF_InterForm interform(pPage->m_pDocument); 228 int z_order = -1; 229 (void)interform.GetControlAtPoint( 230 pPage, 231 CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y)), 232 &z_order); 233 return z_order; 234 } 235 236 DLLEXPORT FPDF_FORMHANDLE STDCALL 237 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document, 238 FPDF_FORMFILLINFO* formInfo) { 239 #ifdef PDF_ENABLE_XFA 240 const int kRequiredVersion = 2; 241 #else // PDF_ENABLE_XFA 242 const int kRequiredVersion = 1; 243 #endif // PDF_ENABLE_XFA 244 if (!formInfo || formInfo->version != kRequiredVersion) 245 return nullptr; 246 247 UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document); 248 if (!pDocument) 249 return nullptr; 250 251 #ifdef PDF_ENABLE_XFA 252 // If the CPDFXFA_Context has a FormFillEnvironment already then we've done 253 // this and can just return the old Env. Otherwise, we'll end up setting a new 254 // environment into the XFADocument and, that could get weird. 255 if (pDocument->GetFormFillEnv()) 256 return pDocument->GetFormFillEnv(); 257 #endif 258 259 CPDFSDK_FormFillEnvironment* pFormFillEnv = 260 new CPDFSDK_FormFillEnvironment(pDocument, formInfo); 261 262 #ifdef PDF_ENABLE_XFA 263 pDocument->SetFormFillEnv(pFormFillEnv); 264 #endif // PDF_ENABLE_XFA 265 266 return pFormFillEnv; 267 } 268 269 DLLEXPORT void STDCALL 270 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) { 271 if (!hHandle) 272 return; 273 274 CPDFSDK_FormFillEnvironment* pFormFillEnv = 275 HandleToCPDFSDKEnvironment(hHandle); 276 277 #ifdef PDF_ENABLE_XFA 278 // Reset the focused annotations and remove the SDK document from the 279 // XFA document. 280 pFormFillEnv->ClearAllFocusedAnnots(); 281 // If the document was closed first, it's possible the XFA document 282 // is now a nullptr. 283 if (pFormFillEnv->GetXFAContext()) 284 pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr); 285 #endif // PDF_ENABLE_XFA 286 287 delete pFormFillEnv; 288 } 289 290 DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, 291 FPDF_PAGE page, 292 int modifier, 293 double page_x, 294 double page_y) { 295 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 296 if (!pPageView) 297 return false; 298 return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier); 299 } 300 301 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, 302 FPDF_PAGE page, 303 int modifier, 304 double page_x, 305 double page_y) { 306 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 307 if (!pPageView) 308 return false; 309 return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier); 310 } 311 312 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, 313 FPDF_PAGE page, 314 int modifier, 315 double page_x, 316 double page_y) { 317 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 318 if (!pPageView) 319 return false; 320 321 CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); 322 return pPageView->OnLButtonUp(pt, modifier); 323 } 324 325 #ifdef PDF_ENABLE_XFA 326 DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, 327 FPDF_PAGE page, 328 int modifier, 329 double page_x, 330 double page_y) { 331 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 332 if (!pPageView) 333 return false; 334 return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier); 335 } 336 337 DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, 338 FPDF_PAGE page, 339 int modifier, 340 double page_x, 341 double page_y) { 342 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 343 if (!pPageView) 344 return false; 345 346 CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); 347 return pPageView->OnRButtonUp(pt, modifier); 348 } 349 #endif // PDF_ENABLE_XFA 350 351 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, 352 FPDF_PAGE page, 353 int nKeyCode, 354 int modifier) { 355 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 356 if (!pPageView) 357 return false; 358 359 return pPageView->OnKeyDown(nKeyCode, modifier); 360 } 361 362 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, 363 FPDF_PAGE page, 364 int nKeyCode, 365 int modifier) { 366 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 367 if (!pPageView) 368 return false; 369 370 return pPageView->OnKeyUp(nKeyCode, modifier); 371 } 372 373 DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle, 374 FPDF_PAGE page, 375 int nChar, 376 int modifier) { 377 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); 378 if (!pPageView) 379 return false; 380 381 return pPageView->OnChar(nChar, modifier); 382 } 383 384 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) { 385 CPDFSDK_FormFillEnvironment* pFormFillEnv = 386 HandleToCPDFSDKEnvironment(hHandle); 387 if (!pFormFillEnv) 388 return false; 389 return pFormFillEnv->KillFocusAnnot(0); 390 } 391 392 DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, 393 FPDF_BITMAP bitmap, 394 FPDF_PAGE page, 395 int start_x, 396 int start_y, 397 int size_x, 398 int size_y, 399 int rotate, 400 int flags) { 401 FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y, 402 rotate, flags); 403 } 404 405 #ifdef _SKIA_SUPPORT_ 406 DLLEXPORT void STDCALL FPDF_FFLRecord(FPDF_FORMHANDLE hHandle, 407 FPDF_RECORDER recorder, 408 FPDF_PAGE page, 409 int start_x, 410 int start_y, 411 int size_x, 412 int size_y, 413 int rotate, 414 int flags) { 415 FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y, 416 rotate, flags); 417 } 418 #endif 419 420 #ifdef PDF_ENABLE_XFA 421 DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document, 422 FPDF_WIDGET hWidget) { 423 if (!hWidget || !document) 424 return; 425 426 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 427 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 428 pContext->GetDocType() != XFA_DOCTYPE_Static) 429 return; 430 431 static_cast<CXFA_FFWidget*>(hWidget)->Undo(); 432 } 433 434 DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document, 435 FPDF_WIDGET hWidget) { 436 if (!hWidget || !document) 437 return; 438 439 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 440 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 441 pContext->GetDocType() != XFA_DOCTYPE_Static) 442 return; 443 444 static_cast<CXFA_FFWidget*>(hWidget)->Redo(); 445 } 446 447 DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document, 448 FPDF_WIDGET hWidget) { 449 if (!hWidget || !document) 450 return; 451 452 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 453 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 454 pContext->GetDocType() != XFA_DOCTYPE_Static) 455 return; 456 457 static_cast<CXFA_FFWidget*>(hWidget)->SelectAll(); 458 } 459 460 DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document, 461 FPDF_WIDGET hWidget, 462 FPDF_WIDESTRING wsText, 463 FPDF_DWORD* size) { 464 if (!hWidget || !document) 465 return; 466 467 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 468 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 469 pContext->GetDocType() != XFA_DOCTYPE_Static) 470 return; 471 472 CFX_WideString wsCpText; 473 static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsCpText); 474 475 CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode(); 476 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short); 477 if (!wsText) { 478 *size = len; 479 return; 480 } 481 482 uint32_t real_size = len < *size ? len : *size; 483 if (real_size > 0) { 484 FXSYS_memcpy((void*)wsText, 485 bsCpText.GetBuffer(real_size * sizeof(unsigned short)), 486 real_size * sizeof(unsigned short)); 487 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short)); 488 } 489 *size = real_size; 490 } 491 492 DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document, 493 FPDF_WIDGET hWidget, 494 FPDF_WIDESTRING wsText, 495 FPDF_DWORD* size) { 496 if (!hWidget || !document) 497 return; 498 499 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 500 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 501 pContext->GetDocType() != XFA_DOCTYPE_Static) 502 return; 503 504 CFX_WideString wsCpText; 505 static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsCpText); 506 507 CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode(); 508 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short); 509 if (!wsText) { 510 *size = len; 511 return; 512 } 513 514 uint32_t real_size = len < *size ? len : *size; 515 if (real_size > 0) { 516 FXSYS_memcpy((void*)wsText, 517 bsCpText.GetBuffer(real_size * sizeof(unsigned short)), 518 real_size * sizeof(unsigned short)); 519 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short)); 520 } 521 *size = real_size; 522 } 523 524 DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document, 525 FPDF_WIDGET hWidget, 526 FPDF_WIDESTRING wsText, 527 FPDF_DWORD size) { 528 if (!hWidget || !document) 529 return; 530 531 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 532 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 533 pContext->GetDocType() != XFA_DOCTYPE_Static) 534 return; 535 536 CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size); 537 static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr); 538 } 539 540 DLLEXPORT void STDCALL 541 FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document, 542 FPDF_WIDGET hWidget, 543 float x, 544 float y, 545 FPDF_BYTESTRING bsText) { 546 if (!hWidget || !document) 547 return; 548 549 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 550 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 551 pContext->GetDocType() != XFA_DOCTYPE_Static) 552 return; 553 554 CFX_PointF ptPopup; 555 ptPopup.x = x; 556 ptPopup.y = y; 557 CFX_ByteStringC bs(bsText); 558 static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs); 559 } 560 561 DLLEXPORT void STDCALL 562 FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document, 563 FPDF_WIDGET hWidget, 564 float x, 565 float y, 566 FPDF_STRINGHANDLE* stringHandle) { 567 if (!hWidget || !document) 568 return; 569 570 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); 571 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic && 572 pContext->GetDocType() != XFA_DOCTYPE_Static) 573 return; 574 575 std::vector<CFX_ByteString>* sSuggestWords = new std::vector<CFX_ByteString>; 576 CFX_PointF ptPopup; 577 ptPopup.x = x; 578 ptPopup.y = y; 579 static_cast<CXFA_FFWidget*>(hWidget) 580 ->GetSuggestWords(ptPopup, *sSuggestWords); 581 *stringHandle = ToFPDFStringHandle(sSuggestWords); 582 } 583 584 DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) { 585 std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle); 586 return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1; 587 } 588 589 DLLEXPORT FPDF_BOOL STDCALL 590 FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle, 591 int index, 592 FPDF_BYTESTRING bsText, 593 FPDF_DWORD* size) { 594 if (!sHandle || !size) 595 return false; 596 597 int count = FPDF_StringHandleCounts(sHandle); 598 if (index < 0 || index >= count) 599 return false; 600 601 std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle); 602 uint32_t len = (*sSuggestWords)[index].GetLength(); 603 if (!bsText) { 604 *size = len; 605 return true; 606 } 607 608 uint32_t real_size = len < *size ? len : *size; 609 if (real_size > 0) 610 FXSYS_memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size); 611 *size = real_size; 612 return true; 613 } 614 615 DLLEXPORT void STDCALL 616 FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) { 617 delete FromFPDFStringHandle(stringHandle); 618 } 619 620 DLLEXPORT FPDF_BOOL STDCALL 621 FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle, 622 FPDF_BYTESTRING bsText, 623 FPDF_DWORD size) { 624 if (!stringHandle || !bsText || size == 0) 625 return false; 626 627 FromFPDFStringHandle(stringHandle)->push_back(CFX_ByteString(bsText, size)); 628 return true; 629 } 630 #endif // PDF_ENABLE_XFA 631 632 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, 633 int fieldType, 634 unsigned long color) { 635 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 636 pInterForm->SetHighlightColor(color, fieldType); 637 } 638 639 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, 640 unsigned char alpha) { 641 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 642 pInterForm->SetHighlightAlpha(alpha); 643 } 644 645 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) { 646 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 647 pInterForm->RemoveAllHighLight(); 648 } 649 650 DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page, 651 FPDF_FORMHANDLE hHandle) { 652 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page)) 653 pPageView->SetValid(true); 654 } 655 656 DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page, 657 FPDF_FORMHANDLE hHandle) { 658 if (!hHandle) 659 return; 660 661 CPDFSDK_FormFillEnvironment* pFormFillEnv = 662 HandleToCPDFSDKEnvironment(hHandle); 663 if (!pFormFillEnv) 664 return; 665 666 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 667 if (!pPage) 668 return; 669 670 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false); 671 if (pPageView) { 672 pPageView->SetValid(false); 673 // RemovePageView() takes care of the delete for us. 674 pFormFillEnv->RemovePageView(pPage); 675 } 676 } 677 678 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) { 679 CPDFSDK_FormFillEnvironment* pFormFillEnv = 680 HandleToCPDFSDKEnvironment(hHandle); 681 if (pFormFillEnv && pFormFillEnv->IsJSInitiated()) 682 pFormFillEnv->ProcJavascriptFun(); 683 } 684 685 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) { 686 CPDFSDK_FormFillEnvironment* pFormFillEnv = 687 HandleToCPDFSDKEnvironment(hHandle); 688 if (pFormFillEnv && pFormFillEnv->IsJSInitiated()) 689 pFormFillEnv->ProcOpenAction(); 690 } 691 692 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, 693 int aaType) { 694 CPDFSDK_FormFillEnvironment* pFormFillEnv = 695 HandleToCPDFSDKEnvironment(hHandle); 696 if (!pFormFillEnv) 697 return; 698 699 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument(); 700 CPDF_Dictionary* pDic = pDoc->GetRoot(); 701 if (!pDic) 702 return; 703 704 CPDF_AAction aa(pDic->GetDictFor("AA")); 705 if (aa.ActionExist((CPDF_AAction::AActionType)aaType)) { 706 CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType); 707 CPDFSDK_ActionHandler* pActionHandler = 708 HandleToCPDFSDKEnvironment(hHandle)->GetActionHander(); 709 pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType, 710 pFormFillEnv); 711 } 712 } 713 714 DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, 715 FPDF_FORMHANDLE hHandle, 716 int aaType) { 717 if (!hHandle) 718 return; 719 720 CPDFSDK_FormFillEnvironment* pFormFillEnv = 721 HandleToCPDFSDKEnvironment(hHandle); 722 if (!pFormFillEnv) 723 return; 724 725 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); 726 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page); 727 if (!pPDFPage) 728 return; 729 730 if (!pFormFillEnv->GetPageView(pPage, false)) 731 return; 732 733 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHander(); 734 CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict; 735 CPDF_AAction aa(pPageDict->GetDictFor("AA")); 736 if (FPDFPAGE_AACTION_OPEN == aaType) { 737 if (aa.ActionExist(CPDF_AAction::OpenPage)) { 738 CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage); 739 pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, 740 pFormFillEnv); 741 } 742 } else { 743 if (aa.ActionExist(CPDF_AAction::ClosePage)) { 744 CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage); 745 pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, 746 pFormFillEnv); 747 } 748 } 749 } 750