• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/cpdfsdk_pageview.h"
8 
9 #include <memory>
10 #include <vector>
11 
12 #include "core/fpdfapi/parser/cpdf_dictionary.h"
13 #include "core/fpdfapi/parser/cpdf_document.h"
14 #include "core/fpdfapi/render/cpdf_renderoptions.h"
15 #include "core/fpdfdoc/cpdf_annotlist.h"
16 #include "core/fpdfdoc/cpdf_interactiveform.h"
17 #include "core/fxcrt/autorestorer.h"
18 #include "fpdfsdk/cpdfsdk_annot.h"
19 #include "fpdfsdk/cpdfsdk_annotiteration.h"
20 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
21 #include "fpdfsdk/cpdfsdk_helpers.h"
22 #include "fpdfsdk/cpdfsdk_interactiveform.h"
23 #include "third_party/base/ptr_util.h"
24 #include "third_party/base/stl_util.h"
25 
26 #ifdef PDF_ENABLE_XFA
27 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
28 #include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
29 #include "xfa/fxfa/cxfa_ffdocview.h"
30 #include "xfa/fxfa/cxfa_ffpageview.h"
31 #endif  // PDF_ENABLE_XFA
32 
CPDFSDK_PageView(CPDFSDK_FormFillEnvironment * pFormFillEnv,IPDF_Page * page)33 CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_FormFillEnvironment* pFormFillEnv,
34                                    IPDF_Page* page)
35     : m_page(page), m_pFormFillEnv(pFormFillEnv) {
36   ASSERT(m_page);
37   CPDF_Page* pPDFPage = ToPDFPage(page);
38   if (pPDFPage) {
39     CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
40     CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
41     pPDFForm->FixPageFields(pPDFPage);
42     if (!page->AsXFAPage())
43       pPDFPage->SetView(this);
44   }
45 }
46 
~CPDFSDK_PageView()47 CPDFSDK_PageView::~CPDFSDK_PageView() {
48   if (!m_page->AsXFAPage()) {
49     // The call to |ReleaseAnnot| can cause the page pointed to by |m_page| to
50     // be freed, which will cause issues if we try to cleanup the pageview
51     // pointer in |m_page|. So, reset the pageview pointer before doing anything
52     // else.
53     m_page->AsPDFPage()->SetView(nullptr);
54   }
55 
56   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
57       m_pFormFillEnv->GetAnnotHandlerMgr();
58   for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray)
59     pAnnotHandlerMgr->ReleaseAnnot(pdfium::WrapUnique(pAnnot));
60 
61   m_SDKAnnotArray.clear();
62   m_pAnnotList.reset();
63 }
64 
PageView_OnDraw(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,CPDF_RenderOptions * pOptions,const FX_RECT & pClip)65 void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice,
66                                        const CFX_Matrix& mtUser2Device,
67                                        CPDF_RenderOptions* pOptions,
68                                        const FX_RECT& pClip) {
69   m_curMatrix = mtUser2Device;
70 
71 #ifdef PDF_ENABLE_XFA
72   IPDF_Page* pPage = GetXFAPage();
73   CPDF_Document::Extension* pContext =
74       pPage ? pPage->GetDocument()->GetExtension() : nullptr;
75   if (pContext && pContext->ContainsExtensionFullForm()) {
76     static_cast<CPDFXFA_Page*>(pPage)->DrawFocusAnnot(pDevice, GetFocusAnnot(),
77                                                       mtUser2Device, pClip);
78     return;
79   }
80 #endif  // PDF_ENABLE_XFA
81 
82   // for pdf/static xfa.
83   CPDFSDK_AnnotIteration annotIteration(this, true);
84   for (const auto& pSDKAnnot : annotIteration) {
85     m_pFormFillEnv->GetAnnotHandlerMgr()->Annot_OnDraw(
86         this, pSDKAnnot.Get(), pDevice, mtUser2Device,
87         pOptions->GetDrawAnnots());
88   }
89 }
90 
GetFXAnnotAtPoint(const CFX_PointF & point)91 CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(const CFX_PointF& point) {
92   CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
93   CPDFSDK_AnnotIteration annotIteration(this, false);
94   for (const auto& pSDKAnnot : annotIteration) {
95     CFX_FloatRect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
96     if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP)
97       continue;
98     if (rc.Contains(point))
99       return pSDKAnnot.Get();
100   }
101   return nullptr;
102 }
103 
GetFXWidgetAtPoint(const CFX_PointF & point)104 CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(const CFX_PointF& point) {
105   CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
106   CPDFSDK_AnnotIteration annotIteration(this, false);
107   for (const auto& pSDKAnnot : annotIteration) {
108     bool bHitTest = pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET;
109 #ifdef PDF_ENABLE_XFA
110     bHitTest = bHitTest ||
111                pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::XFAWIDGET;
112 #endif  // PDF_ENABLE_XFA
113     if (bHitTest) {
114       pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
115       if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot.Get(), point))
116         return pSDKAnnot.Get();
117     }
118   }
119   return nullptr;
120 }
121 
122 #ifdef PDF_ENABLE_XFA
AddAnnot(CXFA_FFWidget * pPDFAnnot)123 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CXFA_FFWidget* pPDFAnnot) {
124   CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot);
125   if (pSDKAnnot)
126     return pSDKAnnot;
127 
128   CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pFormFillEnv->GetAnnotHandlerMgr();
129   std::unique_ptr<CPDFSDK_Annot> pNewAnnot =
130       pAnnotHandler->NewXFAAnnot(pPDFAnnot, this);
131   ASSERT(pNewAnnot);
132   pSDKAnnot = pNewAnnot.get();
133   // TODO(thestig): See if |m_SDKAnnotArray|, which takes ownership of
134   // |pNewAnnot|, can hold std::unique_ptrs instead of raw pointers.
135   m_SDKAnnotArray.push_back(pNewAnnot.release());
136   return pSDKAnnot;
137 }
138 
DeleteAnnot(CPDFSDK_Annot * pAnnot)139 bool CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) {
140   IPDF_Page* pPage = pAnnot->GetXFAPage();
141   if (!pPage)
142     return false;
143 
144   CPDF_Document::Extension* pContext = pPage->GetDocument()->GetExtension();
145   if (pContext && !pContext->ContainsExtensionForm())
146     return false;
147 
148   ObservedPtr<CPDFSDK_Annot> pObserved(pAnnot);
149   if (GetFocusAnnot() == pAnnot)
150     m_pFormFillEnv->KillFocusAnnot(0);  // May invoke JS, invalidating pAnnot.
151 
152   if (pObserved) {
153     CPDFSDK_AnnotHandlerMgr* pAnnotHandler =
154         m_pFormFillEnv->GetAnnotHandlerMgr();
155     if (pAnnotHandler)
156       pAnnotHandler->ReleaseAnnot(pdfium::WrapUnique(pObserved.Get()));
157   }
158 
159   auto it = std::find(m_SDKAnnotArray.begin(), m_SDKAnnotArray.end(), pAnnot);
160   if (it != m_SDKAnnotArray.end())
161     m_SDKAnnotArray.erase(it);
162   if (m_pCaptureWidget.Get() == pAnnot)
163     m_pCaptureWidget.Reset();
164 
165   return true;
166 }
167 #endif  // PDF_ENABLE_XFA
168 
GetPDFDocument()169 CPDF_Document* CPDFSDK_PageView::GetPDFDocument() {
170   return m_page->GetDocument();
171 }
172 
GetPDFPage() const173 CPDF_Page* CPDFSDK_PageView::GetPDFPage() const {
174   return ToPDFPage(m_page);
175 }
176 
GetAnnotByDict(CPDF_Dictionary * pDict)177 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary* pDict) {
178   for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
179     if (pAnnot->GetPDFAnnot()->GetAnnotDict() == pDict)
180       return pAnnot;
181   }
182   return nullptr;
183 }
184 
185 #ifdef PDF_ENABLE_XFA
GetAnnotByXFAWidget(CXFA_FFWidget * hWidget)186 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) {
187   if (!hWidget)
188     return nullptr;
189 
190   for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
191     if (ToXFAWidget(pAnnot)->GetXFAFFWidget() == hWidget)
192       return pAnnot;
193   }
194   return nullptr;
195 }
196 
GetXFAPage()197 IPDF_Page* CPDFSDK_PageView::GetXFAPage() {
198   return ToXFAPage(m_page);
199 }
200 #endif  // PDF_ENABLE_XFA
201 
GetFocusedFormText()202 WideString CPDFSDK_PageView::GetFocusedFormText() {
203   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
204     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
205         m_pFormFillEnv->GetAnnotHandlerMgr();
206     return pAnnotHandlerMgr->Annot_GetText(pAnnot);
207   }
208 
209   return WideString();
210 }
211 
GetSelectedText()212 WideString CPDFSDK_PageView::GetSelectedText() {
213   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
214     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
215         m_pFormFillEnv->GetAnnotHandlerMgr();
216     return pAnnotHandlerMgr->Annot_GetSelectedText(pAnnot);
217   }
218 
219   return WideString();
220 }
221 
ReplaceSelection(const WideString & text)222 void CPDFSDK_PageView::ReplaceSelection(const WideString& text) {
223   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
224     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
225         m_pFormFillEnv->GetAnnotHandlerMgr();
226     pAnnotHandlerMgr->Annot_ReplaceSelection(pAnnot, text);
227   }
228 }
229 
CanUndo()230 bool CPDFSDK_PageView::CanUndo() {
231   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
232     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
233         m_pFormFillEnv->GetAnnotHandlerMgr();
234     return pAnnotHandlerMgr->Annot_CanUndo(pAnnot);
235   }
236   return false;
237 }
238 
CanRedo()239 bool CPDFSDK_PageView::CanRedo() {
240   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
241     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
242         m_pFormFillEnv->GetAnnotHandlerMgr();
243     return pAnnotHandlerMgr->Annot_CanRedo(pAnnot);
244   }
245   return false;
246 }
247 
Undo()248 bool CPDFSDK_PageView::Undo() {
249   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
250     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
251         m_pFormFillEnv->GetAnnotHandlerMgr();
252     return pAnnotHandlerMgr->Annot_Undo(pAnnot);
253   }
254   return false;
255 }
256 
Redo()257 bool CPDFSDK_PageView::Redo() {
258   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
259     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
260         m_pFormFillEnv->GetAnnotHandlerMgr();
261     return pAnnotHandlerMgr->Annot_Redo(pAnnot);
262   }
263   return false;
264 }
265 
OnFocus(const CFX_PointF & point,uint32_t nFlag)266 bool CPDFSDK_PageView::OnFocus(const CFX_PointF& point, uint32_t nFlag) {
267   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
268   if (!pAnnot) {
269     m_pFormFillEnv->KillFocusAnnot(nFlag);
270     return false;
271   }
272 
273   m_pFormFillEnv->SetFocusAnnot(&pAnnot);
274   return true;
275 }
276 
OnLButtonDown(const CFX_PointF & point,uint32_t nFlag)277 bool CPDFSDK_PageView::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
278   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
279   if (!pAnnot) {
280     m_pFormFillEnv->KillFocusAnnot(nFlag);
281     return false;
282   }
283 
284   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
285       m_pFormFillEnv->GetAnnotHandlerMgr();
286   if (!pAnnotHandlerMgr->Annot_OnLButtonDown(this, &pAnnot, nFlag, point))
287     return false;
288 
289   if (!pAnnot)
290     return false;
291 
292   m_pFormFillEnv->SetFocusAnnot(&pAnnot);
293   return true;
294 }
295 
OnLButtonUp(const CFX_PointF & point,uint32_t nFlag)296 bool CPDFSDK_PageView::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
297   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
298       m_pFormFillEnv->GetAnnotHandlerMgr();
299   ObservedPtr<CPDFSDK_Annot> pFXAnnot(GetFXWidgetAtPoint(point));
300   ObservedPtr<CPDFSDK_Annot> pFocusAnnot(GetFocusAnnot());
301   if (pFocusAnnot && pFocusAnnot != pFXAnnot) {
302     // Last focus Annot gets a chance to handle the event.
303     if (pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFocusAnnot, nFlag, point))
304       return true;
305   }
306   return pFXAnnot &&
307          pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFXAnnot, nFlag, point);
308 }
309 
OnLButtonDblClk(const CFX_PointF & point,uint32_t nFlag)310 bool CPDFSDK_PageView::OnLButtonDblClk(const CFX_PointF& point,
311                                        uint32_t nFlag) {
312   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
313   if (!pAnnot) {
314     m_pFormFillEnv->KillFocusAnnot(nFlag);
315     return false;
316   }
317 
318   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
319       m_pFormFillEnv->GetAnnotHandlerMgr();
320   if (!pAnnotHandlerMgr->Annot_OnLButtonDblClk(this, &pAnnot, nFlag, point))
321     return false;
322 
323   if (!pAnnot)
324     return false;
325 
326   m_pFormFillEnv->SetFocusAnnot(&pAnnot);
327   return true;
328 }
329 
OnRButtonDown(const CFX_PointF & point,uint32_t nFlag)330 bool CPDFSDK_PageView::OnRButtonDown(const CFX_PointF& point, uint32_t nFlag) {
331   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
332   if (!pAnnot)
333     return false;
334 
335   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
336       m_pFormFillEnv->GetAnnotHandlerMgr();
337   bool ok = pAnnotHandlerMgr->Annot_OnRButtonDown(this, &pAnnot, nFlag, point);
338   if (!pAnnot)
339     return false;
340 
341   if (ok)
342     m_pFormFillEnv->SetFocusAnnot(&pAnnot);
343 
344   return true;
345 }
346 
OnRButtonUp(const CFX_PointF & point,uint32_t nFlag)347 bool CPDFSDK_PageView::OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) {
348   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
349   if (!pAnnot)
350     return false;
351 
352   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
353       m_pFormFillEnv->GetAnnotHandlerMgr();
354   bool ok = pAnnotHandlerMgr->Annot_OnRButtonUp(this, &pAnnot, nFlag, point);
355   if (!pAnnot)
356     return false;
357 
358   if (ok)
359     m_pFormFillEnv->SetFocusAnnot(&pAnnot);
360 
361   return true;
362 }
363 
OnMouseMove(const CFX_PointF & point,int nFlag)364 bool CPDFSDK_PageView::OnMouseMove(const CFX_PointF& point, int nFlag) {
365   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
366       m_pFormFillEnv->GetAnnotHandlerMgr();
367 
368   ObservedPtr<CPDFSDK_Annot> pFXAnnot(GetFXAnnotAtPoint(point));
369   ObservedPtr<CPDFSDK_PageView> pThis(this);
370 
371   if (m_bOnWidget && m_pCaptureWidget != pFXAnnot)
372     ExitWidget(pAnnotHandlerMgr, true, nFlag);
373 
374   // ExitWidget() may have invalidated objects.
375   if (!pThis || !pFXAnnot)
376     return false;
377 
378   if (!m_bOnWidget) {
379     EnterWidget(pAnnotHandlerMgr, &pFXAnnot, nFlag);
380 
381     // EnterWidget() may have invalidated objects.
382     if (!pThis)
383       return false;
384 
385     if (!pFXAnnot) {
386       ExitWidget(pAnnotHandlerMgr, false, nFlag);
387       return true;
388     }
389   }
390   pAnnotHandlerMgr->Annot_OnMouseMove(this, &pFXAnnot, nFlag, point);
391   return true;
392 }
393 
EnterWidget(CPDFSDK_AnnotHandlerMgr * pAnnotHandlerMgr,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)394 void CPDFSDK_PageView::EnterWidget(CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr,
395                                    ObservedPtr<CPDFSDK_Annot>* pAnnot,
396                                    uint32_t nFlag) {
397   m_bOnWidget = true;
398   m_pCaptureWidget.Reset(pAnnot->Get());
399   pAnnotHandlerMgr->Annot_OnMouseEnter(this, pAnnot, nFlag);
400 }
401 
ExitWidget(CPDFSDK_AnnotHandlerMgr * pAnnotHandlerMgr,bool callExitCallback,uint32_t nFlag)402 void CPDFSDK_PageView::ExitWidget(CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr,
403                                   bool callExitCallback,
404                                   uint32_t nFlag) {
405   m_bOnWidget = false;
406   if (m_pCaptureWidget) {
407     if (callExitCallback)
408       pAnnotHandlerMgr->Annot_OnMouseExit(this, &m_pCaptureWidget, nFlag);
409 
410     m_pCaptureWidget.Reset();
411   }
412 }
413 
OnMouseWheel(double deltaX,double deltaY,const CFX_PointF & point,int nFlag)414 bool CPDFSDK_PageView::OnMouseWheel(double deltaX,
415                                     double deltaY,
416                                     const CFX_PointF& point,
417                                     int nFlag) {
418   ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
419   if (!pAnnot)
420     return false;
421 
422   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
423       m_pFormFillEnv->GetAnnotHandlerMgr();
424   return pAnnotHandlerMgr->Annot_OnMouseWheel(this, &pAnnot, nFlag,
425                                               static_cast<int>(deltaY), point);
426 }
427 
SetIndexSelected(int index,bool selected)428 bool CPDFSDK_PageView::SetIndexSelected(int index, bool selected) {
429   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
430     ObservedPtr<CPDFSDK_Annot> pAnnotObserved(pAnnot);
431     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
432         m_pFormFillEnv->GetAnnotHandlerMgr();
433     return pAnnotHandlerMgr->Annot_SetIndexSelected(&pAnnotObserved, index,
434                                                     selected);
435   }
436 
437   return false;
438 }
439 
IsIndexSelected(int index)440 bool CPDFSDK_PageView::IsIndexSelected(int index) {
441   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
442     ObservedPtr<CPDFSDK_Annot> pAnnotObserved(pAnnot);
443     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
444         m_pFormFillEnv->GetAnnotHandlerMgr();
445     return pAnnotHandlerMgr->Annot_IsIndexSelected(&pAnnotObserved, index);
446   }
447 
448   return false;
449 }
450 
OnChar(int nChar,uint32_t nFlag)451 bool CPDFSDK_PageView::OnChar(int nChar, uint32_t nFlag) {
452   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
453     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
454         m_pFormFillEnv->GetAnnotHandlerMgr();
455     return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
456   }
457 
458   return false;
459 }
460 
OnKeyDown(int nKeyCode,int nFlag)461 bool CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag) {
462   if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
463     CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
464         m_pFormFillEnv->GetAnnotHandlerMgr();
465     return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
466   }
467   return false;
468 }
469 
OnKeyUp(int nKeyCode,int nFlag)470 bool CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag) {
471   return false;
472 }
473 
LoadFXAnnots()474 void CPDFSDK_PageView::LoadFXAnnots() {
475   CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
476       m_pFormFillEnv->GetAnnotHandlerMgr();
477 
478   AutoRestorer<bool> lock(&m_bLocked);
479   m_bLocked = true;
480 
481 #ifdef PDF_ENABLE_XFA
482   RetainPtr<CPDFXFA_Page> protector(ToXFAPage(m_page));
483   CPDF_Document::Extension* pContext = m_pFormFillEnv->GetDocExtension();
484   if (pContext && pContext->ContainsExtensionFullForm()) {
485     CXFA_FFPageView* pageView = protector->GetXFAPageView();
486     std::unique_ptr<IXFA_WidgetIterator> pWidgetHandler =
487         pageView->CreateFormWidgetIterator(XFA_WidgetStatus_Visible |
488                                            XFA_WidgetStatus_Viewable);
489 
490     while (CXFA_FFWidget* pXFAAnnot = pWidgetHandler->MoveToNext()) {
491       std::unique_ptr<CPDFSDK_Annot> pNewAnnot =
492           pAnnotHandlerMgr->NewXFAAnnot(pXFAAnnot, this);
493       ASSERT(pNewAnnot);
494       CPDFSDK_Annot* pAnnot = pNewAnnot.get();
495       m_SDKAnnotArray.push_back(pNewAnnot.release());
496       pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
497     }
498 
499     return;
500   }
501 #endif  // PDF_ENABLE_XFA
502 
503   CPDF_Page* pPage = GetPDFPage();
504   ASSERT(pPage);
505   bool bUpdateAP = CPDF_InteractiveForm::IsUpdateAPEnabled();
506   // Disable the default AP construction.
507   CPDF_InteractiveForm::SetUpdateAP(false);
508   m_pAnnotList = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
509   CPDF_InteractiveForm::SetUpdateAP(bUpdateAP);
510 
511   const size_t nCount = m_pAnnotList->Count();
512   for (size_t i = 0; i < nCount; ++i) {
513     CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
514     CheckForUnsupportedAnnot(pPDFAnnot);
515     CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
516     if (!pAnnot)
517       continue;
518     m_SDKAnnotArray.push_back(pAnnot);
519     pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
520   }
521 }
522 
UpdateRects(const std::vector<CFX_FloatRect> & rects)523 void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) {
524   for (const auto& rc : rects)
525     m_pFormFillEnv->Invalidate(m_page, rc.GetOuterRect());
526 }
527 
UpdateView(CPDFSDK_Annot * pAnnot)528 void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) {
529   CFX_FloatRect rcWindow = pAnnot->GetRect();
530   m_pFormFillEnv->Invalidate(m_page, rcWindow.GetOuterRect());
531 }
532 
GetPageIndex() const533 int CPDFSDK_PageView::GetPageIndex() const {
534 #ifdef PDF_ENABLE_XFA
535   CPDF_Document::Extension* pContext = m_page->GetDocument()->GetExtension();
536   if (pContext && pContext->ContainsExtensionFullForm()) {
537     CXFA_FFPageView* pPageView = m_page->AsXFAPage()->GetXFAPageView();
538     return pPageView ? pPageView->GetLayoutItem()->GetPageIndex() : -1;
539   }
540 #endif  // PDF_ENABLE_XFA
541   return GetPageIndexForStaticPDF();
542 }
543 
IsValidAnnot(const CPDF_Annot * p) const544 bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const {
545   if (!p)
546     return false;
547 
548   const auto& annots = m_pAnnotList->All();
549   auto it = std::find_if(annots.begin(), annots.end(),
550                          [p](const std::unique_ptr<CPDF_Annot>& annot) {
551                            return annot.get() == p;
552                          });
553   return it != annots.end();
554 }
555 
IsValidSDKAnnot(const CPDFSDK_Annot * p) const556 bool CPDFSDK_PageView::IsValidSDKAnnot(const CPDFSDK_Annot* p) const {
557   if (!p)
558     return false;
559   return pdfium::ContainsValue(m_SDKAnnotArray, p);
560 }
561 
GetFocusAnnot()562 CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() {
563   CPDFSDK_Annot* pFocusAnnot = m_pFormFillEnv->GetFocusAnnot();
564   return IsValidSDKAnnot(pFocusAnnot) ? pFocusAnnot : nullptr;
565 }
566 
GetPageIndexForStaticPDF() const567 int CPDFSDK_PageView::GetPageIndexForStaticPDF() const {
568   const CPDF_Dictionary* pDict = GetPDFPage()->GetDict();
569   CPDF_Document* pDoc = m_pFormFillEnv->GetPDFDocument();
570   return pDoc->GetPageIndex(pDict->GetObjNum());
571 }
572