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