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