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