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
16DLLEXPORT 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
44DLLEXPORT 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
64DLLEXPORT 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
78DLLEXPORT 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
99DLLEXPORT 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
116DLLEXPORT 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
133DLLEXPORT 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
148DLLEXPORT 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
164DLLEXPORT 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
178DLLEXPORT 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
189DLLEXPORT 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
266DLLEXPORT 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
283DLLEXPORT 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
295DLLEXPORT 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
307DLLEXPORT 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
322DLLEXPORT 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}
336DLLEXPORT 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
348DLLEXPORT 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}
358DLLEXPORT 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}
380DLLEXPORT 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