1 // Copyright 2014 PDFium Authors. All rights reserved.
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 <vector>
11
12 #include "core/fpdfapi/page/cpdf_page.h"
13 #include "core/fpdfapi/parser/cpdf_document.h"
14 #include "core/fpdfapi/render/cpdf_renderoptions.h"
15 #include "core/fpdfdoc/cpdf_formcontrol.h"
16 #include "core/fpdfdoc/cpdf_formfield.h"
17 #include "core/fpdfdoc/cpdf_interform.h"
18 #include "core/fpdfdoc/cpdf_occontext.h"
19 #include "core/fxge/cfx_defaultrenderdevice.h"
20 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
21 #include "fpdfsdk/cpdfsdk_interform.h"
22 #include "fpdfsdk/cpdfsdk_pageview.h"
23 #include "fpdfsdk/fsdk_actionhandler.h"
24 #include "fpdfsdk/fsdk_define.h"
25 #include "public/fpdfview.h"
26 #include "third_party/base/ptr_util.h"
27 #include "third_party/base/stl_util.h"
28
29 #ifdef PDF_ENABLE_XFA
30 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
31 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
32 #include "xfa/fxfa/cxfa_ffdocview.h"
33 #include "xfa/fxfa/cxfa_ffpageview.h"
34 #include "xfa/fxfa/cxfa_ffwidget.h"
35
36 static_assert(static_cast<int>(FormType::kNone) == FORMTYPE_NONE,
37 "None form types must match");
38 static_assert(static_cast<int>(FormType::kAcroForm) == FORMTYPE_ACRO_FORM,
39 "AcroForm form types must match");
40 static_assert(static_cast<int>(FormType::kXFAFull) == FORMTYPE_XFA_FULL,
41 "XFA full form types must match");
42 static_assert(static_cast<int>(FormType::kXFAForeground) ==
43 FORMTYPE_XFA_FOREGROUND,
44 "XFA foreground form types must match");
45 #endif // PDF_ENABLE_XFA
46
47 static_assert(static_cast<int>(FormFieldType::kUnknown) ==
48 FPDF_FORMFIELD_UNKNOWN,
49 "Unknown form field types must match");
50 static_assert(static_cast<int>(FormFieldType::kPushButton) ==
51 FPDF_FORMFIELD_PUSHBUTTON,
52 "PushButton form field types must match");
53 static_assert(static_cast<int>(FormFieldType::kCheckBox) ==
54 FPDF_FORMFIELD_CHECKBOX,
55 "CheckBox form field types must match");
56 static_assert(static_cast<int>(FormFieldType::kRadioButton) ==
57 FPDF_FORMFIELD_RADIOBUTTON,
58 "RadioButton form field types must match");
59 static_assert(static_cast<int>(FormFieldType::kComboBox) ==
60 FPDF_FORMFIELD_COMBOBOX,
61 "ComboBox form field types must match");
62 static_assert(static_cast<int>(FormFieldType::kListBox) ==
63 FPDF_FORMFIELD_LISTBOX,
64 "ListBox form field types must match");
65 static_assert(static_cast<int>(FormFieldType::kTextField) ==
66 FPDF_FORMFIELD_TEXTFIELD,
67 "TextField form field types must match");
68 static_assert(static_cast<int>(FormFieldType::kSignature) ==
69 FPDF_FORMFIELD_SIGNATURE,
70 "Signature form field types must match");
71 #ifdef PDF_ENABLE_XFA
72 static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA,
73 "XFA form field types must match");
74 static_assert(static_cast<int>(FormFieldType::kXFA_CheckBox) ==
75 FPDF_FORMFIELD_XFA_CHECKBOX,
76 "XFA CheckBox form field types must match");
77 static_assert(static_cast<int>(FormFieldType::kXFA_ComboBox) ==
78 FPDF_FORMFIELD_XFA_COMBOBOX,
79 "XFA ComboBox form field types must match");
80 static_assert(static_cast<int>(FormFieldType::kXFA_ImageField) ==
81 FPDF_FORMFIELD_XFA_IMAGEFIELD,
82 "XFA ImageField form field types must match");
83 static_assert(static_cast<int>(FormFieldType::kXFA_ListBox) ==
84 FPDF_FORMFIELD_XFA_LISTBOX,
85 "XFA ListBox form field types must match");
86 static_assert(static_cast<int>(FormFieldType::kXFA_PushButton) ==
87 FPDF_FORMFIELD_XFA_PUSHBUTTON,
88 "XFA PushButton form field types must match");
89 static_assert(static_cast<int>(FormFieldType::kXFA_Signature) ==
90 FPDF_FORMFIELD_XFA_SIGNATURE,
91 "XFA Signature form field types must match");
92 static_assert(static_cast<int>(FormFieldType::kXFA_TextField) ==
93 FPDF_FORMFIELD_XFA_TEXTFIELD,
94 "XFA TextField form field types must match");
95 #endif // PDF_ENABLE_XFA
96 static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT,
97 "Number of form field types must match");
98
99 namespace {
100
HandleToCPDFSDKEnvironment(FPDF_FORMHANDLE handle)101 CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
102 FPDF_FORMHANDLE handle) {
103 return static_cast<CPDFSDK_FormFillEnvironment*>(handle);
104 }
105
FormHandleToInterForm(FPDF_FORMHANDLE hHandle)106 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
107 CPDFSDK_FormFillEnvironment* pFormFillEnv =
108 HandleToCPDFSDKEnvironment(hHandle);
109 return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr;
110 }
111
FormHandleToPageView(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)112 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
113 FPDF_PAGE page) {
114 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
115 if (!pPage)
116 return nullptr;
117
118 CPDFSDK_FormFillEnvironment* pFormFillEnv =
119 HandleToCPDFSDKEnvironment(hHandle);
120 return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
121 }
122
123 #ifdef PDF_ENABLE_XFA
FromFPDFStringHandle(FPDF_STRINGHANDLE handle)124 std::vector<ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) {
125 return static_cast<std::vector<ByteString>*>(handle);
126 }
127
ToFPDFStringHandle(std::vector<ByteString> * strings)128 FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<ByteString>* strings) {
129 return static_cast<FPDF_STRINGHANDLE>(strings);
130 }
131 #endif // PDF_ENABLE_XFA
132
FFLCommon(FPDF_FORMHANDLE hHandle,FPDF_BITMAP bitmap,FPDF_RECORDER recorder,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags)133 void FFLCommon(FPDF_FORMHANDLE hHandle,
134 FPDF_BITMAP bitmap,
135 FPDF_RECORDER recorder,
136 FPDF_PAGE page,
137 int start_x,
138 int start_y,
139 int size_x,
140 int size_y,
141 int rotate,
142 int flags) {
143 if (!hHandle)
144 return;
145
146 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
147 if (!pPage)
148 return;
149
150 #ifdef PDF_ENABLE_XFA
151 CPDFXFA_Context* pContext = pPage->GetContext();
152 if (!pContext)
153 return;
154 CPDF_Document* pPDFDoc = pContext->GetPDFDoc();
155 if (!pPDFDoc)
156 return;
157 CPDFSDK_FormFillEnvironment* pFormFillEnv =
158 HandleToCPDFSDKEnvironment(hHandle);
159 if (!pFormFillEnv)
160 return;
161 #endif // PDF_ENABLE_XFA
162
163 CFX_Matrix matrix =
164 pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
165 FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y);
166
167 auto pDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
168 #ifdef _SKIA_SUPPORT_
169 pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
170 #endif
171 RetainPtr<CFX_DIBitmap> holder(CFXBitmapFromFPDFBitmap(bitmap));
172 pDevice->Attach(holder, false, nullptr, false);
173 {
174 CFX_RenderDevice::StateRestorer restorer(pDevice.get());
175 pDevice->SetClip_Rect(clip);
176
177 CPDF_RenderOptions options;
178 uint32_t option_flags = options.GetFlags();
179 if (flags & FPDF_LCD_TEXT)
180 option_flags |= RENDER_CLEARTYPE;
181 else
182 option_flags &= ~RENDER_CLEARTYPE;
183 options.SetFlags(option_flags);
184
185 // Grayscale output
186 if (flags & FPDF_GRAYSCALE)
187 options.SetColorMode(CPDF_RenderOptions::kGray);
188
189 options.SetDrawAnnots(flags & FPDF_ANNOT);
190
191 #ifdef PDF_ENABLE_XFA
192 options.SetOCContext(
193 pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View));
194 if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true))
195 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip);
196 #else // PDF_ENABLE_XFA
197 options.SetOCContext(pdfium::MakeRetain<CPDF_OCContext>(
198 pPage->m_pDocument.Get(), CPDF_OCContext::View));
199 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
200 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
201 #endif // PDF_ENABLE_XFA
202 }
203 #ifdef _SKIA_SUPPORT_PATHS_
204 pDevice->Flush(true);
205 holder->UnPreMultiply();
206 #endif
207 }
208
209 } // namespace
210
211 FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)212 FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
213 FPDF_PAGE page,
214 double page_x,
215 double page_y) {
216 if (!hHandle)
217 return -1;
218 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
219 if (pPage) {
220 CPDF_InterForm interform(pPage->m_pDocument.Get());
221 CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
222 pPage,
223 CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
224 nullptr);
225 if (!pFormCtrl)
226 return -1;
227 CPDF_FormField* pFormField = pFormCtrl->GetField();
228 return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1;
229 }
230
231 #ifdef PDF_ENABLE_XFA
232 CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page);
233 if (!pXFAPage)
234 return -1;
235
236 CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView();
237 if (!pPageView)
238 return -1;
239
240 CXFA_FFDocView* pDocView = pPageView->GetDocView();
241 if (!pDocView)
242 return -1;
243
244 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
245 if (!pWidgetHandler)
246 return -1;
247
248 std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
249 pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form,
250 XFA_WidgetStatus_Viewable));
251 if (!pWidgetIterator)
252 return -1;
253
254 CXFA_FFWidget* pXFAAnnot;
255 while ((pXFAAnnot = pWidgetIterator->MoveToNext()) != nullptr) {
256 CFX_RectF rcBBox = pXFAAnnot->GetBBox(0);
257 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
258 rcBBox.top + rcBBox.height);
259 rcWidget.Inflate(1.0f, 1.0f);
260 if (rcWidget.Contains(CFX_PointF(static_cast<float>(page_x),
261 static_cast<float>(page_y)))) {
262 return static_cast<int>(pXFAAnnot->GetFormFieldType());
263 }
264 }
265 #endif // PDF_ENABLE_XFA
266 return -1;
267 }
268
269 FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)270 FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
271 FPDF_PAGE page,
272 double page_x,
273 double page_y) {
274 if (!hHandle)
275 return -1;
276 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
277 if (!pPage)
278 return -1;
279 CPDF_InterForm interform(pPage->m_pDocument.Get());
280 int z_order = -1;
281 (void)interform.GetControlAtPoint(
282 pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
283 &z_order);
284 return z_order;
285 }
286
287 FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,FPDF_FORMFILLINFO * formInfo)288 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
289 FPDF_FORMFILLINFO* formInfo) {
290 #ifdef PDF_ENABLE_XFA
291 const int kRequiredVersion = 2;
292 #else // PDF_ENABLE_XFA
293 const int kRequiredVersion = 1;
294 #endif // PDF_ENABLE_XFA
295 if (!formInfo || formInfo->version != kRequiredVersion)
296 return nullptr;
297
298 UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document);
299 if (!pDocument)
300 return nullptr;
301
302 #ifdef PDF_ENABLE_XFA
303 // If the CPDFXFA_Context has a FormFillEnvironment already then we've done
304 // this and can just return the old Env. Otherwise, we'll end up setting a new
305 // environment into the XFADocument and, that could get weird.
306 if (pDocument->GetFormFillEnv())
307 return pDocument->GetFormFillEnv();
308 #endif
309
310 auto pFormFillEnv =
311 pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(pDocument, formInfo);
312
313 #ifdef PDF_ENABLE_XFA
314 pDocument->SetFormFillEnv(pFormFillEnv.get());
315 #endif // PDF_ENABLE_XFA
316
317 return pFormFillEnv.release(); // Caller takes ownership.
318 }
319
320 FPDF_EXPORT void FPDF_CALLCONV
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle)321 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
322 CPDFSDK_FormFillEnvironment* pFormFillEnv =
323 HandleToCPDFSDKEnvironment(hHandle);
324 if (!pFormFillEnv)
325 return;
326
327 #ifdef PDF_ENABLE_XFA
328 // Reset the focused annotations and remove the SDK document from the
329 // XFA document.
330 pFormFillEnv->ClearAllFocusedAnnots();
331 // If the document was closed first, it's possible the XFA document
332 // is now a nullptr.
333 if (pFormFillEnv->GetXFAContext())
334 pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr);
335 #endif // PDF_ENABLE_XFA
336 delete pFormFillEnv;
337 }
338
FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)339 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
340 FPDF_PAGE page,
341 int modifier,
342 double page_x,
343 double page_y) {
344 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
345 if (!pPageView)
346 return false;
347 return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier);
348 }
349
FORM_OnFocus(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)350 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnFocus(FPDF_FORMHANDLE hHandle,
351 FPDF_PAGE page,
352 int modifier,
353 double page_x,
354 double page_y) {
355 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
356 if (!pPageView)
357 return false;
358 return pPageView->OnFocus(CFX_PointF(page_x, page_y), modifier);
359 }
360
FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)361 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
362 FPDF_PAGE page,
363 int modifier,
364 double page_x,
365 double page_y) {
366 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
367 if (!pPageView)
368 return false;
369 return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier);
370 }
371
FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)372 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
373 FPDF_PAGE page,
374 int modifier,
375 double page_x,
376 double page_y) {
377 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
378 if (!pPageView)
379 return false;
380 return pPageView->OnLButtonUp(CFX_PointF(page_x, page_y), modifier);
381 }
382
383 #ifdef PDF_ENABLE_XFA
FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)384 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
385 FPDF_PAGE page,
386 int modifier,
387 double page_x,
388 double page_y) {
389 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
390 if (!pPageView)
391 return false;
392 return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier);
393 }
394
FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)395 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonUp(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 if (!pPageView)
402 return false;
403 return pPageView->OnRButtonUp(CFX_PointF(page_x, page_y), modifier);
404 }
405 #endif // PDF_ENABLE_XFA
406
FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)407 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
408 FPDF_PAGE page,
409 int nKeyCode,
410 int modifier) {
411 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
412 if (!pPageView)
413 return false;
414 return pPageView->OnKeyDown(nKeyCode, modifier);
415 }
416
FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)417 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
418 FPDF_PAGE page,
419 int nKeyCode,
420 int modifier) {
421 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
422 if (!pPageView)
423 return false;
424 return pPageView->OnKeyUp(nKeyCode, modifier);
425 }
426
FORM_OnChar(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nChar,int modifier)427 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle,
428 FPDF_PAGE page,
429 int nChar,
430 int modifier) {
431 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
432 if (!pPageView)
433 return false;
434 return pPageView->OnChar(nChar, modifier);
435 }
436
437 FPDF_EXPORT unsigned long FPDF_CALLCONV
FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,void * buffer,unsigned long buflen)438 FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
439 FPDF_PAGE page,
440 void* buffer,
441 unsigned long buflen) {
442 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
443 if (!pPageView)
444 return 0;
445
446 WideString wide_str_form_text = pPageView->GetSelectedText();
447 ByteString encoded_form_text = wide_str_form_text.UTF16LE_Encode();
448 unsigned long form_text_len = encoded_form_text.GetLength();
449
450 if (buffer && buflen >= form_text_len)
451 memcpy(buffer, encoded_form_text.c_str(), form_text_len);
452
453 return form_text_len;
454 }
455
FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,FPDF_WIDESTRING wsText)456 FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,
457 FPDF_PAGE page,
458 FPDF_WIDESTRING wsText) {
459 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
460 if (!pPageView)
461 return;
462
463 size_t len = WideString::WStringLength(wsText);
464 WideString wide_str_text = WideString::FromUTF16LE(wsText, len);
465
466 pPageView->ReplaceSelection(wide_str_text);
467 }
468
469 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)470 FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
471 CPDFSDK_FormFillEnvironment* pFormFillEnv =
472 HandleToCPDFSDKEnvironment(hHandle);
473 if (!pFormFillEnv)
474 return false;
475 return pFormFillEnv->KillFocusAnnot(0);
476 }
477
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)478 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
479 FPDF_BITMAP bitmap,
480 FPDF_PAGE page,
481 int start_x,
482 int start_y,
483 int size_x,
484 int size_y,
485 int rotate,
486 int flags) {
487 FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
488 rotate, flags);
489 }
490
491 #ifdef _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)492 FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,
493 FPDF_RECORDER recorder,
494 FPDF_PAGE page,
495 int start_x,
496 int start_y,
497 int size_x,
498 int size_y,
499 int rotate,
500 int flags) {
501 FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y,
502 rotate, flags);
503 }
504 #endif
505
506 #ifdef PDF_ENABLE_XFA
FPDF_Widget_Undo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)507 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Undo(FPDF_DOCUMENT document,
508 FPDF_WIDGET hWidget) {
509 if (!hWidget || !document)
510 return;
511
512 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
513 if (!pContext->ContainsXFAForm())
514 return;
515
516 static_cast<CXFA_FFWidget*>(hWidget)->Undo();
517 }
518
FPDF_Widget_Redo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)519 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Redo(FPDF_DOCUMENT document,
520 FPDF_WIDGET hWidget) {
521 if (!hWidget || !document)
522 return;
523
524 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
525 if (!pContext->ContainsXFAForm())
526 return;
527
528 static_cast<CXFA_FFWidget*>(hWidget)->Redo();
529 }
530
FPDF_Widget_SelectAll(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)531 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
532 FPDF_WIDGET hWidget) {
533 if (!hWidget || !document)
534 return;
535
536 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
537 if (!pContext->ContainsXFAForm())
538 return;
539
540 static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
541 }
542
FPDF_Widget_Copy(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)543 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Copy(FPDF_DOCUMENT document,
544 FPDF_WIDGET hWidget,
545 FPDF_WIDESTRING wsText,
546 FPDF_DWORD* size) {
547 if (!hWidget || !document)
548 return;
549
550 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
551 if (!pContext->ContainsXFAForm())
552 return;
553
554 WideString wsCpText =
555 static_cast<CXFA_FFWidget*>(hWidget)->Copy().value_or(WideString());
556
557 ByteString bsCpText = wsCpText.UTF16LE_Encode();
558 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
559 if (!wsText) {
560 *size = len;
561 return;
562 }
563
564 uint32_t real_size = len < *size ? len : *size;
565 if (real_size > 0) {
566 memcpy((void*)wsText,
567 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
568 real_size * sizeof(unsigned short));
569 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
570 }
571 *size = real_size;
572 }
573
FPDF_Widget_Cut(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)574 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Cut(FPDF_DOCUMENT document,
575 FPDF_WIDGET hWidget,
576 FPDF_WIDESTRING wsText,
577 FPDF_DWORD* size) {
578 if (!hWidget || !document)
579 return;
580
581 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
582 if (!pContext->ContainsXFAForm())
583 return;
584
585 WideString wsCpText =
586 static_cast<CXFA_FFWidget*>(hWidget)->Cut().value_or(WideString());
587
588 ByteString bsCpText = wsCpText.UTF16LE_Encode();
589 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
590 if (!wsText) {
591 *size = len;
592 return;
593 }
594
595 uint32_t real_size = len < *size ? len : *size;
596 if (real_size > 0) {
597 memcpy((void*)wsText,
598 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
599 real_size * sizeof(unsigned short));
600 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
601 }
602 *size = real_size;
603 }
604
FPDF_Widget_Paste(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD size)605 FPDF_EXPORT void FPDF_CALLCONV FPDF_Widget_Paste(FPDF_DOCUMENT document,
606 FPDF_WIDGET hWidget,
607 FPDF_WIDESTRING wsText,
608 FPDF_DWORD size) {
609 if (!hWidget || !document)
610 return;
611
612 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
613 if (!pContext->ContainsXFAForm())
614 return;
615
616 WideString wstr = WideString::FromUTF16LE(wsText, size);
617 static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr);
618 }
619
620 FPDF_EXPORT void FPDF_CALLCONV
FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_BYTESTRING bsText)621 FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
622 FPDF_WIDGET hWidget,
623 float x,
624 float y,
625 FPDF_BYTESTRING bsText) {
626 if (!hWidget || !document)
627 return;
628
629 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
630 if (!pContext->ContainsXFAForm())
631 return;
632
633 CFX_PointF ptPopup;
634 ptPopup.x = x;
635 ptPopup.y = y;
636 ByteStringView bs(bsText);
637 static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs);
638 }
639
640 FPDF_EXPORT void FPDF_CALLCONV
FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_STRINGHANDLE * stringHandle)641 FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
642 FPDF_WIDGET hWidget,
643 float x,
644 float y,
645 FPDF_STRINGHANDLE* stringHandle) {
646 if (!hWidget || !document)
647 return;
648
649 auto* pContext = static_cast<CPDFXFA_Context*>(document);
650 if (!pContext->ContainsXFAForm())
651 return;
652
653 CFX_PointF ptPopup;
654 ptPopup.x = x;
655 ptPopup.y = y;
656 auto sSuggestWords = pdfium::MakeUnique<std::vector<ByteString>>();
657 static_cast<CXFA_FFWidget*>(hWidget)->GetSuggestWords(ptPopup,
658 sSuggestWords.get());
659
660 // Caller takes ownership.
661 *stringHandle = ToFPDFStringHandle(sSuggestWords.release());
662 }
663
664 FPDF_EXPORT int FPDF_CALLCONV
FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle)665 FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) {
666 std::vector<ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
667 return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1;
668 }
669
670 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,int index,FPDF_BYTESTRING bsText,FPDF_DWORD * size)671 FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,
672 int index,
673 FPDF_BYTESTRING bsText,
674 FPDF_DWORD* size) {
675 if (!sHandle || !size)
676 return false;
677
678 int count = FPDF_StringHandleCounts(sHandle);
679 if (index < 0 || index >= count)
680 return false;
681
682 std::vector<ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
683 uint32_t len = (*sSuggestWords)[index].GetLength();
684 if (!bsText) {
685 *size = len;
686 return true;
687 }
688
689 uint32_t real_size = len < *size ? len : *size;
690 if (real_size > 0)
691 memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size);
692 *size = real_size;
693 return true;
694 }
695
696 FPDF_EXPORT void FPDF_CALLCONV
FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle)697 FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) {
698 delete FromFPDFStringHandle(stringHandle);
699 }
700
701 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,FPDF_BYTESTRING bsText,FPDF_DWORD size)702 FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
703 FPDF_BYTESTRING bsText,
704 FPDF_DWORD size) {
705 if (!stringHandle || !bsText || size == 0)
706 return false;
707
708 FromFPDFStringHandle(stringHandle)->push_back(ByteString(bsText, size));
709 return true;
710 }
711 #endif // PDF_ENABLE_XFA
712
713 FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,int fieldType,unsigned long color)714 FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
715 int fieldType,
716 unsigned long color) {
717 CPDFSDK_InterForm* interForm = FormHandleToInterForm(hHandle);
718 if (!interForm)
719 return;
720
721 Optional<FormFieldType> cast_input = IntToFormFieldType(fieldType);
722 if (!cast_input)
723 return;
724
725 if (cast_input.value() == FormFieldType::kUnknown) {
726 interForm->SetAllHighlightColors(color);
727 } else {
728 interForm->SetHighlightColor(color, cast_input.value());
729 }
730 }
731
732 FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,unsigned char alpha)733 FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) {
734 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
735 pInterForm->SetHighlightAlpha(alpha);
736 }
737
738 FPDF_EXPORT void FPDF_CALLCONV
FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)739 FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
740 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
741 pInterForm->RemoveAllHighLights();
742 }
743
FORM_OnAfterLoadPage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)744 FPDF_EXPORT void FPDF_CALLCONV FORM_OnAfterLoadPage(FPDF_PAGE page,
745 FPDF_FORMHANDLE hHandle) {
746 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
747 pPageView->SetValid(true);
748 }
749
FORM_OnBeforeClosePage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)750 FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page,
751 FPDF_FORMHANDLE hHandle) {
752 CPDFSDK_FormFillEnvironment* pFormFillEnv =
753 HandleToCPDFSDKEnvironment(hHandle);
754 if (!pFormFillEnv)
755 return;
756
757 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
758 if (!pPage)
759 return;
760
761 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false);
762 if (pPageView) {
763 pPageView->SetValid(false);
764 // RemovePageView() takes care of the delete for us.
765 pFormFillEnv->RemovePageView(pPage);
766 }
767 }
768
769 FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)770 FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
771 CPDFSDK_FormFillEnvironment* pFormFillEnv =
772 HandleToCPDFSDKEnvironment(hHandle);
773 if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
774 pFormFillEnv->ProcJavascriptFun();
775 }
776
777 FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)778 FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
779 CPDFSDK_FormFillEnvironment* pFormFillEnv =
780 HandleToCPDFSDKEnvironment(hHandle);
781 if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
782 pFormFillEnv->ProcOpenAction();
783 }
784
FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,int aaType)785 FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
786 int aaType) {
787 CPDFSDK_FormFillEnvironment* pFormFillEnv =
788 HandleToCPDFSDKEnvironment(hHandle);
789 if (!pFormFillEnv)
790 return;
791
792 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
793 const CPDF_Dictionary* pDict = pDoc->GetRoot();
794 if (!pDict)
795 return;
796
797 CPDF_AAction aa(pDict->GetDictFor("AA"));
798 auto type = static_cast<CPDF_AAction::AActionType>(aaType);
799 if (aa.ActionExist(type)) {
800 CPDF_Action action = aa.GetAction(type);
801 CPDFSDK_ActionHandler* pActionHandler =
802 HandleToCPDFSDKEnvironment(hHandle)->GetActionHandler();
803 pActionHandler->DoAction_Document(action, type, pFormFillEnv);
804 }
805 }
806
FORM_DoPageAAction(FPDF_PAGE page,FPDF_FORMHANDLE hHandle,int aaType)807 FPDF_EXPORT void FPDF_CALLCONV FORM_DoPageAAction(FPDF_PAGE page,
808 FPDF_FORMHANDLE hHandle,
809 int aaType) {
810 CPDFSDK_FormFillEnvironment* pFormFillEnv =
811 HandleToCPDFSDKEnvironment(hHandle);
812 if (!pFormFillEnv)
813 return;
814
815 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
816 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
817 if (!pPDFPage)
818 return;
819
820 if (!pFormFillEnv->GetPageView(pPage, false))
821 return;
822
823 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHandler();
824 CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict.Get();
825 CPDF_AAction aa(pPageDict->GetDictFor("AA"));
826 CPDF_AAction::AActionType type = aaType == FPDFPAGE_AACTION_OPEN
827 ? CPDF_AAction::OpenPage
828 : CPDF_AAction::ClosePage;
829 if (aa.ActionExist(type)) {
830 CPDF_Action action = aa.GetAction(type);
831 pActionHandler->DoAction_Page(action, type, pFormFillEnv);
832 }
833 }
834