Home | History | Annotate | Download | only in formfiller
      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 
     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 
     30 CFFL_FormFiller::~CFFL_FormFiller() {
     31   DestroyWindows();
     32 }
     33 
     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 
     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 
     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 
     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 
     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 
    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 
    110 void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
    111                                    CPDFSDK_Annot* pAnnot) {}
    112 
    113 void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
    114                                   CPDFSDK_Annot* pAnnot) {
    115   EndTimer();
    116   ASSERT(m_pWidget);
    117 }
    118 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    280 bool CFFL_FormFiller::IsValid() const {
    281   return m_bValid;
    282 }
    283 
    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 
    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 
    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 
    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 
    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 
    432 CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
    433   ASSERT(m_pFormFillEnv);
    434 
    435   return L"";
    436 }
    437 
    438 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 
    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 
    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 
    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 
    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 
    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 
    489 CFX_PointF CFFL_FormFiller::PWLtoFFL(const CFX_PointF& point) {
    490   return GetCurMatrix().Transform(point);
    491 }
    492 
    493 CFX_PointF CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
    494                                      const CFX_PointF& pt) {
    495   return FFLtoPWL(pt);
    496 }
    497 
    498 CFX_FloatRect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
    499                                         const CFX_FloatRect& rect) {
    500   return rect;
    501 }
    502 
    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 
    534 bool CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
    535   return false;
    536 }
    537 
    538 void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
    539 
    540 #ifdef PDF_ENABLE_XFA
    541 bool CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
    542   return false;
    543 }
    544 #endif  // PDF_ENABLE_XFA
    545 
    546 void CFFL_FormFiller::SetChangeMark() {
    547   m_pFormFillEnv->OnChange();
    548 }
    549 
    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 
    556 void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
    557                                     CPDF_AAction::AActionType type,
    558                                     const PDFSDK_FieldAction& fa) {}
    559 
    560 bool CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
    561                                           const PDFSDK_FieldAction& faOld,
    562                                           const PDFSDK_FieldAction& faNew) {
    563   return false;
    564 }
    565 
    566 void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
    567 
    568 void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
    569 
    570 CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
    571                                           bool bRestoreValue) {
    572   return GetPDFWindow(pPageView, false);
    573 }
    574 
    575 void CFFL_FormFiller::TimerProc() {}
    576 
    577 CFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
    578   return m_pFormFillEnv->GetSysHandler();
    579 }
    580 
    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 
    590 void CFFL_FormFiller::InvalidateRect(const FX_RECT& rect) {
    591   m_pFormFillEnv->Invalidate(m_pWidget->GetUnderlyingPage(), rect);
    592 }
    593 
    594 CFFL_Button::CFFL_Button(CPDFSDK_FormFillEnvironment* pApp,
    595                          CPDFSDK_Annot* pWidget)
    596     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(false), m_bMouseDown(false) {}
    597 
    598 CFFL_Button::~CFFL_Button() {}
    599 
    600 void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
    601                                CPDFSDK_Annot* pAnnot) {
    602   m_bMouseIn = true;
    603   InvalidateRect(GetViewBBox(pPageView, pAnnot));
    604 }
    605 
    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 
    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 
    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 
    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 
    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 
    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