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