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
FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle)23 CPDFSDK_Document* FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle) {
24 CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
25 return pEnv ? pEnv->GetSDKDocument() : nullptr;
26 }
27
FormHandleToInterForm(FPDF_FORMHANDLE hHandle)28 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
29 CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
30 return pSDKDoc ? pSDKDoc->GetInterForm() : nullptr;
31 }
32
FormHandleToPageView(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)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
FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)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
FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)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
FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)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
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,FPDF_FORMFILLINFO * formInfo)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
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle)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
FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)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
FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)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
FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)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
FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)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
FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)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
FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)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
FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)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
FORM_OnChar(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nChar,int modifier)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
FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)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
FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,FPDF_BITMAP bitmap,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)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
FPDF_Widget_Undo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)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 }
FPDF_Widget_Redo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)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
FPDF_Widget_SelectAll(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)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 }
FPDF_Widget_Copy(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)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 }
FPDF_Widget_Cut(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)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 }
FPDF_Widget_Paste(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD size)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
FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_BYTESTRING bsText)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
FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_STRINGHANDLE * stringHandle)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 }
FPDF_StringHandleCounts(FPDF_STRINGHANDLE stringHandle)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
FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE stringHandle,int index,FPDF_BYTESTRING bsText,FPDF_DWORD * size)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
FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle)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
FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,FPDF_BYTESTRING bsText,FPDF_DWORD size)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
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,int fieldType,unsigned long color)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
FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,unsigned char alpha)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
FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)651 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
652 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
653 pInterForm->RemoveAllHighLight();
654 }
655
FORM_OnAfterLoadPage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)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
FORM_OnBeforeClosePage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)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
FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)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
FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)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
FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,int aaType)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
FORM_DoPageAAction(FPDF_PAGE page,FPDF_FORMHANDLE hHandle,int aaType)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