• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/formfiller/cffl_formfiller.h"
8 
9 #include "core/fpdfapi/page/cpdf_page.h"
10 #include "core/fxge/cfx_renderdevice.h"
11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
12 #include "fpdfsdk/cpdfsdk_pageview.h"
13 #include "fpdfsdk/cpdfsdk_widget.h"
14 #include "fpdfsdk/formfiller/cba_fontmap.h"
15 #include "fpdfsdk/fsdk_common.h"
16 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
17 
18 #define GetRed(rgb) ((uint8_t)(rgb))
19 #define GetGreen(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8))
20 #define GetBlue(rgb) ((uint8_t)((rgb) >> 16))
21 
22 #define FFL_HINT_ELAPSE 800
23 
CFFL_FormFiller(CPDFSDK_FormFillEnvironment * pFormFillEnv,CPDFSDK_Annot * pAnnot)24 CFFL_FormFiller::CFFL_FormFiller(CPDFSDK_FormFillEnvironment* pFormFillEnv,
25                                  CPDFSDK_Annot* pAnnot)
26     : m_pFormFillEnv(pFormFillEnv), m_pAnnot(pAnnot), m_bValid(false) {
27   m_pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
28 }
29 
~CFFL_FormFiller()30 CFFL_FormFiller::~CFFL_FormFiller() {
31   DestroyWindows();
32 }
33 
DestroyWindows()34 void CFFL_FormFiller::DestroyWindows() {
35   for (const auto& it : m_Maps) {
36     CPWL_Wnd* pWnd = it.second;
37     CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
38     pWnd->InvalidateProvider(this);
39     pWnd->Destroy();
40     delete pWnd;
41     delete pData;
42   }
43   m_Maps.clear();
44 }
45 
SetWindowRect(CPDFSDK_PageView * pPageView,const CFX_FloatRect & rcWindow)46 void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
47                                     const CFX_FloatRect& rcWindow) {
48   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
49     pWnd->Move(CFX_FloatRect(rcWindow), true, false);
50   }
51 }
52 
GetWindowRect(CPDFSDK_PageView * pPageView)53 CFX_FloatRect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
54   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
55     return pWnd->GetWindowRect();
56   }
57 
58   return CFX_FloatRect(0, 0, 0, 0);
59 }
60 
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)61 FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
62                                      CPDFSDK_Annot* pAnnot) {
63   ASSERT(pPageView);
64   ASSERT(pAnnot);
65 
66   CFX_FloatRect rcAnnot = m_pWidget->GetRect();
67 
68   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
69     CFX_FloatRect rcWindow = pWnd->GetWindowRect();
70     rcAnnot = PWLtoFFL(rcWindow);
71   }
72 
73   CFX_FloatRect rcWin = rcAnnot;
74 
75   CFX_FloatRect rcFocus = GetFocusBox(pPageView);
76   if (!rcFocus.IsEmpty())
77     rcWin.Union(rcFocus);
78 
79   CFX_FloatRect rect = CPWL_Utils::InflateRect(rcWin, 1);
80 
81   return rect.GetOuterRect();
82 }
83 
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)84 void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
85                              CPDFSDK_Annot* pAnnot,
86                              CFX_RenderDevice* pDevice,
87                              CFX_Matrix* pUser2Device) {
88   ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
89 
90   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
91     CFX_Matrix mt = GetCurMatrix();
92     mt.Concat(*pUser2Device);
93     pWnd->DrawAppearance(pDevice, &mt);
94   } else {
95     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
96     if (CFFL_InteractiveFormFiller::IsVisible(pWidget))
97       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
98                               nullptr);
99   }
100 }
101 
OnDrawDeactive(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)102 void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
103                                      CPDFSDK_Annot* pAnnot,
104                                      CFX_RenderDevice* pDevice,
105                                      CFX_Matrix* pUser2Device) {
106   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
107   pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
108 }
109 
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)110 void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
111                                    CPDFSDK_Annot* pAnnot) {}
112 
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)113 void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
114                                   CPDFSDK_Annot* pAnnot) {
115   EndTimer();
116   ASSERT(m_pWidget);
117 }
118 
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)119 bool CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
120                                     CPDFSDK_Annot* pAnnot,
121                                     uint32_t nFlags,
122                                     const CFX_PointF& point) {
123   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true)) {
124     m_bValid = true;
125     FX_RECT rect = GetViewBBox(pPageView, pAnnot);
126     InvalidateRect(rect);
127     if (!rect.Contains(static_cast<int>(point.x), static_cast<int>(point.y)))
128       return false;
129 
130     return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
131   }
132 
133   return false;
134 }
135 
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)136 bool CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
137                                   CPDFSDK_Annot* pAnnot,
138                                   uint32_t nFlags,
139                                   const CFX_PointF& point) {
140   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
141   if (!pWnd)
142     return false;
143 
144   InvalidateRect(GetViewBBox(pPageView, pAnnot));
145   pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
146   return true;
147 }
148 
OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)149 bool CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
150                                       CPDFSDK_Annot* pAnnot,
151                                       uint32_t nFlags,
152                                       const CFX_PointF& point) {
153   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
154   if (!pWnd)
155     return false;
156 
157   pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
158   return true;
159 }
160 
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)161 bool CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
162                                   CPDFSDK_Annot* pAnnot,
163                                   uint32_t nFlags,
164                                   const CFX_PointF& point) {
165   if (m_ptOldPos != point)
166     m_ptOldPos = point;
167 
168   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
169   if (!pWnd)
170     return false;
171 
172   pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
173   return true;
174 }
175 
OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)176 bool CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
177                                    CPDFSDK_Annot* pAnnot,
178                                    uint32_t nFlags,
179                                    short zDelta,
180                                    const CFX_PointF& point) {
181   if (!IsValid())
182     return false;
183 
184   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true);
185   return pWnd && pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
186 }
187 
OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)188 bool CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
189                                     CPDFSDK_Annot* pAnnot,
190                                     uint32_t nFlags,
191                                     const CFX_PointF& point) {
192   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true);
193   if (!pWnd)
194     return false;
195 
196   pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
197   return true;
198 }
199 
OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)200 bool CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
201                                   CPDFSDK_Annot* pAnnot,
202                                   uint32_t nFlags,
203                                   const CFX_PointF& point) {
204   CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
205   if (!pWnd)
206     return false;
207 
208   pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
209   return true;
210 }
211 
OnKeyDown(CPDFSDK_Annot * pAnnot,uint32_t nKeyCode,uint32_t nFlags)212 bool CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
213                                 uint32_t nKeyCode,
214                                 uint32_t nFlags) {
215   if (IsValid()) {
216     CPDFSDK_PageView* pPageView = GetCurPageView(true);
217     ASSERT(pPageView);
218 
219     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
220       return pWnd->OnKeyDown(nKeyCode, nFlags);
221     }
222   }
223 
224   return false;
225 }
226 
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)227 bool CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
228                              uint32_t nChar,
229                              uint32_t nFlags) {
230   if (IsValid()) {
231     CPDFSDK_PageView* pPageView = GetCurPageView(true);
232     ASSERT(pPageView);
233 
234     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
235       return pWnd->OnChar(nChar, nFlags);
236     }
237   }
238 
239   return false;
240 }
241 
SetFocusForAnnot(CPDFSDK_Annot * pAnnot,uint32_t nFlag)242 void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
243   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
244   UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
245   CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, true);
246   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true))
247     pWnd->SetFocus();
248 
249   m_bValid = true;
250   InvalidateRect(GetViewBBox(pPageView, pAnnot));
251 }
252 
KillFocusForAnnot(CPDFSDK_Annot * pAnnot,uint32_t nFlag)253 void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
254   if (!IsValid())
255     return;
256 
257   CPDFSDK_PageView* pPageView = GetCurPageView(false);
258   if (!pPageView)
259     return;
260 
261   CommitData(pPageView, nFlag);
262 
263   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false))
264     pWnd->KillFocus();
265 
266   bool bDestroyPDFWindow;
267   switch (m_pWidget->GetFieldType()) {
268     case FIELDTYPE_PUSHBUTTON:
269     case FIELDTYPE_CHECKBOX:
270     case FIELDTYPE_RADIOBUTTON:
271       bDestroyPDFWindow = true;
272       break;
273     default:
274       bDestroyPDFWindow = false;
275       break;
276   }
277   EscapeFiller(pPageView, bDestroyPDFWindow);
278 }
279 
IsValid() const280 bool CFFL_FormFiller::IsValid() const {
281   return m_bValid;
282 }
283 
GetCreateParam()284 PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
285   ASSERT(m_pFormFillEnv);
286 
287   PWL_CREATEPARAM cp;
288   cp.pParentWnd = nullptr;
289   cp.pProvider.Reset(this);
290   cp.rcRectWnd = GetPDFWindowRect();
291 
292   uint32_t dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
293   uint32_t dwFieldFlag = m_pWidget->GetFieldFlags();
294   if (dwFieldFlag & FIELDFLAG_READONLY) {
295     dwCreateFlags |= PWS_READONLY;
296   }
297 
298   FX_COLORREF color;
299   if (m_pWidget->GetFillColor(color)) {
300     cp.sBackgroundColor =
301         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
302   }
303 
304   if (m_pWidget->GetBorderColor(color)) {
305     cp.sBorderColor =
306         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
307   }
308 
309   cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
310 
311   if (m_pWidget->GetTextColor(color)) {
312     cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
313   }
314 
315   cp.fFontSize = m_pWidget->GetFontSize();
316   cp.dwBorderWidth = m_pWidget->GetBorderWidth();
317 
318   cp.nBorderStyle = m_pWidget->GetBorderStyle();
319   switch (cp.nBorderStyle) {
320     case BorderStyle::DASH:
321       cp.sDash = CPWL_Dash(3, 3, 0);
322       break;
323     case BorderStyle::BEVELED:
324       cp.dwBorderWidth *= 2;
325       break;
326     case BorderStyle::INSET:
327       cp.dwBorderWidth *= 2;
328       break;
329     default:
330       break;
331   }
332 
333   if (cp.fFontSize <= 0)
334     dwCreateFlags |= PWS_AUTOFONTSIZE;
335 
336   cp.dwFlags = dwCreateFlags;
337   cp.pSystemHandler = m_pFormFillEnv->GetSysHandler();
338   return cp;
339 }
340 
GetPDFWindow(CPDFSDK_PageView * pPageView,bool bNew)341 CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
342                                         bool bNew) {
343   ASSERT(pPageView);
344 
345   auto it = m_Maps.find(pPageView);
346   const bool found = it != m_Maps.end();
347   CPWL_Wnd* pWnd = found ? it->second : nullptr;
348   if (!bNew)
349     return pWnd;
350 
351   if (found) {
352     CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
353     if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
354       return ResetPDFWindow(
355           pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
356     }
357   } else {
358     PWL_CREATEPARAM cp = GetCreateParam();
359     cp.pAttachedWidget.Reset(m_pWidget);
360 
361     CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
362     pPrivateData->pWidget = m_pWidget;
363     pPrivateData->pPageView = pPageView;
364     pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
365     pPrivateData->nValueAge = 0;
366 
367     cp.pAttachedData = pPrivateData;
368 
369     pWnd = NewPDFWindow(cp, pPageView);
370     m_Maps[pPageView] = pWnd;
371   }
372 
373   return pWnd;
374 }
375 
DestroyPDFWindow(CPDFSDK_PageView * pPageView)376 void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
377   auto it = m_Maps.find(pPageView);
378   if (it == m_Maps.end())
379     return;
380 
381   CPWL_Wnd* pWnd = it->second;
382   CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
383   pWnd->Destroy();
384   delete pWnd;
385   delete pData;
386 
387   m_Maps.erase(it);
388 }
389 
GetWindowMatrix(void * pAttachedData)390 CFX_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
391   if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
392     if (pPrivateData->pPageView) {
393       CFX_Matrix mtPageView;
394       pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
395 
396       CFX_Matrix mt = GetCurMatrix();
397       mt.Concat(mtPageView);
398 
399       return mt;
400     }
401   }
402   return CFX_Matrix(1, 0, 0, 1, 0, 0);
403 }
404 
GetCurMatrix()405 CFX_Matrix CFFL_FormFiller::GetCurMatrix() {
406   CFX_Matrix mt;
407 
408   CFX_FloatRect rcDA = m_pWidget->GetPDFAnnot()->GetRect();
409 
410   switch (m_pWidget->GetRotate()) {
411     default:
412     case 0:
413       mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
414       break;
415     case 90:
416       mt = CFX_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
417       break;
418     case 180:
419       mt = CFX_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
420                       rcDA.top - rcDA.bottom);
421       break;
422     case 270:
423       mt = CFX_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
424       break;
425   }
426   mt.e += rcDA.left;
427   mt.f += rcDA.bottom;
428 
429   return mt;
430 }
431 
LoadPopupMenuString(int nIndex)432 CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
433   ASSERT(m_pFormFillEnv);
434 
435   return L"";
436 }
437 
GetPDFWindowRect() const438 CFX_FloatRect CFFL_FormFiller::GetPDFWindowRect() const {
439   CFX_FloatRect rectAnnot = m_pWidget->GetPDFAnnot()->GetRect();
440 
441   FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
442   FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
443   if ((m_pWidget->GetRotate() / 90) & 0x01)
444     return CFX_FloatRect(0, 0, fHeight, fWidth);
445 
446   return CFX_FloatRect(0, 0, fWidth, fHeight);
447 }
448 
GetCurPageView(bool renew)449 CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView(bool renew) {
450   UnderlyingPageType* pPage = m_pAnnot->GetUnderlyingPage();
451   return m_pFormFillEnv ? m_pFormFillEnv->GetPageView(pPage, renew) : nullptr;
452 }
453 
GetFocusBox(CPDFSDK_PageView * pPageView)454 CFX_FloatRect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
455   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
456     CFX_FloatRect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
457     CFX_FloatRect rcPage = pPageView->GetPDFPage()->GetPageBBox();
458     if (rcPage.Contains(rcFocus))
459       return rcFocus;
460   }
461   return CFX_FloatRect(0, 0, 0, 0);
462 }
463 
FFLtoPWL(const CFX_FloatRect & rect)464 CFX_FloatRect CFFL_FormFiller::FFLtoPWL(const CFX_FloatRect& rect) {
465   CFX_Matrix mt;
466   mt.SetReverse(GetCurMatrix());
467 
468   CFX_FloatRect temp = rect;
469   mt.TransformRect(temp);
470 
471   return temp;
472 }
473 
PWLtoFFL(const CFX_FloatRect & rect)474 CFX_FloatRect CFFL_FormFiller::PWLtoFFL(const CFX_FloatRect& rect) {
475   CFX_Matrix mt = GetCurMatrix();
476 
477   CFX_FloatRect temp = rect;
478   mt.TransformRect(temp);
479 
480   return temp;
481 }
482 
FFLtoPWL(const CFX_PointF & point)483 CFX_PointF CFFL_FormFiller::FFLtoPWL(const CFX_PointF& point) {
484   CFX_Matrix mt;
485   mt.SetReverse(GetCurMatrix());
486   return mt.Transform(point);
487 }
488 
PWLtoFFL(const CFX_PointF & point)489 CFX_PointF CFFL_FormFiller::PWLtoFFL(const CFX_PointF& point) {
490   return GetCurMatrix().Transform(point);
491 }
492 
WndtoPWL(CPDFSDK_PageView * pPageView,const CFX_PointF & pt)493 CFX_PointF CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
494                                      const CFX_PointF& pt) {
495   return FFLtoPWL(pt);
496 }
497 
FFLtoWnd(CPDFSDK_PageView * pPageView,const CFX_FloatRect & rect)498 CFX_FloatRect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
499                                         const CFX_FloatRect& rect) {
500   return rect;
501 }
502 
CommitData(CPDFSDK_PageView * pPageView,uint32_t nFlag)503 bool CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView, uint32_t nFlag) {
504   if (IsDataChanged(pPageView)) {
505     bool bRC = true;
506     bool bExit = false;
507     CFFL_InteractiveFormFiller* pFormFiller =
508         m_pFormFillEnv->GetInteractiveFormFiller();
509     CPDFSDK_Annot::ObservedPtr pObserved(m_pWidget);
510     pFormFiller->OnKeyStrokeCommit(&pObserved, pPageView, bRC, bExit, nFlag);
511     if (!pObserved || bExit)
512       return true;
513     if (!bRC) {
514       ResetPDFWindow(pPageView, false);
515       return true;
516     }
517     pFormFiller->OnValidate(&pObserved, pPageView, bRC, bExit, nFlag);
518     if (!pObserved || bExit)
519       return true;
520     if (!bRC) {
521       ResetPDFWindow(pPageView, false);
522       return true;
523     }
524     SaveData(pPageView);
525     pFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
526     if (bExit)
527       return true;
528 
529     pFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
530   }
531   return true;
532 }
533 
IsDataChanged(CPDFSDK_PageView * pPageView)534 bool CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
535   return false;
536 }
537 
SaveData(CPDFSDK_PageView * pPageView)538 void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
539 
540 #ifdef PDF_ENABLE_XFA
IsFieldFull(CPDFSDK_PageView * pPageView)541 bool CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
542   return false;
543 }
544 #endif  // PDF_ENABLE_XFA
545 
SetChangeMark()546 void CFFL_FormFiller::SetChangeMark() {
547   m_pFormFillEnv->OnChange();
548 }
549 
GetActionData(CPDFSDK_PageView * pPageView,CPDF_AAction::AActionType type,PDFSDK_FieldAction & fa)550 void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
551                                     CPDF_AAction::AActionType type,
552                                     PDFSDK_FieldAction& fa) {
553   fa.sValue = m_pWidget->GetValue();
554 }
555 
SetActionData(CPDFSDK_PageView * pPageView,CPDF_AAction::AActionType type,const PDFSDK_FieldAction & fa)556 void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
557                                     CPDF_AAction::AActionType type,
558                                     const PDFSDK_FieldAction& fa) {}
559 
IsActionDataChanged(CPDF_AAction::AActionType type,const PDFSDK_FieldAction & faOld,const PDFSDK_FieldAction & faNew)560 bool CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
561                                           const PDFSDK_FieldAction& faOld,
562                                           const PDFSDK_FieldAction& faNew) {
563   return false;
564 }
565 
SaveState(CPDFSDK_PageView * pPageView)566 void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
567 
RestoreState(CPDFSDK_PageView * pPageView)568 void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
569 
ResetPDFWindow(CPDFSDK_PageView * pPageView,bool bRestoreValue)570 CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
571                                           bool bRestoreValue) {
572   return GetPDFWindow(pPageView, false);
573 }
574 
TimerProc()575 void CFFL_FormFiller::TimerProc() {}
576 
GetSystemHandler() const577 CFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
578   return m_pFormFillEnv->GetSysHandler();
579 }
580 
EscapeFiller(CPDFSDK_PageView * pPageView,bool bDestroyPDFWindow)581 void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
582                                    bool bDestroyPDFWindow) {
583   m_bValid = false;
584 
585   InvalidateRect(GetViewBBox(pPageView, m_pWidget));
586   if (bDestroyPDFWindow)
587     DestroyPDFWindow(pPageView);
588 }
589 
InvalidateRect(const FX_RECT & rect)590 void CFFL_FormFiller::InvalidateRect(const FX_RECT& rect) {
591   m_pFormFillEnv->Invalidate(m_pWidget->GetUnderlyingPage(), rect);
592 }
593 
CFFL_Button(CPDFSDK_FormFillEnvironment * pApp,CPDFSDK_Annot * pWidget)594 CFFL_Button::CFFL_Button(CPDFSDK_FormFillEnvironment* pApp,
595                          CPDFSDK_Annot* pWidget)
596     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(false), m_bMouseDown(false) {}
597 
~CFFL_Button()598 CFFL_Button::~CFFL_Button() {}
599 
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)600 void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
601                                CPDFSDK_Annot* pAnnot) {
602   m_bMouseIn = true;
603   InvalidateRect(GetViewBBox(pPageView, pAnnot));
604 }
605 
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)606 void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
607                               CPDFSDK_Annot* pAnnot) {
608   m_bMouseIn = false;
609 
610   InvalidateRect(GetViewBBox(pPageView, pAnnot));
611   EndTimer();
612   ASSERT(m_pWidget);
613 }
614 
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)615 bool CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
616                                 CPDFSDK_Annot* pAnnot,
617                                 uint32_t nFlags,
618                                 const CFX_PointF& point) {
619   if (!pAnnot->GetRect().Contains(point))
620     return false;
621 
622   m_bMouseDown = true;
623   m_bValid = true;
624   InvalidateRect(GetViewBBox(pPageView, pAnnot));
625   return true;
626 }
627 
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)628 bool CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
629                               CPDFSDK_Annot* pAnnot,
630                               uint32_t nFlags,
631                               const CFX_PointF& point) {
632   if (!pAnnot->GetRect().Contains(point))
633     return false;
634 
635   m_bMouseDown = false;
636   m_pWidget->GetPDFPage();
637 
638   InvalidateRect(GetViewBBox(pPageView, pAnnot));
639   return true;
640 }
641 
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)642 bool CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
643                               CPDFSDK_Annot* pAnnot,
644                               uint32_t nFlags,
645                               const CFX_PointF& point) {
646   ASSERT(m_pFormFillEnv);
647   return true;
648 }
649 
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)650 void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
651                          CPDFSDK_Annot* pAnnot,
652                          CFX_RenderDevice* pDevice,
653                          CFX_Matrix* pUser2Device) {
654   ASSERT(pPageView);
655   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
656   CPDF_FormControl* pCtrl = pWidget->GetFormControl();
657   CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
658 
659   if (eHM != CPDF_FormControl::Push) {
660     pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
661     return;
662   }
663 
664   if (m_bMouseDown) {
665     if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
666       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, nullptr);
667     else
668       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
669                               nullptr);
670   } else if (m_bMouseIn) {
671     if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
672       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
673                               nullptr);
674     else
675       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
676                               nullptr);
677   } else {
678     pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
679   }
680 }
681 
OnDrawDeactive(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)682 void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
683                                  CPDFSDK_Annot* pAnnot,
684                                  CFX_RenderDevice* pDevice,
685                                  CFX_Matrix* pUser2Device) {
686   OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
687 }
688