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