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 <utility>
11 #include <vector>
12
13 #include "core/fpdfapi/page/cpdf_occontext.h"
14 #include "core/fpdfapi/page/cpdf_page.h"
15 #include "core/fpdfapi/parser/cpdf_dictionary.h"
16 #include "core/fpdfapi/parser/cpdf_document.h"
17 #include "core/fpdfapi/render/cpdf_renderoptions.h"
18 #include "core/fpdfdoc/cpdf_formcontrol.h"
19 #include "core/fpdfdoc/cpdf_formfield.h"
20 #include "core/fpdfdoc/cpdf_interactiveform.h"
21 #include "core/fxge/cfx_defaultrenderdevice.h"
22 #include "fpdfsdk/cpdfsdk_actionhandler.h"
23 #include "fpdfsdk/cpdfsdk_baannothandler.h"
24 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
25 #include "fpdfsdk/cpdfsdk_helpers.h"
26 #include "fpdfsdk/cpdfsdk_interactiveform.h"
27 #include "fpdfsdk/cpdfsdk_pageview.h"
28 #include "fpdfsdk/cpdfsdk_widgethandler.h"
29 #include "public/fpdfview.h"
30 #include "third_party/base/ptr_util.h"
31
32 #ifdef PDF_ENABLE_XFA
33 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
34 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
35 #include "fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h"
36
37 static_assert(static_cast<int>(AlertButton::kDefault) ==
38 JSPLATFORM_ALERT_BUTTON_DEFAULT,
39 "Default alert button types must match");
40 static_assert(static_cast<int>(AlertButton::kOK) == JSPLATFORM_ALERT_BUTTON_OK,
41 "OK alert button types must match");
42 static_assert(static_cast<int>(AlertButton::kOKCancel) ==
43 JSPLATFORM_ALERT_BUTTON_OKCANCEL,
44 "OKCancel alert button types must match");
45 static_assert(static_cast<int>(AlertButton::kYesNo) ==
46 JSPLATFORM_ALERT_BUTTON_YESNO,
47 "YesNo alert button types must match");
48 static_assert(static_cast<int>(AlertButton::kYesNoCancel) ==
49 JSPLATFORM_ALERT_BUTTON_YESNOCANCEL,
50 "YesNoCancel alert button types must match");
51
52 static_assert(static_cast<int>(AlertIcon::kDefault) ==
53 JSPLATFORM_ALERT_ICON_DEFAULT,
54 "Default alert icon types must match");
55 static_assert(static_cast<int>(AlertIcon::kError) ==
56 JSPLATFORM_ALERT_ICON_ERROR,
57 "Error alert icon types must match");
58 static_assert(static_cast<int>(AlertIcon::kWarning) ==
59 JSPLATFORM_ALERT_ICON_WARNING,
60 "Warning alert icon types must match");
61 static_assert(static_cast<int>(AlertIcon::kQuestion) ==
62 JSPLATFORM_ALERT_ICON_QUESTION,
63 "Question alert icon types must match");
64 static_assert(static_cast<int>(AlertIcon::kStatus) ==
65 JSPLATFORM_ALERT_ICON_STATUS,
66 "Status alert icon types must match");
67 static_assert(static_cast<int>(AlertIcon::kAsterisk) ==
68 JSPLATFORM_ALERT_ICON_ASTERISK,
69 "Asterisk alert icon types must match");
70
71 static_assert(static_cast<int>(AlertReturn::kOK) == JSPLATFORM_ALERT_RETURN_OK,
72 "OK alert return types must match");
73 static_assert(static_cast<int>(AlertReturn::kCancel) ==
74 JSPLATFORM_ALERT_RETURN_CANCEL,
75 "Cancel alert return types must match");
76 static_assert(static_cast<int>(AlertReturn::kNo) == JSPLATFORM_ALERT_RETURN_NO,
77 "No alert return types must match");
78 static_assert(static_cast<int>(AlertReturn::kYes) ==
79 JSPLATFORM_ALERT_RETURN_YES,
80 "Yes alert return types must match");
81
82 static_assert(static_cast<int>(FormType::kNone) == FORMTYPE_NONE,
83 "None form types must match");
84 static_assert(static_cast<int>(FormType::kAcroForm) == FORMTYPE_ACRO_FORM,
85 "AcroForm form types must match");
86 static_assert(static_cast<int>(FormType::kXFAFull) == FORMTYPE_XFA_FULL,
87 "XFA full form types must match");
88 static_assert(static_cast<int>(FormType::kXFAForeground) ==
89 FORMTYPE_XFA_FOREGROUND,
90 "XFA foreground form types must match");
91 #endif // PDF_ENABLE_XFA
92
93 static_assert(static_cast<int>(FormFieldType::kUnknown) ==
94 FPDF_FORMFIELD_UNKNOWN,
95 "Unknown form field types must match");
96 static_assert(static_cast<int>(FormFieldType::kPushButton) ==
97 FPDF_FORMFIELD_PUSHBUTTON,
98 "PushButton form field types must match");
99 static_assert(static_cast<int>(FormFieldType::kCheckBox) ==
100 FPDF_FORMFIELD_CHECKBOX,
101 "CheckBox form field types must match");
102 static_assert(static_cast<int>(FormFieldType::kRadioButton) ==
103 FPDF_FORMFIELD_RADIOBUTTON,
104 "RadioButton form field types must match");
105 static_assert(static_cast<int>(FormFieldType::kComboBox) ==
106 FPDF_FORMFIELD_COMBOBOX,
107 "ComboBox form field types must match");
108 static_assert(static_cast<int>(FormFieldType::kListBox) ==
109 FPDF_FORMFIELD_LISTBOX,
110 "ListBox form field types must match");
111 static_assert(static_cast<int>(FormFieldType::kTextField) ==
112 FPDF_FORMFIELD_TEXTFIELD,
113 "TextField form field types must match");
114 static_assert(static_cast<int>(FormFieldType::kSignature) ==
115 FPDF_FORMFIELD_SIGNATURE,
116 "Signature form field types must match");
117 #ifdef PDF_ENABLE_XFA
118 static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA,
119 "XFA form field types must match");
120 static_assert(static_cast<int>(FormFieldType::kXFA_CheckBox) ==
121 FPDF_FORMFIELD_XFA_CHECKBOX,
122 "XFA CheckBox form field types must match");
123 static_assert(static_cast<int>(FormFieldType::kXFA_ComboBox) ==
124 FPDF_FORMFIELD_XFA_COMBOBOX,
125 "XFA ComboBox form field types must match");
126 static_assert(static_cast<int>(FormFieldType::kXFA_ImageField) ==
127 FPDF_FORMFIELD_XFA_IMAGEFIELD,
128 "XFA ImageField form field types must match");
129 static_assert(static_cast<int>(FormFieldType::kXFA_ListBox) ==
130 FPDF_FORMFIELD_XFA_LISTBOX,
131 "XFA ListBox form field types must match");
132 static_assert(static_cast<int>(FormFieldType::kXFA_PushButton) ==
133 FPDF_FORMFIELD_XFA_PUSHBUTTON,
134 "XFA PushButton form field types must match");
135 static_assert(static_cast<int>(FormFieldType::kXFA_Signature) ==
136 FPDF_FORMFIELD_XFA_SIGNATURE,
137 "XFA Signature form field types must match");
138 static_assert(static_cast<int>(FormFieldType::kXFA_TextField) ==
139 FPDF_FORMFIELD_XFA_TEXTFIELD,
140 "XFA TextField form field types must match");
141 #endif // PDF_ENABLE_XFA
142 static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT,
143 "Number of form field types must match");
144
145 static_assert(static_cast<int>(CPDF_AAction::kCloseDocument) ==
146 FPDFDOC_AACTION_WC,
147 "CloseDocument action must match");
148 static_assert(static_cast<int>(CPDF_AAction::kSaveDocument) ==
149 FPDFDOC_AACTION_WS,
150 "SaveDocument action must match");
151 static_assert(static_cast<int>(CPDF_AAction::kDocumentSaved) ==
152 FPDFDOC_AACTION_DS,
153 "DocumentSaved action must match");
154 static_assert(static_cast<int>(CPDF_AAction::kPrintDocument) ==
155 FPDFDOC_AACTION_WP,
156 "PrintDocument action must match");
157 static_assert(static_cast<int>(CPDF_AAction::kDocumentPrinted) ==
158 FPDFDOC_AACTION_DP,
159 "DocumentPrinted action must match");
160
161 namespace {
162
FormHandleToPageView(FPDF_FORMHANDLE hHandle,FPDF_PAGE fpdf_page)163 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
164 FPDF_PAGE fpdf_page) {
165 IPDF_Page* pPage = IPDFPageFromFPDFPage(fpdf_page);
166 if (!pPage)
167 return nullptr;
168
169 CPDFSDK_FormFillEnvironment* pFormFillEnv =
170 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
171 return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
172 }
173
FFLCommon(FPDF_FORMHANDLE hHandle,FPDF_BITMAP bitmap,FPDF_RECORDER recorder,FPDF_PAGE fpdf_page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)174 void FFLCommon(FPDF_FORMHANDLE hHandle,
175 FPDF_BITMAP bitmap,
176 FPDF_RECORDER recorder,
177 FPDF_PAGE fpdf_page,
178 int start_x,
179 int start_y,
180 int size_x,
181 int size_y,
182 int rotate,
183 int flags) {
184 if (!hHandle)
185 return;
186
187 IPDF_Page* pPage = IPDFPageFromFPDFPage(fpdf_page);
188 if (!pPage)
189 return;
190
191 CPDF_Document* pPDFDoc = pPage->GetDocument();
192 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, fpdf_page);
193
194 const FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
195 CFX_Matrix matrix = pPage->GetDisplayMatrix(rect, rotate);
196
197 auto pDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
198 #ifdef _SKIA_SUPPORT_
199 pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
200 #endif
201
202 RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
203 pDevice->Attach(holder, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
204 {
205 CFX_RenderDevice::StateRestorer restorer(pDevice.get());
206 pDevice->SetClip_Rect(rect);
207
208 CPDF_RenderOptions options;
209 options.GetOptions().bClearType = !!(flags & FPDF_LCD_TEXT);
210
211 // Grayscale output
212 if (flags & FPDF_GRAYSCALE)
213 options.SetColorMode(CPDF_RenderOptions::kGray);
214
215 options.SetDrawAnnots(flags & FPDF_ANNOT);
216 options.SetOCContext(
217 pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View));
218
219 if (pPageView)
220 pPageView->PageView_OnDraw(pDevice.get(), matrix, &options, rect);
221 }
222
223 #ifdef _SKIA_SUPPORT_PATHS_
224 pDevice->Flush(true);
225 holder->UnPreMultiply();
226 #endif
227 }
228
229 } // namespace
230
231 FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)232 FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
233 FPDF_PAGE page,
234 double page_x,
235 double page_y) {
236 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
237 if (pPage) {
238 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
239 if (!pForm)
240 return -1;
241
242 CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
243 CPDF_FormControl* pFormCtrl = pPDFForm->GetControlAtPoint(
244 pPage,
245 CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
246 nullptr);
247 if (!pFormCtrl)
248 return -1;
249 CPDF_FormField* pFormField = pFormCtrl->GetField();
250 return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1;
251 }
252
253 #ifdef PDF_ENABLE_XFA
254 CPDFXFA_Page* pXFAPage = ToXFAPage(IPDFPageFromFPDFPage(page));
255 if (pXFAPage) {
256 return pXFAPage->HasFormFieldAtPoint(
257 CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)));
258 }
259 #endif // PDF_ENABLE_XFA
260
261 return -1;
262 }
263
264 FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)265 FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
266 FPDF_PAGE page,
267 double page_x,
268 double page_y) {
269 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
270 if (!pForm)
271 return -1;
272
273 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
274 if (!pPage)
275 return -1;
276
277 CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
278 int z_order = -1;
279 pPDFForm->GetControlAtPoint(
280 pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
281 &z_order);
282 return z_order;
283 }
284
285 FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,FPDF_FORMFILLINFO * formInfo)286 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
287 FPDF_FORMFILLINFO* formInfo) {
288 #ifdef PDF_ENABLE_XFA
289 constexpr int kRequiredVersion = 2;
290 #else // PDF_ENABLE_XFA
291 constexpr int kRequiredVersion = 1;
292 #endif // PDF_ENABLE_XFA
293 if (!formInfo || formInfo->version != kRequiredVersion)
294 return nullptr;
295
296 auto* pDocument = CPDFDocumentFromFPDFDocument(document);
297 if (!pDocument)
298 return nullptr;
299
300 std::unique_ptr<IPDFSDK_AnnotHandler> pXFAHandler;
301 #ifdef PDF_ENABLE_XFA
302 CPDFXFA_Context* pContext = nullptr;
303 if (!formInfo->xfa_disabled) {
304 if (!pDocument->GetExtension()) {
305 pDocument->SetExtension(pdfium::MakeUnique<CPDFXFA_Context>(pDocument));
306 }
307
308 // If the CPDFXFA_Context has a FormFillEnvironment already then we've done
309 // this and can just return the old Env. Otherwise, we'll end up setting a
310 // new environment into the XFADocument and, that could get weird.
311 pContext = static_cast<CPDFXFA_Context*>(pDocument->GetExtension());
312 if (pContext->GetFormFillEnv()) {
313 return FPDFFormHandleFromCPDFSDKFormFillEnvironment(
314 pContext->GetFormFillEnv());
315 }
316 pXFAHandler = pdfium::MakeUnique<CPDFXFA_WidgetHandler>();
317 }
318 #endif // PDF_ENABLE_XFA
319
320 auto pFormFillEnv = pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(
321 pDocument, formInfo,
322 pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(
323 pdfium::MakeUnique<CPDFSDK_BAAnnotHandler>(),
324 pdfium::MakeUnique<CPDFSDK_WidgetHandler>(), std::move(pXFAHandler)));
325
326 #ifdef PDF_ENABLE_XFA
327 if (pContext)
328 pContext->SetFormFillEnv(pFormFillEnv.get());
329 #endif // PDF_ENABLE_XFA
330
331 ReportUnsupportedXFA(pDocument);
332
333 return FPDFFormHandleFromCPDFSDKFormFillEnvironment(
334 pFormFillEnv.release()); // Caller takes ownership.
335 }
336
337 FPDF_EXPORT void FPDF_CALLCONV
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle)338 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
339 if (!hHandle)
340 return;
341
342 // Take back ownership of the form fill environment. This is the inverse of
343 // FPDFDOC_InitFormFillEnvironment() above.
344 std::unique_ptr<CPDFSDK_FormFillEnvironment> pFormFillEnv(
345 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle));
346
347 #ifdef PDF_ENABLE_XFA
348 // Reset the focused annotations and remove the SDK document from the
349 // XFA document.
350 pFormFillEnv->ClearAllFocusedAnnots();
351 // If the document was closed first, it's possible the XFA document
352 // is now a nullptr.
353 auto* pContext =
354 static_cast<CPDFXFA_Context*>(pFormFillEnv->GetDocExtension());
355 if (pContext)
356 pContext->SetFormFillEnv(nullptr);
357 #endif // PDF_ENABLE_XFA
358 }
359
FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)360 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
361 FPDF_PAGE page,
362 int modifier,
363 double page_x,
364 double page_y) {
365 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
366 if (!pPageView)
367 return false;
368 return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier);
369 }
370
FORM_OnFocus(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)371 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnFocus(FPDF_FORMHANDLE hHandle,
372 FPDF_PAGE page,
373 int modifier,
374 double page_x,
375 double page_y) {
376 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
377 if (!pPageView)
378 return false;
379 return pPageView->OnFocus(CFX_PointF(page_x, page_y), modifier);
380 }
381
FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)382 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
383 FPDF_PAGE page,
384 int modifier,
385 double page_x,
386 double page_y) {
387 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
388 if (!pPageView)
389 return false;
390 #ifdef PDF_ENABLE_CLICK_LOGGING
391 fprintf(stderr, "mousedown,left,%d,%d\n", static_cast<int>(round(page_x)),
392 static_cast<int>(round(page_y)));
393 #endif // PDF_ENABLE_CLICK_LOGGING
394 return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier);
395 }
396
FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)397 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
398 FPDF_PAGE page,
399 int modifier,
400 double page_x,
401 double page_y) {
402 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
403 if (!pPageView)
404 return false;
405 #ifdef PDF_ENABLE_CLICK_LOGGING
406 fprintf(stderr, "mouseup,left,%d,%d\n", static_cast<int>(round(page_x)),
407 static_cast<int>(round(page_y)));
408 #endif // PDF_ENABLE_CLICK_LOGGING
409 return pPageView->OnLButtonUp(CFX_PointF(page_x, page_y), modifier);
410 }
411
412 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_OnLButtonDoubleClick(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)413 FORM_OnLButtonDoubleClick(FPDF_FORMHANDLE hHandle,
414 FPDF_PAGE page,
415 int modifier,
416 double page_x,
417 double page_y) {
418 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
419 if (!pPageView)
420 return false;
421 #ifdef PDF_ENABLE_CLICK_LOGGING
422 fprintf(stderr, "mousedown,doubleleft,%d,%d\n",
423 static_cast<int>(round(page_x)), static_cast<int>(round(page_y)));
424 #endif // PDF_ENABLE_CLICK_LOGGING
425 return pPageView->OnLButtonDblClk(CFX_PointF(page_x, page_y), modifier);
426 }
427
FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)428 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
429 FPDF_PAGE page,
430 int modifier,
431 double page_x,
432 double page_y) {
433 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
434 if (!pPageView)
435 return false;
436 #ifdef PDF_ENABLE_CLICK_LOGGING
437 fprintf(stderr, "mousedown,right,%d,%d\n", static_cast<int>(round(page_x)),
438 static_cast<int>(round(page_y)));
439 #endif // PDF_ENABLE_CLICK_LOGGING
440 return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier);
441 }
442
FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)443 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
444 FPDF_PAGE page,
445 int modifier,
446 double page_x,
447 double page_y) {
448 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
449 if (!pPageView)
450 return false;
451 #ifdef PDF_ENABLE_CLICK_LOGGING
452 fprintf(stderr, "mouseup,right,%d,%d\n", static_cast<int>(round(page_x)),
453 static_cast<int>(round(page_y)));
454 #endif // PDF_ENABLE_CLICK_LOGGING
455 return pPageView->OnRButtonUp(CFX_PointF(page_x, page_y), modifier);
456 }
457
FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)458 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
459 FPDF_PAGE page,
460 int nKeyCode,
461 int modifier) {
462 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
463 if (!pPageView)
464 return false;
465 return pPageView->OnKeyDown(nKeyCode, modifier);
466 }
467
FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)468 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
469 FPDF_PAGE page,
470 int nKeyCode,
471 int modifier) {
472 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
473 if (!pPageView)
474 return false;
475 return pPageView->OnKeyUp(nKeyCode, modifier);
476 }
477
FORM_OnChar(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nChar,int modifier)478 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle,
479 FPDF_PAGE page,
480 int nChar,
481 int modifier) {
482 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
483 if (!pPageView)
484 return false;
485 return pPageView->OnChar(nChar, modifier);
486 }
487
488 FPDF_EXPORT unsigned long FPDF_CALLCONV
FORM_GetFocusedText(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,void * buffer,unsigned long buflen)489 FORM_GetFocusedText(FPDF_FORMHANDLE hHandle,
490 FPDF_PAGE page,
491 void* buffer,
492 unsigned long buflen) {
493 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
494 if (!pPageView)
495 return 0;
496
497 return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetFocusedFormText(),
498 buffer, buflen);
499 }
500
501 FPDF_EXPORT unsigned long FPDF_CALLCONV
FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,void * buffer,unsigned long buflen)502 FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
503 FPDF_PAGE page,
504 void* buffer,
505 unsigned long buflen) {
506 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
507 if (!pPageView)
508 return 0;
509
510 return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetSelectedText(),
511 buffer, buflen);
512 }
513
FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,FPDF_WIDESTRING wsText)514 FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,
515 FPDF_PAGE page,
516 FPDF_WIDESTRING wsText) {
517 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
518 if (!pPageView)
519 return;
520
521 pPageView->ReplaceSelection(WideStringFromFPDFWideString(wsText));
522 }
523
FORM_CanUndo(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)524 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanUndo(FPDF_FORMHANDLE hHandle,
525 FPDF_PAGE page) {
526 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
527 if (!pPageView)
528 return false;
529 return pPageView->CanUndo();
530 }
531
FORM_CanRedo(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)532 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanRedo(FPDF_FORMHANDLE hHandle,
533 FPDF_PAGE page) {
534 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
535 if (!pPageView)
536 return false;
537 return pPageView->CanRedo();
538 }
539
FORM_Undo(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)540 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Undo(FPDF_FORMHANDLE hHandle,
541 FPDF_PAGE page) {
542 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
543 if (!pPageView)
544 return false;
545 return pPageView->Undo();
546 }
547
FORM_Redo(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)548 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Redo(FPDF_FORMHANDLE hHandle,
549 FPDF_PAGE page) {
550 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
551 if (!pPageView)
552 return false;
553 return pPageView->Redo();
554 }
555
556 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)557 FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
558 CPDFSDK_FormFillEnvironment* pFormFillEnv =
559 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
560 if (!pFormFillEnv)
561 return false;
562 return pFormFillEnv->KillFocusAnnot(0);
563 }
564
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)565 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
566 FPDF_BITMAP bitmap,
567 FPDF_PAGE page,
568 int start_x,
569 int start_y,
570 int size_x,
571 int size_y,
572 int rotate,
573 int flags) {
574 FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
575 rotate, flags);
576 }
577
578 #ifdef _SKIA_SUPPORT_
FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,FPDF_RECORDER recorder,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)579 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,
580 FPDF_RECORDER recorder,
581 FPDF_PAGE page,
582 int start_x,
583 int start_y,
584 int size_x,
585 int size_y,
586 int rotate,
587 int flags) {
588 FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y,
589 rotate, flags);
590 }
591 #endif
592
593 FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,int fieldType,unsigned long color)594 FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
595 int fieldType,
596 unsigned long color) {
597 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
598 if (!pForm)
599 return;
600
601 Optional<FormFieldType> cast_input =
602 CPDF_FormField::IntToFormFieldType(fieldType);
603 if (!cast_input)
604 return;
605
606 if (cast_input.value() == FormFieldType::kUnknown)
607 pForm->SetAllHighlightColors(color);
608 else
609 pForm->SetHighlightColor(color, cast_input.value());
610 }
611
612 FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,unsigned char alpha)613 FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) {
614 if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
615 pForm->SetHighlightAlpha(alpha);
616 }
617
618 FPDF_EXPORT void FPDF_CALLCONV
FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)619 FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
620 if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
621 pForm->RemoveAllHighLights();
622 }
623
FORM_OnAfterLoadPage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)624 FPDF_EXPORT void FPDF_CALLCONV FORM_OnAfterLoadPage(FPDF_PAGE page,
625 FPDF_FORMHANDLE hHandle) {
626 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
627 pPageView->SetValid(true);
628 }
629
FORM_OnBeforeClosePage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)630 FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page,
631 FPDF_FORMHANDLE hHandle) {
632 CPDFSDK_FormFillEnvironment* pFormFillEnv =
633 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
634 if (!pFormFillEnv)
635 return;
636
637 IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
638 if (!pPage)
639 return;
640
641 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false);
642 if (pPageView) {
643 pPageView->SetValid(false);
644 // RemovePageView() takes care of the delete for us.
645 pFormFillEnv->RemovePageView(pPage);
646 }
647 }
648
649 FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)650 FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
651 CPDFSDK_FormFillEnvironment* pFormFillEnv =
652 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
653 if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
654 pFormFillEnv->ProcJavascriptAction();
655 }
656
657 FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)658 FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
659 CPDFSDK_FormFillEnvironment* pFormFillEnv =
660 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
661 if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
662 pFormFillEnv->ProcOpenAction();
663 }
664
FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,int aaType)665 FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
666 int aaType) {
667 CPDFSDK_FormFillEnvironment* pFormFillEnv =
668 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
669 if (!pFormFillEnv)
670 return;
671
672 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
673 CPDF_Dictionary* pDict = pDoc->GetRoot();
674 if (!pDict)
675 return;
676
677 CPDF_AAction aa(pDict->GetDictFor("AA"));
678 auto type = static_cast<CPDF_AAction::AActionType>(aaType);
679 if (aa.ActionExist(type)) {
680 CPDF_Action action = aa.GetAction(type);
681 pFormFillEnv->GetActionHandler()->DoAction_Document(action, type,
682 pFormFillEnv);
683 }
684 }
685
FORM_DoPageAAction(FPDF_PAGE page,FPDF_FORMHANDLE hHandle,int aaType)686 FPDF_EXPORT void FPDF_CALLCONV FORM_DoPageAAction(FPDF_PAGE page,
687 FPDF_FORMHANDLE hHandle,
688 int aaType) {
689 CPDFSDK_FormFillEnvironment* pFormFillEnv =
690 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
691 if (!pFormFillEnv)
692 return;
693
694 IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
695 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
696 if (!pPDFPage)
697 return;
698
699 if (!pFormFillEnv->GetPageView(pPage, false))
700 return;
701
702 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHandler();
703 CPDF_Dictionary* pPageDict = pPDFPage->GetDict();
704 CPDF_AAction aa(pPageDict->GetDictFor("AA"));
705 CPDF_AAction::AActionType type = aaType == FPDFPAGE_AACTION_OPEN
706 ? CPDF_AAction::kOpenPage
707 : CPDF_AAction::kClosePage;
708 if (aa.ActionExist(type)) {
709 CPDF_Action action = aa.GetAction(type);
710 pActionHandler->DoAction_Page(action, type, pFormFillEnv);
711 }
712 }
713
714 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_SetIndexSelected(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int index,FPDF_BOOL selected)715 FORM_SetIndexSelected(FPDF_FORMHANDLE hHandle,
716 FPDF_PAGE page,
717 int index,
718 FPDF_BOOL selected) {
719 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
720 if (!pPageView)
721 return false;
722 return pPageView->SetIndexSelected(index, selected);
723 }
724
725 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_IsIndexSelected(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int index)726 FORM_IsIndexSelected(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int index) {
727 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
728 if (!pPageView)
729 return false;
730 return pPageView->IsIndexSelected(index);
731 }
732