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