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