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