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_fxgedevice.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/xfa_ffdocview.h"
33 #include "xfa/fxfa/xfa_ffpageview.h"
34 #include "xfa/fxfa/xfa_ffwidget.h"
35 #endif // PDF_ENABLE_XFA
36
37 namespace {
38
HandleToCPDFSDKEnvironment(FPDF_FORMHANDLE handle)39 CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
40 FPDF_FORMHANDLE handle) {
41 return static_cast<CPDFSDK_FormFillEnvironment*>(handle);
42 }
43
FormHandleToInterForm(FPDF_FORMHANDLE hHandle)44 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
45 CPDFSDK_FormFillEnvironment* pFormFillEnv =
46 HandleToCPDFSDKEnvironment(hHandle);
47 return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr;
48 }
49
FormHandleToPageView(FPDF_FORMHANDLE hHandle,FPDF_PAGE page)50 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
51 FPDF_PAGE page) {
52 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
53 if (!pPage)
54 return nullptr;
55
56 CPDFSDK_FormFillEnvironment* pFormFillEnv =
57 HandleToCPDFSDKEnvironment(hHandle);
58 return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
59 }
60
61 #ifdef PDF_ENABLE_XFA
FromFPDFStringHandle(FPDF_STRINGHANDLE handle)62 std::vector<CFX_ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) {
63 return reinterpret_cast<std::vector<CFX_ByteString>*>(handle);
64 }
65
ToFPDFStringHandle(std::vector<CFX_ByteString> * strings)66 FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<CFX_ByteString>* strings) {
67 return reinterpret_cast<FPDF_STRINGHANDLE>(strings);
68 }
69 #endif // PDF_ENABLE_XFA
70
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)71 void FFLCommon(FPDF_FORMHANDLE hHandle,
72 FPDF_BITMAP bitmap,
73 FPDF_RECORDER recorder,
74 FPDF_PAGE page,
75 int start_x,
76 int start_y,
77 int size_x,
78 int size_y,
79 int rotate,
80 int flags) {
81 if (!hHandle)
82 return;
83
84 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
85 if (!pPage)
86 return;
87
88 #ifdef PDF_ENABLE_XFA
89 CPDFXFA_Context* pContext = pPage->GetContext();
90 if (!pContext)
91 return;
92 CPDF_Document* pPDFDoc = pContext->GetPDFDoc();
93 if (!pPDFDoc)
94 return;
95 CPDFSDK_FormFillEnvironment* pFormFillEnv =
96 HandleToCPDFSDKEnvironment(hHandle);
97 if (!pFormFillEnv)
98 return;
99 #endif // PDF_ENABLE_XFA
100
101 CFX_Matrix matrix =
102 pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
103 FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y);
104
105 std::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice);
106 #ifdef _SKIA_SUPPORT_
107 pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
108 #endif
109 pDevice->Attach(CFXBitmapFromFPDFBitmap(bitmap), false, nullptr, false);
110 pDevice->SaveState();
111 pDevice->SetClip_Rect(clip);
112
113 CPDF_RenderOptions options;
114 if (flags & FPDF_LCD_TEXT)
115 options.m_Flags |= RENDER_CLEARTYPE;
116 else
117 options.m_Flags &= ~RENDER_CLEARTYPE;
118
119 // Grayscale output
120 if (flags & FPDF_GRAYSCALE) {
121 options.m_ColorMode = RENDER_COLOR_GRAY;
122 options.m_ForeColor = 0;
123 options.m_BackColor = 0xffffff;
124 }
125 options.m_AddFlags = flags >> 8;
126 options.m_bDrawAnnots = flags & FPDF_ANNOT;
127
128 #ifdef PDF_ENABLE_XFA
129 options.m_pOCContext =
130 pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View);
131 if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true))
132 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip);
133 #else // PDF_ENABLE_XFA
134 options.m_pOCContext = pdfium::MakeRetain<CPDF_OCContext>(
135 pPage->m_pDocument, CPDF_OCContext::View);
136 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
137 pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
138 #endif // PDF_ENABLE_XFA
139
140 pDevice->RestoreState(false);
141 #ifdef _SKIA_SUPPORT_PATHS_
142 pDevice->Flush();
143 CFXBitmapFromFPDFBitmap(bitmap)->UnPreMultiply();
144 #endif
145 }
146
147 } // namespace
148
FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)149 DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
150 FPDF_PAGE page,
151 double page_x,
152 double page_y) {
153 if (!hHandle)
154 return -1;
155 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
156 if (pPage) {
157 CPDF_InterForm interform(pPage->m_pDocument);
158 CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
159 pPage, CFX_PointF(static_cast<FX_FLOAT>(page_x),
160 static_cast<FX_FLOAT>(page_y)),
161 nullptr);
162 if (!pFormCtrl)
163 return -1;
164 CPDF_FormField* pFormField = pFormCtrl->GetField();
165 return pFormField ? pFormField->GetFieldType() : -1;
166 }
167
168 #ifdef PDF_ENABLE_XFA
169 CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page);
170 if (!pXFAPage)
171 return -1;
172
173 CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView();
174 if (!pPageView)
175 return -1;
176
177 CXFA_FFDocView* pDocView = pPageView->GetDocView();
178 if (!pDocView)
179 return -1;
180
181 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
182 if (!pWidgetHandler)
183 return -1;
184
185 std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
186 pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form,
187 XFA_WidgetStatus_Viewable));
188 if (!pWidgetIterator)
189 return -1;
190
191 CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext();
192 while (pXFAAnnot) {
193 CFX_RectF rcBBox = pXFAAnnot->GetBBox(0);
194 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
195 rcBBox.top + rcBBox.height);
196 rcWidget.left -= 1.0f;
197 rcWidget.right += 1.0f;
198 rcWidget.bottom -= 1.0f;
199 rcWidget.top += 1.0f;
200
201 if (rcWidget.Contains(CFX_PointF(static_cast<FX_FLOAT>(page_x),
202 static_cast<FX_FLOAT>(page_y)))) {
203 return FPDF_FORMFIELD_XFA;
204 }
205 pXFAAnnot = pWidgetIterator->MoveToNext();
206 }
207 #endif // PDF_ENABLE_XFA
208 return -1;
209 }
210
FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)211 DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
212 FPDF_PAGE page,
213 double page_x,
214 double page_y) {
215 return FPDFPage_HasFormFieldAtPoint(hHandle, page, page_x, page_y);
216 }
217
FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,double page_x,double page_y)218 DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
219 FPDF_PAGE page,
220 double page_x,
221 double page_y) {
222 if (!hHandle)
223 return -1;
224 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
225 if (!pPage)
226 return -1;
227 CPDF_InterForm interform(pPage->m_pDocument);
228 int z_order = -1;
229 (void)interform.GetControlAtPoint(
230 pPage,
231 CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y)),
232 &z_order);
233 return z_order;
234 }
235
236 DLLEXPORT FPDF_FORMHANDLE STDCALL
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,FPDF_FORMFILLINFO * formInfo)237 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
238 FPDF_FORMFILLINFO* formInfo) {
239 #ifdef PDF_ENABLE_XFA
240 const int kRequiredVersion = 2;
241 #else // PDF_ENABLE_XFA
242 const int kRequiredVersion = 1;
243 #endif // PDF_ENABLE_XFA
244 if (!formInfo || formInfo->version != kRequiredVersion)
245 return nullptr;
246
247 UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document);
248 if (!pDocument)
249 return nullptr;
250
251 #ifdef PDF_ENABLE_XFA
252 // If the CPDFXFA_Context has a FormFillEnvironment already then we've done
253 // this and can just return the old Env. Otherwise, we'll end up setting a new
254 // environment into the XFADocument and, that could get weird.
255 if (pDocument->GetFormFillEnv())
256 return pDocument->GetFormFillEnv();
257 #endif
258
259 CPDFSDK_FormFillEnvironment* pFormFillEnv =
260 new CPDFSDK_FormFillEnvironment(pDocument, formInfo);
261
262 #ifdef PDF_ENABLE_XFA
263 pDocument->SetFormFillEnv(pFormFillEnv);
264 #endif // PDF_ENABLE_XFA
265
266 return pFormFillEnv;
267 }
268
269 DLLEXPORT void STDCALL
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle)270 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
271 if (!hHandle)
272 return;
273
274 CPDFSDK_FormFillEnvironment* pFormFillEnv =
275 HandleToCPDFSDKEnvironment(hHandle);
276
277 #ifdef PDF_ENABLE_XFA
278 // Reset the focused annotations and remove the SDK document from the
279 // XFA document.
280 pFormFillEnv->ClearAllFocusedAnnots();
281 // If the document was closed first, it's possible the XFA document
282 // is now a nullptr.
283 if (pFormFillEnv->GetXFAContext())
284 pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr);
285 #endif // PDF_ENABLE_XFA
286
287 delete pFormFillEnv;
288 }
289
FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)290 DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
291 FPDF_PAGE page,
292 int modifier,
293 double page_x,
294 double page_y) {
295 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
296 if (!pPageView)
297 return false;
298 return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier);
299 }
300
FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)301 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
302 FPDF_PAGE page,
303 int modifier,
304 double page_x,
305 double page_y) {
306 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
307 if (!pPageView)
308 return false;
309 return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier);
310 }
311
FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)312 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
313 FPDF_PAGE page,
314 int modifier,
315 double page_x,
316 double page_y) {
317 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
318 if (!pPageView)
319 return false;
320
321 CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
322 return pPageView->OnLButtonUp(pt, modifier);
323 }
324
325 #ifdef PDF_ENABLE_XFA
FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)326 DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
327 FPDF_PAGE page,
328 int modifier,
329 double page_x,
330 double page_y) {
331 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
332 if (!pPageView)
333 return false;
334 return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier);
335 }
336
FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int modifier,double page_x,double page_y)337 DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
338 FPDF_PAGE page,
339 int modifier,
340 double page_x,
341 double page_y) {
342 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
343 if (!pPageView)
344 return false;
345
346 CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
347 return pPageView->OnRButtonUp(pt, modifier);
348 }
349 #endif // PDF_ENABLE_XFA
350
FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)351 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
352 FPDF_PAGE page,
353 int nKeyCode,
354 int modifier) {
355 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
356 if (!pPageView)
357 return false;
358
359 return pPageView->OnKeyDown(nKeyCode, modifier);
360 }
361
FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nKeyCode,int modifier)362 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
363 FPDF_PAGE page,
364 int nKeyCode,
365 int modifier) {
366 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
367 if (!pPageView)
368 return false;
369
370 return pPageView->OnKeyUp(nKeyCode, modifier);
371 }
372
FORM_OnChar(FPDF_FORMHANDLE hHandle,FPDF_PAGE page,int nChar,int modifier)373 DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
374 FPDF_PAGE page,
375 int nChar,
376 int modifier) {
377 CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
378 if (!pPageView)
379 return false;
380
381 return pPageView->OnChar(nChar, modifier);
382 }
383
FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)384 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
385 CPDFSDK_FormFillEnvironment* pFormFillEnv =
386 HandleToCPDFSDKEnvironment(hHandle);
387 if (!pFormFillEnv)
388 return false;
389 return pFormFillEnv->KillFocusAnnot(0);
390 }
391
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)392 DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
393 FPDF_BITMAP bitmap,
394 FPDF_PAGE page,
395 int start_x,
396 int start_y,
397 int size_x,
398 int size_y,
399 int rotate,
400 int flags) {
401 FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
402 rotate, flags);
403 }
404
405 #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)406 DLLEXPORT void STDCALL FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,
407 FPDF_RECORDER recorder,
408 FPDF_PAGE page,
409 int start_x,
410 int start_y,
411 int size_x,
412 int size_y,
413 int rotate,
414 int flags) {
415 FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y,
416 rotate, flags);
417 }
418 #endif
419
420 #ifdef PDF_ENABLE_XFA
FPDF_Widget_Undo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)421 DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document,
422 FPDF_WIDGET hWidget) {
423 if (!hWidget || !document)
424 return;
425
426 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
427 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
428 pContext->GetDocType() != XFA_DOCTYPE_Static)
429 return;
430
431 static_cast<CXFA_FFWidget*>(hWidget)->Undo();
432 }
433
FPDF_Widget_Redo(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)434 DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document,
435 FPDF_WIDGET hWidget) {
436 if (!hWidget || !document)
437 return;
438
439 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
440 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
441 pContext->GetDocType() != XFA_DOCTYPE_Static)
442 return;
443
444 static_cast<CXFA_FFWidget*>(hWidget)->Redo();
445 }
446
FPDF_Widget_SelectAll(FPDF_DOCUMENT document,FPDF_WIDGET hWidget)447 DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
448 FPDF_WIDGET hWidget) {
449 if (!hWidget || !document)
450 return;
451
452 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
453 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
454 pContext->GetDocType() != XFA_DOCTYPE_Static)
455 return;
456
457 static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
458 }
459
FPDF_Widget_Copy(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)460 DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document,
461 FPDF_WIDGET hWidget,
462 FPDF_WIDESTRING wsText,
463 FPDF_DWORD* size) {
464 if (!hWidget || !document)
465 return;
466
467 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
468 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
469 pContext->GetDocType() != XFA_DOCTYPE_Static)
470 return;
471
472 CFX_WideString wsCpText;
473 static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsCpText);
474
475 CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
476 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
477 if (!wsText) {
478 *size = len;
479 return;
480 }
481
482 uint32_t real_size = len < *size ? len : *size;
483 if (real_size > 0) {
484 FXSYS_memcpy((void*)wsText,
485 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
486 real_size * sizeof(unsigned short));
487 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
488 }
489 *size = real_size;
490 }
491
FPDF_Widget_Cut(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD * size)492 DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document,
493 FPDF_WIDGET hWidget,
494 FPDF_WIDESTRING wsText,
495 FPDF_DWORD* size) {
496 if (!hWidget || !document)
497 return;
498
499 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
500 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
501 pContext->GetDocType() != XFA_DOCTYPE_Static)
502 return;
503
504 CFX_WideString wsCpText;
505 static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsCpText);
506
507 CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
508 uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
509 if (!wsText) {
510 *size = len;
511 return;
512 }
513
514 uint32_t real_size = len < *size ? len : *size;
515 if (real_size > 0) {
516 FXSYS_memcpy((void*)wsText,
517 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
518 real_size * sizeof(unsigned short));
519 bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
520 }
521 *size = real_size;
522 }
523
FPDF_Widget_Paste(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,FPDF_WIDESTRING wsText,FPDF_DWORD size)524 DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document,
525 FPDF_WIDGET hWidget,
526 FPDF_WIDESTRING wsText,
527 FPDF_DWORD size) {
528 if (!hWidget || !document)
529 return;
530
531 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
532 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
533 pContext->GetDocType() != XFA_DOCTYPE_Static)
534 return;
535
536 CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size);
537 static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr);
538 }
539
540 DLLEXPORT void STDCALL
FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_BYTESTRING bsText)541 FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
542 FPDF_WIDGET hWidget,
543 float x,
544 float y,
545 FPDF_BYTESTRING bsText) {
546 if (!hWidget || !document)
547 return;
548
549 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
550 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
551 pContext->GetDocType() != XFA_DOCTYPE_Static)
552 return;
553
554 CFX_PointF ptPopup;
555 ptPopup.x = x;
556 ptPopup.y = y;
557 CFX_ByteStringC bs(bsText);
558 static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs);
559 }
560
561 DLLEXPORT void STDCALL
FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,FPDF_WIDGET hWidget,float x,float y,FPDF_STRINGHANDLE * stringHandle)562 FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
563 FPDF_WIDGET hWidget,
564 float x,
565 float y,
566 FPDF_STRINGHANDLE* stringHandle) {
567 if (!hWidget || !document)
568 return;
569
570 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
571 if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
572 pContext->GetDocType() != XFA_DOCTYPE_Static)
573 return;
574
575 std::vector<CFX_ByteString>* sSuggestWords = new std::vector<CFX_ByteString>;
576 CFX_PointF ptPopup;
577 ptPopup.x = x;
578 ptPopup.y = y;
579 static_cast<CXFA_FFWidget*>(hWidget)
580 ->GetSuggestWords(ptPopup, *sSuggestWords);
581 *stringHandle = ToFPDFStringHandle(sSuggestWords);
582 }
583
FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle)584 DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) {
585 std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
586 return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1;
587 }
588
589 DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,int index,FPDF_BYTESTRING bsText,FPDF_DWORD * size)590 FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,
591 int index,
592 FPDF_BYTESTRING bsText,
593 FPDF_DWORD* size) {
594 if (!sHandle || !size)
595 return false;
596
597 int count = FPDF_StringHandleCounts(sHandle);
598 if (index < 0 || index >= count)
599 return false;
600
601 std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
602 uint32_t len = (*sSuggestWords)[index].GetLength();
603 if (!bsText) {
604 *size = len;
605 return true;
606 }
607
608 uint32_t real_size = len < *size ? len : *size;
609 if (real_size > 0)
610 FXSYS_memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size);
611 *size = real_size;
612 return true;
613 }
614
615 DLLEXPORT void STDCALL
FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle)616 FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) {
617 delete FromFPDFStringHandle(stringHandle);
618 }
619
620 DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,FPDF_BYTESTRING bsText,FPDF_DWORD size)621 FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
622 FPDF_BYTESTRING bsText,
623 FPDF_DWORD size) {
624 if (!stringHandle || !bsText || size == 0)
625 return false;
626
627 FromFPDFStringHandle(stringHandle)->push_back(CFX_ByteString(bsText, size));
628 return true;
629 }
630 #endif // PDF_ENABLE_XFA
631
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,int fieldType,unsigned long color)632 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
633 int fieldType,
634 unsigned long color) {
635 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
636 pInterForm->SetHighlightColor(color, fieldType);
637 }
638
FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,unsigned char alpha)639 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
640 unsigned char alpha) {
641 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
642 pInterForm->SetHighlightAlpha(alpha);
643 }
644
FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)645 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
646 if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
647 pInterForm->RemoveAllHighLight();
648 }
649
FORM_OnAfterLoadPage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)650 DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
651 FPDF_FORMHANDLE hHandle) {
652 if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
653 pPageView->SetValid(true);
654 }
655
FORM_OnBeforeClosePage(FPDF_PAGE page,FPDF_FORMHANDLE hHandle)656 DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
657 FPDF_FORMHANDLE hHandle) {
658 if (!hHandle)
659 return;
660
661 CPDFSDK_FormFillEnvironment* pFormFillEnv =
662 HandleToCPDFSDKEnvironment(hHandle);
663 if (!pFormFillEnv)
664 return;
665
666 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
667 if (!pPage)
668 return;
669
670 CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false);
671 if (pPageView) {
672 pPageView->SetValid(false);
673 // RemovePageView() takes care of the delete for us.
674 pFormFillEnv->RemovePageView(pPage);
675 }
676 }
677
FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)678 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
679 CPDFSDK_FormFillEnvironment* pFormFillEnv =
680 HandleToCPDFSDKEnvironment(hHandle);
681 if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
682 pFormFillEnv->ProcJavascriptFun();
683 }
684
FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)685 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
686 CPDFSDK_FormFillEnvironment* pFormFillEnv =
687 HandleToCPDFSDKEnvironment(hHandle);
688 if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
689 pFormFillEnv->ProcOpenAction();
690 }
691
FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,int aaType)692 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
693 int aaType) {
694 CPDFSDK_FormFillEnvironment* pFormFillEnv =
695 HandleToCPDFSDKEnvironment(hHandle);
696 if (!pFormFillEnv)
697 return;
698
699 CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
700 CPDF_Dictionary* pDic = pDoc->GetRoot();
701 if (!pDic)
702 return;
703
704 CPDF_AAction aa(pDic->GetDictFor("AA"));
705 if (aa.ActionExist((CPDF_AAction::AActionType)aaType)) {
706 CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
707 CPDFSDK_ActionHandler* pActionHandler =
708 HandleToCPDFSDKEnvironment(hHandle)->GetActionHander();
709 pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType,
710 pFormFillEnv);
711 }
712 }
713
FORM_DoPageAAction(FPDF_PAGE page,FPDF_FORMHANDLE hHandle,int aaType)714 DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
715 FPDF_FORMHANDLE hHandle,
716 int aaType) {
717 if (!hHandle)
718 return;
719
720 CPDFSDK_FormFillEnvironment* pFormFillEnv =
721 HandleToCPDFSDKEnvironment(hHandle);
722 if (!pFormFillEnv)
723 return;
724
725 UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
726 CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
727 if (!pPDFPage)
728 return;
729
730 if (!pFormFillEnv->GetPageView(pPage, false))
731 return;
732
733 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHander();
734 CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict;
735 CPDF_AAction aa(pPageDict->GetDictFor("AA"));
736 if (FPDFPAGE_AACTION_OPEN == aaType) {
737 if (aa.ActionExist(CPDF_AAction::OpenPage)) {
738 CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);
739 pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage,
740 pFormFillEnv);
741 }
742 } else {
743 if (aa.ActionExist(CPDF_AAction::ClosePage)) {
744 CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);
745 pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage,
746 pFormFillEnv);
747 }
748 }
749 }
750