clang-format all pdfium code.
[pdfium.git] / fpdfsdk / src / fpdfformfill.cpp
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 #include "../../public/fpdfview.h"
9 #include "../../third_party/base/nonstd_unique_ptr.h"
10 #include "../include/fsdk_define.h"
11 #include "../include/fsdk_mgr.h"
12 #include "../include/javascript/IJavaScript.h"
13
14 namespace {
15
16 CPDFSDK_Document* FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle) {
17   CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
18   return pEnv ? pEnv->GetSDKDocument() : nullptr;
19 }
20
21 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
22   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
23   return pSDKDoc ? pSDKDoc->GetInterForm() : nullptr;
24 }
25
26 CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
27                                        FPDF_PAGE page) {
28   if (!page)
29     return nullptr;
30
31   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
32   return pSDKDoc ? pSDKDoc->GetPageView((CPDF_Page*)page, TRUE) : nullptr;
33 }
34
35 }  // namespace
36
37 DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
38                                                   FPDF_PAGE page,
39                                                   double page_x,
40                                                   double page_y) {
41   if (!page || !hHandle)
42     return -1;
43   CPDF_Page* pPage = (CPDF_Page*)page;
44
45   nonstd::unique_ptr<CPDF_InterForm> pInterForm(
46       new CPDF_InterForm(pPage->m_pDocument, FALSE));
47   CPDF_FormControl* pFormCtrl =
48       pInterForm->GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y);
49   if (!pFormCtrl)
50     return -1;
51
52   CPDF_FormField* pFormField = pFormCtrl->GetField();
53   if (!pFormField)
54     return -1;
55
56   return pFormField->GetFieldType();
57 }
58
59 DLLEXPORT FPDF_FORMHANDLE STDCALL
60 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
61                                 FPDF_FORMFILLINFO* formInfo) {
62   if (!document || !formInfo || formInfo->version != 1)
63     return nullptr;
64
65   CPDF_Document* pDocument = (CPDF_Document*)document;
66   CPDFDoc_Environment* pEnv = new CPDFDoc_Environment(pDocument, formInfo);
67   pEnv->SetSDKDocument(new CPDFSDK_Document(pDocument, pEnv));
68   return pEnv;
69 }
70
71 DLLEXPORT void STDCALL
72 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
73   if (!hHandle)
74     return;
75
76   CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
77   if (CPDFSDK_Document* pSDKDoc = pEnv->GetSDKDocument()) {
78     pEnv->SetSDKDocument(NULL);
79     delete pSDKDoc;
80   }
81   delete pEnv;
82 }
83
84 DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
85                                              FPDF_PAGE page,
86                                              int modifier,
87                                              double page_x,
88                                              double page_y) {
89   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
90   if (!pPageView)
91     return FALSE;
92
93   CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
94   return pPageView->OnMouseMove(pt, modifier);
95 }
96
97 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
98                                                FPDF_PAGE page,
99                                                int modifier,
100                                                double page_x,
101                                                double page_y) {
102   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
103   if (!pPageView)
104     return FALSE;
105
106   CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
107   return pPageView->OnLButtonDown(pt, modifier);
108 }
109
110 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
111                                              FPDF_PAGE page,
112                                              int modifier,
113                                              double page_x,
114                                              double page_y) {
115   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
116   if (!pPageView)
117     return FALSE;
118
119   CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
120   return pPageView->OnLButtonUp(pt, modifier);
121 }
122
123 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
124                                            FPDF_PAGE page,
125                                            int nKeyCode,
126                                            int modifier) {
127   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
128   if (!pPageView)
129     return FALSE;
130
131   return pPageView->OnKeyDown(nKeyCode, modifier);
132 }
133
134 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
135                                          FPDF_PAGE page,
136                                          int nKeyCode,
137                                          int modifier) {
138   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
139   if (!pPageView)
140     return FALSE;
141
142   return pPageView->OnKeyUp(nKeyCode, modifier);
143 }
144
145 DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
146                                         FPDF_PAGE page,
147                                         int nChar,
148                                         int modifier) {
149   CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
150   if (!pPageView)
151     return FALSE;
152
153   return pPageView->OnChar(nChar, modifier);
154 }
155
156 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
157   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
158   if (!pSDKDoc)
159     return FALSE;
160
161   return pSDKDoc->KillFocusAnnot(0);
162 }
163
164 DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
165                                     FPDF_BITMAP bitmap,
166                                     FPDF_PAGE page,
167                                     int start_x,
168                                     int start_y,
169                                     int size_x,
170                                     int size_y,
171                                     int rotate,
172                                     int flags) {
173   if (!hHandle || !page)
174     return;
175
176   CPDF_Page* pPage = (CPDF_Page*)page;
177   CPDF_RenderOptions options;
178   if (flags & FPDF_LCD_TEXT)
179     options.m_Flags |= RENDER_CLEARTYPE;
180   else
181     options.m_Flags &= ~RENDER_CLEARTYPE;
182
183   // Grayscale output
184   if (flags & FPDF_GRAYSCALE) {
185     options.m_ColorMode = RENDER_COLOR_GRAY;
186     options.m_ForeColor = 0;
187     options.m_BackColor = 0xffffff;
188   }
189
190   options.m_AddFlags = flags >> 8;
191   options.m_pOCContext = new CPDF_OCContext(pPage->m_pDocument);
192
193   CFX_AffineMatrix matrix;
194   pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
195
196   FX_RECT clip;
197   clip.left = start_x;
198   clip.right = start_x + size_x;
199   clip.top = start_y;
200   clip.bottom = start_y + size_y;
201
202 #ifdef _SKIA_SUPPORT_
203   nonstd::unique_ptr<CFX_SkiaDevice> pDevice(new CFX_SkiaDevice);
204 #else
205   nonstd::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice);
206 #endif
207   pDevice->Attach((CFX_DIBitmap*)bitmap);
208   pDevice->SaveState();
209   pDevice->SetClip_Rect(&clip);
210
211   if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
212     pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
213
214   pDevice->RestoreState();
215   delete options.m_pOCContext;
216 }
217
218 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
219                                                        int fieldType,
220                                                        unsigned long color) {
221   if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
222     pInterForm->SetHighlightColor(color, fieldType);
223 }
224
225 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
226                                                        unsigned char alpha) {
227   if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
228     pInterForm->SetHighlightAlpha(alpha);
229 }
230
231 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
232   if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
233     pInterForm->RemoveAllHighLight();
234 }
235
236 DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
237                                             FPDF_FORMHANDLE hHandle) {
238   if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
239     pPageView->SetValid(TRUE);
240 }
241
242 DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
243                                               FPDF_FORMHANDLE hHandle) {
244   if (!hHandle || !page)
245     return;
246
247   CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetSDKDocument();
248   if (!pSDKDoc)
249     return;
250
251   CPDF_Page* pPage = (CPDF_Page*)page;
252   CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
253   if (pPageView) {
254     pPageView->SetValid(FALSE);
255     // ReMovePageView() takes care of the delete for us.
256     pSDKDoc->ReMovePageView(pPage);
257   }
258 }
259
260 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
261   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
262   if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
263     pSDKDoc->ProcJavascriptFun();
264 }
265
266 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
267   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
268   if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
269     pSDKDoc->ProcOpenAction();
270 }
271
272 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
273                                               int aaType) {
274   CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
275   if (!pSDKDoc)
276     return;
277
278   CPDF_Document* pDoc = pSDKDoc->GetDocument();
279   CPDF_Dictionary* pDic = pDoc->GetRoot();
280   if (!pDic)
281     return;
282
283   CPDF_AAction aa = pDic->GetDict(FX_BSTRC("AA"));
284   if (aa.ActionExist((CPDF_AAction::AActionType)aaType)) {
285     CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
286     CPDFSDK_ActionHandler* pActionHandler =
287         ((CPDFDoc_Environment*)hHandle)->GetActionHander();
288     ASSERT(pActionHandler != NULL);
289     pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType,
290                                       pSDKDoc);
291   }
292 }
293
294 DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
295                                           FPDF_FORMHANDLE hHandle,
296                                           int aaType) {
297   if (!hHandle || !page)
298     return;
299   CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetSDKDocument();
300   CPDF_Page* pPage = (CPDF_Page*)page;
301   CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
302   if (pPageView) {
303     CPDFDoc_Environment* pEnv = pSDKDoc->GetEnv();
304     ASSERT(pEnv != NULL);
305
306     CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
307     ASSERT(pActionHandler != NULL);
308
309     CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
310     ASSERT(pPageDict != NULL);
311
312     CPDF_AAction aa = pPageDict->GetDict(FX_BSTRC("AA"));
313
314     FX_BOOL bExistOAAction = FALSE;
315     FX_BOOL bExistCAAction = FALSE;
316     if (FPDFPAGE_AACTION_OPEN == aaType) {
317       bExistOAAction = aa.ActionExist(CPDF_AAction::OpenPage);
318       if (bExistOAAction) {
319         CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);
320         pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, pSDKDoc);
321       }
322     } else {
323       bExistCAAction = aa.ActionExist(CPDF_AAction::ClosePage);
324       if (bExistCAAction) {
325         CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);
326         pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, pSDKDoc);
327       }
328     }
329   }
330 }