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