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