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