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/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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
    103 void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}
    104 
    105 void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}
    106 
    107 void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}
    108 
    109 void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
    110                                    CPDFSDK_Annot* pAnnot) {}
    111 
    112 void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
    113                                   CPDFSDK_Annot* pAnnot) {
    114   EndTimer();
    115   ASSERT(m_pWidget);
    116 }
    117 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    287 FX_BOOL CFFL_FormFiller::IsValid() const {
    288   return m_bValid;
    289 }
    290 
    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 
    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 
    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 
    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 
    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 
    448 CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
    449   ASSERT(m_pApp);
    450 
    451   return L"";
    452 }
    453 
    454 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 
    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 
    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 
    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 
    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 
    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 
    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 
    520 CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
    521                                      const CPDF_Point& pt) {
    522   return FFLtoPWL(pt);
    523 }
    524 
    525 CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
    526                                     const CPDF_Rect& rect) {
    527   return rect;
    528 }
    529 
    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 
    562 FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
    563   return FALSE;
    564 }
    565 
    566 void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
    567 
    568 #ifdef PDF_ENABLE_XFA
    569 FX_BOOL CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
    570   return FALSE;
    571 }
    572 #endif  // PDF_ENABLE_XFA
    573 
    574 void CFFL_FormFiller::SetChangeMark() {
    575   m_pApp->FFI_OnChange();
    576 }
    577 
    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 
    584 void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
    585                                     CPDF_AAction::AActionType type,
    586                                     const PDFSDK_FieldAction& fa) {}
    587 
    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 
    594 void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
    595 
    596 void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
    597 
    598 CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
    599                                           FX_BOOL bRestoreValue) {
    600   return GetPDFWindow(pPageView, FALSE);
    601 }
    602 
    603 void CFFL_FormFiller::TimerProc() {}
    604 
    605 IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
    606   return m_pApp->GetSysHandler();
    607 }
    608 
    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 
    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 
    628 CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
    629     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
    630 
    631 CFFL_Button::~CFFL_Button() {}
    632 
    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 
    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 
    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 
    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 
    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 
    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 
    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