• 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_xfawidgethandler.h"
8 
9 #include "core/fpdfdoc/cpdf_interform.h"
10 #include "fpdfsdk/cpdfsdk_annot.h"
11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
12 #include "fpdfsdk/cpdfsdk_interform.h"
13 #include "fpdfsdk/cpdfsdk_pageview.h"
14 #include "fpdfsdk/cpdfsdk_xfawidget.h"
15 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
16 #include "xfa/fwl/cfwl_app.h"
17 #include "xfa/fwl/fwl_widgethit.h"
18 #include "xfa/fxfa/fxfa_basic.h"
19 #include "xfa/fxfa/xfa_ffdocview.h"
20 #include "xfa/fxfa/xfa_ffpageview.h"
21 #include "xfa/fxfa/xfa_ffwidget.h"
22 #include "xfa/fxfa/xfa_ffwidgethandler.h"
23 #include "xfa/fxgraphics/cfx_graphics.h"
24 
CPDFSDK_XFAWidgetHandler(CPDFSDK_FormFillEnvironment * pFormFillEnv)25 CPDFSDK_XFAWidgetHandler::CPDFSDK_XFAWidgetHandler(
26     CPDFSDK_FormFillEnvironment* pFormFillEnv)
27     : m_pFormFillEnv(pFormFillEnv) {}
28 
~CPDFSDK_XFAWidgetHandler()29 CPDFSDK_XFAWidgetHandler::~CPDFSDK_XFAWidgetHandler() {}
30 
CanAnswer(CPDFSDK_Annot * pAnnot)31 bool CPDFSDK_XFAWidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
32   return !!pAnnot->GetXFAWidget();
33 }
34 
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPage)35 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
36                                                   CPDFSDK_PageView* pPage) {
37   return nullptr;
38 }
39 
NewAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPage)40 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CXFA_FFWidget* pAnnot,
41                                                   CPDFSDK_PageView* pPage) {
42   CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
43   CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
44   pInterForm->AddXFAMap(pAnnot, pWidget);
45   return pWidget;
46 }
47 
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,bool bDrawAnnots)48 void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
49                                       CPDFSDK_Annot* pAnnot,
50                                       CFX_RenderDevice* pDevice,
51                                       CFX_Matrix* pUser2Device,
52                                       bool bDrawAnnots) {
53   ASSERT(pPageView);
54   ASSERT(pAnnot);
55 
56   CFX_Graphics gs(pDevice);
57 
58   CFX_Matrix mt = *pUser2Device;
59   bool bIsHighlight = false;
60   if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot)
61     bIsHighlight = true;
62 
63   GetXFAWidgetHandler(pAnnot)->RenderWidget(pAnnot->GetXFAWidget(), &gs, &mt,
64                                             bIsHighlight);
65 
66   // to do highlight and shadow
67 }
68 
OnLoad(CPDFSDK_Annot * pAnnot)69 void CPDFSDK_XFAWidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {}
70 
ReleaseAnnot(CPDFSDK_Annot * pAnnot)71 void CPDFSDK_XFAWidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
72   CPDFSDK_XFAWidget* pWidget = reinterpret_cast<CPDFSDK_XFAWidget*>(pAnnot);
73   CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
74   pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
75 
76   delete pWidget;
77 }
78 
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)79 CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
80                                                     CPDFSDK_Annot* pAnnot) {
81   ASSERT(pAnnot);
82 
83   CFX_RectF rcBBox;
84   XFA_Element eType = pAnnot->GetXFAWidget()->GetDataAcc()->GetUIType();
85   if (eType == XFA_Element::Signature)
86     rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_Visible, true);
87   else
88     rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_None);
89 
90   CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
91                          rcBBox.top + rcBBox.height);
92   rcWidget.left -= 1.0f;
93   rcWidget.right += 1.0f;
94   rcWidget.bottom -= 1.0f;
95   rcWidget.top += 1.0f;
96 
97   return rcWidget;
98 }
99 
HitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)100 bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
101                                        CPDFSDK_Annot* pAnnot,
102                                        const CFX_PointF& point) {
103   if (!pPageView || !pAnnot)
104     return false;
105 
106   CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
107   if (!pFormFillEnv)
108     return false;
109 
110   CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
111   if (!pContext)
112     return false;
113 
114   CXFA_FFDocView* pDocView = pContext->GetXFADocView();
115   if (!pDocView)
116     return false;
117 
118   CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
119   if (!pWidgetHandler)
120     return false;
121 
122   FWL_WidgetHit dwHitTest =
123       pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point);
124   return dwHitTest != FWL_WidgetHit::Unknown;
125 }
126 
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)127 void CPDFSDK_XFAWidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
128                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
129                                             uint32_t nFlag) {
130   if (!pPageView || !(*pAnnot))
131     return;
132   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
133   pWidgetHandler->OnMouseEnter((*pAnnot)->GetXFAWidget());
134 }
135 
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)136 void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
137                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
138                                            uint32_t nFlag) {
139   if (!pPageView || !(*pAnnot))
140     return;
141 
142   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
143   pWidgetHandler->OnMouseExit((*pAnnot)->GetXFAWidget());
144 }
145 
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)146 bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
147                                              CPDFSDK_Annot::ObservedPtr* pAnnot,
148                                              uint32_t nFlags,
149                                              const CFX_PointF& point) {
150   if (!pPageView || !(*pAnnot))
151     return false;
152 
153   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
154   return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(),
155                                        GetFWLFlags(nFlags), point);
156 }
157 
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)158 bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
159                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
160                                            uint32_t nFlags,
161                                            const CFX_PointF& point) {
162   if (!pPageView || !(*pAnnot))
163     return false;
164 
165   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
166   return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(),
167                                      GetFWLFlags(nFlags), point);
168 }
169 
OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)170 bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk(
171     CPDFSDK_PageView* pPageView,
172     CPDFSDK_Annot::ObservedPtr* pAnnot,
173     uint32_t nFlags,
174     const CFX_PointF& point) {
175   if (!pPageView || !(*pAnnot))
176     return false;
177 
178   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
179   return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(),
180                                          GetFWLFlags(nFlags), point);
181 }
182 
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)183 bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
184                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
185                                            uint32_t nFlags,
186                                            const CFX_PointF& point) {
187   if (!pPageView || !(*pAnnot))
188     return false;
189 
190   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
191   return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(),
192                                      GetFWLFlags(nFlags), point);
193 }
194 
OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)195 bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
196                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
197                                             uint32_t nFlags,
198                                             short zDelta,
199                                             const CFX_PointF& point) {
200   if (!pPageView || !(*pAnnot))
201     return false;
202 
203   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
204   return pWidgetHandler->OnMouseWheel((*pAnnot)->GetXFAWidget(),
205                                       GetFWLFlags(nFlags), zDelta, point);
206 }
207 
OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)208 bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
209                                              CPDFSDK_Annot::ObservedPtr* pAnnot,
210                                              uint32_t nFlags,
211                                              const CFX_PointF& point) {
212   if (!pPageView || !(*pAnnot))
213     return false;
214 
215   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
216   return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(),
217                                        GetFWLFlags(nFlags), point);
218 }
219 
OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)220 bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
221                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
222                                            uint32_t nFlags,
223                                            const CFX_PointF& point) {
224   if (!pPageView || !(*pAnnot))
225     return false;
226 
227   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
228   return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(),
229                                      GetFWLFlags(nFlags), point);
230 }
231 
OnRButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)232 bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk(
233     CPDFSDK_PageView* pPageView,
234     CPDFSDK_Annot::ObservedPtr* pAnnot,
235     uint32_t nFlags,
236     const CFX_PointF& point) {
237   if (!pPageView || !(*pAnnot))
238     return false;
239 
240   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
241   return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(),
242                                          GetFWLFlags(nFlags), point);
243 }
244 
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)245 bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
246                                       uint32_t nChar,
247                                       uint32_t nFlags) {
248   if (!pAnnot)
249     return false;
250 
251   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
252   return pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar,
253                                 GetFWLFlags(nFlags));
254 }
255 
OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)256 bool CPDFSDK_XFAWidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
257                                          int nKeyCode,
258                                          int nFlag) {
259   if (!pAnnot)
260     return false;
261 
262   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
263   return pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode,
264                                    GetFWLFlags(nFlag));
265 }
266 
OnKeyUp(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)267 bool CPDFSDK_XFAWidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
268                                        int nKeyCode,
269                                        int nFlag) {
270   if (!pAnnot)
271     return false;
272 
273   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
274   return pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode,
275                                  GetFWLFlags(nFlag));
276 }
277 
OnSetFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)278 bool CPDFSDK_XFAWidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
279                                           uint32_t nFlag) {
280   return true;
281 }
282 
OnKillFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)283 bool CPDFSDK_XFAWidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
284                                            uint32_t nFlag) {
285   return true;
286 }
287 
OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr * pOldAnnot,CPDFSDK_Annot::ObservedPtr * pNewAnnot)288 bool CPDFSDK_XFAWidgetHandler::OnXFAChangedFocus(
289     CPDFSDK_Annot::ObservedPtr* pOldAnnot,
290     CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
291   CXFA_FFWidgetHandler* pWidgetHandler = nullptr;
292   if (*pOldAnnot)
293     pWidgetHandler = GetXFAWidgetHandler(pOldAnnot->Get());
294   else if (*pNewAnnot)
295     pWidgetHandler = GetXFAWidgetHandler(pNewAnnot->Get());
296 
297   if (!pWidgetHandler)
298     return true;
299 
300   CXFA_FFWidget* hWidget = *pNewAnnot ? (*pNewAnnot)->GetXFAWidget() : nullptr;
301   if (!hWidget)
302     return true;
303 
304   CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
305   if (!pXFAPageView)
306     return true;
307 
308   bool bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
309   if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
310     bRet = true;
311 
312   return bRet;
313 }
314 
GetXFAWidgetHandler(CPDFSDK_Annot * pAnnot)315 CXFA_FFWidgetHandler* CPDFSDK_XFAWidgetHandler::GetXFAWidgetHandler(
316     CPDFSDK_Annot* pAnnot) {
317   if (!pAnnot)
318     return nullptr;
319 
320   CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
321   if (!pPageView)
322     return nullptr;
323 
324   CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
325   if (!pFormFillEnv)
326     return nullptr;
327 
328   CPDFXFA_Context* pDoc = pFormFillEnv->GetXFAContext();
329   if (!pDoc)
330     return nullptr;
331 
332   CXFA_FFDocView* pDocView = pDoc->GetXFADocView();
333   if (!pDocView)
334     return nullptr;
335 
336   return pDocView->GetWidgetHandler();
337 }
338 
GetFWLFlags(uint32_t dwFlag)339 uint32_t CPDFSDK_XFAWidgetHandler::GetFWLFlags(uint32_t dwFlag) {
340   uint32_t dwFWLFlag = 0;
341 
342   if (dwFlag & FWL_EVENTFLAG_ControlKey)
343     dwFWLFlag |= FWL_KEYFLAG_Ctrl;
344   if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
345     dwFWLFlag |= FWL_KEYFLAG_LButton;
346   if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
347     dwFWLFlag |= FWL_KEYFLAG_MButton;
348   if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
349     dwFWLFlag |= FWL_KEYFLAG_RButton;
350   if (dwFlag & FWL_EVENTFLAG_ShiftKey)
351     dwFWLFlag |= FWL_KEYFLAG_Shift;
352   if (dwFlag & FWL_EVENTFLAG_AltKey)
353     dwFWLFlag |= FWL_KEYFLAG_Alt;
354 
355   return dwFWLFlag;
356 }
357