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