101146b09966cc3246eac85190156a9b0efd7c76
[pdfium.git] / fpdfsdk / src / fpdfformfill.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4  \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../include/fpdfview.h"\r
8 #include "../include/fpdfformfill.h"\r
9 #include "../include/fsdk_define.h"\r
10 #include "../include/fsdk_mgr.h"\r
11 \r
12 \r
13 #include "../include/javascript/IJavaScript.h"\r
14 \r
15 \r
16 DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, FPDF_PAGE page,double page_x, double page_y)\r
17 {\r
18         if(!page || !hHandle)\r
19                 return -1;\r
20         CPDF_Page * pPage = (CPDF_Page*) page;\r
21 \r
22         CPDF_InterForm * pInterForm = NULL;\r
23         pInterForm = new CPDF_InterForm(pPage->m_pDocument,FALSE);\r
24         if (!pInterForm)\r
25                 return -1;\r
26         CPDF_FormControl* pFormCtrl = pInterForm->GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y);\r
27         if(!pFormCtrl)\r
28         {\r
29                 delete pInterForm;\r
30                 return -1;\r
31         }\r
32         CPDF_FormField* pFormField = pFormCtrl->GetField();\r
33         if(!pFormField)\r
34         {\r
35                 delete pInterForm;\r
36                 return -1;\r
37         }\r
38         \r
39         int nType = pFormField->GetFieldType();\r
40         delete pInterForm;\r
41         return nType;\r
42 }\r
43 \r
44 DLLEXPORT FPDF_FORMHANDLE STDCALL FPDFDOC_InitFormFillEnviroument(FPDF_DOCUMENT document, FPDF_FORMFILLINFO* formInfo)\r
45 {\r
46         if(!document || !formInfo || formInfo->version!=1)\r
47                 return NULL;\r
48         CPDF_Document * pDocument = (CPDF_Document*) document;\r
49         CPDFDoc_Environment * pEnv = NULL;\r
50         pEnv = new CPDFDoc_Environment(pDocument);\r
51         if (!pEnv)\r
52                 return NULL;\r
53         pEnv->RegAppHandle(formInfo);\r
54 \r
55         if(pEnv->GetPDFDocument())\r
56         {\r
57                 CPDFSDK_Document* pSDKDoc = new CPDFSDK_Document(pEnv->GetPDFDocument(), pEnv);\r
58                 if(pSDKDoc)\r
59                         pEnv->SetCurrentDoc(pSDKDoc);\r
60         }\r
61         return pEnv;\r
62 }\r
63 \r
64 DLLEXPORT void STDCALL FPDFDOC_ExitFormFillEnviroument(FPDF_FORMHANDLE hHandle)\r
65 {\r
66         if(!hHandle)\r
67                 return; \r
68         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
69         if(pSDKDoc)\r
70         {\r
71                 ((CPDFDoc_Environment*)hHandle)->SetCurrentDoc(NULL);\r
72                 delete pSDKDoc;\r
73         }\r
74         delete (CPDFDoc_Environment*)hHandle;\r
75         hHandle = NULL;\r
76 }\r
77 \r
78 DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)\r
79 {       \r
80         if (!hHandle || !page)\r
81                 return FALSE;\r
82 //      CPDF_Page * pPage = (CPDF_Page*) page;\r
83 //      CPDF_Document * pDoc = pPage->m_pDocument;\r
84 //      CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;\r
85         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
86         if(!pFXDoc)\r
87                 return FALSE;\r
88         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
89         if(!pPageView)\r
90                 return FALSE;\r
91         \r
92 //      double page_x = 0;\r
93 //      double page_y = 0;\r
94 //      pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y);\r
95         CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);\r
96         return pPageView->OnMouseMove(pt, modifier);\r
97 }\r
98 \r
99 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)\r
100 {\r
101         if (!hHandle || !page)\r
102                 return FALSE;\r
103         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
104         if(!pFXDoc)\r
105                 return FALSE;\r
106         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
107         if(!pPageView)\r
108                 return FALSE;\r
109 //      double page_x = 0;\r
110 //      double page_y = 0;\r
111 //      pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y);\r
112         CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);\r
113         return pPageView->OnLButtonDown(pt, modifier);\r
114 }\r
115 \r
116 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)\r
117 {\r
118         if (!hHandle || !page)\r
119                 return FALSE;\r
120         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
121         if(!pFXDoc)\r
122                 return FALSE;\r
123         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
124         if(!pPageView)\r
125                 return FALSE;\r
126 //      double page_x = 0;\r
127 //      double page_y = 0;\r
128 //      pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y);\r
129         CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);\r
130         return pPageView->OnLButtonUp(pt, modifier);\r
131 }\r
132 \r
133 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier)\r
134 {\r
135         if (!hHandle || !page)\r
136                 return FALSE;\r
137         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
138         if(!pFXDoc)\r
139                 return FALSE;\r
140         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
141         if(!pPageView)\r
142                 return FALSE;\r
143         \r
144         \r
145         return pPageView->OnKeyDown(nKeyCode, modifier);\r
146 }\r
147 \r
148 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier)\r
149 {\r
150         if (!hHandle || !page)\r
151                 return FALSE;\r
152         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
153         if(!pFXDoc)\r
154                 return FALSE;\r
155         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
156         if(!pPageView)\r
157                 return FALSE;\r
158         \r
159         \r
160         return pPageView->OnKeyUp(nKeyCode, modifier);\r
161 }\r
162 \r
163 \r
164 DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nChar,  int modifier)\r
165 {\r
166         if (!hHandle || !page)\r
167                 return FALSE;\r
168         CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
169         if(!pFXDoc)\r
170                 return FALSE;\r
171         CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);\r
172         if(!pPageView)\r
173                 return FALSE;\r
174         return pPageView->OnChar(nChar, modifier);\r
175 \r
176 }\r
177 \r
178 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle)\r
179 {\r
180         if(!hHandle)\r
181                 return FALSE;\r
182         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
183         if(!pSDKDoc)\r
184                 return FALSE;\r
185         //Kill the current focus. \r
186         return pSDKDoc->KillFocusAnnot(0);\r
187 }\r
188 \r
189 DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y, \r
190                                                                                                   int size_x, int size_y, int rotate, int flags)\r
191 {\r
192         if (!hHandle || !page)\r
193                 return ;\r
194         CPDF_Page* pPage = (CPDF_Page*)page;\r
195         \r
196         CPDF_RenderOptions options;\r
197         if (flags & FPDF_LCD_TEXT)\r
198                 options.m_Flags |= RENDER_CLEARTYPE;\r
199         else\r
200                 options.m_Flags &= ~RENDER_CLEARTYPE;\r
201         \r
202         //Grayscale output\r
203         if (flags & FPDF_GRAYSCALE)\r
204         {\r
205                 options.m_ColorMode = RENDER_COLOR_GRAY;\r
206                 options.m_ForeColor = 0;\r
207                 options.m_BackColor = 0xffffff;\r
208         }\r
209         \r
210         options.m_AddFlags = flags >> 8;\r
211 \r
212         options.m_pOCContext = FX_NEW CPDF_OCContext(pPage->m_pDocument);\r
213 \r
214         //FXMT_CSLOCK_OBJ(&pPage->m_PageLock);\r
215         \r
216         CFX_AffineMatrix matrix;\r
217         pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); \r
218         \r
219         FX_RECT clip;\r
220         clip.left = start_x;\r
221         clip.right = start_x + size_x;\r
222         clip.top = start_y;\r
223         clip.bottom = start_y + size_y;\r
224 \r
225 #ifdef _SKIA_SUPPORT_\r
226         CFX_SkiaDevice* pDevice = FX_NEW CFX_SkiaDevice;\r
227 #else\r
228         CFX_FxgeDevice* pDevice = NULL;\r
229         pDevice = FX_NEW CFX_FxgeDevice;\r
230 #endif\r
231 \r
232         if (!pDevice)\r
233                 return;\r
234         pDevice->Attach((CFX_DIBitmap*)bitmap);\r
235         pDevice->SaveState();\r
236         pDevice->SetClip_Rect(&clip);\r
237         \r
238 \r
239         CPDF_RenderContext* pContext = NULL;\r
240         pContext = FX_NEW CPDF_RenderContext;\r
241         if (!pContext)\r
242         {\r
243                 delete pDevice;\r
244                 pDevice = NULL;\r
245                 return;\r
246         }\r
247 \r
248 \r
249 //      CPDF_Document* pDoc = pPage->m_pDocument;\r
250         CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;\r
251         CPDFSDK_Document* pFXDoc = pEnv->GetCurrentDoc();\r
252         if(!pFXDoc)\r
253         {\r
254                 delete pContext;\r
255                 delete pDevice;\r
256                 pContext = NULL;\r
257                 pDevice = NULL;\r
258                 return;\r
259         }\r
260         if(CPDFSDK_PageView* pPageView = pFXDoc->GetPageView(pPage))\r
261         {\r
262                 pPageView->PageView_OnDraw(pDevice, &matrix, &options);\r
263         }\r
264         pDevice->RestoreState();\r
265 \r
266         if(options.m_pOCContext)\r
267         {\r
268                 delete options.m_pOCContext;\r
269                 options.m_pOCContext = NULL;\r
270         }\r
271         if(pContext)\r
272         {\r
273                 delete pContext;\r
274                 pContext = NULL;\r
275         }\r
276         if(pDevice)\r
277         {\r
278                 delete pDevice;\r
279                 pDevice = NULL;\r
280         }\r
281 \r
282 }\r
283 \r
284 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, int fieldType, unsigned long color)\r
285 {\r
286         if (!hHandle)\r
287                 return;\r
288 //      CPDFDoc_Environment* pEnv = (CPDFDoc_Environment* )hHandle;\r
289         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
290         if(pSDKDoc)\r
291         {\r
292                 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())\r
293                 {\r
294                         pInterForm->SetHighlightColor(color, fieldType);\r
295                 }\r
296         \r
297         }\r
298 \r
299 }\r
300 \r
301 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha)\r
302 {\r
303         if (!hHandle)\r
304                 return;\r
305         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
306         if(pSDKDoc)\r
307         {\r
308                 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())\r
309                         pInterForm->SetHighlightAlpha(alpha);\r
310         }\r
311 }\r
312 \r
313 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)\r
314 {\r
315         if (!hHandle)\r
316                 return;\r
317         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
318         if(pSDKDoc)\r
319         {\r
320                 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())\r
321                         pInterForm->RemoveAllHighLight();\r
322         }\r
323 }\r
324 \r
325 DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)\r
326 {\r
327         if(!hHandle || !page)\r
328                 return;\r
329         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
330         if(!pSDKDoc)\r
331                 return;\r
332         CPDF_Page* pPage = (CPDF_Page*)page;\r
333         CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, TRUE);\r
334         if(pPageView)\r
335         {\r
336                 pPageView->SetValid(TRUE);\r
337         }       \r
338 }\r
339 \r
340 DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)\r
341 {\r
342         if(!hHandle || !page)\r
343                 return;\r
344         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
345         CPDF_Page* pPage = (CPDF_Page*)page;\r
346         CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);\r
347         if(pPageView)\r
348         {\r
349                 pPageView->SetValid(FALSE);\r
350                 // ReMovePageView() takes care of the delete for us.\r
351                 pSDKDoc->ReMovePageView(pPage);\r
352         }\r
353 }\r
354 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)\r
355 {\r
356         if(!hHandle)\r
357                 return;\r
358         if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc())\r
359         {\r
360                 pSDKDoc->InitPageView();\r
361                 if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated())\r
362                         pSDKDoc->ProcJavascriptFun();\r
363         }       \r
364 }\r
365 \r
366 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)\r
367 {\r
368         if(!hHandle)\r
369                 return;\r
370         if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc())\r
371         {\r
372                 if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated())\r
373                         pSDKDoc->ProcOpenAction();\r
374         }\r
375 }\r
376 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaType)\r
377 {\r
378         if(!hHandle)\r
379                 return;\r
380         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
381         if(pSDKDoc)\r
382         {\r
383                 CPDF_Document* pDoc = pSDKDoc->GetDocument();\r
384                 CPDF_Dictionary* pDic = pDoc->GetRoot();\r
385                 if (!pDic)\r
386                         return;\r
387                 CPDF_AAction aa = pDic->GetDict(FX_BSTRC("AA"));\r
388                 \r
389                 if(aa.ActionExist((CPDF_AAction::AActionType)aaType))\r
390                 {\r
391                         CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);\r
392                         CPDFSDK_ActionHandler *pActionHandler = ((CPDFDoc_Environment*)hHandle)->GetActionHander();\r
393                         ASSERT(pActionHandler != NULL);\r
394                         pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType, pSDKDoc);\r
395                 }\r
396         }\r
397 }\r
398 DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandle, int aaType)\r
399 {\r
400         if(!hHandle || !page)\r
401                 return;\r
402         CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();\r
403         CPDF_Page* pPage = (CPDF_Page*)page;\r
404         CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);\r
405         if(pPageView)\r
406         {\r
407                 CPDFDoc_Environment *pEnv = pSDKDoc->GetEnv();\r
408                 ASSERT(pEnv != NULL);\r
409                         \r
410                 CPDFSDK_ActionHandler *pActionHandler = pEnv->GetActionHander();\r
411                 ASSERT(pActionHandler != NULL);\r
412                 \r
413                 CPDF_Dictionary *pPageDict = pPage->m_pFormDict;\r
414                 ASSERT(pPageDict != NULL);\r
415                  \r
416                 CPDF_AAction aa = pPageDict->GetDict(FX_BSTRC("AA"));\r
417 \r
418                 FX_BOOL bExistOAAction = FALSE;\r
419                 FX_BOOL bExistCAAction = FALSE;\r
420                 if (FPDFPAGE_AACTION_OPEN == aaType)\r
421                 {\r
422                         bExistOAAction = aa.ActionExist(CPDF_AAction::OpenPage);\r
423                         if (bExistOAAction)\r
424                         {\r
425                                 CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);\r
426                                 pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, pSDKDoc);\r
427                         }\r
428                 }\r
429                 else\r
430                 {\r
431                         bExistCAAction = aa.ActionExist(CPDF_AAction::ClosePage);\r
432                         if (bExistCAAction)\r
433                         {\r
434                                 CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);\r
435                                 pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, pSDKDoc);\r
436                         }\r
437                 }\r
438         }\r
439 }\r
440 \r
441 \r