Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_formfill.cpp
Go to the documentation of this file.
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)
39class SkCanvas;
40#endif // defined(PDF_USE_SKIA)
41
42#ifdef PDF_ENABLE_XFA
43static_assert(static_cast<int>(AlertButton::kDefault) ==
44 JSPLATFORM_ALERT_BUTTON_DEFAULT,
45 "Default alert button types must match");
46static_assert(static_cast<int>(AlertButton::kOK) == JSPLATFORM_ALERT_BUTTON_OK,
47 "OK alert button types must match");
48static_assert(static_cast<int>(AlertButton::kOKCancel) ==
49 JSPLATFORM_ALERT_BUTTON_OKCANCEL,
50 "OKCancel alert button types must match");
51static_assert(static_cast<int>(AlertButton::kYesNo) ==
52 JSPLATFORM_ALERT_BUTTON_YESNO,
53 "YesNo alert button types must match");
54static_assert(static_cast<int>(AlertButton::kYesNoCancel) ==
55 JSPLATFORM_ALERT_BUTTON_YESNOCANCEL,
56 "YesNoCancel alert button types must match");
57
58static_assert(static_cast<int>(AlertIcon::kDefault) ==
59 JSPLATFORM_ALERT_ICON_DEFAULT,
60 "Default alert icon types must match");
61static_assert(static_cast<int>(AlertIcon::kError) ==
62 JSPLATFORM_ALERT_ICON_ERROR,
63 "Error alert icon types must match");
64static_assert(static_cast<int>(AlertIcon::kWarning) ==
65 JSPLATFORM_ALERT_ICON_WARNING,
66 "Warning alert icon types must match");
67static_assert(static_cast<int>(AlertIcon::kQuestion) ==
68 JSPLATFORM_ALERT_ICON_QUESTION,
69 "Question alert icon types must match");
70static_assert(static_cast<int>(AlertIcon::kStatus) ==
71 JSPLATFORM_ALERT_ICON_STATUS,
72 "Status alert icon types must match");
73static_assert(static_cast<int>(AlertIcon::kAsterisk) ==
74 JSPLATFORM_ALERT_ICON_ASTERISK,
75 "Asterisk alert icon types must match");
76
77static_assert(static_cast<int>(AlertReturn::kOK) == JSPLATFORM_ALERT_RETURN_OK,
78 "OK alert return types must match");
79static_assert(static_cast<int>(AlertReturn::kCancel) ==
80 JSPLATFORM_ALERT_RETURN_CANCEL,
81 "Cancel alert return types must match");
82static_assert(static_cast<int>(AlertReturn::kNo) == JSPLATFORM_ALERT_RETURN_NO,
83 "No alert return types must match");
84static_assert(static_cast<int>(AlertReturn::kYes) ==
85 JSPLATFORM_ALERT_RETURN_YES,
86 "Yes alert return types must match");
87
88static_assert(static_cast<int>(FormType::kNone) == FORMTYPE_NONE,
89 "None form types must match");
90static_assert(static_cast<int>(FormType::kAcroForm) == FORMTYPE_ACRO_FORM,
91 "AcroForm form types must match");
92static_assert(static_cast<int>(FormType::kXFAFull) == FORMTYPE_XFA_FULL,
93 "XFA full form types must match");
94static_assert(static_cast<int>(FormType::kXFAForeground) ==
95 FORMTYPE_XFA_FOREGROUND,
96 "XFA foreground form types must match");
97#endif // PDF_ENABLE_XFA
98
99static_assert(static_cast<int>(FormFieldType::kUnknown) ==
101 "Unknown form field types must match");
102static_assert(static_cast<int>(FormFieldType::kPushButton) ==
104 "PushButton form field types must match");
105static_assert(static_cast<int>(FormFieldType::kCheckBox) ==
107 "CheckBox form field types must match");
108static_assert(static_cast<int>(FormFieldType::kRadioButton) ==
110 "RadioButton form field types must match");
111static_assert(static_cast<int>(FormFieldType::kComboBox) ==
113 "ComboBox form field types must match");
114static_assert(static_cast<int>(FormFieldType::kListBox) ==
116 "ListBox form field types must match");
117static_assert(static_cast<int>(FormFieldType::kTextField) ==
119 "TextField form field types must match");
120static_assert(static_cast<int>(FormFieldType::kSignature) ==
122 "Signature form field types must match");
123#ifdef PDF_ENABLE_XFA
124static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA,
125 "XFA form field types must match");
126static_assert(static_cast<int>(FormFieldType::kXFA_CheckBox) ==
127 FPDF_FORMFIELD_XFA_CHECKBOX,
128 "XFA CheckBox form field types must match");
129static_assert(static_cast<int>(FormFieldType::kXFA_ComboBox) ==
130 FPDF_FORMFIELD_XFA_COMBOBOX,
131 "XFA ComboBox form field types must match");
132static_assert(static_cast<int>(FormFieldType::kXFA_ImageField) ==
133 FPDF_FORMFIELD_XFA_IMAGEFIELD,
134 "XFA ImageField form field types must match");
135static_assert(static_cast<int>(FormFieldType::kXFA_ListBox) ==
136 FPDF_FORMFIELD_XFA_LISTBOX,
137 "XFA ListBox form field types must match");
138static_assert(static_cast<int>(FormFieldType::kXFA_PushButton) ==
139 FPDF_FORMFIELD_XFA_PUSHBUTTON,
140 "XFA PushButton form field types must match");
141static_assert(static_cast<int>(FormFieldType::kXFA_Signature) ==
142 FPDF_FORMFIELD_XFA_SIGNATURE,
143 "XFA Signature form field types must match");
144static_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
148static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT,
149 "Number of form field types must match");
150
151static_assert(static_cast<int>(CPDF_AAction::kCloseDocument) ==
153 "CloseDocument action must match");
154static_assert(static_cast<int>(CPDF_AAction::kSaveDocument) ==
156 "SaveDocument action must match");
157static_assert(static_cast<int>(CPDF_AAction::kDocumentSaved) ==
159 "DocumentSaved action must match");
160static_assert(static_cast<int>(CPDF_AAction::kPrintDocument) ==
162 "PrintDocument action must match");
163static_assert(static_cast<int>(CPDF_AAction::kDocumentPrinted) ==
165 "DocumentPrinted action must match");
166
167namespace {
168
169CPDFSDK_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 =
177 return pFormFillEnv ? pFormFillEnv->GetOrCreatePageView(pPage) : nullptr;
178}
179
180#if defined(PDF_USE_SKIA)
181using BitmapOrCanvas = absl::variant<CFX_DIBitmap*, SkCanvas*>;
182#else
183using BitmapOrCanvas = absl::variant<CFX_DIBitmap*>;
184#endif
185
186// `dest` must be non-null.
187void 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)
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.
267bool 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
282FPDFPage_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
315FPDFPage_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
328 int z_order = -1;
330 pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
331 &z_order);
332 return z_order;
333}
334
335FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV
336FPDFDOC_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
378FPDFDOC_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(
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
400FPDF_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
413FORM_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
429FPDF_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
441FPDF_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
457FPDF_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
474FORM_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
490FPDF_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
506FPDF_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
522FPDF_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
533FPDF_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
540FPDF_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
550FPDF_EXPORT unsigned long FPDF_CALLCONV
551FORM_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
565FPDF_EXPORT unsigned long FPDF_CALLCONV
566FORM_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
581FORM_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.
591}
592
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(
603}
604
605FPDF_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
611FPDF_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
619FPDF_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
627FPDF_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
635FPDF_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
644FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
645 CPDFSDK_FormFillEnvironment* pFormFillEnv =
647 if (!pFormFillEnv)
648 return false;
649 return pFormFillEnv->KillFocusAnnot({});
650}
651
653FORM_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 =
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
697FORM_SetFocusedAnnot(FPDF_FORMHANDLE handle, FPDF_ANNOTATION annot) {
698 CPDFSDK_FormFillEnvironment* form_fill_env =
700 if (!form_fill_env)
701 return false;
702
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
721FPDF_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
743#if defined(PDF_USE_SKIA)
744FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDrawSkia(FPDF_FORMHANDLE hHandle,
745 FPDF_SKIA_CANVAS canvas,
746 FPDF_PAGE page,
747 int start_x,
748 int start_y,
749 int size_x,
750 int size_y,
751 int rotate,
752 int flags) {
753 SkCanvas* sk_canvas = SkCanvasFromFPDFSkiaCanvas(canvas);
754 if (!sk_canvas) {
755 return;
756 }
757
758 FFLCommon(hHandle, page, sk_canvas, start_x, start_y, size_x, size_y, rotate,
759 flags);
760}
761#endif // defined(PDF_USE_SKIA)
762
764FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
765 int fieldType,
766 unsigned long color) {
767 CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
768 if (!pForm)
769 return;
770
771 std::optional<FormFieldType> cast_input =
772 CPDF_FormField::IntToFormFieldType(fieldType);
773 if (!cast_input.has_value())
774 return;
775
776 if (cast_input.value() == FormFieldType::kUnknown) {
777 pForm->SetAllHighlightColors(static_cast<FX_COLORREF>(color));
778 } else {
779 pForm->SetHighlightColor(static_cast<FX_COLORREF>(color),
780 cast_input.value());
781 }
782}
783
785FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) {
786 if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
787 pForm->SetHighlightAlpha(alpha);
788}
789
791FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
792 if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
794}
795
797 FPDF_FORMHANDLE hHandle) {
798 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
799 pPageView->SetValid(true);
800}
801
803 FPDF_FORMHANDLE hHandle) {
804 CPDFSDK_FormFillEnvironment* pFormFillEnv =
806 if (!pFormFillEnv)
807 return;
808
810 if (!pPage)
811 return;
812
813 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage);
814 if (pPageView) {
815 pPageView->SetValid(false);
816 // RemovePageView() takes care of the delete for us.
817 pFormFillEnv->RemovePageView(pPage);
818 }
819}
820
822FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
823 CPDFSDK_FormFillEnvironment* pFormFillEnv =
825 if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
826 pFormFillEnv->ProcJavascriptAction();
827}
828
830FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
831 CPDFSDK_FormFillEnvironment* pFormFillEnv =
833 if (pFormFillEnv)
834 pFormFillEnv->ProcOpenAction();
835}
836
838 int aaType) {
839 CPDFSDK_FormFillEnvironment* pFormFillEnv =
841 if (!pFormFillEnv)
842 return;
843
844 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
845 const CPDF_Dictionary* pDict = pDoc->GetRoot();
846 if (!pDict)
847 return;
848
850 auto type = static_cast<CPDF_AAction::AActionType>(aaType);
851 if (aa.ActionExist(type))
852 pFormFillEnv->DoActionDocument(aa.GetAction(type), type);
853}
854
856 FPDF_FORMHANDLE hHandle,
857 int aaType) {
858 CPDFSDK_FormFillEnvironment* pFormFillEnv =
860 if (!pFormFillEnv)
861 return;
862
864 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
865 if (!pPDFPage)
866 return;
867
868 if (!pFormFillEnv->GetPageView(pPage))
869 return;
870
871 CPDF_AAction aa(pPDFPage->GetDict()->GetDictFor(pdfium::form_fields::kAA));
875 if (aa.ActionExist(type))
876 pFormFillEnv->DoActionPage(aa.GetAction(type), type);
877}
878
880FORM_SetIndexSelected(FPDF_FORMHANDLE hHandle,
881 FPDF_PAGE page,
882 int index,
883 FPDF_BOOL selected) {
884 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
885 return pPageView && pPageView->SetIndexSelected(index, selected);
886}
887
889FORM_IsIndexSelected(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int index) {
890 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
891 return pPageView && pPageView->IsIndexSelected(index);
892}
IPDF_Page * GetPage()
CPDFSDK_PageView * GetPageView() const
virtual CPDFXFA_Widget * AsXFAWidget()
CPDFSDK_PageView * GetPageView(IPDF_Page *pUnderlyingPage) override
CPDFSDK_Annot * GetFocusAnnot() const override
bool DoActionDocument(const CPDF_Action &action, CPDF_AAction::AActionType eType)
CPDFSDK_PageView * GetOrCreatePageView(IPDF_Page *pUnderlyingPage) override
bool KillFocusAnnot(Mask< FWL_EVENTFLAG > nFlags)
bool DoActionPage(const CPDF_Action &action, CPDF_AAction::AActionType eType)
void RemovePageView(IPDF_Page *pUnderlyingPage)
bool SetFocusAnnot(ObservedPtr< CPDFSDK_Annot > &pAnnot) override
void SetHighlightColor(FX_COLORREF clr, FormFieldType fieldType)
void SetAllHighlightColors(FX_COLORREF clr)
CPDF_InteractiveForm * GetInteractiveForm() const
void SetHighlightAlpha(uint8_t alpha)
void SetValid(bool bValid)
void ReplaceSelection(const WideString &text)
void PageView_OnDraw(CFX_RenderDevice *pDevice, const CFX_Matrix &mtUser2Device, CPDF_RenderOptions *pOptions, const FX_RECT &pClip)
void ReplaceAndKeepSelection(const WideString &text)
bool IsIndexSelected(int index)
bool SetIndexSelected(int index, bool selected)
bool ActionExist(AActionType eType) const
CPDF_Action GetAction(AActionType eType) const
IPDF_Page * GetPage() const
RetainPtr< const CPDF_Dictionary > GetDictFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
const CPDF_Dictionary * GetRoot() const
CPDF_FormField * GetField() const
FormFieldType GetFieldType() const
const CPDF_FormControl * GetControlAtPoint(const CPDF_Page *pPage, const CFX_PointF &point, int *z_order) const
void SetOCContext(RetainPtr< CPDF_OCContext > context)
void SetDrawAnnots(bool draw)
void SetColorMode(Type mode)
virtual CPDF_Document * GetDocument() const =0
virtual CFX_Matrix GetDisplayMatrix(const FX_RECT &rect, int iRotate) const =0
#define UNSAFE_BUFFERS(...)
FormFieldType
UNSAFE_BUFFER_USAGE WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string)
IPDF_Page * IPDFPageFromFPDFPage(FPDF_PAGE page)
CFX_DIBitmap * CFXDIBitmapFromFPDFBitmap(FPDF_BITMAP bitmap)
CPDFSDK_FormFillEnvironment * CPDFSDKFormFillEnvironmentFromFPDFFormHandle(FPDF_FORMHANDLE handle)
CPDF_AnnotContext * CPDFAnnotContextFromFPDFAnnotation(FPDF_ANNOTATION annot)
void ReportUnsupportedXFA(const CPDF_Document *pDoc)
CPDF_Page * CPDFPageFromFPDFPage(FPDF_PAGE page)
CPDF_Document * CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc)
CPDFSDK_InteractiveForm * FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
#define FPDFDOC_AACTION_WC
#define FPDFDOC_AACTION_WS
FPDF_EXPORT void FPDF_CALLCONV FORM_OnAfterLoadPage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_SetIndexSelected(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int index, FPDF_BOOL selected)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT void FPDF_CALLCONV FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnFocus(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
#define FPDF_FORMFIELD_PUSHBUTTON
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
#define FPDF_FORMFIELD_CHECKBOX
#define FPDF_FORMFIELD_COMBOBOX
#define FPDF_FORMFIELD_TEXTFIELD
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)
FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceAndKeepSelection(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, FPDF_WIDESTRING wsText)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier)
#define FPDF_FORMFIELD_RADIOBUTTON
#define FPDF_FORMFIELD_COUNT
FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)
#define FPDF_FORMFIELD_LISTBOX
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDoubleClick(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
#define FPDF_FORMFIELD_SIGNATURE
FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, FPDF_WIDESTRING wsText)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, double page_x, double page_y)
FPDF_EXPORT void FPDF_CALLCONV FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandle, int aaType)
#define FPDF_FORMFIELD_UNKNOWN
#define FPDFDOC_AACTION_DS
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanRedo(FPDF_FORMHANDLE hHandle, FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_SetFocusedAnnot(FPDF_FORMHANDLE handle, FPDF_ANNOTATION annot)
FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_GetFocusedAnnot(FPDF_FORMHANDLE handle, int *page_index, FPDF_ANNOTATION *annot)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT unsigned long FPDF_CALLCONV FORM_GetSelectedText(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, void *buffer, unsigned long buflen)
#define FPDFDOC_AACTION_WP
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaType)
FPDF_EXPORT void FPDF_CALLCONV FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, int fieldType, unsigned long color)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Redo(FPDF_FORMHANDLE hHandle, FPDF_PAGE page)
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, double page_x, double page_y)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nChar, int modifier)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_IsIndexSelected(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int index)
FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document, FPDF_FORMFILLINFO *formInfo)
#define FPDFDOC_AACTION_DP
FPDF_EXPORT unsigned long FPDF_CALLCONV FORM_GetFocusedText(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, void *buffer, unsigned long buflen)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanUndo(FPDF_FORMHANDLE hHandle, FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier)
FPDF_EXPORT void FPDF_CALLCONV FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)
FPDF_EXPORT void FPDF_CALLCONV FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle)
#define FPDFPAGE_AACTION_OPEN
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_SelectAllText(FPDF_FORMHANDLE hHandle, FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Undo(FPDF_FORMHANDLE hHandle, FPDF_PAGE page)
FPDF_EXPORT void FPDF_CALLCONV 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)
#define FPDF_REVERSE_BYTE_ORDER
Definition fpdfview.h:817
#define FPDF_CALLCONV
Definition fpdfview.h:229
#define FPDF_EXPORT
Definition fpdfview.h:223
#define FPDF_GRAYSCALE
Definition fpdfview.h:797
#define FPDF_ANNOT
Definition fpdfview.h:790
#define FPDF_LCD_TEXT
Definition fpdfview.h:793
uint32_t FX_COLORREF
Definition fx_dib.h:42
#define CHECK(cvref)
constexpr FX_RECT(int l, int t, int r, int b)