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 21 namespace { 22 23 CPDFSDK_Document* FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle) { 24 CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle; 25 return pEnv ? pEnv->GetSDKDocument() : nullptr; 26 } 27 28 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) { 29 CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle); 30 return pSDKDoc ? pSDKDoc->GetInterForm() : nullptr; 31 } 32 33 CPDFSDK_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 45 DLLEXPORT 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 121 DLLEXPORT 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 128 DLLEXPORT 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 144 DLLEXPORT FPDF_FORMHANDLE STDCALL 145 FPDFDOC_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 170 DLLEXPORT void STDCALL 171 FPDFDOC_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 187 DLLEXPORT 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 200 DLLEXPORT 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 213 DLLEXPORT 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 227 DLLEXPORT 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 240 DLLEXPORT 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 254 DLLEXPORT 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 265 DLLEXPORT 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 276 DLLEXPORT 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 287 DLLEXPORT 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 295 DLLEXPORT 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 387 DLLEXPORT 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 } 404 DLLEXPORT 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 422 DLLEXPORT 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 } 439 DLLEXPORT 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 } 475 DLLEXPORT 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 } 510 DLLEXPORT 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 } 530 DLLEXPORT void STDCALL 531 FPDF_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 } 555 DLLEXPORT void STDCALL 556 FPDF_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 } 582 DLLEXPORT 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 } 588 DLLEXPORT FPDF_BOOL STDCALL 589 FPDF_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 } 615 DLLEXPORT void STDCALL 616 FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) { 617 if (stringHandle == NULL) 618 return; 619 CFX_ByteStringArray* sSuggestWords = (CFX_ByteStringArray*)stringHandle; 620 delete sSuggestWords; 621 } 622 623 DLLEXPORT FPDF_BOOL STDCALL 624 FPDF_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 638 DLLEXPORT 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 645 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, 646 unsigned char alpha) { 647 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 648 pInterForm->SetHighlightAlpha(alpha); 649 } 650 651 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) { 652 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle)) 653 pInterForm->RemoveAllHighLight(); 654 } 655 656 DLLEXPORT 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 662 DLLEXPORT 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 683 DLLEXPORT 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 689 DLLEXPORT 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 695 DLLEXPORT 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 716 DLLEXPORT 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