Revert "FX_BOOL considered harmful, part 2."
[pdfium.git] / fpdfsdk / src / fsdk_mgr.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_ext.h"
8 #include "../../third_party/base/nonstd_unique_ptr.h"
9 #include "../include/fsdk_define.h"
10 #include "../include/fsdk_mgr.h"
11 #include "../include/formfiller/FFL_FormFiller.h"
12 #include "../include/javascript/IJavaScript.h"
13
14 #if _FX_OS_ == _FX_ANDROID_
15 #include "time.h"
16 #else
17 #include <ctime>
18 #endif
19
20 //extern CPDFDoc_Environment* g_pFormFillApp;
21 class CFX_SystemHandler:public IFX_SystemHandler
22 {
23 public:
24     CFX_SystemHandler(CPDFDoc_Environment* pEnv):m_pEnv(pEnv),m_nCharSet(-1) {}
25 public:
26     virtual void                InvalidateRect(FX_HWND hWnd, FX_RECT rect) ;
27     virtual void                OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect);
28
29     virtual FX_BOOL             IsSelectionImplemented();
30
31     virtual CFX_WideString      GetClipboardText(FX_HWND hWnd){return L"";}
32     virtual FX_BOOL             SetClipboardText(FX_HWND hWnd, CFX_WideString string) {return FALSE;}
33
34     virtual void                ClientToScreen(FX_HWND hWnd, int32_t& x, int32_t& y) {}
35     virtual void                ScreenToClient(FX_HWND hWnd, int32_t& x, int32_t& y) {}
36
37     /*cursor style
38     FXCT_ARROW
39     FXCT_NESW
40     FXCT_NWSE
41     FXCT_VBEAM
42     FXCT_HBEAM
43     FXCT_HAND
44     */
45     virtual void                SetCursor(int32_t nCursorType);
46
47     virtual FX_HMENU            CreatePopupMenu() {return NULL;}
48     virtual FX_BOOL             AppendMenuItem(FX_HMENU hMenu, int32_t nIDNewItem, CFX_WideString string) {return FALSE;}
49     virtual FX_BOOL             EnableMenuItem(FX_HMENU hMenu, int32_t nIDItem, FX_BOOL bEnabled) {return FALSE;}
50     virtual int32_t         TrackPopupMenu(FX_HMENU hMenu, int32_t x, int32_t y, FX_HWND hParent) {return -1;}
51     virtual void                DestroyMenu(FX_HMENU hMenu) {}
52
53     virtual CFX_ByteString      GetNativeTrueTypeFont(int32_t nCharset);
54     virtual FX_BOOL             FindNativeTrueTypeFont(int32_t nCharset, CFX_ByteString sFontFaceName);
55     virtual CPDF_Font*          AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc, CFX_ByteString sFontFaceName, uint8_t nCharset);
56
57     virtual int32_t         SetTimer(int32_t uElapse, TimerCallback lpTimerFunc) ;
58     virtual void                KillTimer(int32_t nID) ;
59
60
61     virtual FX_BOOL             IsSHIFTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsSHIFTKeyDown(nFlag);}
62     virtual FX_BOOL             IsCTRLKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsCTRLKeyDown(nFlag);}
63     virtual FX_BOOL             IsALTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsALTKeyDown(nFlag);}
64     virtual FX_BOOL             IsINSERTKeyDown(FX_DWORD nFlag) {return m_pEnv->FFI_IsINSERTKeyDown(nFlag);}
65
66     virtual FX_SYSTEMTIME       GetLocalTime();
67
68     virtual int32_t         GetCharSet() {return m_nCharSet;}
69     virtual void                SetCharSet(int32_t nCharSet) {m_nCharSet = nCharSet;}
70 private:
71     CPDFDoc_Environment* m_pEnv;
72     int     m_nCharSet;
73 };
74
75 void CFX_SystemHandler::SetCursor(int32_t nCursorType)
76 {
77
78     m_pEnv->FFI_SetCursor(nCursorType);
79 }
80
81 void CFX_SystemHandler::InvalidateRect(FX_HWND hWnd, FX_RECT rect)
82 {
83     //g_pFormFillApp->FFI_Invalidate();
84     CPDFSDK_Annot* pSDKAnnot = (CPDFSDK_Annot*)hWnd;
85     CPDF_Page* pPage = NULL;
86     CPDFSDK_PageView* pPageView = NULL;
87     pPageView = pSDKAnnot->GetPageView();
88     pPage = pSDKAnnot->GetPDFPage();
89     if(!pPage || !pPageView)
90         return;
91     CPDF_Matrix page2device;
92     pPageView->GetCurrentMatrix(page2device);
93     CPDF_Matrix device2page;
94     device2page.SetReverse(page2device);
95     FX_FLOAT left, top, right,bottom;
96     device2page.Transform((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, left, top);
97     device2page.Transform((FX_FLOAT)rect.right, (FX_FLOAT)rect.bottom, right, bottom);
98 //  m_pEnv->FFI_DeviceToPage(pPage, rect.left, rect.top, (double*)&left, (double*)&top);
99 //  m_pEnv->FFI_DeviceToPage(pPage, rect.right, rect.bottom, (double*)&right, (double*)&bottom);
100     CPDF_Rect rcPDF(left, bottom, right, top);
101     rcPDF.Normalize();
102
103     m_pEnv->FFI_Invalidate(pPage, rcPDF.left, rcPDF.top, rcPDF.right, rcPDF.bottom);
104 }
105 void CFX_SystemHandler::OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect)
106 {
107     CFFL_FormFiller* pFFL = (CFFL_FormFiller*)pFormFiller;
108     if(pFFL)
109     {
110         CPDF_Point leftbottom = CPDF_Point(rect.left, rect.bottom);
111         CPDF_Point righttop = CPDF_Point(rect.right, rect.top);
112         CPDF_Point ptA = pFFL->PWLtoFFL(leftbottom);
113         CPDF_Point ptB = pFFL->PWLtoFFL(righttop);
114
115
116         CPDFSDK_Annot* pAnnot  = pFFL->GetSDKAnnot();
117         ASSERT(pAnnot);
118         CPDF_Page* pPage = pAnnot->GetPDFPage();
119         ASSERT(pPage);
120         m_pEnv->FFI_OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y);
121     }
122
123 }
124
125 FX_BOOL CFX_SystemHandler::IsSelectionImplemented()
126 {
127     if(m_pEnv)
128     {
129         FPDF_FORMFILLINFO* pInfo = m_pEnv->GetFormFillInfo();
130         if(pInfo && pInfo->FFI_OutputSelectedRect)
131             return TRUE;
132     }
133     return FALSE;
134 }
135
136 CFX_ByteString CFX_SystemHandler::GetNativeTrueTypeFont(int32_t nCharset)
137 {
138     return "";
139 }
140
141 FX_BOOL CFX_SystemHandler::FindNativeTrueTypeFont(int32_t nCharset, CFX_ByteString sFontFaceName)
142 {
143     CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
144     if(pFontMgr)
145     {
146         CFX_FontMapper* pFontMapper = pFontMgr->m_pBuiltinMapper;
147         if(pFontMapper)
148         {
149             int nSize = pFontMapper->m_InstalledTTFonts.GetSize();
150             if(nSize ==0)
151             {
152                 pFontMapper->LoadInstalledFonts();
153                 nSize = pFontMapper->m_InstalledTTFonts.GetSize();
154             }
155
156             for(int i=0; i<nSize; i++)
157             {
158                 if(pFontMapper->m_InstalledTTFonts[i].Compare(sFontFaceName))
159                     return TRUE;
160             }
161         }
162
163     }
164
165     return FALSE;
166 }
167
168 static int CharSet2CP(int charset)
169 {
170     if (charset == 128)
171         return 932;
172     if (charset == 134)
173         return 936;
174     if (charset == 129)
175         return 949;
176     if (charset == 136)
177         return 950;
178     return 0;
179 }
180 CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc, CFX_ByteString sFontFaceName,
181                                                          uint8_t nCharset)
182 {
183     if(pDoc)
184     {
185         CFX_Font* pFXFont = new CFX_Font();
186         pFXFont->LoadSubst(sFontFaceName,TRUE,0,0,0,CharSet2CP(nCharset),FALSE);
187         CPDF_Font* pFont = pDoc->AddFont(pFXFont,nCharset,FALSE);
188         delete pFXFont;
189         return pFont;
190     }
191
192     return NULL;
193 }
194
195
196 int32_t CFX_SystemHandler::SetTimer(int32_t uElapse, TimerCallback lpTimerFunc)
197 {
198     return m_pEnv->FFI_SetTimer(uElapse, lpTimerFunc);
199 }
200 void CFX_SystemHandler::KillTimer(int32_t nID)
201 {
202     m_pEnv->FFI_KillTimer(nID);
203 }
204
205 FX_SYSTEMTIME CFX_SystemHandler::GetLocalTime()
206 {
207     return m_pEnv->FFI_GetLocalTime();
208 }
209
210
211 CJS_RuntimeFactory* GetJSRuntimeFactory()
212 {
213     static CJS_RuntimeFactory s_JSRuntimeFactory;
214     return &s_JSRuntimeFactory;
215 }
216
217 CPDFDoc_Environment::CPDFDoc_Environment(CPDF_Document* pDoc, FPDF_FORMFILLINFO* pFFinfo) :
218     m_pAnnotHandlerMgr(NULL),
219     m_pActionHandler(NULL),
220     m_pJSRuntime(NULL),
221     m_pInfo(pFFinfo),
222     m_pSDKDoc(NULL),
223     m_pPDFDoc(pDoc),
224     m_pIFormFiller(NULL)
225 {
226     m_pSysHandler = new CFX_SystemHandler(this);
227     m_pJSRuntimeFactory = GetJSRuntimeFactory();
228     m_pJSRuntimeFactory->AddRef();
229 }
230
231 CPDFDoc_Environment::~CPDFDoc_Environment()
232 {
233     delete m_pIFormFiller;
234     m_pIFormFiller = NULL;
235     if (m_pJSRuntime && m_pJSRuntimeFactory)
236         m_pJSRuntimeFactory->DeleteJSRuntime(m_pJSRuntime);
237     m_pJSRuntimeFactory->Release();
238
239     delete m_pSysHandler;
240     m_pSysHandler = NULL;
241
242     delete m_pAnnotHandlerMgr;
243     m_pAnnotHandlerMgr = NULL;
244     delete m_pActionHandler;
245     m_pActionHandler = NULL;
246 }
247
248 int CPDFDoc_Environment::JS_appAlert(const FX_WCHAR* Msg, const FX_WCHAR* Title, FX_UINT Type, FX_UINT Icon)
249 {
250     if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert)
251     {
252         CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
253         CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
254         FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
255         FPDF_WIDESTRING pTitle = (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
256         int ret = m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, pMsg, pTitle, Type, Icon);
257         bsMsg.ReleaseBuffer();
258         bsTitle.ReleaseBuffer();
259         return ret;
260     }
261     return -1;
262 }
263
264 int CPDFDoc_Environment::JS_appResponse(const FX_WCHAR* Question, const FX_WCHAR* Title, const FX_WCHAR* Default,
265                                         const FX_WCHAR* cLabel, FPDF_BOOL bPassword, void* response, int length)
266 {
267     if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_response)
268     {
269         CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode();
270         CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
271         CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode();
272         CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode();
273         FPDF_WIDESTRING pQuestion = (FPDF_WIDESTRING)bsQuestion.GetBuffer(bsQuestion.GetLength());
274         FPDF_WIDESTRING pTitle = (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
275         FPDF_WIDESTRING pDefault = (FPDF_WIDESTRING)bsDefault.GetBuffer(bsDefault.GetLength());
276         FPDF_WIDESTRING pLabel = (FPDF_WIDESTRING)bsLabel.GetBuffer(bsLabel.GetLength());
277         int ret = m_pInfo->m_pJsPlatform->app_response(m_pInfo->m_pJsPlatform, pQuestion, pTitle,
278                                                        pDefault, pLabel, bPassword, response, length);
279         bsQuestion.ReleaseBuffer();
280         bsTitle.ReleaseBuffer();
281         bsDefault.ReleaseBuffer();
282         bsLabel.ReleaseBuffer();
283         return ret;
284     }
285     return -1;
286 }
287
288 CFX_WideString CPDFDoc_Environment::JS_fieldBrowse()
289 {
290     if (!m_pInfo ||
291         !m_pInfo->m_pJsPlatform ||
292         !m_pInfo->m_pJsPlatform->Field_browse) {
293         return L"";
294     }
295
296     const int nRequiredLen = m_pInfo->m_pJsPlatform->Field_browse(
297             m_pInfo->m_pJsPlatform, nullptr, 0);
298     if (nRequiredLen <= 0)
299         return L"";
300
301     nonstd::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
302     memset(pBuff.get(), 0, nRequiredLen);
303     const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse(
304             m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
305     if (nActualLen <= 0 || nActualLen > nRequiredLen)
306         return L"";
307
308     CFX_ByteString bsRet = CFX_ByteString(pBuff.get(), nActualLen);
309     CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
310     return wsRet;
311 }
312
313 CFX_WideString CPDFDoc_Environment::JS_docGetFilePath()
314 {
315     if (!m_pInfo ||
316         !m_pInfo->m_pJsPlatform ||
317         !m_pInfo->m_pJsPlatform->Doc_getFilePath) {
318         return L"";
319     }
320
321     const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
322             m_pInfo->m_pJsPlatform, nullptr, 0);
323     if (nRequiredLen <= 0)
324         return L"";
325
326     nonstd::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
327     memset(pBuff.get(), 0, nRequiredLen);
328     const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
329             m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
330     if (nActualLen <= 0 || nActualLen > nRequiredLen)
331         return L"";
332
333     CFX_ByteString bsRet = CFX_ByteString(pBuff.get(), nActualLen);
334     CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
335     return wsRet;
336 }
337
338 void CPDFDoc_Environment::JS_docSubmitForm(void* formData, int length, const FX_WCHAR* URL)
339 {
340     if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_submitForm)
341     {
342         CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode();
343         FPDF_WIDESTRING pDestination = (FPDF_WIDESTRING)bsDestination.GetBuffer(bsDestination.GetLength());
344         m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData, length, pDestination);
345         bsDestination.ReleaseBuffer();
346     }
347 }
348
349 void CPDFDoc_Environment::JS_docmailForm(void* mailData, int length, FPDF_BOOL bUI,
350                                          const FX_WCHAR* To, const FX_WCHAR* Subject,
351                                          const FX_WCHAR* CC, const FX_WCHAR* BCC,
352                                          const FX_WCHAR* Msg)
353 {
354     if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_mail)
355     {
356         CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
357         CFX_ByteString bsCC = CFX_WideString(Subject).UTF16LE_Encode();
358         CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
359         CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
360         CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
361         FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
362         FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
363         FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
364         FPDF_WIDESTRING pSubject = (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
365         FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
366         m_pInfo->m_pJsPlatform->Doc_mail(m_pInfo->m_pJsPlatform, mailData, length, bUI, pTo, pSubject,
367                                          pCC, pBcc, pMsg);
368         bsTo.ReleaseBuffer();
369         bsCC.ReleaseBuffer();
370         bsBcc.ReleaseBuffer();
371         bsSubject.ReleaseBuffer();
372         bsMsg.ReleaseBuffer();
373     }
374 }
375
376 IFXJS_Runtime* CPDFDoc_Environment::GetJSRuntime()
377 {
378     if (!IsJSInitiated())
379         return NULL;
380     if (!m_pJSRuntime)
381         m_pJSRuntime = m_pJSRuntimeFactory->NewJSRuntime(this);
382     return m_pJSRuntime;
383 }
384
385 CPDFSDK_AnnotHandlerMgr* CPDFDoc_Environment::GetAnnotHandlerMgr()
386 {
387     if (!m_pAnnotHandlerMgr)
388         m_pAnnotHandlerMgr = new CPDFSDK_AnnotHandlerMgr(this);
389     return m_pAnnotHandlerMgr;
390 }
391
392 CPDFSDK_ActionHandler* CPDFDoc_Environment::GetActionHander()
393 {
394     if (!m_pActionHandler)
395         m_pActionHandler = new CPDFSDK_ActionHandler(this);
396     return m_pActionHandler;
397 }
398
399 CFFL_IFormFiller* CPDFDoc_Environment::GetIFormFiller()
400 {
401     if (!m_pIFormFiller)
402         m_pIFormFiller = new CFFL_IFormFiller(this);
403     return m_pIFormFiller;
404 }
405
406 CPDFSDK_Document::CPDFSDK_Document(CPDF_Document* pDoc,CPDFDoc_Environment* pEnv) :
407     m_pDoc(pDoc),
408     m_pInterForm(nullptr),
409     m_pFocusAnnot(nullptr),
410     m_pEnv(pEnv),
411     m_pOccontent(nullptr),
412     m_bChangeMask(FALSE)
413 {
414 }
415
416 CPDFSDK_Document::~CPDFSDK_Document()
417 {
418     for (auto& it : m_pageMap)
419         delete it.second;
420     m_pageMap.clear();
421
422     delete m_pInterForm;
423     m_pInterForm = nullptr;
424
425     delete m_pOccontent;
426     m_pOccontent = nullptr;
427 }
428
429 CPDFSDK_PageView* CPDFSDK_Document::GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew)
430 {
431     auto it = m_pageMap.find(pPDFPage);
432     if (it != m_pageMap.end())
433         return it->second;
434
435     if (!ReNew)
436         return nullptr;
437
438     CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pPDFPage);
439     m_pageMap[pPDFPage] = pPageView;
440     // Delay to load all the annotations, to avoid endless loop.
441     pPageView->LoadFXAnnots();
442     return pPageView;
443 }
444
445 CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView()
446 {
447     CPDF_Page* pPage = (CPDF_Page*)m_pEnv->FFI_GetCurrentPage(m_pDoc);
448     return pPage ? GetPageView(pPage, TRUE) : nullptr;
449 }
450
451 CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex)
452 {
453     CPDF_Page* pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc, nIndex);
454     if (!pTempPage)
455         return nullptr;
456
457     auto it = m_pageMap.find(pTempPage);
458     return it->second;
459 }
460
461 void CPDFSDK_Document:: ProcJavascriptFun()
462 {
463     CPDF_Document* pPDFDoc = GetDocument();
464     CPDF_DocJSActions docJS(pPDFDoc);
465     int iCount = docJS.CountJSActions();
466     if (iCount < 1) return;
467     for (int i = 0; i < iCount; i ++)
468     {
469         CFX_ByteString csJSName;
470         CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
471         if(m_pEnv->GetActionHander())
472             m_pEnv->GetActionHander()->DoAction_JavaScript(jsAction,CFX_WideString::FromLocal(csJSName),this);
473     }
474
475 }
476
477 FX_BOOL CPDFSDK_Document::ProcOpenAction()
478 {
479     if(!m_pDoc)
480         return FALSE;
481
482     CPDF_Dictionary* pRoot = m_pDoc->GetRoot();
483     if (!pRoot)
484         return FALSE;
485
486     CPDF_Object* pOpenAction = pRoot->GetDict("OpenAction");
487     if(!pOpenAction)
488         pOpenAction = pRoot->GetArray("OpenAction");
489
490     if(!pOpenAction)
491         return FALSE;
492
493     if(pOpenAction->GetType()==PDFOBJ_ARRAY)
494         return TRUE;
495
496     if(pOpenAction->GetType()==PDFOBJ_DICTIONARY)
497     {
498         CPDF_Dictionary * pDict=(CPDF_Dictionary*)pOpenAction;
499         CPDF_Action action(pDict);
500         if(m_pEnv->GetActionHander())
501             m_pEnv->GetActionHander()->DoAction_DocOpen(action, this);
502         return TRUE;
503     }
504     return FALSE;
505 }
506
507 CPDF_OCContext* CPDFSDK_Document::GetOCContext()
508 {
509     if(!m_pOccontent)
510         m_pOccontent = new CPDF_OCContext(m_pDoc);
511     return m_pOccontent;
512 }
513
514 void CPDFSDK_Document::ReMovePageView(CPDF_Page* pPDFPage)
515 {
516     auto it = m_pageMap.find(pPDFPage);
517     if (it == m_pageMap.end())
518         return;
519
520     CPDFSDK_PageView* pPageView = it->second;
521     if (pPageView->IsLocked())
522         return;
523
524     delete pPageView;
525     m_pageMap.erase(it);
526 }
527
528 CPDF_Page * CPDFSDK_Document::GetPage(int nIndex)
529 {
530     CPDF_Page * pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
531     if(!pTempPage)
532         return NULL;
533     return pTempPage;
534 }
535
536 CPDFSDK_InterForm* CPDFSDK_Document::GetInterForm()
537 {
538     if(!m_pInterForm)
539         m_pInterForm = new CPDFSDK_InterForm(this);
540     return m_pInterForm;
541 }
542
543 void CPDFSDK_Document::UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot)
544 {
545     for (const auto& it : m_pageMap) {
546         CPDFSDK_PageView* pPageView = it.second;
547         if (pPageView != pSender) {
548             pPageView->UpdateView(pAnnot);
549         }
550     }
551 }
552
553 CPDFSDK_Annot* CPDFSDK_Document::GetFocusAnnot()
554 {
555     return m_pFocusAnnot;
556 }
557
558 FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
559 {
560
561     if(m_pFocusAnnot==pAnnot) return TRUE;
562
563     if(m_pFocusAnnot)
564     {
565         if(!KillFocusAnnot(nFlag) ) return FALSE;
566     }
567     CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
568     if(pAnnot && pPageView->IsValid())
569     {
570         CPDFSDK_AnnotHandlerMgr *pAnnotHandler=m_pEnv->GetAnnotHandlerMgr();
571
572         if(pAnnotHandler&&!m_pFocusAnnot)
573         {
574             if (!pAnnotHandler->Annot_OnSetFocus(pAnnot,nFlag))
575                 return FALSE;
576             if(!m_pFocusAnnot)
577             {
578                 m_pFocusAnnot=pAnnot;
579                 return TRUE;
580             }
581         }
582     }
583     return FALSE;
584 }
585
586 FX_BOOL CPDFSDK_Document::KillFocusAnnot(FX_UINT nFlag)
587 {
588     if(m_pFocusAnnot)
589     {
590         CPDFSDK_AnnotHandlerMgr *pAnnotHandler=m_pEnv->GetAnnotHandlerMgr();
591         if(pAnnotHandler)
592         {
593             CPDFSDK_Annot* pFocusAnnot = m_pFocusAnnot;
594             m_pFocusAnnot = NULL;
595             if(pAnnotHandler->Annot_OnKillFocus(pFocusAnnot, nFlag))
596             {
597
598                 if(pFocusAnnot->GetType() == FX_BSTRC("Widget"))
599                 {
600                     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pFocusAnnot;
601                     int nFieldType = pWidget->GetFieldType();
602                     if(FIELDTYPE_TEXTFIELD == nFieldType || FIELDTYPE_COMBOBOX == nFieldType)
603                         m_pEnv->FFI_OnSetFieldInputFocus(NULL, NULL, 0, FALSE);
604                 }
605
606                 if(!m_pFocusAnnot)
607                     return TRUE;
608             }
609             else
610             {
611                 m_pFocusAnnot = pFocusAnnot;
612             }
613         }
614     }
615     return FALSE;
616 }
617
618 void CPDFSDK_Document::OnCloseDocument()
619 {
620     KillFocusAnnot();
621 }
622
623 FX_BOOL CPDFSDK_Document::GetPermissions(int nFlag)
624 {
625     FX_DWORD dwPermissions = m_pDoc->GetUserPermissions();
626     return dwPermissions&nFlag;
627 }
628
629 IFXJS_Runtime * CPDFSDK_Document::GetJsRuntime()
630 {
631     ASSERT(m_pEnv!=NULL);
632     return m_pEnv->GetJSRuntime();
633 }
634
635 CFX_WideString  CPDFSDK_Document::GetPath()
636 {
637     ASSERT(m_pEnv != NULL);
638     return m_pEnv->JS_docGetFilePath();
639 }
640
641
642 CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page):m_page(page),m_pSDKDoc(pSDKDoc)
643 {
644     CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm();
645     if(pInterForm)
646     {
647         CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
648         pPDFInterForm->FixPageFields(page);
649     }
650         m_page->SetPrivateData((void*)m_page, (void*)this, NULL);
651     m_fxAnnotArray.RemoveAll();
652
653     m_bEnterWidget = FALSE;
654     m_bExitWidget = FALSE;
655     m_bOnWidget = FALSE;
656     m_CaptureWidget = NULL;
657     m_bValid = FALSE;
658         m_bLocked = FALSE;
659         m_bTakeOverPage = FALSE;
660 }
661
662 CPDFSDK_PageView::~CPDFSDK_PageView()
663 {
664     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
665     int nAnnotCount = m_fxAnnotArray.GetSize();
666
667     for (int i=0; i<nAnnotCount; i++)
668     {
669         CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
670         //if there is a focused annot on the page, we should kill the focus first.
671         if(pAnnot == m_pSDKDoc->GetFocusAnnot())
672             KillFocusAnnot();
673         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
674         ASSERT(pAnnotHandlerMgr);
675         pAnnotHandlerMgr->ReleaseAnnot(pAnnot);
676     }
677     m_fxAnnotArray.RemoveAll();
678
679         delete m_pAnnotList;
680         m_pAnnotList = NULL;
681
682         m_page->RemovePrivateData((void*)m_page);
683         if(m_bTakeOverPage) {
684             delete m_page;
685         }
686 }
687
688 void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions)
689 {
690     m_curMatrix = *pUser2Device;
691
692     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
693     CPDFSDK_AnnotIterator annotIterator(this, TRUE);
694     CPDFSDK_Annot* pSDKAnnot = nullptr;
695     int index = -1;
696     while ((pSDKAnnot = annotIterator.Next(index))) {
697         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
698         ASSERT(pAnnotHandlerMgr);
699         pAnnotHandlerMgr->Annot_OnDraw(
700             this, pSDKAnnot, pDevice, pUser2Device, 0);
701     }
702 }
703
704 CPDF_Annot* CPDFSDK_PageView::GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
705 {
706
707     int nCount = m_pAnnotList->Count();
708     for(int i = 0 ; i<nCount; i++)
709     {
710         CPDF_Annot* pAnnot = m_pAnnotList->GetAt(i);
711         CFX_FloatRect annotRect;
712         pAnnot->GetRect(annotRect);
713         if(annotRect.Contains(pageX, pageY))
714             return pAnnot;
715     }
716     return NULL;
717 }
718
719 CPDF_Annot* CPDFSDK_PageView::GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
720 {
721
722     int nCount = m_pAnnotList->Count();
723     for(int i = 0 ; i<nCount; i++)
724     {
725         CPDF_Annot* pAnnot = m_pAnnotList->GetAt(i);
726         if(pAnnot->GetSubType() == "Widget")
727         {
728             CFX_FloatRect annotRect;
729             pAnnot->GetRect(annotRect);
730             if(annotRect.Contains(pageX, pageY))
731                 return pAnnot;
732         }
733     }
734     return NULL;
735 }
736
737 CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
738 {
739
740     CPDFSDK_AnnotIterator annotIterator(this, FALSE);
741     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
742     CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
743     CPDFSDK_Annot* pSDKAnnot = NULL;
744     int index = -1;
745     while((pSDKAnnot = annotIterator.Next(index)))
746     {
747         CPDF_Rect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
748         if(rc.Contains(pageX, pageY))
749             return pSDKAnnot;
750     }
751
752     return NULL;
753 }
754
755 CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
756 {
757
758     CPDFSDK_AnnotIterator annotIterator(this, FALSE);
759     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
760     CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
761     CPDFSDK_Annot* pSDKAnnot = NULL;
762     int index = -1;
763     while((pSDKAnnot = annotIterator.Next(index)))
764     {
765         if(pSDKAnnot->GetType() == "Widget")
766         {
767             pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
768             CPDF_Point point(pageX, pageY);
769             if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot, point))
770                 return pSDKAnnot;
771         }
772     }
773
774     return NULL;
775 }
776
777
778 FX_BOOL CPDFSDK_PageView::Annot_HasAppearance(CPDF_Annot* pAnnot)
779 {
780     CPDF_Dictionary* pAnnotDic = pAnnot->GetAnnotDict();
781     if(pAnnotDic)
782         return  pAnnotDic->KeyExist("AS");
783     return FALSE;
784 }
785
786 CPDFSDK_Annot*  CPDFSDK_PageView::AddAnnot(CPDF_Annot * pPDFAnnot)
787 {
788     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
789     ASSERT(pEnv);
790     CPDFSDK_AnnotHandlerMgr * pAnnotHandler= pEnv->GetAnnotHandlerMgr();
791
792     CPDFSDK_Annot* pSDKAnnot =NULL;
793
794     if(pAnnotHandler)
795     {
796         pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
797     }
798     if(!pSDKAnnot)
799         return NULL;
800
801     m_fxAnnotArray.Add(pSDKAnnot);
802
803     if(pAnnotHandler)
804     {
805         pAnnotHandler->Annot_OnCreate(pSDKAnnot);
806
807     }
808
809      return pSDKAnnot;
810 }
811
812 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Dictionary * pDict)
813 {
814     return pDict ? AddAnnot(pDict->GetString("Subtype"), pDict) : nullptr;
815 }
816
817 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(const FX_CHAR* lpSubType,CPDF_Dictionary * pDict)
818 {
819     return NULL;
820 }
821
822 FX_BOOL  CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot)
823 {
824     return FALSE;
825 }
826
827 CPDF_Document* CPDFSDK_PageView::GetPDFDocument()
828 {
829     if(m_page)
830     {
831         return m_page->m_pDocument;
832     }
833     return NULL;
834 }
835
836 int CPDFSDK_PageView::CountAnnots()
837 {
838     return m_pAnnotList->Count();
839 }
840
841 CPDFSDK_Annot*  CPDFSDK_PageView::GetAnnot(int nIndex)
842 {
843     int nCount = m_fxAnnotArray.GetSize();
844     if ( nIndex < 0 || nIndex >= nCount )
845     {
846         return NULL;
847     }
848
849     return (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(nIndex);
850 }
851
852 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary * pDict)
853 {
854     int nCount = m_fxAnnotArray.GetSize();
855     for(int i=0; i<nCount; i++)
856     {
857         CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
858         if (pDict == pAnnot->GetPDFAnnot()->GetAnnotDict())
859             return pAnnot;
860     }
861     return NULL;
862 }
863
864 FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag)
865 {
866     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
867     ASSERT(pEnv);
868     CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
869     if(!pFXAnnot)
870     {
871         KillFocusAnnot(nFlag);
872     }
873     else
874     {
875         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
876         ASSERT(pAnnotHandlerMgr);
877
878         FX_BOOL bRet = pAnnotHandlerMgr->Annot_OnLButtonDown(this, pFXAnnot, nFlag,point);
879         if(bRet)
880         {
881             SetFocusAnnot(pFXAnnot);
882         }
883         return bRet;
884     }
885     return FALSE;
886 }
887
888
889 FX_BOOL CPDFSDK_PageView::OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag)
890 {
891     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
892     ASSERT(pEnv);
893     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
894     ASSERT(pAnnotHandlerMgr);
895     CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
896     CPDFSDK_Annot* pFocusAnnot = GetFocusAnnot();
897     FX_BOOL bRet  = FALSE;
898     if(pFocusAnnot && pFocusAnnot != pFXAnnot)
899     {
900         //Last focus Annot gets a chance to handle the event.
901         bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFocusAnnot, nFlag,point);
902     }
903     if(pFXAnnot && !bRet)
904     {
905         bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFXAnnot, nFlag,point);
906         return bRet;
907     }
908     return bRet;
909 }
910
911 FX_BOOL CPDFSDK_PageView::OnMouseMove(const CPDF_Point & point, int nFlag)
912 {
913
914     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
915     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
916     ASSERT(pAnnotHandlerMgr);
917     if(CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y))
918     {
919         if(m_CaptureWidget && m_CaptureWidget != pFXAnnot)
920         {
921             m_bExitWidget = TRUE;
922             m_bEnterWidget = FALSE;
923             pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
924         }
925         m_CaptureWidget = (CPDFSDK_Widget*)pFXAnnot;
926         m_bOnWidget = TRUE;
927         if(!m_bEnterWidget)
928         {
929             m_bEnterWidget = TRUE;
930             m_bExitWidget = FALSE;
931             pAnnotHandlerMgr->Annot_OnMouseEnter(this, pFXAnnot,nFlag);
932         }
933         pAnnotHandlerMgr->Annot_OnMouseMove(this, pFXAnnot, nFlag, point);
934         return TRUE;
935     }
936     if(m_bOnWidget)
937     {
938         m_bOnWidget = FALSE;
939         m_bExitWidget = TRUE;
940         m_bEnterWidget = FALSE;
941         if(m_CaptureWidget)
942         {
943             pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
944             m_CaptureWidget = NULL;
945         }
946     }
947     return FALSE;
948 }
949
950 FX_BOOL CPDFSDK_PageView::OnMouseWheel(double deltaX, double deltaY,const CPDF_Point& point, int nFlag)
951 {
952     if(CPDFSDK_Annot* pAnnot = GetFXWidgetAtPoint(point.x, point.y))
953     {
954         CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
955         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
956         ASSERT(pAnnotHandlerMgr);
957         return pAnnotHandlerMgr->Annot_OnMouseWheel(this, pAnnot, nFlag, (int)deltaY, point);
958     }
959     return FALSE;
960
961 }
962
963 FX_BOOL CPDFSDK_PageView::OnChar(int nChar, FX_UINT nFlag)
964 {
965     if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
966     {
967         CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
968         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
969         ASSERT(pAnnotHandlerMgr);
970         return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
971     }
972
973     return FALSE;
974 }
975
976 FX_BOOL CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag)
977 {
978     if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
979     {
980         CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
981         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
982         ASSERT(pAnnotHandlerMgr);
983         return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
984     }
985     return FALSE;
986 }
987
988 FX_BOOL CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag)
989 {
990 //  if(CPDFSDK_Annot* pAnnot = GetFocusAnnot())
991 //  {
992 //      CFFL_IFormFiller* pIFormFiller = g_pFormFillApp->GetIFormFiller();
993 //      return pIFormFiller->OnKeyUp(pAnnot, nKeyCode, nFlag);
994 //  }
995     return FALSE;
996 }
997
998 extern void CheckUnSupportAnnot(CPDF_Document * pDoc, CPDF_Annot* pPDFAnnot);
999
1000 void CPDFSDK_PageView::LoadFXAnnots()
1001 {
1002     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
1003
1004     FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
1005     //Disable the default AP construction.
1006     CPDF_InterForm::EnableUpdateAP(FALSE);
1007     m_pAnnotList = new CPDF_AnnotList(m_page);
1008     CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
1009     int nCount = m_pAnnotList->Count();
1010         SetLock(TRUE);
1011     for(int i=0; i<nCount; i++)
1012     {
1013         CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
1014         CPDF_Document * pDoc = GetPDFDocument();
1015
1016         CheckUnSupportAnnot(pDoc, pPDFAnnot);
1017
1018         CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
1019         ASSERT(pAnnotHandlerMgr != NULL);
1020
1021         if(pAnnotHandlerMgr)
1022         {
1023             CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
1024             if(!pAnnot)
1025                 continue;
1026             m_fxAnnotArray.Add(pAnnot);
1027
1028             pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
1029         }
1030
1031     }
1032         SetLock(FALSE);
1033 }
1034
1035 void    CPDFSDK_PageView::UpdateRects(CFX_RectArray& rects)
1036 {
1037     for(int i=0; i<rects.GetSize(); i++)
1038     {
1039         CPDF_Rect rc = rects.GetAt(i);
1040         CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
1041         pEnv->FFI_Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom);
1042     }
1043 }
1044
1045 void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot)
1046 {
1047     CPDF_Rect rcWindow = pAnnot->GetRect();
1048     CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
1049     pEnv->FFI_Invalidate(
1050         m_page, rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
1051 }
1052
1053 int CPDFSDK_PageView::GetPageIndex()
1054 {
1055     if(m_page)
1056     {
1057         CPDF_Dictionary* pDic = m_page->m_pFormDict;
1058         CPDF_Document* pDoc = m_pSDKDoc->GetDocument();
1059         if(pDoc && pDic)
1060         {
1061             return pDoc->GetPageIndex(pDic->GetObjNum());
1062         }
1063     }
1064     return -1;
1065 }
1066
1067 FX_BOOL CPDFSDK_PageView::IsValidAnnot(void* p)
1068 {
1069     if (p == NULL) return FALSE;
1070     int iCount = m_pAnnotList->Count();
1071     for (int i = 0; i < iCount; i++)
1072     {
1073         if (m_pAnnotList->GetAt(i) == p)
1074             return TRUE;
1075     }
1076     return FALSE;
1077 }
1078
1079
1080 CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot()
1081 {
1082     CPDFSDK_Annot* pFocusAnnot = m_pSDKDoc->GetFocusAnnot();
1083     if(!pFocusAnnot)
1084         return NULL;
1085
1086     for(int i=0; i<m_fxAnnotArray.GetSize(); i++)
1087     {
1088         CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
1089         if(pAnnot == pFocusAnnot)
1090             return pAnnot;
1091     }
1092     return NULL;
1093 }