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
20CFFL_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
26CFFL_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
38void 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
45CPDF_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
53FX_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
76void 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
94void 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
103void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}
104
105void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}
106
107void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}
108
109void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
110                                   CPDFSDK_Annot* pAnnot) {}
111
112void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
113                                  CPDFSDK_Annot* pAnnot) {
114  EndTimer();
115  ASSERT(m_pWidget);
116}
117
118FX_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
136FX_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
150FX_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
162FX_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
178FX_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
193FX_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
205FX_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
217FX_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
232FX_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
247void 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
260void 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
287FX_BOOL CFFL_FormFiller::IsValid() const {
288  return m_bValid;
289}
290
291PWL_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
357CPWL_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
392void 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
406CFX_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
420CFX_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
448CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
449  ASSERT(m_pApp);
450
451  return L"";
452}
453
454CPDF_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
466CPDFSDK_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
472CPDF_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
482CPDF_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
492CPDF_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
501CPDF_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
511CPDF_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
520CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
521                                     const CPDF_Point& pt) {
522  return FFLtoPWL(pt);
523}
524
525CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
526                                    const CPDF_Rect& rect) {
527  return rect;
528}
529
530FX_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
562FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
563  return FALSE;
564}
565
566void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
567
568#ifdef PDF_ENABLE_XFA
569FX_BOOL CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
570  return FALSE;
571}
572#endif  // PDF_ENABLE_XFA
573
574void CFFL_FormFiller::SetChangeMark() {
575  m_pApp->FFI_OnChange();
576}
577
578void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
579                                    CPDF_AAction::AActionType type,
580                                    PDFSDK_FieldAction& fa) {
581  fa.sValue = m_pWidget->GetValue();
582}
583
584void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
585                                    CPDF_AAction::AActionType type,
586                                    const PDFSDK_FieldAction& fa) {}
587
588FX_BOOL CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
589                                             const PDFSDK_FieldAction& faOld,
590                                             const PDFSDK_FieldAction& faNew) {
591  return FALSE;
592}
593
594void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
595
596void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
597
598CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
599                                          FX_BOOL bRestoreValue) {
600  return GetPDFWindow(pPageView, FALSE);
601}
602
603void CFFL_FormFiller::TimerProc() {}
604
605IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
606  return m_pApp->GetSysHandler();
607}
608
609void 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
620void 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
628CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
629    : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
630
631CFFL_Button::~CFFL_Button() {}
632
633void 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
640void 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
650FX_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
665FX_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
681FX_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
690void 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
721void 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