• 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_annothandlermgr.h"
8 
9 #include <utility>
10 
11 #include "core/fpdfapi/parser/cpdf_number.h"
12 #include "core/fpdfapi/parser/cpdf_string.h"
13 #include "core/fpdfdoc/cpdf_annot.h"
14 #include "fpdfsdk/cpdfsdk_annot.h"
15 #include "fpdfsdk/cpdfsdk_annotiterator.h"
16 #include "fpdfsdk/cpdfsdk_baannot.h"
17 #include "fpdfsdk/cpdfsdk_baannothandler.h"
18 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
19 #include "fpdfsdk/cpdfsdk_pageview.h"
20 #include "fpdfsdk/cpdfsdk_widget.h"
21 #include "fpdfsdk/cpdfsdk_widgethandler.h"
22 #include "fpdfsdk/pwl/cpwl_wnd.h"
23 #include "public/fpdf_fwlevent.h"
24 #include "third_party/base/ptr_util.h"
25 
26 #ifdef PDF_ENABLE_XFA
27 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
28 #include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
29 #include "fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h"
30 #endif  // PDF_ENABLE_XFA
31 
CPDFSDK_AnnotHandlerMgr(std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler)32 CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
33     std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,
34     std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,
35     std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler)
36     : m_pBAAnnotHandler(std::move(pBAAnnotHandler)),
37       m_pWidgetHandler(std::move(pWidgetHandler)),
38       m_pXFAWidgetHandler(std::move(pXFAWidgetHandler)) {
39   ASSERT(m_pBAAnnotHandler);
40   ASSERT(m_pWidgetHandler);
41 }
42 
43 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() = default;
44 
SetFormFillEnv(CPDFSDK_FormFillEnvironment * pFormFillEnv)45 void CPDFSDK_AnnotHandlerMgr::SetFormFillEnv(
46     CPDFSDK_FormFillEnvironment* pFormFillEnv) {
47   m_pBAAnnotHandler->SetFormFillEnvironment(pFormFillEnv);
48   m_pWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
49   if (m_pXFAWidgetHandler)
50     m_pXFAWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
51 }
52 
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)53 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
54                                                  CPDFSDK_PageView* pPageView) {
55   ASSERT(pPageView);
56   return GetAnnotHandlerOfType(pAnnot->GetSubtype())
57       ->NewAnnot(pAnnot, pPageView);
58 }
59 
60 #ifdef PDF_ENABLE_XFA
NewXFAAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPageView)61 std::unique_ptr<CPDFSDK_Annot> CPDFSDK_AnnotHandlerMgr::NewXFAAnnot(
62     CXFA_FFWidget* pAnnot,
63     CPDFSDK_PageView* pPageView) {
64   ASSERT(pAnnot);
65   ASSERT(pPageView);
66   return static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
67       ->NewAnnotForXFA(pAnnot, pPageView);
68 }
69 #endif  // PDF_ENABLE_XFA
70 
ReleaseAnnot(std::unique_ptr<CPDFSDK_Annot> pAnnot)71 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(
72     std::unique_ptr<CPDFSDK_Annot> pAnnot) {
73   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot.get());
74   pAnnotHandler->ReleaseAnnot(std::move(pAnnot));
75 }
76 
Annot_OnLoad(CPDFSDK_Annot * pAnnot)77 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
78   ASSERT(pAnnot);
79   GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
80 }
81 
Annot_GetText(CPDFSDK_Annot * pAnnot)82 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetText(CPDFSDK_Annot* pAnnot) {
83   return GetAnnotHandler(pAnnot)->GetText(pAnnot);
84 }
85 
Annot_GetSelectedText(CPDFSDK_Annot * pAnnot)86 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText(
87     CPDFSDK_Annot* pAnnot) {
88   return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot);
89 }
90 
Annot_ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)91 void CPDFSDK_AnnotHandlerMgr::Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot,
92                                                      const WideString& text) {
93   GetAnnotHandler(pAnnot)->ReplaceSelection(pAnnot, text);
94 }
95 
Annot_CanUndo(CPDFSDK_Annot * pAnnot)96 bool CPDFSDK_AnnotHandlerMgr::Annot_CanUndo(CPDFSDK_Annot* pAnnot) {
97   return GetAnnotHandler(pAnnot)->CanUndo(pAnnot);
98 }
99 
Annot_CanRedo(CPDFSDK_Annot * pAnnot)100 bool CPDFSDK_AnnotHandlerMgr::Annot_CanRedo(CPDFSDK_Annot* pAnnot) {
101   return GetAnnotHandler(pAnnot)->CanRedo(pAnnot);
102 }
103 
Annot_Undo(CPDFSDK_Annot * pAnnot)104 bool CPDFSDK_AnnotHandlerMgr::Annot_Undo(CPDFSDK_Annot* pAnnot) {
105   return GetAnnotHandler(pAnnot)->Undo(pAnnot);
106 }
107 
Annot_Redo(CPDFSDK_Annot * pAnnot)108 bool CPDFSDK_AnnotHandlerMgr::Annot_Redo(CPDFSDK_Annot* pAnnot) {
109   return GetAnnotHandler(pAnnot)->Redo(pAnnot);
110 }
111 
GetAnnotHandler(CPDFSDK_Annot * pAnnot) const112 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
113     CPDFSDK_Annot* pAnnot) const {
114   return GetAnnotHandlerOfType(pAnnot->GetAnnotSubtype());
115 }
116 
GetAnnotHandlerOfType(CPDF_Annot::Subtype nAnnotSubtype) const117 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandlerOfType(
118     CPDF_Annot::Subtype nAnnotSubtype) const {
119   if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
120     return m_pWidgetHandler.get();
121 
122 #ifdef PDF_ENABLE_XFA
123   if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
124     return m_pXFAWidgetHandler.get();
125 #endif  // PDF_ENABLE_XFA
126 
127   return m_pBAAnnotHandler.get();
128 }
129 
Annot_OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,bool bDrawAnnots)130 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
131                                            CPDFSDK_Annot* pAnnot,
132                                            CFX_RenderDevice* pDevice,
133                                            const CFX_Matrix& mtUser2Device,
134                                            bool bDrawAnnots) {
135   ASSERT(pAnnot);
136   GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, mtUser2Device,
137                                   bDrawAnnots);
138 }
139 
Annot_OnLButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)140 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
141     CPDFSDK_PageView* pPageView,
142     ObservedPtr<CPDFSDK_Annot>* pAnnot,
143     uint32_t nFlags,
144     const CFX_PointF& point) {
145   ASSERT(pAnnot->HasObservable());
146   return GetAnnotHandler(pAnnot->Get())
147       ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
148 }
149 
Annot_OnLButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)150 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
151     CPDFSDK_PageView* pPageView,
152     ObservedPtr<CPDFSDK_Annot>* pAnnot,
153     uint32_t nFlags,
154     const CFX_PointF& point) {
155   ASSERT(pAnnot->HasObservable());
156   return GetAnnotHandler(pAnnot->Get())
157       ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
158 }
159 
Annot_OnLButtonDblClk(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)160 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
161     CPDFSDK_PageView* pPageView,
162     ObservedPtr<CPDFSDK_Annot>* pAnnot,
163     uint32_t nFlags,
164     const CFX_PointF& point) {
165   ASSERT(pAnnot->HasObservable());
166   return GetAnnotHandler(pAnnot->Get())
167       ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
168 }
169 
Annot_OnMouseMove(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)170 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
171     CPDFSDK_PageView* pPageView,
172     ObservedPtr<CPDFSDK_Annot>* pAnnot,
173     uint32_t nFlags,
174     const CFX_PointF& point) {
175   ASSERT(pAnnot->HasObservable());
176   return GetAnnotHandler(pAnnot->Get())
177       ->OnMouseMove(pPageView, pAnnot, nFlags, point);
178 }
179 
Annot_OnMouseWheel(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)180 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
181     CPDFSDK_PageView* pPageView,
182     ObservedPtr<CPDFSDK_Annot>* pAnnot,
183     uint32_t nFlags,
184     short zDelta,
185     const CFX_PointF& point) {
186   ASSERT(pAnnot->HasObservable());
187   return GetAnnotHandler(pAnnot->Get())
188       ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
189 }
190 
Annot_OnRButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)191 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
192     CPDFSDK_PageView* pPageView,
193     ObservedPtr<CPDFSDK_Annot>* pAnnot,
194     uint32_t nFlags,
195     const CFX_PointF& point) {
196   ASSERT(pAnnot->HasObservable());
197   return GetAnnotHandler(pAnnot->Get())
198       ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
199 }
200 
Annot_OnRButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)201 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
202     CPDFSDK_PageView* pPageView,
203     ObservedPtr<CPDFSDK_Annot>* pAnnot,
204     uint32_t nFlags,
205     const CFX_PointF& point) {
206   ASSERT(pAnnot->HasObservable());
207   return GetAnnotHandler(pAnnot->Get())
208       ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
209 }
210 
Annot_OnMouseEnter(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)211 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
212     CPDFSDK_PageView* pPageView,
213     ObservedPtr<CPDFSDK_Annot>* pAnnot,
214     uint32_t nFlag) {
215   ASSERT(pAnnot->HasObservable());
216   GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
217 }
218 
Annot_OnMouseExit(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)219 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
220     CPDFSDK_PageView* pPageView,
221     ObservedPtr<CPDFSDK_Annot>* pAnnot,
222     uint32_t nFlag) {
223   ASSERT(pAnnot->HasObservable());
224   GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
225 }
226 
Annot_OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)227 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
228                                            uint32_t nChar,
229                                            uint32_t nFlags) {
230   return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
231 }
232 
Annot_OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)233 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
234                                               int nKeyCode,
235                                               int nFlag) {
236   if (CPWL_Wnd::IsCTRLKeyDown(nFlag) || CPWL_Wnd::IsALTKeyDown(nFlag)) {
237     return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
238   }
239   ObservedPtr<CPDFSDK_Annot> pObservedAnnot(pAnnot);
240   CPDFSDK_PageView* pPage = pAnnot->GetPageView();
241   CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
242   if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
243     ObservedPtr<CPDFSDK_Annot> pNext(
244         GetNextAnnot(pFocusAnnot, !CPWL_Wnd::IsSHIFTKeyDown(nFlag)));
245     if (pNext && pNext.Get() != pFocusAnnot) {
246       pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
247       return true;
248     }
249   }
250 
251   // Check |pAnnot| again because JS may have destroyed it in |GetNextAnnot|
252   if (!pObservedAnnot)
253     return false;
254 
255   return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
256 }
257 
Annot_OnSetFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)258 bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
259     ObservedPtr<CPDFSDK_Annot>* pAnnot,
260     uint32_t nFlag) {
261   ASSERT(pAnnot->HasObservable());
262   return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
263 }
264 
Annot_OnKillFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)265 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
266     ObservedPtr<CPDFSDK_Annot>* pAnnot,
267     uint32_t nFlag) {
268   ASSERT(pAnnot->HasObservable());
269   return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
270 }
271 
Annot_SetIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index,bool selected)272 bool CPDFSDK_AnnotHandlerMgr::Annot_SetIndexSelected(
273     ObservedPtr<CPDFSDK_Annot>* pAnnot,
274     int index,
275     bool selected) {
276   return GetAnnotHandler(pAnnot->Get())
277       ->SetIndexSelected(pAnnot, index, selected);
278 }
279 
Annot_IsIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index)280 bool CPDFSDK_AnnotHandlerMgr::Annot_IsIndexSelected(
281     ObservedPtr<CPDFSDK_Annot>* pAnnot,
282     int index) {
283   return GetAnnotHandler(pAnnot->Get())->IsIndexSelected(pAnnot, index);
284 }
285 
286 #ifdef PDF_ENABLE_XFA
Annot_OnChangeFocus(ObservedPtr<CPDFSDK_Annot> * pSetAnnot,ObservedPtr<CPDFSDK_Annot> * pKillAnnot)287 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
288     ObservedPtr<CPDFSDK_Annot>* pSetAnnot,
289     ObservedPtr<CPDFSDK_Annot>* pKillAnnot) {
290   CPDFXFA_Widget* pSetXFAWidget = ToXFAWidget(pSetAnnot->Get());
291   CPDFXFA_Widget* pKillXFAWidget = ToXFAWidget(pKillAnnot->Get());
292   bool bXFA = (pSetXFAWidget && pSetXFAWidget->GetXFAFFWidget()) ||
293               (pKillXFAWidget && pKillXFAWidget->GetXFAFFWidget());
294 
295   return !bXFA || static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
296                       ->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
297 }
298 #endif  // PDF_ENABLE_XFA
299 
Annot_OnGetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)300 CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
301     CPDFSDK_PageView* pPageView,
302     CPDFSDK_Annot* pAnnot) {
303   ASSERT(pAnnot);
304   return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
305 }
306 
Annot_OnHitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)307 bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
308                                               CPDFSDK_Annot* pAnnot,
309                                               const CFX_PointF& point) {
310   ASSERT(pAnnot);
311   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
312   if (pAnnotHandler->CanAnswer(pAnnot))
313     return pAnnotHandler->HitTest(pPageView, pAnnot, point);
314 
315   return false;
316 }
317 
GetNextAnnot(CPDFSDK_Annot * pSDKAnnot,bool bNext)318 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
319                                                      bool bNext) {
320 #ifdef PDF_ENABLE_XFA
321   IPDF_Page* pPage = pSDKAnnot->GetPageView()->GetXFAPage();
322   if (pPage && !pPage->AsPDFPage()) {
323     // For xfa annots in XFA pages not backed by PDF pages.
324     return static_cast<CPDFXFA_Page*>(pPage)->GetNextXFAAnnot(pSDKAnnot, bNext);
325   }
326 #endif  // PDF_ENABLE_XFA
327 
328   // For PDF annots.
329   CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pSDKAnnot);
330   CPDFSDK_AnnotIterator ai(pWidget->GetPageView(), pWidget->GetAnnotSubtype());
331   return bNext ? ai.GetNextAnnot(pWidget) : ai.GetPrevAnnot(pWidget);
332 }
333