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 "../include/fpdfview.h"
8#include "../include/fpdfformfill.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_InitFormFillEnviroument(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_ExitFormFillEnviroument(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
212	options.m_pOCContext = FX_NEW CPDF_OCContext(pPage->m_pDocument);
213
214	//FXMT_CSLOCK_OBJ(&pPage->m_PageLock);
215
216	CFX_AffineMatrix matrix;
217	pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
218
219	FX_RECT clip;
220	clip.left = start_x;
221	clip.right = start_x + size_x;
222	clip.top = start_y;
223	clip.bottom = start_y + size_y;
224
225#ifdef _SKIA_SUPPORT_
226	CFX_SkiaDevice* pDevice = FX_NEW CFX_SkiaDevice;
227#else
228	CFX_FxgeDevice* pDevice = NULL;
229	pDevice = FX_NEW CFX_FxgeDevice;
230#endif
231
232	if (!pDevice)
233		return;
234	pDevice->Attach((CFX_DIBitmap*)bitmap);
235	pDevice->SaveState();
236	pDevice->SetClip_Rect(&clip);
237
238
239	CPDF_RenderContext* pContext = NULL;
240	pContext = FX_NEW CPDF_RenderContext;
241	if (!pContext)
242	{
243		delete pDevice;
244		pDevice = NULL;
245		return;
246	}
247
248
249//	CPDF_Document* pDoc = pPage->m_pDocument;
250	CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
251	CPDFSDK_Document* pFXDoc = pEnv->GetCurrentDoc();
252	if(!pFXDoc)
253	{
254		delete pContext;
255		delete pDevice;
256		pContext = NULL;
257		pDevice = NULL;
258		return;
259	}
260	if(CPDFSDK_PageView* pPageView = pFXDoc->GetPageView(pPage))
261	{
262		pPageView->PageView_OnDraw(pDevice, &matrix, &options);
263	}
264	pDevice->RestoreState();
265
266	if(options.m_pOCContext)
267	{
268		delete options.m_pOCContext;
269		options.m_pOCContext = NULL;
270	}
271	if(pContext)
272	{
273		delete pContext;
274		pContext = NULL;
275	}
276	if(pDevice)
277	{
278		delete pDevice;
279		pDevice = NULL;
280	}
281
282}
283
284DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, int fieldType, unsigned long color)
285{
286	if (!hHandle)
287		return;
288//	CPDFDoc_Environment* pEnv = (CPDFDoc_Environment* )hHandle;
289	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
290	if(pSDKDoc)
291	{
292		if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())
293		{
294			pInterForm->SetHighlightColor(color, fieldType);
295		}
296
297	}
298
299}
300
301DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha)
302{
303	if (!hHandle)
304		return;
305	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
306	if(pSDKDoc)
307	{
308		if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())
309			pInterForm->SetHighlightAlpha(alpha);
310	}
311}
312
313DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle)
314{
315	if (!hHandle)
316		return;
317	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
318	if(pSDKDoc)
319	{
320		if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm())
321			pInterForm->RemoveAllHighLight();
322	}
323}
324
325DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)
326{
327	if(!hHandle || !page)
328		return;
329	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
330	if(!pSDKDoc)
331		return;
332	CPDF_Page* pPage = (CPDF_Page*)page;
333	CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, TRUE);
334	if(pPageView)
335	{
336		pPageView->SetValid(TRUE);
337	}
338}
339
340DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle)
341{
342	if(!hHandle || !page)
343		return;
344	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
345	CPDF_Page* pPage = (CPDF_Page*)page;
346	CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
347	if(pPageView)
348	{
349		pPageView->SetValid(FALSE);
350		// ReMovePageView() takes care of the delete for us.
351		pSDKDoc->ReMovePageView(pPage);
352	}
353}
354DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle)
355{
356	if(!hHandle)
357		return;
358	if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc())
359	{
360		pSDKDoc->InitPageView();
361		if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
362			pSDKDoc->ProcJavascriptFun();
363	}
364}
365
366DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle)
367{
368	if(!hHandle)
369		return;
370	if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc())
371	{
372		if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
373			pSDKDoc->ProcOpenAction();
374	}
375}
376DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaType)
377{
378	if(!hHandle)
379		return;
380	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
381	if(pSDKDoc)
382	{
383		CPDF_Document* pDoc = pSDKDoc->GetDocument();
384		CPDF_Dictionary* pDic = pDoc->GetRoot();
385		if (!pDic)
386			return;
387		CPDF_AAction aa = pDic->GetDict(FX_BSTRC("AA"));
388
389		if(aa.ActionExist((CPDF_AAction::AActionType)aaType))
390		{
391			CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
392			CPDFSDK_ActionHandler *pActionHandler = ((CPDFDoc_Environment*)hHandle)->GetActionHander();
393			ASSERT(pActionHandler != NULL);
394			pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType, pSDKDoc);
395		}
396	}
397}
398DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandle, int aaType)
399{
400	if(!hHandle || !page)
401		return;
402	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
403	CPDF_Page* pPage = (CPDF_Page*)page;
404	CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
405	if(pPageView)
406	{
407		CPDFDoc_Environment *pEnv = pSDKDoc->GetEnv();
408		ASSERT(pEnv != NULL);
409
410		CPDFSDK_ActionHandler *pActionHandler = pEnv->GetActionHander();
411		ASSERT(pActionHandler != NULL);
412
413		CPDF_Dictionary *pPageDict = pPage->m_pFormDict;
414		ASSERT(pPageDict != NULL);
415
416		CPDF_AAction aa = pPageDict->GetDict(FX_BSTRC("AA"));
417
418		FX_BOOL bExistOAAction = FALSE;
419		FX_BOOL bExistCAAction = FALSE;
420		if (FPDFPAGE_AACTION_OPEN == aaType)
421		{
422			bExistOAAction = aa.ActionExist(CPDF_AAction::OpenPage);
423			if (bExistOAAction)
424			{
425				CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);
426				pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, pSDKDoc);
427			}
428		}
429		else
430		{
431			bExistCAAction = aa.ActionExist(CPDF_AAction::ClosePage);
432			if (bExistCAAction)
433			{
434				CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);
435				pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, pSDKDoc);
436			}
437		}
438	}
439}
440
441
442