OLD | NEW |
| (Empty) |
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 "fpdfsdk/include/fsdk_mgr.h" | |
8 | |
9 #include <algorithm> | |
10 #include <memory> | |
11 | |
12 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" | |
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | |
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | |
15 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" | |
16 #include "core/fpdfdoc/include/cpdf_docjsactions.h" | |
17 #include "core/fpdfdoc/include/cpdf_interform.h" | |
18 #include "core/fxcrt/include/cfx_retain_ptr.h" | |
19 #include "core/fxge/include/cfx_renderdevice.h" | |
20 #include "fpdfsdk/formfiller/cffl_formfiller.h" | |
21 #include "fpdfsdk/include/cpdfsdk_annothandlermgr.h" | |
22 #include "fpdfsdk/include/cpdfsdk_annotiterator.h" | |
23 #include "fpdfsdk/include/cpdfsdk_interform.h" | |
24 #include "fpdfsdk/include/cpdfsdk_widget.h" | |
25 #include "fpdfsdk/include/fsdk_define.h" | |
26 #include "fpdfsdk/include/ipdfsdk_annothandler.h" | |
27 #include "fpdfsdk/javascript/ijs_runtime.h" | |
28 #include "public/fpdf_ext.h" | |
29 #include "third_party/base/stl_util.h" | |
30 | |
31 #ifdef PDF_ENABLE_XFA | |
32 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_app.h" | |
33 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h" | |
34 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_page.h" | |
35 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h" | |
36 #include "xfa/fxfa/include/xfa_ffdocview.h" | |
37 #include "xfa/fxfa/include/xfa_ffpageview.h" | |
38 #include "xfa/fxfa/include/xfa_ffwidgethandler.h" | |
39 #include "xfa/fxfa/include/xfa_rendercontext.h" | |
40 #include "xfa/fxgraphics/include/cfx_graphics.h" | |
41 #endif // PDF_ENABLE_XFA | |
42 | |
43 #if _FX_OS_ == _FX_ANDROID_ | |
44 #include "time.h" | |
45 #else | |
46 #include <ctime> | |
47 #endif | |
48 | |
49 namespace { | |
50 | |
51 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken | |
52 // since modifying the result would impact |bsUTF16LE|. | |
53 FPDF_WIDESTRING AsFPDFWideString(CFX_ByteString* bsUTF16LE) { | |
54 return reinterpret_cast<FPDF_WIDESTRING>( | |
55 bsUTF16LE->GetBuffer(bsUTF16LE->GetLength())); | |
56 } | |
57 | |
58 } // namespace | |
59 | |
60 CPDFDoc_Environment::CPDFDoc_Environment(UnderlyingDocumentType* pDoc, | |
61 FPDF_FORMFILLINFO* pFFinfo) | |
62 : m_pInfo(pFFinfo), m_pSDKDoc(nullptr), m_pUnderlyingDoc(pDoc) { | |
63 m_pSysHandler.reset(new CFX_SystemHandler(this)); | |
64 } | |
65 | |
66 CPDFDoc_Environment::~CPDFDoc_Environment() { | |
67 #ifdef PDF_ENABLE_XFA | |
68 CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance(); | |
69 if (pProvider->m_pEnvList.GetSize() == 0) | |
70 pProvider->SetJavaScriptInitialized(FALSE); | |
71 #endif // PDF_ENABLE_XFA | |
72 if (m_pInfo && m_pInfo->Release) | |
73 m_pInfo->Release(m_pInfo); | |
74 } | |
75 | |
76 int CPDFDoc_Environment::JS_appAlert(const FX_WCHAR* Msg, | |
77 const FX_WCHAR* Title, | |
78 FX_UINT Type, | |
79 FX_UINT Icon) { | |
80 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
81 !m_pInfo->m_pJsPlatform->app_alert) { | |
82 return -1; | |
83 } | |
84 CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode(); | |
85 CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode(); | |
86 return m_pInfo->m_pJsPlatform->app_alert( | |
87 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsMsg), | |
88 AsFPDFWideString(&bsTitle), Type, Icon); | |
89 } | |
90 | |
91 int CPDFDoc_Environment::JS_appResponse(const FX_WCHAR* Question, | |
92 const FX_WCHAR* Title, | |
93 const FX_WCHAR* Default, | |
94 const FX_WCHAR* cLabel, | |
95 FPDF_BOOL bPassword, | |
96 void* response, | |
97 int length) { | |
98 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
99 !m_pInfo->m_pJsPlatform->app_response) { | |
100 return -1; | |
101 } | |
102 CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode(); | |
103 CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode(); | |
104 CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode(); | |
105 CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode(); | |
106 return m_pInfo->m_pJsPlatform->app_response( | |
107 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsQuestion), | |
108 AsFPDFWideString(&bsTitle), AsFPDFWideString(&bsDefault), | |
109 AsFPDFWideString(&bsLabel), bPassword, response, length); | |
110 } | |
111 | |
112 void CPDFDoc_Environment::JS_appBeep(int nType) { | |
113 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
114 !m_pInfo->m_pJsPlatform->app_beep) { | |
115 return; | |
116 } | |
117 m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType); | |
118 } | |
119 | |
120 CFX_WideString CPDFDoc_Environment::JS_fieldBrowse() { | |
121 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
122 !m_pInfo->m_pJsPlatform->Field_browse) { | |
123 return CFX_WideString(); | |
124 } | |
125 const int nRequiredLen = | |
126 m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0); | |
127 if (nRequiredLen <= 0) | |
128 return CFX_WideString(); | |
129 | |
130 std::unique_ptr<char[]> pBuff(new char[nRequiredLen]); | |
131 memset(pBuff.get(), 0, nRequiredLen); | |
132 const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse( | |
133 m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen); | |
134 if (nActualLen <= 0 || nActualLen > nRequiredLen) | |
135 return CFX_WideString(); | |
136 | |
137 return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen)); | |
138 } | |
139 | |
140 CFX_WideString CPDFDoc_Environment::JS_docGetFilePath() { | |
141 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
142 !m_pInfo->m_pJsPlatform->Doc_getFilePath) { | |
143 return CFX_WideString(); | |
144 } | |
145 const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath( | |
146 m_pInfo->m_pJsPlatform, nullptr, 0); | |
147 if (nRequiredLen <= 0) | |
148 return CFX_WideString(); | |
149 | |
150 std::unique_ptr<char[]> pBuff(new char[nRequiredLen]); | |
151 memset(pBuff.get(), 0, nRequiredLen); | |
152 const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath( | |
153 m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen); | |
154 if (nActualLen <= 0 || nActualLen > nRequiredLen) | |
155 return CFX_WideString(); | |
156 | |
157 return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen)); | |
158 } | |
159 | |
160 void CPDFDoc_Environment::JS_docSubmitForm(void* formData, | |
161 int length, | |
162 const FX_WCHAR* URL) { | |
163 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
164 !m_pInfo->m_pJsPlatform->Doc_submitForm) { | |
165 return; | |
166 } | |
167 CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode(); | |
168 m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData, | |
169 length, | |
170 AsFPDFWideString(&bsDestination)); | |
171 } | |
172 | |
173 void CPDFDoc_Environment::JS_docmailForm(void* mailData, | |
174 int length, | |
175 FPDF_BOOL bUI, | |
176 const FX_WCHAR* To, | |
177 const FX_WCHAR* Subject, | |
178 const FX_WCHAR* CC, | |
179 const FX_WCHAR* BCC, | |
180 const FX_WCHAR* Msg) { | |
181 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
182 !m_pInfo->m_pJsPlatform->Doc_mail) { | |
183 return; | |
184 } | |
185 CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode(); | |
186 CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode(); | |
187 CFX_ByteString bsCC = CFX_WideString(CC).UTF16LE_Encode(); | |
188 CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode(); | |
189 CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode(); | |
190 m_pInfo->m_pJsPlatform->Doc_mail( | |
191 m_pInfo->m_pJsPlatform, mailData, length, bUI, AsFPDFWideString(&bsTo), | |
192 AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC), | |
193 AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg)); | |
194 } | |
195 | |
196 void CPDFDoc_Environment::JS_docprint(FPDF_BOOL bUI, | |
197 int nStart, | |
198 int nEnd, | |
199 FPDF_BOOL bSilent, | |
200 FPDF_BOOL bShrinkToFit, | |
201 FPDF_BOOL bPrintAsImage, | |
202 FPDF_BOOL bReverse, | |
203 FPDF_BOOL bAnnotations) { | |
204 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
205 !m_pInfo->m_pJsPlatform->Doc_print) { | |
206 return; | |
207 } | |
208 m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd, | |
209 bSilent, bShrinkToFit, bPrintAsImage, | |
210 bReverse, bAnnotations); | |
211 } | |
212 | |
213 void CPDFDoc_Environment::JS_docgotoPage(int nPageNum) { | |
214 if (!m_pInfo || !m_pInfo->m_pJsPlatform || | |
215 !m_pInfo->m_pJsPlatform->Doc_gotoPage) { | |
216 return; | |
217 } | |
218 m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum); | |
219 } | |
220 | |
221 IJS_Runtime* CPDFDoc_Environment::GetJSRuntime() { | |
222 if (!IsJSInitiated()) | |
223 return nullptr; | |
224 if (!m_pJSRuntime) | |
225 m_pJSRuntime.reset(IJS_Runtime::Create(this)); | |
226 return m_pJSRuntime.get(); | |
227 } | |
228 | |
229 CPDFSDK_AnnotHandlerMgr* CPDFDoc_Environment::GetAnnotHandlerMgr() { | |
230 if (!m_pAnnotHandlerMgr) | |
231 m_pAnnotHandlerMgr.reset(new CPDFSDK_AnnotHandlerMgr(this)); | |
232 return m_pAnnotHandlerMgr.get(); | |
233 } | |
234 | |
235 CPDFSDK_ActionHandler* CPDFDoc_Environment::GetActionHander() { | |
236 if (!m_pActionHandler) | |
237 m_pActionHandler.reset(new CPDFSDK_ActionHandler()); | |
238 return m_pActionHandler.get(); | |
239 } | |
240 | |
241 CFFL_IFormFiller* CPDFDoc_Environment::GetIFormFiller() { | |
242 if (!m_pIFormFiller) | |
243 m_pIFormFiller.reset(new CFFL_IFormFiller(this)); | |
244 return m_pIFormFiller.get(); | |
245 } | |
246 | |
247 // static | |
248 CPDFSDK_Document* CPDFSDK_Document::FromFPDFFormHandle( | |
249 FPDF_FORMHANDLE hHandle) { | |
250 CPDFDoc_Environment* pEnv = static_cast<CPDFDoc_Environment*>(hHandle); | |
251 return pEnv ? pEnv->GetSDKDocument() : nullptr; | |
252 } | |
253 | |
254 CPDFSDK_Document::CPDFSDK_Document(UnderlyingDocumentType* pDoc, | |
255 CPDFDoc_Environment* pEnv) | |
256 : m_pDoc(pDoc), | |
257 m_pFocusAnnot(nullptr), | |
258 m_pEnv(pEnv), | |
259 m_bChangeMask(FALSE), | |
260 m_bBeingDestroyed(FALSE) {} | |
261 | |
262 CPDFSDK_Document::~CPDFSDK_Document() { | |
263 m_bBeingDestroyed = TRUE; | |
264 | |
265 for (auto& it : m_pageMap) | |
266 it.second->KillFocusAnnotIfNeeded(); | |
267 | |
268 for (auto& it : m_pageMap) | |
269 delete it.second; | |
270 m_pageMap.clear(); | |
271 } | |
272 | |
273 CPDFSDK_PageView* CPDFSDK_Document::GetPageView( | |
274 UnderlyingPageType* pUnderlyingPage, | |
275 bool ReNew) { | |
276 auto it = m_pageMap.find(pUnderlyingPage); | |
277 if (it != m_pageMap.end()) | |
278 return it->second; | |
279 | |
280 if (!ReNew) | |
281 return nullptr; | |
282 | |
283 CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage); | |
284 m_pageMap[pUnderlyingPage] = pPageView; | |
285 // Delay to load all the annotations, to avoid endless loop. | |
286 pPageView->LoadFXAnnots(); | |
287 return pPageView; | |
288 } | |
289 | |
290 CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView() { | |
291 UnderlyingPageType* pPage = | |
292 UnderlyingFromFPDFPage(m_pEnv->FFI_GetCurrentPage(m_pDoc)); | |
293 return pPage ? GetPageView(pPage, true) : nullptr; | |
294 } | |
295 | |
296 CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex) { | |
297 UnderlyingPageType* pTempPage = | |
298 UnderlyingFromFPDFPage(m_pEnv->FFI_GetPage(m_pDoc, nIndex)); | |
299 if (!pTempPage) | |
300 return nullptr; | |
301 | |
302 auto it = m_pageMap.find(pTempPage); | |
303 return it != m_pageMap.end() ? it->second : nullptr; | |
304 } | |
305 | |
306 void CPDFSDK_Document::ProcJavascriptFun() { | |
307 CPDF_Document* pPDFDoc = GetPDFDocument(); | |
308 CPDF_DocJSActions docJS(pPDFDoc); | |
309 int iCount = docJS.CountJSActions(); | |
310 if (iCount < 1) | |
311 return; | |
312 for (int i = 0; i < iCount; i++) { | |
313 CFX_ByteString csJSName; | |
314 CPDF_Action jsAction = docJS.GetJSAction(i, csJSName); | |
315 if (m_pEnv->GetActionHander()) | |
316 m_pEnv->GetActionHander()->DoAction_JavaScript( | |
317 jsAction, CFX_WideString::FromLocal(csJSName.AsStringC()), this); | |
318 } | |
319 } | |
320 | |
321 FX_BOOL CPDFSDK_Document::ProcOpenAction() { | |
322 if (!m_pDoc) | |
323 return FALSE; | |
324 | |
325 CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot(); | |
326 if (!pRoot) | |
327 return FALSE; | |
328 | |
329 CPDF_Object* pOpenAction = pRoot->GetDictBy("OpenAction"); | |
330 if (!pOpenAction) | |
331 pOpenAction = pRoot->GetArrayBy("OpenAction"); | |
332 | |
333 if (!pOpenAction) | |
334 return FALSE; | |
335 | |
336 if (pOpenAction->IsArray()) | |
337 return TRUE; | |
338 | |
339 if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) { | |
340 CPDF_Action action(pDict); | |
341 if (m_pEnv->GetActionHander()) | |
342 m_pEnv->GetActionHander()->DoAction_DocOpen(action, this); | |
343 return TRUE; | |
344 } | |
345 return FALSE; | |
346 } | |
347 | |
348 CPDF_OCContext* CPDFSDK_Document::GetOCContext() { | |
349 if (!m_pOccontent) { | |
350 m_pOccontent.reset( | |
351 new CPDF_OCContext(GetPDFDocument(), CPDF_OCContext::View)); | |
352 } | |
353 return m_pOccontent.get(); | |
354 } | |
355 | |
356 void CPDFSDK_Document::RemovePageView(UnderlyingPageType* pUnderlyingPage) { | |
357 auto it = m_pageMap.find(pUnderlyingPage); | |
358 if (it == m_pageMap.end()) | |
359 return; | |
360 | |
361 CPDFSDK_PageView* pPageView = it->second; | |
362 if (pPageView->IsLocked()) | |
363 return; | |
364 | |
365 // This must happen before we remove |pPageView| from the map because | |
366 // |KillFocusAnnotIfNeeded| can call into the |GetPage| method which will | |
367 // look for this page view in the map, if it doesn't find it a new one will | |
368 // be created. We then have two page views pointing to the same page and | |
369 // bad things happen. | |
370 pPageView->KillFocusAnnotIfNeeded(); | |
371 | |
372 // Remove the page from the map to make sure we don't accidentally attempt | |
373 // to use the |pPageView| while we're cleaning it up. | |
374 m_pageMap.erase(it); | |
375 | |
376 delete pPageView; | |
377 } | |
378 | |
379 UnderlyingPageType* CPDFSDK_Document::GetPage(int nIndex) { | |
380 return UnderlyingFromFPDFPage(m_pEnv->FFI_GetPage(m_pDoc, nIndex)); | |
381 } | |
382 | |
383 CPDFSDK_InterForm* CPDFSDK_Document::GetInterForm() { | |
384 if (!m_pInterForm) | |
385 m_pInterForm.reset(new CPDFSDK_InterForm(this)); | |
386 return m_pInterForm.get(); | |
387 } | |
388 | |
389 void CPDFSDK_Document::UpdateAllViews(CPDFSDK_PageView* pSender, | |
390 CPDFSDK_Annot* pAnnot) { | |
391 for (const auto& it : m_pageMap) { | |
392 CPDFSDK_PageView* pPageView = it.second; | |
393 if (pPageView != pSender) { | |
394 pPageView->UpdateView(pAnnot); | |
395 } | |
396 } | |
397 } | |
398 | |
399 CPDFSDK_Annot* CPDFSDK_Document::GetFocusAnnot() { | |
400 return m_pFocusAnnot; | |
401 } | |
402 | |
403 FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) { | |
404 if (m_bBeingDestroyed) | |
405 return FALSE; | |
406 | |
407 if (m_pFocusAnnot == pAnnot) | |
408 return TRUE; | |
409 | |
410 if (m_pFocusAnnot) { | |
411 if (!KillFocusAnnot(nFlag)) | |
412 return FALSE; | |
413 } | |
414 | |
415 if (!pAnnot) | |
416 return FALSE; | |
417 | |
418 #ifdef PDF_ENABLE_XFA | |
419 CPDFSDK_Annot* pLastFocusAnnot = m_pFocusAnnot; | |
420 #endif // PDF_ENABLE_XFA | |
421 CPDFSDK_PageView* pPageView = pAnnot->GetPageView(); | |
422 if (pPageView && pPageView->IsValid()) { | |
423 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pEnv->GetAnnotHandlerMgr(); | |
424 if (!m_pFocusAnnot) { | |
425 #ifdef PDF_ENABLE_XFA | |
426 if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, pLastFocusAnnot)) | |
427 return FALSE; | |
428 #endif // PDF_ENABLE_XFA | |
429 if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, nFlag)) | |
430 return FALSE; | |
431 if (!m_pFocusAnnot) { | |
432 m_pFocusAnnot = pAnnot; | |
433 return TRUE; | |
434 } | |
435 } | |
436 } | |
437 return FALSE; | |
438 } | |
439 | |
440 FX_BOOL CPDFSDK_Document::KillFocusAnnot(FX_UINT nFlag) { | |
441 if (m_pFocusAnnot) { | |
442 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pEnv->GetAnnotHandlerMgr(); | |
443 CPDFSDK_Annot* pFocusAnnot = m_pFocusAnnot; | |
444 m_pFocusAnnot = nullptr; | |
445 | |
446 #ifdef PDF_ENABLE_XFA | |
447 if (!pAnnotHandler->Annot_OnChangeFocus(nullptr, pFocusAnnot)) | |
448 return FALSE; | |
449 #endif // PDF_ENABLE_XFA | |
450 | |
451 if (pAnnotHandler->Annot_OnKillFocus(pFocusAnnot, nFlag)) { | |
452 if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) { | |
453 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pFocusAnnot; | |
454 int nFieldType = pWidget->GetFieldType(); | |
455 if (FIELDTYPE_TEXTFIELD == nFieldType || | |
456 FIELDTYPE_COMBOBOX == nFieldType) { | |
457 m_pEnv->FFI_OnSetFieldInputFocus(nullptr, nullptr, 0, FALSE); | |
458 } | |
459 } | |
460 | |
461 if (!m_pFocusAnnot) | |
462 return TRUE; | |
463 } else { | |
464 m_pFocusAnnot = pFocusAnnot; | |
465 } | |
466 } | |
467 return FALSE; | |
468 } | |
469 | |
470 void CPDFSDK_Document::OnCloseDocument() { | |
471 KillFocusAnnot(); | |
472 } | |
473 | |
474 FX_BOOL CPDFSDK_Document::GetPermissions(int nFlag) { | |
475 return GetPDFDocument()->GetUserPermissions() & nFlag; | |
476 } | |
477 | |
478 IJS_Runtime* CPDFSDK_Document::GetJsRuntime() { | |
479 return m_pEnv->GetJSRuntime(); | |
480 } | |
481 | |
482 CFX_WideString CPDFSDK_Document::GetPath() { | |
483 return m_pEnv->JS_docGetFilePath(); | |
484 } | |
485 | |
486 CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc, | |
487 UnderlyingPageType* page) | |
488 : m_page(page), | |
489 m_pSDKDoc(pSDKDoc), | |
490 m_CaptureWidget(nullptr), | |
491 #ifndef PDF_ENABLE_XFA | |
492 m_bOwnsPage(false), | |
493 #endif // PDF_ENABLE_XFA | |
494 m_bEnterWidget(FALSE), | |
495 m_bExitWidget(FALSE), | |
496 m_bOnWidget(FALSE), | |
497 m_bValid(FALSE), | |
498 m_bLocked(FALSE) { | |
499 CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm(); | |
500 if (pInterForm) { | |
501 CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm(); | |
502 #ifdef PDF_ENABLE_XFA | |
503 if (page->GetPDFPage()) | |
504 pPDFInterForm->FixPageFields(page->GetPDFPage()); | |
505 #else // PDF_ENABLE_XFA | |
506 pPDFInterForm->FixPageFields(page); | |
507 #endif // PDF_ENABLE_XFA | |
508 } | |
509 #ifndef PDF_ENABLE_XFA | |
510 m_page->SetView(this); | |
511 #endif // PDF_ENABLE_XFA | |
512 } | |
513 | |
514 CPDFSDK_PageView::~CPDFSDK_PageView() { | |
515 #ifndef PDF_ENABLE_XFA | |
516 // The call to |ReleaseAnnot| can cause the page pointed to by |m_page| to | |
517 // be freed, which will cause issues if we try to cleanup the pageview pointer | |
518 // in |m_page|. So, reset the pageview pointer before doing anything else. | |
519 m_page->SetView(nullptr); | |
520 #endif // PDF_ENABLE_XFA | |
521 | |
522 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
523 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
524 for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) | |
525 pAnnotHandlerMgr->ReleaseAnnot(pAnnot); | |
526 | |
527 m_fxAnnotArray.clear(); | |
528 m_pAnnotList.reset(); | |
529 | |
530 #ifndef PDF_ENABLE_XFA | |
531 if (m_bOwnsPage) | |
532 delete m_page; | |
533 #endif // PDF_ENABLE_XFA | |
534 } | |
535 | |
536 void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, | |
537 CFX_Matrix* pUser2Device, | |
538 #ifdef PDF_ENABLE_XFA | |
539 CPDF_RenderOptions* pOptions, | |
540 const FX_RECT& pClip) { | |
541 #else | |
542 CPDF_RenderOptions* pOptions) { | |
543 #endif // PDF_ENABLE_XFA | |
544 m_curMatrix = *pUser2Device; | |
545 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
546 | |
547 #ifdef PDF_ENABLE_XFA | |
548 CPDFXFA_Page* pPage = GetPDFXFAPage(); | |
549 if (!pPage) | |
550 return; | |
551 | |
552 if (pPage->GetDocument()->GetDocType() == DOCTYPE_DYNAMIC_XFA) { | |
553 CFX_Graphics gs; | |
554 gs.Create(pDevice); | |
555 CFX_RectF rectClip; | |
556 rectClip.Set(static_cast<FX_FLOAT>(pClip.left), | |
557 static_cast<FX_FLOAT>(pClip.top), | |
558 static_cast<FX_FLOAT>(pClip.Width()), | |
559 static_cast<FX_FLOAT>(pClip.Height())); | |
560 gs.SetClipRect(rectClip); | |
561 std::unique_ptr<CXFA_RenderContext> pRenderContext(new CXFA_RenderContext); | |
562 CXFA_RenderOptions renderOptions; | |
563 renderOptions.m_bHighlight = TRUE; | |
564 CXFA_FFPageView* xfaView = pPage->GetXFAPageView(); | |
565 pRenderContext->StartRender(xfaView, &gs, *pUser2Device, renderOptions); | |
566 pRenderContext->DoRender(); | |
567 pRenderContext->StopRender(); | |
568 CXFA_FFDocView* docView = xfaView->GetDocView(); | |
569 if (!docView) | |
570 return; | |
571 CPDFSDK_Annot* annot = GetFocusAnnot(); | |
572 if (!annot) | |
573 return; | |
574 // Render the focus widget | |
575 docView->GetWidgetHandler()->RenderWidget(annot->GetXFAWidget(), &gs, | |
576 pUser2Device, FALSE); | |
577 return; | |
578 } | |
579 #endif // PDF_ENABLE_XFA | |
580 | |
581 // for pdf/static xfa. | |
582 CPDFSDK_AnnotIterator annotIterator(this, true); | |
583 while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) { | |
584 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
585 pAnnotHandlerMgr->Annot_OnDraw(this, pSDKAnnot, pDevice, pUser2Device, | |
586 pOptions->m_bDrawAnnots); | |
587 } | |
588 } | |
589 | |
590 const CPDF_Annot* CPDFSDK_PageView::GetPDFAnnotAtPoint(FX_FLOAT pageX, | |
591 FX_FLOAT pageY) { | |
592 for (const auto& pAnnot : m_pAnnotList->All()) { | |
593 CFX_FloatRect annotRect = pAnnot->GetRect(); | |
594 if (annotRect.Contains(pageX, pageY)) | |
595 return pAnnot.get(); | |
596 } | |
597 return nullptr; | |
598 } | |
599 | |
600 const CPDF_Annot* CPDFSDK_PageView::GetPDFWidgetAtPoint(FX_FLOAT pageX, | |
601 FX_FLOAT pageY) { | |
602 for (const auto& pAnnot : m_pAnnotList->All()) { | |
603 if (pAnnot->GetSubtype() == CPDF_Annot::Subtype::WIDGET) { | |
604 CFX_FloatRect annotRect = pAnnot->GetRect(); | |
605 if (annotRect.Contains(pageX, pageY)) | |
606 return pAnnot.get(); | |
607 } | |
608 } | |
609 return nullptr; | |
610 } | |
611 | |
612 CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX, | |
613 FX_FLOAT pageY) { | |
614 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
615 CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr(); | |
616 CPDFSDK_AnnotIterator annotIterator(this, false); | |
617 while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) { | |
618 CFX_FloatRect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot); | |
619 if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP) | |
620 continue; | |
621 if (rc.Contains(pageX, pageY)) | |
622 return pSDKAnnot; | |
623 } | |
624 | |
625 return nullptr; | |
626 } | |
627 | |
628 CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, | |
629 FX_FLOAT pageY) { | |
630 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
631 CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr(); | |
632 CPDFSDK_AnnotIterator annotIterator(this, false); | |
633 while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) { | |
634 bool bHitTest = pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET; | |
635 #ifdef PDF_ENABLE_XFA | |
636 bHitTest = bHitTest || | |
637 pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::XFAWIDGET; | |
638 #endif // PDF_ENABLE_XFA | |
639 if (bHitTest) { | |
640 pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot); | |
641 CFX_FloatPoint point(pageX, pageY); | |
642 if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot, point)) | |
643 return pSDKAnnot; | |
644 } | |
645 } | |
646 | |
647 return nullptr; | |
648 } | |
649 | |
650 void CPDFSDK_PageView::KillFocusAnnotIfNeeded() { | |
651 // if there is a focused annot on the page, we should kill the focus first. | |
652 if (CPDFSDK_Annot* focusedAnnot = m_pSDKDoc->GetFocusAnnot()) { | |
653 if (pdfium::ContainsValue(m_fxAnnotArray, focusedAnnot)) | |
654 KillFocusAnnot(); | |
655 } | |
656 } | |
657 | |
658 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Annot* pPDFAnnot) { | |
659 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
660 ASSERT(pEnv); | |
661 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr(); | |
662 CPDFSDK_Annot* pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this); | |
663 if (!pSDKAnnot) | |
664 return nullptr; | |
665 | |
666 m_fxAnnotArray.push_back(pSDKAnnot); | |
667 pAnnotHandler->Annot_OnCreate(pSDKAnnot); | |
668 return pSDKAnnot; | |
669 } | |
670 | |
671 #ifdef PDF_ENABLE_XFA | |
672 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CXFA_FFWidget* pPDFAnnot) { | |
673 if (!pPDFAnnot) | |
674 return nullptr; | |
675 | |
676 CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot); | |
677 if (pSDKAnnot) | |
678 return pSDKAnnot; | |
679 | |
680 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
681 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr(); | |
682 pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this); | |
683 if (!pSDKAnnot) | |
684 return nullptr; | |
685 | |
686 m_fxAnnotArray.push_back(pSDKAnnot); | |
687 return pSDKAnnot; | |
688 } | |
689 #endif // PDF_ENABLE_XFA | |
690 | |
691 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Dictionary* pDict) { | |
692 return pDict ? AddAnnot(pDict->GetStringBy("Subtype").c_str(), pDict) | |
693 : nullptr; | |
694 } | |
695 | |
696 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(const FX_CHAR* lpSubType, | |
697 CPDF_Dictionary* pDict) { | |
698 return nullptr; | |
699 } | |
700 | |
701 FX_BOOL CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) { | |
702 #ifdef PDF_ENABLE_XFA | |
703 if (!pAnnot) | |
704 return FALSE; | |
705 CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage(); | |
706 if (!pPage || (pPage->GetDocument()->GetDocType() != DOCTYPE_STATIC_XFA && | |
707 pPage->GetDocument()->GetDocType() != DOCTYPE_DYNAMIC_XFA)) | |
708 return FALSE; | |
709 | |
710 if (GetFocusAnnot() == pAnnot) | |
711 KillFocusAnnot(); | |
712 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
713 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr(); | |
714 if (pAnnotHandler) | |
715 pAnnotHandler->ReleaseAnnot(pAnnot); | |
716 | |
717 auto it = std::find(m_fxAnnotArray.begin(), m_fxAnnotArray.end(), pAnnot); | |
718 if (it != m_fxAnnotArray.end()) | |
719 m_fxAnnotArray.erase(it); | |
720 if (m_CaptureWidget == pAnnot) | |
721 m_CaptureWidget = nullptr; | |
722 | |
723 return TRUE; | |
724 #else // PDF_ENABLE_XFA | |
725 return FALSE; | |
726 #endif // PDF_ENABLE_XFA | |
727 } | |
728 | |
729 CPDF_Document* CPDFSDK_PageView::GetPDFDocument() { | |
730 if (m_page) { | |
731 #ifdef PDF_ENABLE_XFA | |
732 return m_page->GetDocument()->GetPDFDoc(); | |
733 #else // PDF_ENABLE_XFA | |
734 return m_page->m_pDocument; | |
735 #endif // PDF_ENABLE_XFA | |
736 } | |
737 return nullptr; | |
738 } | |
739 | |
740 CPDF_Page* CPDFSDK_PageView::GetPDFPage() const { | |
741 #ifdef PDF_ENABLE_XFA | |
742 return m_page ? m_page->GetPDFPage() : nullptr; | |
743 #else // PDF_ENABLE_XFA | |
744 return m_page; | |
745 #endif // PDF_ENABLE_XFA | |
746 } | |
747 | |
748 size_t CPDFSDK_PageView::CountAnnots() const { | |
749 return m_fxAnnotArray.size(); | |
750 } | |
751 | |
752 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnot(size_t nIndex) { | |
753 return nIndex < m_fxAnnotArray.size() ? m_fxAnnotArray[nIndex] : nullptr; | |
754 } | |
755 | |
756 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary* pDict) { | |
757 for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) { | |
758 if (pAnnot->GetPDFAnnot()->GetAnnotDict() == pDict) | |
759 return pAnnot; | |
760 } | |
761 return nullptr; | |
762 } | |
763 | |
764 #ifdef PDF_ENABLE_XFA | |
765 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) { | |
766 if (!hWidget) | |
767 return nullptr; | |
768 | |
769 for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) { | |
770 if (pAnnot->GetXFAWidget() == hWidget) | |
771 return pAnnot; | |
772 } | |
773 return nullptr; | |
774 } | |
775 #endif // PDF_ENABLE_XFA | |
776 | |
777 FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CFX_FloatPoint& point, | |
778 FX_UINT nFlag) { | |
779 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
780 ASSERT(pEnv); | |
781 CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y); | |
782 if (!pFXAnnot) { | |
783 KillFocusAnnot(nFlag); | |
784 return FALSE; | |
785 } | |
786 | |
787 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
788 FX_BOOL bRet = | |
789 pAnnotHandlerMgr->Annot_OnLButtonDown(this, pFXAnnot, nFlag, point); | |
790 if (bRet) | |
791 SetFocusAnnot(pFXAnnot); | |
792 return bRet; | |
793 } | |
794 | |
795 #ifdef PDF_ENABLE_XFA | |
796 FX_BOOL CPDFSDK_PageView::OnRButtonDown(const CFX_FloatPoint& point, | |
797 FX_UINT nFlag) { | |
798 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
799 ASSERT(pEnv); | |
800 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
801 ASSERT(pAnnotHandlerMgr); | |
802 | |
803 CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y); | |
804 | |
805 if (!pFXAnnot) | |
806 return FALSE; | |
807 | |
808 if (pAnnotHandlerMgr->Annot_OnRButtonDown(this, pFXAnnot, nFlag, point)) | |
809 SetFocusAnnot(pFXAnnot); | |
810 | |
811 return TRUE; | |
812 } | |
813 | |
814 FX_BOOL CPDFSDK_PageView::OnRButtonUp(const CFX_FloatPoint& point, | |
815 FX_UINT nFlag) { | |
816 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
817 ASSERT(pEnv); | |
818 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
819 | |
820 CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y); | |
821 | |
822 if (!pFXAnnot) | |
823 return FALSE; | |
824 | |
825 if (pAnnotHandlerMgr->Annot_OnRButtonUp(this, pFXAnnot, nFlag, point)) | |
826 SetFocusAnnot(pFXAnnot); | |
827 | |
828 return TRUE; | |
829 } | |
830 #endif // PDF_ENABLE_XFA | |
831 | |
832 FX_BOOL CPDFSDK_PageView::OnLButtonUp(const CFX_FloatPoint& point, | |
833 FX_UINT nFlag) { | |
834 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
835 ASSERT(pEnv); | |
836 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
837 CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y); | |
838 CPDFSDK_Annot* pFocusAnnot = GetFocusAnnot(); | |
839 FX_BOOL bRet = FALSE; | |
840 if (pFocusAnnot && pFocusAnnot != pFXAnnot) { | |
841 // Last focus Annot gets a chance to handle the event. | |
842 bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFocusAnnot, nFlag, point); | |
843 } | |
844 if (pFXAnnot && !bRet) | |
845 bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFXAnnot, nFlag, point); | |
846 return bRet; | |
847 } | |
848 | |
849 FX_BOOL CPDFSDK_PageView::OnMouseMove(const CFX_FloatPoint& point, int nFlag) { | |
850 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
851 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
852 if (CPDFSDK_Annot* pFXAnnot = GetFXAnnotAtPoint(point.x, point.y)) { | |
853 if (m_CaptureWidget && m_CaptureWidget != pFXAnnot) { | |
854 m_bExitWidget = TRUE; | |
855 m_bEnterWidget = FALSE; | |
856 pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag); | |
857 } | |
858 m_CaptureWidget = pFXAnnot; | |
859 m_bOnWidget = TRUE; | |
860 if (!m_bEnterWidget) { | |
861 m_bEnterWidget = TRUE; | |
862 m_bExitWidget = FALSE; | |
863 pAnnotHandlerMgr->Annot_OnMouseEnter(this, pFXAnnot, nFlag); | |
864 } | |
865 pAnnotHandlerMgr->Annot_OnMouseMove(this, pFXAnnot, nFlag, point); | |
866 return TRUE; | |
867 } | |
868 if (m_bOnWidget) { | |
869 m_bOnWidget = FALSE; | |
870 m_bExitWidget = TRUE; | |
871 m_bEnterWidget = FALSE; | |
872 if (m_CaptureWidget) { | |
873 pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag); | |
874 m_CaptureWidget = nullptr; | |
875 } | |
876 } | |
877 return FALSE; | |
878 } | |
879 | |
880 FX_BOOL CPDFSDK_PageView::OnMouseWheel(double deltaX, | |
881 double deltaY, | |
882 const CFX_FloatPoint& point, | |
883 int nFlag) { | |
884 if (CPDFSDK_Annot* pAnnot = GetFXWidgetAtPoint(point.x, point.y)) { | |
885 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
886 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
887 return pAnnotHandlerMgr->Annot_OnMouseWheel(this, pAnnot, nFlag, | |
888 (int)deltaY, point); | |
889 } | |
890 return FALSE; | |
891 } | |
892 | |
893 FX_BOOL CPDFSDK_PageView::OnChar(int nChar, FX_UINT nFlag) { | |
894 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) { | |
895 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
896 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
897 return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag); | |
898 } | |
899 | |
900 return FALSE; | |
901 } | |
902 | |
903 FX_BOOL CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag) { | |
904 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) { | |
905 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
906 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
907 return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag); | |
908 } | |
909 return FALSE; | |
910 } | |
911 | |
912 FX_BOOL CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag) { | |
913 return FALSE; | |
914 } | |
915 | |
916 void CPDFSDK_PageView::LoadFXAnnots() { | |
917 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
918 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr(); | |
919 | |
920 SetLock(TRUE); | |
921 | |
922 #ifdef PDF_ENABLE_XFA | |
923 CFX_RetainPtr<CPDFXFA_Page> protector(m_page); | |
924 if (m_pSDKDoc->GetXFADocument()->GetDocType() == DOCTYPE_DYNAMIC_XFA) { | |
925 CXFA_FFPageView* pageView = m_page->GetXFAPageView(); | |
926 std::unique_ptr<IXFA_WidgetIterator> pWidgetHander( | |
927 pageView->CreateWidgetIterator( | |
928 XFA_TRAVERSEWAY_Form, | |
929 XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)); | |
930 if (!pWidgetHander) { | |
931 SetLock(FALSE); | |
932 return; | |
933 } | |
934 | |
935 while (CXFA_FFWidget* pXFAAnnot = pWidgetHander->MoveToNext()) { | |
936 CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pXFAAnnot, this); | |
937 if (!pAnnot) | |
938 continue; | |
939 m_fxAnnotArray.push_back(pAnnot); | |
940 pAnnotHandlerMgr->Annot_OnLoad(pAnnot); | |
941 } | |
942 | |
943 SetLock(FALSE); | |
944 return; | |
945 } | |
946 #endif // PDF_ENABLE_XFA | |
947 | |
948 CPDF_Page* pPage = GetPDFPage(); | |
949 ASSERT(pPage); | |
950 FX_BOOL bUpdateAP = CPDF_InterForm::IsUpdateAPEnabled(); | |
951 // Disable the default AP construction. | |
952 CPDF_InterForm::SetUpdateAP(FALSE); | |
953 m_pAnnotList.reset(new CPDF_AnnotList(pPage)); | |
954 CPDF_InterForm::SetUpdateAP(bUpdateAP); | |
955 | |
956 const size_t nCount = m_pAnnotList->Count(); | |
957 for (size_t i = 0; i < nCount; ++i) { | |
958 CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i); | |
959 CheckUnSupportAnnot(GetPDFDocument(), pPDFAnnot); | |
960 CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this); | |
961 if (!pAnnot) | |
962 continue; | |
963 m_fxAnnotArray.push_back(pAnnot); | |
964 pAnnotHandlerMgr->Annot_OnLoad(pAnnot); | |
965 } | |
966 | |
967 SetLock(FALSE); | |
968 } | |
969 | |
970 void CPDFSDK_PageView::ClearFXAnnots() { | |
971 SetLock(TRUE); | |
972 if (m_pSDKDoc && GetFocusAnnot()) | |
973 m_pSDKDoc->SetFocusAnnot(nullptr); | |
974 m_CaptureWidget = nullptr; | |
975 for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) | |
976 m_pSDKDoc->GetEnv()->GetAnnotHandlerMgr()->ReleaseAnnot(pAnnot); | |
977 m_fxAnnotArray.clear(); | |
978 m_pAnnotList.reset(); | |
979 SetLock(FALSE); | |
980 } | |
981 | |
982 void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) { | |
983 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
984 for (const auto& rc : rects) | |
985 pEnv->FFI_Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom); | |
986 } | |
987 | |
988 void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) { | |
989 CFX_FloatRect rcWindow = pAnnot->GetRect(); | |
990 CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); | |
991 pEnv->FFI_Invalidate(m_page, rcWindow.left, rcWindow.top, rcWindow.right, | |
992 rcWindow.bottom); | |
993 } | |
994 | |
995 int CPDFSDK_PageView::GetPageIndex() const { | |
996 if (!m_page) | |
997 return -1; | |
998 | |
999 #ifdef PDF_ENABLE_XFA | |
1000 int nDocType = m_page->GetDocument()->GetDocType(); | |
1001 switch (nDocType) { | |
1002 case DOCTYPE_DYNAMIC_XFA: { | |
1003 CXFA_FFPageView* pPageView = m_page->GetXFAPageView(); | |
1004 return pPageView ? pPageView->GetPageIndex() : -1; | |
1005 } | |
1006 case DOCTYPE_STATIC_XFA: | |
1007 case DOCTYPE_PDF: | |
1008 return GetPageIndexForStaticPDF(); | |
1009 default: | |
1010 return -1; | |
1011 } | |
1012 #else // PDF_ENABLE_XFA | |
1013 return GetPageIndexForStaticPDF(); | |
1014 #endif // PDF_ENABLE_XFA | |
1015 } | |
1016 | |
1017 bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const { | |
1018 if (!p) | |
1019 return false; | |
1020 | |
1021 const auto& annots = m_pAnnotList->All(); | |
1022 auto it = std::find_if(annots.begin(), annots.end(), | |
1023 [p](const std::unique_ptr<CPDF_Annot>& annot) { | |
1024 return annot.get() == p; | |
1025 }); | |
1026 return it != annots.end(); | |
1027 } | |
1028 | |
1029 CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() { | |
1030 CPDFSDK_Annot* pFocusAnnot = m_pSDKDoc->GetFocusAnnot(); | |
1031 if (!pFocusAnnot) | |
1032 return nullptr; | |
1033 | |
1034 for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) { | |
1035 if (pAnnot == pFocusAnnot) | |
1036 return pAnnot; | |
1037 } | |
1038 return nullptr; | |
1039 } | |
1040 | |
1041 int CPDFSDK_PageView::GetPageIndexForStaticPDF() const { | |
1042 CPDF_Dictionary* pDict = GetPDFPage()->m_pFormDict; | |
1043 CPDF_Document* pDoc = m_pSDKDoc->GetPDFDocument(); | |
1044 return (pDoc && pDict) ? pDoc->GetPageIndex(pDict->GetObjNum()) : -1; | |
1045 } | |
OLD | NEW |