Home | History | Annotate | Download | only in src
      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/fsdk_baseform.h"
      8 
      9 #include <memory>
     10 
     11 #include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
     12 #include "fpdfsdk/include/fsdk_actionhandler.h"
     13 #include "fpdfsdk/include/fsdk_baseannot.h"
     14 #include "fpdfsdk/include/fsdk_define.h"
     15 #include "fpdfsdk/include/fsdk_mgr.h"
     16 #include "fpdfsdk/include/javascript/IJavaScript.h"
     17 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
     18 
     19 #ifdef PDF_ENABLE_XFA
     20 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
     21 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
     22 #endif  // PDF_ENABLE_XFA
     23 
     24 #define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01)
     25 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
     26 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
     27 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
     28 
     29 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
     30                                CPDFSDK_PageView* pPageView,
     31                                CPDFSDK_InterForm* pInterForm)
     32     : CPDFSDK_BAAnnot(pAnnot, pPageView),
     33       m_pInterForm(pInterForm),
     34       m_nAppAge(0),
     35       m_nValueAge(0)
     36 #ifdef PDF_ENABLE_XFA
     37       ,
     38       m_hMixXFAWidget(NULL),
     39       m_pWidgetHandler(NULL)
     40 #endif  // PDF_ENABLE_XFA
     41 {
     42 }
     43 
     44 CPDFSDK_Widget::~CPDFSDK_Widget() {}
     45 
     46 #ifdef PDF_ENABLE_XFA
     47 IXFA_Widget* CPDFSDK_Widget::GetMixXFAWidget() const {
     48   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
     49   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
     50   if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
     51     if (!m_hMixXFAWidget) {
     52       if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
     53         CFX_WideString sName;
     54         if (this->GetFieldType() == FIELDTYPE_RADIOBUTTON) {
     55           sName = this->GetAnnotName();
     56           if (sName.IsEmpty())
     57             sName = GetName();
     58         } else
     59           sName = GetName();
     60 
     61         if (!sName.IsEmpty())
     62           m_hMixXFAWidget = pDocView->GetWidgetByName(sName);
     63       }
     64     }
     65     return m_hMixXFAWidget;
     66   }
     67 
     68   return NULL;
     69 }
     70 
     71 IXFA_Widget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
     72   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
     73   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
     74   if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
     75     if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
     76       CFX_WideString sName = GetName();
     77       if (!sName.IsEmpty())
     78         return pDocView->GetWidgetByName(sName);
     79     }
     80   }
     81 
     82   return nullptr;
     83 }
     84 
     85 IXFA_WidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
     86   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
     87   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
     88   if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
     89     if (!m_pWidgetHandler) {
     90       if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
     91         m_pWidgetHandler = pDocView->GetWidgetHandler();
     92       }
     93     }
     94     return m_pWidgetHandler;
     95   }
     96 
     97   return NULL;
     98 }
     99 
    100 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
    101   XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
    102 
    103   switch (eXFAAAT) {
    104     case PDFSDK_XFA_Click:
    105       eEventType = XFA_EVENT_Click;
    106       break;
    107     case PDFSDK_XFA_Full:
    108       eEventType = XFA_EVENT_Full;
    109       break;
    110     case PDFSDK_XFA_PreOpen:
    111       eEventType = XFA_EVENT_PreOpen;
    112       break;
    113     case PDFSDK_XFA_PostOpen:
    114       eEventType = XFA_EVENT_PostOpen;
    115       break;
    116   }
    117 
    118   return eEventType;
    119 }
    120 
    121 static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
    122                                      FX_BOOL bWillCommit) {
    123   XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
    124 
    125   switch (eAAT) {
    126     case CPDF_AAction::CursorEnter:
    127       eEventType = XFA_EVENT_MouseEnter;
    128       break;
    129     case CPDF_AAction::CursorExit:
    130       eEventType = XFA_EVENT_MouseExit;
    131       break;
    132     case CPDF_AAction::ButtonDown:
    133       eEventType = XFA_EVENT_MouseDown;
    134       break;
    135     case CPDF_AAction::ButtonUp:
    136       eEventType = XFA_EVENT_MouseUp;
    137       break;
    138     case CPDF_AAction::GetFocus:
    139       eEventType = XFA_EVENT_Enter;
    140       break;
    141     case CPDF_AAction::LoseFocus:
    142       eEventType = XFA_EVENT_Exit;
    143       break;
    144     case CPDF_AAction::PageOpen:
    145       break;
    146     case CPDF_AAction::PageClose:
    147       break;
    148     case CPDF_AAction::PageVisible:
    149       break;
    150     case CPDF_AAction::PageInvisible:
    151       break;
    152     case CPDF_AAction::KeyStroke:
    153       if (!bWillCommit) {
    154         eEventType = XFA_EVENT_Change;
    155       }
    156       break;
    157     case CPDF_AAction::Validate:
    158       eEventType = XFA_EVENT_Validate;
    159       break;
    160     case CPDF_AAction::OpenPage:
    161     case CPDF_AAction::ClosePage:
    162     case CPDF_AAction::Format:
    163     case CPDF_AAction::Calculate:
    164     case CPDF_AAction::CloseDocument:
    165     case CPDF_AAction::SaveDocument:
    166     case CPDF_AAction::DocumentSaved:
    167     case CPDF_AAction::PrintDocument:
    168     case CPDF_AAction::DocumentPrinted:
    169       break;
    170   }
    171 
    172   return eEventType;
    173 }
    174 
    175 FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
    176   if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    177     if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    178       XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
    179 
    180       if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
    181           GetFieldType() == FIELDTYPE_RADIOBUTTON) {
    182         if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
    183           CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
    184           if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
    185             return TRUE;
    186         }
    187       }
    188 
    189       {
    190         CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
    191         return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
    192       }
    193     }
    194   }
    195 
    196   return FALSE;
    197 }
    198 
    199 FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
    200                                      PDFSDK_FieldAction& data,
    201                                      CPDFSDK_PageView* pPageView) {
    202   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
    203   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
    204   if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
    205     XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
    206 
    207     if (eEventType != XFA_EVENT_Unknown) {
    208       if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    209         CXFA_EventParam param;
    210         param.m_eType = eEventType;
    211         param.m_wsChange = data.sChange;
    212         param.m_iCommitKey = data.nCommitKey;
    213         param.m_bShift = data.bShift;
    214         param.m_iSelStart = data.nSelStart;
    215         param.m_iSelEnd = data.nSelEnd;
    216         param.m_wsFullText = data.sValue;
    217         param.m_bKeyDown = data.bKeyDown;
    218         param.m_bModifier = data.bModifier;
    219         param.m_wsNewText = data.sValue;
    220         if (data.nSelEnd > data.nSelStart)
    221           param.m_wsNewText.Delete(data.nSelStart,
    222                                    data.nSelEnd - data.nSelStart);
    223         for (int i = 0; i < data.sChange.GetLength(); i++)
    224           param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
    225         param.m_wsPrevText = data.sValue;
    226 
    227         if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
    228             GetFieldType() == FIELDTYPE_RADIOBUTTON) {
    229           if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
    230             CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
    231             param.m_pTarget = pAcc;
    232             pXFAWidgetHandler->ProcessEvent(pAcc, &param);
    233           }
    234 
    235           {
    236             CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
    237             param.m_pTarget = pAcc;
    238             int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
    239             return nRet == XFA_EVENTERROR_Sucess;
    240           }
    241         } else {
    242           CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
    243           param.m_pTarget = pAcc;
    244           int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
    245           return nRet == XFA_EVENTERROR_Sucess;
    246         }
    247 
    248         if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
    249           pDocView->UpdateDocView();
    250         }
    251       }
    252     }
    253   }
    254 
    255   return FALSE;
    256 }
    257 
    258 void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) {
    259   if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    260     if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    261       CPDF_FormField* pFormField = GetFormField();
    262       ASSERT(pFormField != NULL);
    263 
    264       if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
    265         switch (GetFieldType()) {
    266           case FIELDTYPE_CHECKBOX:
    267           case FIELDTYPE_RADIOBUTTON: {
    268             CPDF_FormControl* pFormCtrl = GetFormControl();
    269             ASSERT(pFormCtrl != NULL);
    270 
    271             XFA_CHECKSTATE eCheckState =
    272                 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
    273             pWidgetAcc->SetCheckState(eCheckState);
    274           } break;
    275           case FIELDTYPE_TEXTFIELD:
    276             pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
    277             break;
    278           case FIELDTYPE_LISTBOX: {
    279             pWidgetAcc->ClearAllSelections();
    280 
    281             for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz;
    282                  i++) {
    283               int nIndex = pFormField->GetSelectedIndex(i);
    284               if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
    285                 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
    286             }
    287           } break;
    288           case FIELDTYPE_COMBOBOX: {
    289             pWidgetAcc->ClearAllSelections();
    290 
    291             for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz;
    292                  i++) {
    293               int nIndex = pFormField->GetSelectedIndex(i);
    294               if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
    295                 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
    296             }
    297           }
    298 
    299             pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
    300             break;
    301         }
    302 
    303         if (bSynchronizeElse)
    304           pWidgetAcc->ProcessValueChanged();
    305       }
    306     }
    307   }
    308 }
    309 
    310 void CPDFSDK_Widget::SynchronizeXFAValue() {
    311   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
    312   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
    313   IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
    314   if (!pXFADocView)
    315     return;
    316 
    317   if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
    318     if (GetXFAWidgetHandler()) {
    319       CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
    320                                           GetFormControl());
    321     }
    322   }
    323 }
    324 
    325 void CPDFSDK_Widget::SynchronizeXFAItems() {
    326   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
    327   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
    328   IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
    329   if (!pXFADocView)
    330     return;
    331 
    332   if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
    333     if (GetXFAWidgetHandler())
    334       SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
    335   }
    336 }
    337 
    338 void CPDFSDK_Widget::SynchronizeXFAValue(IXFA_DocView* pXFADocView,
    339                                          IXFA_Widget* hWidget,
    340                                          CPDF_FormField* pFormField,
    341                                          CPDF_FormControl* pFormControl) {
    342   ASSERT(pXFADocView != NULL);
    343   ASSERT(hWidget != NULL);
    344 
    345   if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
    346     ASSERT(pFormField != NULL);
    347     ASSERT(pFormControl != NULL);
    348 
    349     switch (pFormField->GetFieldType()) {
    350       case FIELDTYPE_CHECKBOX: {
    351         if (CXFA_WidgetAcc* pWidgetAcc =
    352                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    353           FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
    354 
    355           pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
    356                                    bChecked, TRUE);
    357         }
    358       } break;
    359       case FIELDTYPE_RADIOBUTTON: {
    360         if (CXFA_WidgetAcc* pWidgetAcc =
    361                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    362           FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
    363 
    364           pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
    365                                    bChecked, TRUE);
    366         }
    367       } break;
    368       case FIELDTYPE_TEXTFIELD: {
    369         if (CXFA_WidgetAcc* pWidgetAcc =
    370                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    371           CFX_WideString sValue;
    372           pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
    373           pFormField->SetValue(sValue, TRUE);
    374         }
    375       } break;
    376       case FIELDTYPE_LISTBOX: {
    377         pFormField->ClearSelection(FALSE);
    378 
    379         if (CXFA_WidgetAcc* pWidgetAcc =
    380                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    381           for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
    382             int nIndex = pWidgetAcc->GetSelectedItem(i);
    383 
    384             if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
    385               pFormField->SetItemSelection(nIndex, TRUE, TRUE);
    386             }
    387           }
    388         }
    389       } break;
    390       case FIELDTYPE_COMBOBOX: {
    391         pFormField->ClearSelection(FALSE);
    392 
    393         if (CXFA_WidgetAcc* pWidgetAcc =
    394                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    395           for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
    396             int nIndex = pWidgetAcc->GetSelectedItem(i);
    397 
    398             if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
    399               pFormField->SetItemSelection(nIndex, TRUE, TRUE);
    400             }
    401           }
    402 
    403           CFX_WideString sValue;
    404           pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
    405           pFormField->SetValue(sValue, TRUE);
    406         }
    407       } break;
    408     }
    409   }
    410 }
    411 
    412 void CPDFSDK_Widget::SynchronizeXFAItems(IXFA_DocView* pXFADocView,
    413                                          IXFA_Widget* hWidget,
    414                                          CPDF_FormField* pFormField,
    415                                          CPDF_FormControl* pFormControl) {
    416   ASSERT(pXFADocView != NULL);
    417   ASSERT(hWidget != NULL);
    418 
    419   if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
    420     ASSERT(pFormField != NULL);
    421 
    422     switch (pFormField->GetFieldType()) {
    423       case FIELDTYPE_LISTBOX: {
    424         pFormField->ClearSelection(FALSE);
    425         pFormField->ClearOptions(TRUE);
    426 
    427         if (CXFA_WidgetAcc* pWidgetAcc =
    428                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    429           for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
    430                i++) {
    431             CFX_WideString swText;
    432             pWidgetAcc->GetChoiceListItem(swText, i);
    433 
    434             pFormField->InsertOption(swText, i, TRUE);
    435           }
    436         }
    437       } break;
    438       case FIELDTYPE_COMBOBOX: {
    439         pFormField->ClearSelection(FALSE);
    440         pFormField->ClearOptions(FALSE);
    441 
    442         if (CXFA_WidgetAcc* pWidgetAcc =
    443                 pXFAWidgetHandler->GetDataAcc(hWidget)) {
    444           for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
    445                i++) {
    446             CFX_WideString swText;
    447             pWidgetAcc->GetChoiceListItem(swText, i);
    448 
    449             pFormField->InsertOption(swText, i, FALSE);
    450           }
    451         }
    452 
    453         pFormField->SetValue(L"", TRUE);
    454       } break;
    455     }
    456   }
    457 }
    458 #endif  // PDF_ENABLE_XFA
    459 
    460 FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(
    461     CPDF_Annot::AppearanceMode mode) {
    462   CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP");
    463   if (!pAP)
    464     return FALSE;
    465 
    466   // Choose the right sub-ap
    467   const FX_CHAR* ap_entry = "N";
    468   if (mode == CPDF_Annot::Down)
    469     ap_entry = "D";
    470   else if (mode == CPDF_Annot::Rollover)
    471     ap_entry = "R";
    472   if (!pAP->KeyExist(ap_entry))
    473     ap_entry = "N";
    474 
    475   // Get the AP stream or subdirectory
    476   CPDF_Object* psub = pAP->GetElementValue(ap_entry);
    477   if (!psub)
    478     return FALSE;
    479 
    480   int nFieldType = GetFieldType();
    481   switch (nFieldType) {
    482     case FIELDTYPE_PUSHBUTTON:
    483     case FIELDTYPE_COMBOBOX:
    484     case FIELDTYPE_LISTBOX:
    485     case FIELDTYPE_TEXTFIELD:
    486     case FIELDTYPE_SIGNATURE:
    487       return psub->IsStream();
    488     case FIELDTYPE_CHECKBOX:
    489     case FIELDTYPE_RADIOBUTTON:
    490       if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
    491         return pSubDict->GetStream(GetAppState()) != NULL;
    492       }
    493       return FALSE;
    494   }
    495   return TRUE;
    496 }
    497 
    498 int CPDFSDK_Widget::GetFieldType() const {
    499   return GetFormField()->GetFieldType();
    500 }
    501 
    502 FX_BOOL CPDFSDK_Widget::IsAppearanceValid() {
    503 #ifdef PDF_ENABLE_XFA
    504   CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
    505   CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
    506   int nDocType = pDoc->GetDocType();
    507   if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
    508     return TRUE;
    509 #endif  // PDF_ENABLE_XFA
    510   return CPDFSDK_BAAnnot::IsAppearanceValid();
    511 }
    512 
    513 int CPDFSDK_Widget::GetFieldFlags() const {
    514   CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
    515   CPDF_FormControl* pFormControl =
    516       pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
    517   CPDF_FormField* pFormField = pFormControl->GetField();
    518   return pFormField->GetFieldFlags();
    519 }
    520 
    521 CFX_ByteString CPDFSDK_Widget::GetSubType() const {
    522   int nType = GetFieldType();
    523 
    524   if (nType == FIELDTYPE_SIGNATURE)
    525     return BFFT_SIGNATURE;
    526   return CPDFSDK_Annot::GetSubType();
    527 }
    528 
    529 CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
    530   return GetFormControl()->GetField();
    531 }
    532 
    533 CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
    534   CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
    535   return pPDFInterForm->GetControlByDict(GetAnnotDict());
    536 }
    537 
    538 CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
    539     CPDF_InterForm* pInterForm,
    540     const CPDF_Dictionary* pAnnotDict) {
    541   ASSERT(pAnnotDict);
    542   return pInterForm->GetControlByDict(pAnnotDict);
    543 }
    544 
    545 int CPDFSDK_Widget::GetRotate() const {
    546   CPDF_FormControl* pCtrl = GetFormControl();
    547   return pCtrl->GetRotation() % 360;
    548 }
    549 
    550 #ifdef PDF_ENABLE_XFA
    551 CFX_WideString CPDFSDK_Widget::GetName() const {
    552   CPDF_FormField* pFormField = GetFormField();
    553   return pFormField->GetFullName();
    554 }
    555 #endif  // PDF_ENABLE_XFA
    556 
    557 FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
    558   CPDF_FormControl* pFormCtrl = GetFormControl();
    559   int iColorType = 0;
    560   color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
    561 
    562   return iColorType != COLORTYPE_TRANSPARENT;
    563 }
    564 
    565 FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
    566   CPDF_FormControl* pFormCtrl = GetFormControl();
    567   int iColorType = 0;
    568   color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
    569 
    570   return iColorType != COLORTYPE_TRANSPARENT;
    571 }
    572 
    573 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
    574   CPDF_FormControl* pFormCtrl = GetFormControl();
    575   CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
    576   if (da.HasColor()) {
    577     FX_ARGB argb;
    578     int iColorType = COLORTYPE_TRANSPARENT;
    579     da.GetColor(argb, iColorType);
    580     color = FX_ARGBTOCOLORREF(argb);
    581 
    582     return iColorType != COLORTYPE_TRANSPARENT;
    583   }
    584 
    585   return FALSE;
    586 }
    587 
    588 FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
    589   CPDF_FormControl* pFormCtrl = GetFormControl();
    590   CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
    591   CFX_ByteString csFont = "";
    592   FX_FLOAT fFontSize = 0.0f;
    593   pDa.GetFont(csFont, fFontSize);
    594 
    595   return fFontSize;
    596 }
    597 
    598 int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
    599 #ifdef PDF_ENABLE_XFA
    600   if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    601     if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    602       if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
    603         if (nIndex < pWidgetAcc->CountSelectedItems())
    604           return pWidgetAcc->GetSelectedItem(nIndex);
    605       }
    606     }
    607   }
    608 #endif  // PDF_ENABLE_XFA
    609   CPDF_FormField* pFormField = GetFormField();
    610   return pFormField->GetSelectedIndex(nIndex);
    611 }
    612 
    613 #ifdef PDF_ENABLE_XFA
    614 CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay) const {
    615   if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    616     if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    617       if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
    618         CFX_WideString sValue;
    619         pWidgetAcc->GetValue(sValue, bDisplay ? XFA_VALUEPICTURE_Display
    620                                               : XFA_VALUEPICTURE_Edit);
    621         return sValue;
    622       }
    623     }
    624   }
    625 #else
    626 CFX_WideString CPDFSDK_Widget::GetValue() const {
    627 #endif  // PDF_ENABLE_XFA
    628   CPDF_FormField* pFormField = GetFormField();
    629   return pFormField->GetValue();
    630 }
    631 
    632 CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
    633   CPDF_FormField* pFormField = GetFormField();
    634   return pFormField->GetDefaultValue();
    635 }
    636 
    637 CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
    638   CPDF_FormField* pFormField = GetFormField();
    639   return pFormField->GetOptionLabel(nIndex);
    640 }
    641 
    642 int CPDFSDK_Widget::CountOptions() const {
    643   CPDF_FormField* pFormField = GetFormField();
    644   return pFormField->CountOptions();
    645 }
    646 
    647 FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
    648 #ifdef PDF_ENABLE_XFA
    649   if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    650     if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    651       if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
    652         if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
    653           return pWidgetAcc->GetItemState(nIndex);
    654 
    655         return FALSE;
    656       }
    657     }
    658   }
    659 #endif  // PDF_ENABLE_XFA
    660   CPDF_FormField* pFormField = GetFormField();
    661   return pFormField->IsItemSelected(nIndex);
    662 }
    663 
    664 int CPDFSDK_Widget::GetTopVisibleIndex() const {
    665   CPDF_FormField* pFormField = GetFormField();
    666   return pFormField->GetTopVisibleIndex();
    667 }
    668 
    669 FX_BOOL CPDFSDK_Widget::IsChecked() const {
    670 #ifdef PDF_ENABLE_XFA
    671   if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
    672     if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
    673       if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
    674         FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
    675         return bChecked;
    676       }
    677     }
    678   }
    679 #endif  // PDF_ENABLE_XFA
    680   CPDF_FormControl* pFormCtrl = GetFormControl();
    681   return pFormCtrl->IsChecked();
    682 }
    683 
    684 int CPDFSDK_Widget::GetAlignment() const {
    685   CPDF_FormControl* pFormCtrl = GetFormControl();
    686   return pFormCtrl->GetControlAlignment();
    687 }
    688 
    689 int CPDFSDK_Widget::GetMaxLen() const {
    690   CPDF_FormField* pFormField = GetFormField();
    691   return pFormField->GetMaxLen();
    692 }
    693 
    694 void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify) {
    695   CPDF_FormControl* pFormCtrl = GetFormControl();
    696   CPDF_FormField* pFormField = pFormCtrl->GetField();
    697   pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
    698                            bNotify);
    699 #ifdef PDF_ENABLE_XFA
    700   if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
    701     ResetAppearance(TRUE);
    702   if (!bNotify)
    703     Synchronize(TRUE);
    704 #endif  // PDF_ENABLE_XFA
    705 }
    706 
    707 void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) {
    708   CPDF_FormField* pFormField = GetFormField();
    709   pFormField->SetValue(sValue, bNotify);
    710 #ifdef PDF_ENABLE_XFA
    711   if (!bNotify)
    712     Synchronize(TRUE);
    713 #endif  // PDF_ENABLE_XFA
    714 }
    715 
    716 void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
    717 void CPDFSDK_Widget::SetOptionSelection(int index,
    718                                         FX_BOOL bSelected,
    719                                         FX_BOOL bNotify) {
    720   CPDF_FormField* pFormField = GetFormField();
    721   pFormField->SetItemSelection(index, bSelected, bNotify);
    722 #ifdef PDF_ENABLE_XFA
    723   if (!bNotify)
    724     Synchronize(TRUE);
    725 #endif  // PDF_ENABLE_XFA
    726 }
    727 
    728 void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) {
    729   CPDF_FormField* pFormField = GetFormField();
    730   pFormField->ClearSelection(bNotify);
    731 #ifdef PDF_ENABLE_XFA
    732   if (!bNotify)
    733     Synchronize(TRUE);
    734 #endif  // PDF_ENABLE_XFA
    735 }
    736 
    737 void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
    738 
    739 void CPDFSDK_Widget::SetAppModified() {
    740   m_bAppModified = TRUE;
    741 }
    742 
    743 void CPDFSDK_Widget::ClearAppModified() {
    744   m_bAppModified = FALSE;
    745 }
    746 
    747 FX_BOOL CPDFSDK_Widget::IsAppModified() const {
    748   return m_bAppModified;
    749 }
    750 
    751 #ifdef PDF_ENABLE_XFA
    752 void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) {
    753   switch (GetFieldType()) {
    754     case FIELDTYPE_TEXTFIELD:
    755     case FIELDTYPE_COMBOBOX: {
    756       FX_BOOL bFormated = FALSE;
    757       CFX_WideString sValue = this->OnFormat(bFormated);
    758       if (bFormated)
    759         this->ResetAppearance(sValue, TRUE);
    760       else
    761         this->ResetAppearance(NULL, TRUE);
    762     } break;
    763     default:
    764       this->ResetAppearance(NULL, FALSE);
    765       break;
    766   }
    767 }
    768 #endif  // PDF_ENABLE_XFA
    769 
    770 void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue,
    771                                      FX_BOOL bValueChanged) {
    772   SetAppModified();
    773 
    774   m_nAppAge++;
    775   if (m_nAppAge > 999999)
    776     m_nAppAge = 0;
    777   if (bValueChanged)
    778     m_nValueAge++;
    779 
    780   int nFieldType = GetFieldType();
    781 
    782   switch (nFieldType) {
    783     case FIELDTYPE_PUSHBUTTON:
    784       ResetAppearance_PushButton();
    785       break;
    786     case FIELDTYPE_CHECKBOX:
    787       ResetAppearance_CheckBox();
    788       break;
    789     case FIELDTYPE_RADIOBUTTON:
    790       ResetAppearance_RadioButton();
    791       break;
    792     case FIELDTYPE_COMBOBOX:
    793       ResetAppearance_ComboBox(sValue);
    794       break;
    795     case FIELDTYPE_LISTBOX:
    796       ResetAppearance_ListBox();
    797       break;
    798     case FIELDTYPE_TEXTFIELD:
    799       ResetAppearance_TextField(sValue);
    800       break;
    801   }
    802 
    803   m_pAnnot->ClearCachedAP();
    804 }
    805 
    806 CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) {
    807   CPDF_FormField* pFormField = GetFormField();
    808   ASSERT(pFormField);
    809   return m_pInterForm->OnFormat(pFormField, bFormated);
    810 }
    811 
    812 void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) {
    813   CPDF_FormField* pFormField = GetFormField();
    814   ASSERT(pFormField);
    815   m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
    816 }
    817 
    818 void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
    819                                     const CFX_Matrix* pUser2Device,
    820                                     CPDF_Annot::AppearanceMode mode,
    821                                     const CPDF_RenderOptions* pOptions) {
    822   int nFieldType = GetFieldType();
    823 
    824   if ((nFieldType == FIELDTYPE_CHECKBOX ||
    825        nFieldType == FIELDTYPE_RADIOBUTTON) &&
    826       mode == CPDF_Annot::Normal &&
    827       !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
    828     CFX_PathData pathData;
    829 
    830     CPDF_Rect rcAnnot = GetRect();
    831 
    832     pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
    833                         rcAnnot.top);
    834 
    835     CFX_GraphStateData gsd;
    836     gsd.m_LineWidth = 0.0f;
    837 
    838     pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
    839                       FXFILL_ALTERNATE);
    840   } else {
    841     CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
    842   }
    843 }
    844 
    845 void CPDFSDK_Widget::UpdateField() {
    846   CPDF_FormField* pFormField = GetFormField();
    847   ASSERT(pFormField);
    848   m_pInterForm->UpdateField(pFormField);
    849 }
    850 
    851 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
    852                                 CPDFSDK_PageView* pPageView) {
    853   int nFieldType = GetFieldType();
    854   if (m_pInterForm->IsNeedHighLight(nFieldType)) {
    855     CPDF_Rect rc = GetRect();
    856     FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
    857     uint8_t alpha = m_pInterForm->GetHighlightAlpha();
    858 
    859     CFX_FloatRect rcDevice;
    860     ASSERT(m_pInterForm->GetDocument());
    861     CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
    862     if (!pEnv)
    863       return;
    864     CFX_Matrix page2device;
    865     pPageView->GetCurrentMatrix(page2device);
    866     page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
    867                           rcDevice.left, rcDevice.bottom);
    868     page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
    869                           rcDevice.right, rcDevice.top);
    870 
    871     rcDevice.Normalize();
    872 
    873     FX_ARGB argb = ArgbEncode((int)alpha, color);
    874     FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
    875                   (int)rcDevice.bottom);
    876     pDevice->FillRect(&rcDev, argb);
    877   }
    878 }
    879 
    880 void CPDFSDK_Widget::ResetAppearance_PushButton() {
    881   CPDF_FormControl* pControl = GetFormControl();
    882   CPDF_Rect rcWindow = GetRotatedRect();
    883   int32_t nLayout = 0;
    884   switch (pControl->GetTextPosition()) {
    885     case TEXTPOS_ICON:
    886       nLayout = PPBL_ICON;
    887       break;
    888     case TEXTPOS_BELOW:
    889       nLayout = PPBL_ICONTOPLABELBOTTOM;
    890       break;
    891     case TEXTPOS_ABOVE:
    892       nLayout = PPBL_LABELTOPICONBOTTOM;
    893       break;
    894     case TEXTPOS_RIGHT:
    895       nLayout = PPBL_ICONLEFTLABELRIGHT;
    896       break;
    897     case TEXTPOS_LEFT:
    898       nLayout = PPBL_LABELLEFTICONRIGHT;
    899       break;
    900     case TEXTPOS_OVERLAID:
    901       nLayout = PPBL_LABELOVERICON;
    902       break;
    903     default:
    904       nLayout = PPBL_LABEL;
    905       break;
    906   }
    907 
    908   CPWL_Color crBackground, crBorder;
    909 
    910   int iColorType;
    911   FX_FLOAT fc[4];
    912 
    913   pControl->GetOriginalBackgroundColor(iColorType, fc);
    914   if (iColorType > 0)
    915     crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
    916 
    917   pControl->GetOriginalBorderColor(iColorType, fc);
    918   if (iColorType > 0)
    919     crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
    920 
    921   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
    922   int32_t nBorderStyle = 0;
    923   CPWL_Dash dsBorder(3, 0, 0);
    924   CPWL_Color crLeftTop, crRightBottom;
    925 
    926   switch (GetBorderStyle()) {
    927     case BBS_DASH:
    928       nBorderStyle = PBS_DASH;
    929       dsBorder = CPWL_Dash(3, 3, 0);
    930       break;
    931     case BBS_BEVELED:
    932       nBorderStyle = PBS_BEVELED;
    933       fBorderWidth *= 2;
    934       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
    935       crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
    936       break;
    937     case BBS_INSET:
    938       nBorderStyle = PBS_INSET;
    939       fBorderWidth *= 2;
    940       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
    941       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
    942       break;
    943     case BBS_UNDERLINE:
    944       nBorderStyle = PBS_UNDERLINED;
    945       break;
    946     default:
    947       nBorderStyle = PBS_SOLID;
    948       break;
    949   }
    950 
    951   CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
    952 
    953   CPWL_Color crText(COLORTYPE_GRAY, 0);
    954 
    955   FX_FLOAT fFontSize = 12.0f;
    956   CFX_ByteString csNameTag;
    957 
    958   CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
    959   if (da.HasColor()) {
    960     da.GetColor(iColorType, fc);
    961     crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
    962   }
    963 
    964   if (da.HasFont())
    965     da.GetFont(csNameTag, fFontSize);
    966 
    967   CFX_WideString csWCaption;
    968   CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
    969 
    970   if (pControl->HasMKEntry("CA")) {
    971     csNormalCaption = pControl->GetNormalCaption();
    972   }
    973   if (pControl->HasMKEntry("RC")) {
    974     csRolloverCaption = pControl->GetRolloverCaption();
    975   }
    976   if (pControl->HasMKEntry("AC")) {
    977     csDownCaption = pControl->GetDownCaption();
    978   }
    979 
    980   CPDF_Stream* pNormalIcon = NULL;
    981   CPDF_Stream* pRolloverIcon = NULL;
    982   CPDF_Stream* pDownIcon = NULL;
    983 
    984   if (pControl->HasMKEntry("I")) {
    985     pNormalIcon = pControl->GetNormalIcon();
    986   }
    987   if (pControl->HasMKEntry("RI")) {
    988     pRolloverIcon = pControl->GetRolloverIcon();
    989   }
    990   if (pControl->HasMKEntry("IX")) {
    991     pDownIcon = pControl->GetDownIcon();
    992   }
    993 
    994   if (pNormalIcon) {
    995     if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
    996       if (pImageDict->GetString("Name").IsEmpty())
    997         pImageDict->SetAtString("Name", "ImgA");
    998     }
    999   }
   1000 
   1001   if (pRolloverIcon) {
   1002     if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
   1003       if (pImageDict->GetString("Name").IsEmpty())
   1004         pImageDict->SetAtString("Name", "ImgB");
   1005     }
   1006   }
   1007 
   1008   if (pDownIcon) {
   1009     if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
   1010       if (pImageDict->GetString("Name").IsEmpty())
   1011         pImageDict->SetAtString("Name", "ImgC");
   1012     }
   1013   }
   1014 
   1015   CPDF_IconFit iconFit = pControl->GetIconFit();
   1016 
   1017   CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
   1018   CPDFDoc_Environment* pEnv = pDoc->GetEnv();
   1019 
   1020   CBA_FontMap font_map(this, pEnv->GetSysHandler());
   1021   font_map.SetAPType("N");
   1022 
   1023   CFX_ByteString csAP =
   1024       CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
   1025       CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1026                                      crLeftTop, crRightBottom, nBorderStyle,
   1027                                      dsBorder) +
   1028       CPWL_Utils::GetPushButtonAppStream(
   1029           iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
   1030           pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
   1031 
   1032   WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
   1033   if (pNormalIcon)
   1034     AddImageToAppearance("N", pNormalIcon);
   1035 
   1036   CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
   1037   if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
   1038     if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
   1039       csRolloverCaption = csNormalCaption;
   1040       pRolloverIcon = pNormalIcon;
   1041     }
   1042 
   1043     font_map.SetAPType("R");
   1044 
   1045     csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
   1046            CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1047                                           crLeftTop, crRightBottom,
   1048                                           nBorderStyle, dsBorder) +
   1049            CPWL_Utils::GetPushButtonAppStream(
   1050                iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
   1051                pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
   1052                nLayout);
   1053 
   1054     WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
   1055     if (pRolloverIcon)
   1056       AddImageToAppearance("R", pRolloverIcon);
   1057 
   1058     if (csDownCaption.IsEmpty() && !pDownIcon) {
   1059       csDownCaption = csNormalCaption;
   1060       pDownIcon = pNormalIcon;
   1061     }
   1062 
   1063     switch (nBorderStyle) {
   1064       case PBS_BEVELED: {
   1065         CPWL_Color crTemp = crLeftTop;
   1066         crLeftTop = crRightBottom;
   1067         crRightBottom = crTemp;
   1068       } break;
   1069       case PBS_INSET:
   1070         crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
   1071         crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
   1072         break;
   1073     }
   1074 
   1075     font_map.SetAPType("D");
   1076 
   1077     csAP = CPWL_Utils::GetRectFillAppStream(
   1078                rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
   1079            CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1080                                           crLeftTop, crRightBottom,
   1081                                           nBorderStyle, dsBorder) +
   1082            CPWL_Utils::GetPushButtonAppStream(
   1083                iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
   1084                pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
   1085 
   1086     WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
   1087     if (pDownIcon)
   1088       AddImageToAppearance("D", pDownIcon);
   1089   } else {
   1090     RemoveAppearance("D");
   1091     RemoveAppearance("R");
   1092   }
   1093 }
   1094 
   1095 void CPDFSDK_Widget::ResetAppearance_CheckBox() {
   1096   CPDF_FormControl* pControl = GetFormControl();
   1097   CPWL_Color crBackground, crBorder, crText;
   1098   int iColorType;
   1099   FX_FLOAT fc[4];
   1100 
   1101   pControl->GetOriginalBackgroundColor(iColorType, fc);
   1102   if (iColorType > 0)
   1103     crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1104 
   1105   pControl->GetOriginalBorderColor(iColorType, fc);
   1106   if (iColorType > 0)
   1107     crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1108 
   1109   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
   1110   int32_t nBorderStyle = 0;
   1111   CPWL_Dash dsBorder(3, 0, 0);
   1112   CPWL_Color crLeftTop, crRightBottom;
   1113 
   1114   switch (GetBorderStyle()) {
   1115     case BBS_DASH:
   1116       nBorderStyle = PBS_DASH;
   1117       dsBorder = CPWL_Dash(3, 3, 0);
   1118       break;
   1119     case BBS_BEVELED:
   1120       nBorderStyle = PBS_BEVELED;
   1121       fBorderWidth *= 2;
   1122       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
   1123       crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
   1124       break;
   1125     case BBS_INSET:
   1126       nBorderStyle = PBS_INSET;
   1127       fBorderWidth *= 2;
   1128       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
   1129       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
   1130       break;
   1131     case BBS_UNDERLINE:
   1132       nBorderStyle = PBS_UNDERLINED;
   1133       break;
   1134     default:
   1135       nBorderStyle = PBS_SOLID;
   1136       break;
   1137   }
   1138 
   1139   CPDF_Rect rcWindow = GetRotatedRect();
   1140   CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
   1141 
   1142   CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
   1143   if (da.HasColor()) {
   1144     da.GetColor(iColorType, fc);
   1145     crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1146   }
   1147 
   1148   int32_t nStyle = 0;
   1149 
   1150   CFX_WideString csWCaption = pControl->GetNormalCaption();
   1151   if (csWCaption.GetLength() > 0) {
   1152     switch (csWCaption[0]) {
   1153       case L'l':
   1154         nStyle = PCS_CIRCLE;
   1155         break;
   1156       case L'8':
   1157         nStyle = PCS_CROSS;
   1158         break;
   1159       case L'u':
   1160         nStyle = PCS_DIAMOND;
   1161         break;
   1162       case L'n':
   1163         nStyle = PCS_SQUARE;
   1164         break;
   1165       case L'H':
   1166         nStyle = PCS_STAR;
   1167         break;
   1168       default:  // L'4'
   1169         nStyle = PCS_CHECK;
   1170         break;
   1171     }
   1172   } else {
   1173     nStyle = PCS_CHECK;
   1174   }
   1175 
   1176   CFX_ByteString csAP_N_ON =
   1177       CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
   1178       CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1179                                      crLeftTop, crRightBottom, nBorderStyle,
   1180                                      dsBorder);
   1181 
   1182   CFX_ByteString csAP_N_OFF = csAP_N_ON;
   1183 
   1184   switch (nBorderStyle) {
   1185     case PBS_BEVELED: {
   1186       CPWL_Color crTemp = crLeftTop;
   1187       crLeftTop = crRightBottom;
   1188       crRightBottom = crTemp;
   1189     } break;
   1190     case PBS_INSET:
   1191       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
   1192       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
   1193       break;
   1194   }
   1195 
   1196   CFX_ByteString csAP_D_ON =
   1197       CPWL_Utils::GetRectFillAppStream(
   1198           rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
   1199       CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1200                                      crLeftTop, crRightBottom, nBorderStyle,
   1201                                      dsBorder);
   1202 
   1203   CFX_ByteString csAP_D_OFF = csAP_D_ON;
   1204 
   1205   csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
   1206   csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
   1207 
   1208   WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
   1209                   pControl->GetCheckedAPState());
   1210   WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
   1211 
   1212   WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
   1213                   pControl->GetCheckedAPState());
   1214   WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
   1215 
   1216   CFX_ByteString csAS = GetAppState();
   1217   if (csAS.IsEmpty())
   1218     SetAppState("Off");
   1219 }
   1220 
   1221 void CPDFSDK_Widget::ResetAppearance_RadioButton() {
   1222   CPDF_FormControl* pControl = GetFormControl();
   1223   CPWL_Color crBackground, crBorder, crText;
   1224   int iColorType;
   1225   FX_FLOAT fc[4];
   1226 
   1227   pControl->GetOriginalBackgroundColor(iColorType, fc);
   1228   if (iColorType > 0)
   1229     crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1230 
   1231   pControl->GetOriginalBorderColor(iColorType, fc);
   1232   if (iColorType > 0)
   1233     crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1234 
   1235   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
   1236   int32_t nBorderStyle = 0;
   1237   CPWL_Dash dsBorder(3, 0, 0);
   1238   CPWL_Color crLeftTop, crRightBottom;
   1239 
   1240   switch (GetBorderStyle()) {
   1241     case BBS_DASH:
   1242       nBorderStyle = PBS_DASH;
   1243       dsBorder = CPWL_Dash(3, 3, 0);
   1244       break;
   1245     case BBS_BEVELED:
   1246       nBorderStyle = PBS_BEVELED;
   1247       fBorderWidth *= 2;
   1248       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
   1249       crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
   1250       break;
   1251     case BBS_INSET:
   1252       nBorderStyle = PBS_INSET;
   1253       fBorderWidth *= 2;
   1254       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
   1255       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
   1256       break;
   1257     case BBS_UNDERLINE:
   1258       nBorderStyle = PBS_UNDERLINED;
   1259       break;
   1260     default:
   1261       nBorderStyle = PBS_SOLID;
   1262       break;
   1263   }
   1264 
   1265   CPDF_Rect rcWindow = GetRotatedRect();
   1266   CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
   1267 
   1268   CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
   1269   if (da.HasColor()) {
   1270     da.GetColor(iColorType, fc);
   1271     crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1272   }
   1273 
   1274   int32_t nStyle = 0;
   1275 
   1276   CFX_WideString csWCaption = pControl->GetNormalCaption();
   1277   if (csWCaption.GetLength() > 0) {
   1278     switch (csWCaption[0]) {
   1279       default:  // L'l':
   1280         nStyle = PCS_CIRCLE;
   1281         break;
   1282       case L'8':
   1283         nStyle = PCS_CROSS;
   1284         break;
   1285       case L'u':
   1286         nStyle = PCS_DIAMOND;
   1287         break;
   1288       case L'n':
   1289         nStyle = PCS_SQUARE;
   1290         break;
   1291       case L'H':
   1292         nStyle = PCS_STAR;
   1293         break;
   1294       case L'4':
   1295         nStyle = PCS_CHECK;
   1296         break;
   1297     }
   1298   } else {
   1299     nStyle = PCS_CIRCLE;
   1300   }
   1301 
   1302   CFX_ByteString csAP_N_ON;
   1303 
   1304   CPDF_Rect rcCenter =
   1305       CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
   1306 
   1307   if (nStyle == PCS_CIRCLE) {
   1308     if (nBorderStyle == PBS_BEVELED) {
   1309       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
   1310       crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
   1311     } else if (nBorderStyle == PBS_INSET) {
   1312       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
   1313       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
   1314     }
   1315 
   1316     csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
   1317                 CPWL_Utils::GetCircleBorderAppStream(
   1318                     rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
   1319                     nBorderStyle, dsBorder);
   1320   } else {
   1321     csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
   1322                 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1323                                                crLeftTop, crRightBottom,
   1324                                                nBorderStyle, dsBorder);
   1325   }
   1326 
   1327   CFX_ByteString csAP_N_OFF = csAP_N_ON;
   1328 
   1329   switch (nBorderStyle) {
   1330     case PBS_BEVELED: {
   1331       CPWL_Color crTemp = crLeftTop;
   1332       crLeftTop = crRightBottom;
   1333       crRightBottom = crTemp;
   1334     } break;
   1335     case PBS_INSET:
   1336       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
   1337       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
   1338       break;
   1339   }
   1340 
   1341   CFX_ByteString csAP_D_ON;
   1342 
   1343   if (nStyle == PCS_CIRCLE) {
   1344     CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
   1345     if (nBorderStyle == PBS_BEVELED) {
   1346       crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
   1347       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
   1348       crBK = crBackground;
   1349     } else if (nBorderStyle == PBS_INSET) {
   1350       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
   1351       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
   1352     }
   1353 
   1354     csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
   1355                 CPWL_Utils::GetCircleBorderAppStream(
   1356                     rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
   1357                     nBorderStyle, dsBorder);
   1358   } else {
   1359     csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
   1360                     rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
   1361                 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1362                                                crLeftTop, crRightBottom,
   1363                                                nBorderStyle, dsBorder);
   1364   }
   1365 
   1366   CFX_ByteString csAP_D_OFF = csAP_D_ON;
   1367 
   1368   csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
   1369   csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
   1370 
   1371   WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
   1372                   pControl->GetCheckedAPState());
   1373   WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
   1374 
   1375   WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
   1376                   pControl->GetCheckedAPState());
   1377   WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
   1378 
   1379   CFX_ByteString csAS = GetAppState();
   1380   if (csAS.IsEmpty())
   1381     SetAppState("Off");
   1382 }
   1383 
   1384 void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) {
   1385   CPDF_FormControl* pControl = GetFormControl();
   1386   CPDF_FormField* pField = pControl->GetField();
   1387   CFX_ByteTextBuf sBody, sLines;
   1388 
   1389   CPDF_Rect rcClient = GetClientRect();
   1390   CPDF_Rect rcButton = rcClient;
   1391   rcButton.left = rcButton.right - 13;
   1392   rcButton.Normalize();
   1393 
   1394   if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
   1395     pEdit->EnableRefresh(FALSE);
   1396 
   1397     CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
   1398     CPDFDoc_Environment* pEnv = pDoc->GetEnv();
   1399     CBA_FontMap font_map(this, pEnv->GetSysHandler());
   1400     pEdit->SetFontMap(&font_map);
   1401 
   1402     CPDF_Rect rcEdit = rcClient;
   1403     rcEdit.right = rcButton.left;
   1404     rcEdit.Normalize();
   1405 
   1406     pEdit->SetPlateRect(rcEdit);
   1407     pEdit->SetAlignmentV(1);
   1408 
   1409     FX_FLOAT fFontSize = GetFontSize();
   1410     if (IsFloatZero(fFontSize))
   1411       pEdit->SetAutoFontSize(TRUE);
   1412     else
   1413       pEdit->SetFontSize(fFontSize);
   1414 
   1415     pEdit->Initialize();
   1416 
   1417     if (sValue) {
   1418       pEdit->SetText(sValue);
   1419     } else {
   1420       int32_t nCurSel = pField->GetSelectedIndex(0);
   1421 
   1422       if (nCurSel < 0)
   1423         pEdit->SetText(pField->GetValue().c_str());
   1424       else
   1425         pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
   1426     }
   1427 
   1428     CPDF_Rect rcContent = pEdit->GetContentRect();
   1429 
   1430     CFX_ByteString sEdit =
   1431         CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
   1432     if (sEdit.GetLength() > 0) {
   1433       sBody << "/Tx BMC\n"
   1434             << "q\n";
   1435       if (rcContent.Width() > rcEdit.Width() ||
   1436           rcContent.Height() > rcEdit.Height()) {
   1437         sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
   1438               << " " << rcEdit.Height() << " re\nW\nn\n";
   1439       }
   1440 
   1441       CPWL_Color crText = GetTextPWLColor();
   1442       sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
   1443             << "ET\n"
   1444             << "Q\nEMC\n";
   1445     }
   1446 
   1447     IFX_Edit::DelEdit(pEdit);
   1448   }
   1449 
   1450   sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
   1451 
   1452   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
   1453                        sLines.GetByteString() + sBody.GetByteString();
   1454 
   1455   WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
   1456 }
   1457 
   1458 void CPDFSDK_Widget::ResetAppearance_ListBox() {
   1459   CPDF_FormControl* pControl = GetFormControl();
   1460   CPDF_FormField* pField = pControl->GetField();
   1461   CPDF_Rect rcClient = GetClientRect();
   1462   CFX_ByteTextBuf sBody, sLines;
   1463 
   1464   if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
   1465     pEdit->EnableRefresh(FALSE);
   1466 
   1467     CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
   1468     CPDFDoc_Environment* pEnv = pDoc->GetEnv();
   1469 
   1470     CBA_FontMap font_map(this, pEnv->GetSysHandler());
   1471     pEdit->SetFontMap(&font_map);
   1472 
   1473     pEdit->SetPlateRect(CPDF_Rect(rcClient.left, 0.0f, rcClient.right, 0.0f));
   1474 
   1475     FX_FLOAT fFontSize = GetFontSize();
   1476 
   1477     if (IsFloatZero(fFontSize))
   1478       pEdit->SetFontSize(12.0f);
   1479     else
   1480       pEdit->SetFontSize(fFontSize);
   1481 
   1482     pEdit->Initialize();
   1483 
   1484     CFX_ByteTextBuf sList;
   1485     FX_FLOAT fy = rcClient.top;
   1486 
   1487     int32_t nTop = pField->GetTopVisibleIndex();
   1488     int32_t nCount = pField->CountOptions();
   1489     int32_t nSelCount = pField->CountSelectedItems();
   1490 
   1491     for (int32_t i = nTop; i < nCount; i++) {
   1492       FX_BOOL bSelected = FALSE;
   1493       for (int32_t j = 0; j < nSelCount; j++) {
   1494         if (pField->GetSelectedIndex(j) == i) {
   1495           bSelected = TRUE;
   1496           break;
   1497         }
   1498       }
   1499 
   1500       pEdit->SetText(pField->GetOptionLabel(i).c_str());
   1501 
   1502       CPDF_Rect rcContent = pEdit->GetContentRect();
   1503       FX_FLOAT fItemHeight = rcContent.Height();
   1504 
   1505       if (bSelected) {
   1506         CPDF_Rect rcItem =
   1507             CPDF_Rect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
   1508         sList << "q\n" << CPWL_Utils::GetColorAppStream(
   1509                               CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
   1510                                          113.0f / 255.0f),
   1511                               TRUE)
   1512               << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
   1513               << " " << rcItem.Height() << " re f\n"
   1514               << "Q\n";
   1515 
   1516         sList << "BT\n" << CPWL_Utils::GetColorAppStream(
   1517                                CPWL_Color(COLORTYPE_GRAY, 1), TRUE)
   1518               << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
   1519               << "ET\n";
   1520       } else {
   1521         CPWL_Color crText = GetTextPWLColor();
   1522         sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
   1523               << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
   1524               << "ET\n";
   1525       }
   1526 
   1527       fy -= fItemHeight;
   1528     }
   1529 
   1530     if (sList.GetSize() > 0) {
   1531       sBody << "/Tx BMC\n"
   1532             << "q\n" << rcClient.left << " " << rcClient.bottom << " "
   1533             << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
   1534       sBody << sList << "Q\nEMC\n";
   1535     }
   1536 
   1537     IFX_Edit::DelEdit(pEdit);
   1538   }
   1539 
   1540   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
   1541                        sLines.GetByteString() + sBody.GetByteString();
   1542 
   1543   WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
   1544 }
   1545 
   1546 void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) {
   1547   CPDF_FormControl* pControl = GetFormControl();
   1548   CPDF_FormField* pField = pControl->GetField();
   1549   CFX_ByteTextBuf sBody, sLines;
   1550 
   1551   if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
   1552     pEdit->EnableRefresh(FALSE);
   1553 
   1554     CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
   1555     CPDFDoc_Environment* pEnv = pDoc->GetEnv();
   1556 
   1557     CBA_FontMap font_map(this, pEnv->GetSysHandler());
   1558     pEdit->SetFontMap(&font_map);
   1559 
   1560     CPDF_Rect rcClient = GetClientRect();
   1561     pEdit->SetPlateRect(rcClient);
   1562     pEdit->SetAlignmentH(pControl->GetControlAlignment());
   1563 
   1564     FX_DWORD dwFieldFlags = pField->GetFieldFlags();
   1565     FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
   1566 
   1567     if (bMultiLine) {
   1568       pEdit->SetMultiLine(TRUE);
   1569       pEdit->SetAutoReturn(TRUE);
   1570     } else {
   1571       pEdit->SetAlignmentV(1);
   1572     }
   1573 
   1574     FX_WORD subWord = 0;
   1575     if ((dwFieldFlags >> 13) & 1) {
   1576       subWord = '*';
   1577       pEdit->SetPasswordChar(subWord);
   1578     }
   1579 
   1580     int nMaxLen = pField->GetMaxLen();
   1581     FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
   1582     FX_FLOAT fFontSize = GetFontSize();
   1583 
   1584 #ifdef PDF_ENABLE_XFA
   1585     CFX_WideString sValueTmp;
   1586     if (!sValue && (NULL != this->GetMixXFAWidget())) {
   1587       sValueTmp = GetValue(TRUE);
   1588       sValue = sValueTmp;
   1589     }
   1590 #endif  // PDF_ENABLE_XFA
   1591 
   1592     if (nMaxLen > 0) {
   1593       if (bCharArray) {
   1594         pEdit->SetCharArray(nMaxLen);
   1595 
   1596         if (IsFloatZero(fFontSize)) {
   1597           fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(
   1598               font_map.GetPDFFont(0), rcClient, nMaxLen);
   1599         }
   1600       } else {
   1601         if (sValue)
   1602           nMaxLen = wcslen((const wchar_t*)sValue);
   1603         pEdit->SetLimitChar(nMaxLen);
   1604       }
   1605     }
   1606 
   1607     if (IsFloatZero(fFontSize))
   1608       pEdit->SetAutoFontSize(TRUE);
   1609     else
   1610       pEdit->SetFontSize(fFontSize);
   1611 
   1612     pEdit->Initialize();
   1613 
   1614     if (sValue)
   1615       pEdit->SetText(sValue);
   1616     else
   1617       pEdit->SetText(pField->GetValue().c_str());
   1618 
   1619     CPDF_Rect rcContent = pEdit->GetContentRect();
   1620 
   1621     CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
   1622         pEdit, CPDF_Point(0.0f, 0.0f), NULL, !bCharArray, subWord);
   1623 
   1624     if (sEdit.GetLength() > 0) {
   1625       sBody << "/Tx BMC\n"
   1626             << "q\n";
   1627       if (rcContent.Width() > rcClient.Width() ||
   1628           rcContent.Height() > rcClient.Height()) {
   1629         sBody << rcClient.left << " " << rcClient.bottom << " "
   1630               << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
   1631       }
   1632       CPWL_Color crText = GetTextPWLColor();
   1633       sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
   1634             << "ET\n"
   1635             << "Q\nEMC\n";
   1636     }
   1637 
   1638     if (bCharArray) {
   1639       switch (GetBorderStyle()) {
   1640         case BBS_SOLID: {
   1641           CFX_ByteString sColor =
   1642               CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
   1643           if (sColor.GetLength() > 0) {
   1644             sLines << "q\n" << GetBorderWidth() << " w\n"
   1645                    << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
   1646                    << " 2 J 0 j\n";
   1647 
   1648             for (int32_t i = 1; i < nMaxLen; i++) {
   1649               sLines << rcClient.left +
   1650                             ((rcClient.right - rcClient.left) / nMaxLen) * i
   1651                      << " " << rcClient.bottom << " m\n"
   1652                      << rcClient.left +
   1653                             ((rcClient.right - rcClient.left) / nMaxLen) * i
   1654                      << " " << rcClient.top << " l S\n";
   1655             }
   1656 
   1657             sLines << "Q\n";
   1658           }
   1659         } break;
   1660         case BBS_DASH: {
   1661           CFX_ByteString sColor =
   1662               CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
   1663           if (sColor.GetLength() > 0) {
   1664             CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
   1665 
   1666             sLines << "q\n" << GetBorderWidth() << " w\n"
   1667                    << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
   1668                    << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
   1669                    << dsBorder.nPhase << " d\n";
   1670 
   1671             for (int32_t i = 1; i < nMaxLen; i++) {
   1672               sLines << rcClient.left +
   1673                             ((rcClient.right - rcClient.left) / nMaxLen) * i
   1674                      << " " << rcClient.bottom << " m\n"
   1675                      << rcClient.left +
   1676                             ((rcClient.right - rcClient.left) / nMaxLen) * i
   1677                      << " " << rcClient.top << " l S\n";
   1678             }
   1679 
   1680             sLines << "Q\n";
   1681           }
   1682         } break;
   1683       }
   1684     }
   1685 
   1686     IFX_Edit::DelEdit(pEdit);
   1687   }
   1688 
   1689   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
   1690                        sLines.GetByteString() + sBody.GetByteString();
   1691   WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
   1692 }
   1693 
   1694 CPDF_Rect CPDFSDK_Widget::GetClientRect() const {
   1695   CPDF_Rect rcWindow = GetRotatedRect();
   1696   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
   1697   switch (GetBorderStyle()) {
   1698     case BBS_BEVELED:
   1699     case BBS_INSET:
   1700       fBorderWidth *= 2.0f;
   1701       break;
   1702   }
   1703 
   1704   return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
   1705 }
   1706 
   1707 CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const {
   1708   CPDF_Rect rectAnnot = GetRect();
   1709   FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
   1710   FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
   1711 
   1712   CPDF_FormControl* pControl = GetFormControl();
   1713   CPDF_Rect rcPDFWindow;
   1714   switch (abs(pControl->GetRotation() % 360)) {
   1715     case 0:
   1716     case 180:
   1717     default:
   1718       rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight);
   1719       break;
   1720     case 90:
   1721     case 270:
   1722       rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
   1723       break;
   1724   }
   1725 
   1726   return rcPDFWindow;
   1727 }
   1728 
   1729 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
   1730   CPWL_Color crBackground = GetFillPWLColor();
   1731   if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
   1732     return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
   1733   }
   1734   return "";
   1735 }
   1736 
   1737 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
   1738   CPDF_Rect rcWindow = GetRotatedRect();
   1739   CPWL_Color crBorder = GetBorderPWLColor();
   1740   CPWL_Color crBackground = GetFillPWLColor();
   1741   CPWL_Color crLeftTop, crRightBottom;
   1742 
   1743   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
   1744   int32_t nBorderStyle = 0;
   1745   CPWL_Dash dsBorder(3, 0, 0);
   1746 
   1747   switch (GetBorderStyle()) {
   1748     case BBS_DASH:
   1749       nBorderStyle = PBS_DASH;
   1750       dsBorder = CPWL_Dash(3, 3, 0);
   1751       break;
   1752     case BBS_BEVELED:
   1753       nBorderStyle = PBS_BEVELED;
   1754       fBorderWidth *= 2;
   1755       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
   1756       crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
   1757       break;
   1758     case BBS_INSET:
   1759       nBorderStyle = PBS_INSET;
   1760       fBorderWidth *= 2;
   1761       crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
   1762       crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
   1763       break;
   1764     case BBS_UNDERLINE:
   1765       nBorderStyle = PBS_UNDERLINED;
   1766       break;
   1767     default:
   1768       nBorderStyle = PBS_SOLID;
   1769       break;
   1770   }
   1771 
   1772   return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
   1773                                         crLeftTop, crRightBottom, nBorderStyle,
   1774                                         dsBorder);
   1775 }
   1776 
   1777 CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
   1778   CFX_Matrix mt;
   1779   CPDF_FormControl* pControl = GetFormControl();
   1780   CPDF_Rect rcAnnot = GetRect();
   1781   FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
   1782   FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
   1783 
   1784   switch (abs(pControl->GetRotation() % 360)) {
   1785     case 0:
   1786     default:
   1787       mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
   1788       break;
   1789     case 90:
   1790       mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
   1791       break;
   1792     case 180:
   1793       mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
   1794       break;
   1795     case 270:
   1796       mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
   1797       break;
   1798   }
   1799 
   1800   return mt;
   1801 }
   1802 
   1803 CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
   1804   CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
   1805 
   1806   CPDF_FormControl* pFormCtrl = GetFormControl();
   1807   CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
   1808   if (da.HasColor()) {
   1809     int32_t iColorType;
   1810     FX_FLOAT fc[4];
   1811     da.GetColor(iColorType, fc);
   1812     crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1813   }
   1814 
   1815   return crText;
   1816 }
   1817 
   1818 CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
   1819   CPWL_Color crBorder;
   1820 
   1821   CPDF_FormControl* pFormCtrl = GetFormControl();
   1822   int32_t iColorType;
   1823   FX_FLOAT fc[4];
   1824   pFormCtrl->GetOriginalBorderColor(iColorType, fc);
   1825   if (iColorType > 0)
   1826     crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1827 
   1828   return crBorder;
   1829 }
   1830 
   1831 CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
   1832   CPWL_Color crFill;
   1833 
   1834   CPDF_FormControl* pFormCtrl = GetFormControl();
   1835   int32_t iColorType;
   1836   FX_FLOAT fc[4];
   1837   pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
   1838   if (iColorType > 0)
   1839     crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
   1840 
   1841   return crFill;
   1842 }
   1843 
   1844 void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
   1845                                           CPDF_Stream* pImage) {
   1846   CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
   1847   ASSERT(pDoc);
   1848 
   1849   CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
   1850   CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
   1851   CPDF_Dictionary* pStreamDict = pStream->GetDict();
   1852   CFX_ByteString sImageAlias = "IMG";
   1853 
   1854   if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
   1855     sImageAlias = pImageDict->GetString("Name");
   1856     if (sImageAlias.IsEmpty())
   1857       sImageAlias = "IMG";
   1858   }
   1859 
   1860   CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
   1861   if (!pStreamResList) {
   1862     pStreamResList = new CPDF_Dictionary();
   1863     pStreamDict->SetAt("Resources", pStreamResList);
   1864   }
   1865 
   1866   if (pStreamResList) {
   1867     CPDF_Dictionary* pXObject = new CPDF_Dictionary;
   1868     pXObject->SetAtReference(sImageAlias, pDoc, pImage);
   1869     pStreamResList->SetAt("XObject", pXObject);
   1870   }
   1871 }
   1872 
   1873 void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
   1874   if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP")) {
   1875     pAPDict->RemoveAt(sAPType);
   1876   }
   1877 }
   1878 
   1879 FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
   1880                                   PDFSDK_FieldAction& data,
   1881                                   CPDFSDK_PageView* pPageView) {
   1882   CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
   1883   CPDFDoc_Environment* pEnv = pDocument->GetEnv();
   1884 
   1885 #ifdef PDF_ENABLE_XFA
   1886   CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
   1887   if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
   1888     XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
   1889 
   1890     if (eEventType != XFA_EVENT_Unknown) {
   1891       if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
   1892         CXFA_EventParam param;
   1893         param.m_eType = eEventType;
   1894         param.m_wsChange = data.sChange;
   1895         param.m_iCommitKey = data.nCommitKey;
   1896         param.m_bShift = data.bShift;
   1897         param.m_iSelStart = data.nSelStart;
   1898         param.m_iSelEnd = data.nSelEnd;
   1899         param.m_wsFullText = data.sValue;
   1900         param.m_bKeyDown = data.bKeyDown;
   1901         param.m_bModifier = data.bModifier;
   1902         param.m_wsNewText = data.sValue;
   1903         if (data.nSelEnd > data.nSelStart)
   1904           param.m_wsNewText.Delete(data.nSelStart,
   1905                                    data.nSelEnd - data.nSelStart);
   1906         for (int i = data.sChange.GetLength() - 1; i >= 0; i--)
   1907           param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
   1908         param.m_wsPrevText = data.sValue;
   1909 
   1910         CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
   1911         param.m_pTarget = pAcc;
   1912         int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
   1913 
   1914         if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
   1915           pDocView->UpdateDocView();
   1916         }
   1917 
   1918         if (nRet == XFA_EVENTERROR_Sucess)
   1919           return TRUE;
   1920       }
   1921     }
   1922   }
   1923 #endif  // PDF_ENABLE_XFA
   1924 
   1925   CPDF_Action action = GetAAction(type);
   1926   if (action && action.GetType() != CPDF_Action::Unknown) {
   1927     CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
   1928     return pActionHandler->DoAction_Field(action, type, pDocument,
   1929                                           GetFormField(), data);
   1930   }
   1931   return FALSE;
   1932 }
   1933 
   1934 CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
   1935   switch (eAAT) {
   1936     case CPDF_AAction::CursorEnter:
   1937     case CPDF_AAction::CursorExit:
   1938     case CPDF_AAction::ButtonDown:
   1939     case CPDF_AAction::ButtonUp:
   1940     case CPDF_AAction::GetFocus:
   1941     case CPDF_AAction::LoseFocus:
   1942     case CPDF_AAction::PageOpen:
   1943     case CPDF_AAction::PageClose:
   1944     case CPDF_AAction::PageVisible:
   1945     case CPDF_AAction::PageInvisible:
   1946       return CPDFSDK_BAAnnot::GetAAction(eAAT);
   1947 
   1948     case CPDF_AAction::KeyStroke:
   1949     case CPDF_AAction::Format:
   1950     case CPDF_AAction::Validate:
   1951     case CPDF_AAction::Calculate: {
   1952       CPDF_FormField* pField = GetFormField();
   1953       if (CPDF_AAction aa = pField->GetAdditionalAction())
   1954         return aa.GetAction(eAAT);
   1955       return CPDFSDK_BAAnnot::GetAAction(eAAT);
   1956     }
   1957     default:
   1958       break;
   1959   }
   1960 
   1961   return CPDF_Action();
   1962 }
   1963 
   1964 CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
   1965   CPDF_FormField* pFormField = GetFormField();
   1966   return pFormField->GetAlternateName();
   1967 }
   1968 
   1969 int32_t CPDFSDK_Widget::GetAppearanceAge() const {
   1970   return m_nAppAge;
   1971 }
   1972 
   1973 int32_t CPDFSDK_Widget::GetValueAge() const {
   1974   return m_nValueAge;
   1975 }
   1976 
   1977 FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
   1978   CPDF_Annot* pAnnot = GetPDFAnnot();
   1979   CFX_FloatRect annotRect;
   1980   pAnnot->GetRect(annotRect);
   1981   if (annotRect.Contains(pageX, pageY)) {
   1982     if (!IsVisible())
   1983       return FALSE;
   1984 
   1985     int nFieldFlags = GetFieldFlags();
   1986     if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
   1987       return FALSE;
   1988 
   1989     return TRUE;
   1990   }
   1991   return FALSE;
   1992 }
   1993 
   1994 #ifdef PDF_ENABLE_XFA
   1995 CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(IXFA_Widget* pAnnot,
   1996                                      CPDFSDK_PageView* pPageView,
   1997                                      CPDFSDK_InterForm* pInterForm)
   1998     : CPDFSDK_Annot(pPageView), m_pInterForm(pInterForm), m_hXFAWidget(pAnnot) {
   1999 }
   2000 
   2001 FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
   2002   return TRUE;
   2003 }
   2004 
   2005 CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
   2006   return FSDK_XFAWIDGET_TYPENAME;
   2007 }
   2008 
   2009 CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
   2010   CPDFSDK_PageView* pPageView = GetPageView();
   2011   CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
   2012   CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
   2013   IXFA_DocView* pDocView = pDoc->GetXFADocView();
   2014   IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
   2015 
   2016   CFX_RectF rcBBox;
   2017   pWidgetHandler->GetRect(GetXFAWidget(), rcBBox);
   2018 
   2019   return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
   2020                        rcBBox.top + rcBBox.height);
   2021 }
   2022 #endif  // PDF_ENABLE_XFA
   2023 
   2024 CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
   2025     : m_pDocument(pDocument),
   2026       m_pInterForm(NULL),
   2027 #ifdef PDF_ENABLE_XFA
   2028       m_bXfaCalculate(TRUE),
   2029       m_bXfaValidationsEnabled(TRUE),
   2030 #endif  // PDF_ENABLE_XFA
   2031       m_bCalculate(TRUE),
   2032       m_bBusy(FALSE) {
   2033   m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE);
   2034   m_pInterForm->SetFormNotify(this);
   2035 
   2036   for (int i = 0; i < kNumFieldTypes; ++i)
   2037     m_bNeedHightlight[i] = FALSE;
   2038   m_iHighlightAlpha = 0;
   2039 }
   2040 
   2041 CPDFSDK_InterForm::~CPDFSDK_InterForm() {
   2042   delete m_pInterForm;
   2043   m_pInterForm = nullptr;
   2044   m_Map.clear();
   2045 #ifdef PDF_ENABLE_XFA
   2046   m_XFAMap.RemoveAll();
   2047 #endif  // PDF_ENABLE_XFA
   2048 }
   2049 
   2050 FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
   2051   return FALSE;
   2052 }
   2053 
   2054 CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
   2055                                               FX_BOOL bNext) const {
   2056   std::unique_ptr<CBA_AnnotIterator> pIterator(
   2057       new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
   2058 
   2059   if (bNext) {
   2060     return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
   2061   }
   2062   return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
   2063 }
   2064 
   2065 CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const {
   2066   if (!pControl || !m_pInterForm)
   2067     return nullptr;
   2068 
   2069   CPDFSDK_Widget* pWidget = nullptr;
   2070   const auto it = m_Map.find(pControl);
   2071   if (it != m_Map.end())
   2072     pWidget = it->second;
   2073 
   2074   if (pWidget)
   2075     return pWidget;
   2076 
   2077   CPDF_Dictionary* pControlDict = pControl->GetWidget();
   2078   CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
   2079   CPDFSDK_PageView* pPage = nullptr;
   2080 
   2081   if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P")) {
   2082     int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
   2083     if (nPageIndex >= 0) {
   2084       pPage = m_pDocument->GetPageView(nPageIndex);
   2085     }
   2086   }
   2087 
   2088   if (!pPage) {
   2089     int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
   2090     if (nPageIndex >= 0) {
   2091       pPage = m_pDocument->GetPageView(nPageIndex);
   2092     }
   2093   }
   2094 
   2095   if (!pPage)
   2096     return nullptr;
   2097   return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
   2098 }
   2099 
   2100 void CPDFSDK_InterForm::GetWidgets(
   2101     const CFX_WideString& sFieldName,
   2102     std::vector<CPDFSDK_Widget*>* widgets) const {
   2103   for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
   2104     CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
   2105     ASSERT(pFormField);
   2106     GetWidgets(pFormField, widgets);
   2107   }
   2108 }
   2109 
   2110 void CPDFSDK_InterForm::GetWidgets(
   2111     CPDF_FormField* pField,
   2112     std::vector<CPDFSDK_Widget*>* widgets) const {
   2113   for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
   2114     CPDF_FormControl* pFormCtrl = pField->GetControl(i);
   2115     ASSERT(pFormCtrl);
   2116     CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
   2117     if (pWidget)
   2118       widgets->push_back(pWidget);
   2119   }
   2120 }
   2121 
   2122 int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
   2123     CPDF_Document* pDocument,
   2124     CPDF_Dictionary* pAnnotDict) const {
   2125   ASSERT(pAnnotDict);
   2126 
   2127   for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
   2128     if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
   2129       if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots")) {
   2130         for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
   2131           CPDF_Object* pDict = pAnnots->GetElementValue(j);
   2132           if (pAnnotDict == pDict) {
   2133             return i;
   2134           }
   2135         }
   2136       }
   2137     }
   2138   }
   2139 
   2140   return -1;
   2141 }
   2142 
   2143 void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
   2144                                CPDFSDK_Widget* pWidget) {
   2145   m_Map[pControl] = pWidget;
   2146 }
   2147 
   2148 void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
   2149   m_Map.erase(pControl);
   2150 }
   2151 
   2152 void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
   2153   m_bCalculate = bEnabled;
   2154 }
   2155 
   2156 FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
   2157   return m_bCalculate;
   2158 }
   2159 
   2160 #ifdef PDF_ENABLE_XFA
   2161 void CPDFSDK_InterForm::AddXFAMap(IXFA_Widget* hWidget,
   2162                                   CPDFSDK_XFAWidget* pWidget) {
   2163   m_XFAMap.SetAt(hWidget, pWidget);
   2164 }
   2165 
   2166 void CPDFSDK_InterForm::RemoveXFAMap(IXFA_Widget* hWidget) {
   2167   m_XFAMap.RemoveKey(hWidget);
   2168 }
   2169 
   2170 CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(IXFA_Widget* hWidget) {
   2171   CPDFSDK_XFAWidget* pWidget = NULL;
   2172   m_XFAMap.Lookup(hWidget, pWidget);
   2173 
   2174   return pWidget;
   2175 }
   2176 
   2177 void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
   2178   m_bXfaCalculate = bEnabled;
   2179 }
   2180 FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
   2181   return m_bXfaCalculate;
   2182 }
   2183 
   2184 FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
   2185   return m_bXfaValidationsEnabled;
   2186 }
   2187 void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
   2188   m_bXfaValidationsEnabled = bEnabled;
   2189 }
   2190 #endif  // PDF_ENABLE_XFA
   2191 
   2192 void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
   2193   CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2194   ASSERT(pEnv);
   2195   if (!pEnv->IsJSInitiated())
   2196     return;
   2197 
   2198   if (m_bBusy)
   2199     return;
   2200 
   2201   m_bBusy = TRUE;
   2202 
   2203   if (IsCalculateEnabled()) {
   2204     IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
   2205     pRuntime->SetReaderDocument(m_pDocument);
   2206 
   2207     int nSize = m_pInterForm->CountFieldsInCalculationOrder();
   2208     for (int i = 0; i < nSize; i++) {
   2209       if (CPDF_FormField* pField =
   2210               m_pInterForm->GetFieldInCalculationOrder(i)) {
   2211         int nType = pField->GetFieldType();
   2212         if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
   2213           CPDF_AAction aAction = pField->GetAdditionalAction();
   2214           if (aAction && aAction.ActionExist(CPDF_AAction::Calculate)) {
   2215             CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
   2216             if (action) {
   2217               CFX_WideString csJS = action.GetJavaScript();
   2218               if (!csJS.IsEmpty()) {
   2219                 IJS_Context* pContext = pRuntime->NewContext();
   2220                 CFX_WideString sOldValue = pField->GetValue();
   2221                 CFX_WideString sValue = sOldValue;
   2222                 FX_BOOL bRC = TRUE;
   2223                 pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
   2224 
   2225                 CFX_WideString sInfo;
   2226                 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
   2227                 pRuntime->ReleaseContext(pContext);
   2228 
   2229                 if (bRet) {
   2230                   if (bRC) {
   2231                     if (sValue.Compare(sOldValue) != 0)
   2232                       pField->SetValue(sValue, TRUE);
   2233                   }
   2234                 }
   2235               }
   2236             }
   2237           }
   2238         }
   2239       }
   2240     }
   2241   }
   2242 
   2243   m_bBusy = FALSE;
   2244 }
   2245 
   2246 CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
   2247                                            FX_BOOL& bFormated) {
   2248   CFX_WideString sValue = pFormField->GetValue();
   2249   CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2250   ASSERT(pEnv);
   2251   if (!pEnv->IsJSInitiated()) {
   2252     bFormated = FALSE;
   2253     return sValue;
   2254   }
   2255 
   2256   IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
   2257   pRuntime->SetReaderDocument(m_pDocument);
   2258 
   2259   if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) {
   2260     if (pFormField->CountSelectedItems() > 0) {
   2261       int index = pFormField->GetSelectedIndex(0);
   2262       if (index >= 0)
   2263         sValue = pFormField->GetOptionLabel(index);
   2264     }
   2265   }
   2266 
   2267   bFormated = FALSE;
   2268 
   2269   CPDF_AAction aAction = pFormField->GetAdditionalAction();
   2270   if (aAction && aAction.ActionExist(CPDF_AAction::Format)) {
   2271     CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
   2272     if (action) {
   2273       CFX_WideString script = action.GetJavaScript();
   2274       if (!script.IsEmpty()) {
   2275         CFX_WideString Value = sValue;
   2276 
   2277         IJS_Context* pContext = pRuntime->NewContext();
   2278         pContext->OnField_Format(pFormField, Value, TRUE);
   2279 
   2280         CFX_WideString sInfo;
   2281         FX_BOOL bRet = pContext->RunScript(script, &sInfo);
   2282         pRuntime->ReleaseContext(pContext);
   2283 
   2284         if (bRet) {
   2285           sValue = Value;
   2286           bFormated = TRUE;
   2287         }
   2288       }
   2289     }
   2290   }
   2291 
   2292   return sValue;
   2293 }
   2294 
   2295 void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
   2296                                              const FX_WCHAR* sValue,
   2297                                              FX_BOOL bValueChanged) {
   2298   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
   2299     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
   2300     ASSERT(pFormCtrl);
   2301     if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
   2302       pWidget->ResetAppearance(sValue, bValueChanged);
   2303   }
   2304 }
   2305 
   2306 void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
   2307   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
   2308     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
   2309     ASSERT(pFormCtrl);
   2310 
   2311     if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
   2312       CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2313       CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
   2314       UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
   2315       CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, FALSE);
   2316       FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
   2317 
   2318       pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
   2319                            rcBBox.bottom);
   2320     }
   2321   }
   2322 }
   2323 
   2324 void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
   2325                                           CFX_WideString& csValue,
   2326                                           FX_BOOL& bRC) {
   2327   CPDF_AAction aAction = pFormField->GetAdditionalAction();
   2328   if (aAction && aAction.ActionExist(CPDF_AAction::KeyStroke)) {
   2329     CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
   2330     if (action) {
   2331       CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2332       CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
   2333       PDFSDK_FieldAction fa;
   2334       fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
   2335       fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
   2336       fa.sValue = csValue;
   2337 
   2338       pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
   2339                                                m_pDocument, pFormField, fa);
   2340       bRC = fa.bRC;
   2341     }
   2342   }
   2343 }
   2344 
   2345 void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
   2346                                    CFX_WideString& csValue,
   2347                                    FX_BOOL& bRC) {
   2348   CPDF_AAction aAction = pFormField->GetAdditionalAction();
   2349   if (aAction && aAction.ActionExist(CPDF_AAction::Validate)) {
   2350     CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
   2351     if (action) {
   2352       CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2353       CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
   2354       PDFSDK_FieldAction fa;
   2355       fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
   2356       fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
   2357       fa.sValue = csValue;
   2358 
   2359       pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
   2360                                                m_pDocument, pFormField, fa);
   2361       bRC = fa.bRC;
   2362     }
   2363   }
   2364 }
   2365 
   2366 FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
   2367   ASSERT(action);
   2368 
   2369   CPDF_ActionFields af = action.GetWidgets();
   2370   std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
   2371   std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
   2372 
   2373   FX_BOOL bHide = action.GetHideStatus();
   2374   FX_BOOL bChanged = FALSE;
   2375 
   2376   for (CPDF_FormField* pField : fields) {
   2377     for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
   2378       CPDF_FormControl* pControl = pField->GetControl(i);
   2379       ASSERT(pControl);
   2380 
   2381       if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
   2382         int nFlags = pWidget->GetFlags();
   2383         nFlags &= ~ANNOTFLAG_INVISIBLE;
   2384         nFlags &= ~ANNOTFLAG_NOVIEW;
   2385         if (bHide)
   2386           nFlags |= ANNOTFLAG_HIDDEN;
   2387         else
   2388           nFlags &= ~ANNOTFLAG_HIDDEN;
   2389         pWidget->SetFlags(nFlags);
   2390         pWidget->GetPageView()->UpdateView(pWidget);
   2391         bChanged = TRUE;
   2392       }
   2393     }
   2394   }
   2395 
   2396   return bChanged;
   2397 }
   2398 
   2399 FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
   2400   CFX_WideString sDestination = action.GetFilePath();
   2401   if (sDestination.IsEmpty())
   2402     return FALSE;
   2403 
   2404   CPDF_Dictionary* pActionDict = action.GetDict();
   2405   if (pActionDict->KeyExist("Fields")) {
   2406     CPDF_ActionFields af = action.GetWidgets();
   2407     FX_DWORD dwFlags = action.GetFlags();
   2408     std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
   2409     std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
   2410     if (!fields.empty()) {
   2411       bool bIncludeOrExclude = !(dwFlags & 0x01);
   2412       if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
   2413         return FALSE;
   2414 
   2415       return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE);
   2416     }
   2417   }
   2418   if (m_pInterForm->CheckRequiredFields(nullptr, true))
   2419     return FALSE;
   2420 
   2421   return SubmitForm(sDestination, FALSE);
   2422 }
   2423 
   2424 FX_BOOL CPDFSDK_InterForm::SubmitFields(
   2425     const CFX_WideString& csDestination,
   2426     const std::vector<CPDF_FormField*>& fields,
   2427     FX_BOOL bIncludeOrExclude,
   2428     FX_BOOL bUrlEncoded) {
   2429   CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2430 
   2431   CFX_ByteTextBuf textBuf;
   2432   ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
   2433 
   2434   uint8_t* pBuffer = textBuf.GetBuffer();
   2435   FX_STRSIZE nBufSize = textBuf.GetLength();
   2436 
   2437   if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
   2438     return FALSE;
   2439 
   2440   pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
   2441   return TRUE;
   2442 }
   2443 
   2444 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
   2445                                                CFX_WideString csTxtFile) {
   2446   return TRUE;
   2447 }
   2448 
   2449 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
   2450                                                FX_STRSIZE& nBufSize) {
   2451   CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
   2452   if (pFDF) {
   2453     CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
   2454     if (!pMainDict)
   2455       return FALSE;
   2456 
   2457     // Get fields
   2458     CPDF_Array* pFields = pMainDict->GetArray("Fields");
   2459     if (!pFields)
   2460       return FALSE;
   2461 
   2462     CFX_ByteTextBuf fdfEncodedData;
   2463 
   2464     for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
   2465       CPDF_Dictionary* pField = pFields->GetDict(i);
   2466       if (!pField)
   2467         continue;
   2468       CFX_WideString name;
   2469       name = pField->GetUnicodeText("T");
   2470       CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
   2471       CFX_ByteString csBValue = pField->GetString("V");
   2472       CFX_WideString csWValue = PDF_DecodeText(csBValue);
   2473       CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
   2474 
   2475       fdfEncodedData = fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
   2476       name_b.ReleaseBuffer();
   2477       fdfEncodedData = fdfEncodedData << "=";
   2478       fdfEncodedData = fdfEncodedData
   2479                        << csValue_b.GetBuffer(csValue_b.GetLength());
   2480       csValue_b.ReleaseBuffer();
   2481       if (i != pFields->GetCount() - 1)
   2482         fdfEncodedData = fdfEncodedData << "&";
   2483     }
   2484 
   2485     nBufSize = fdfEncodedData.GetLength();
   2486     pBuf = FX_Alloc(uint8_t, nBufSize);
   2487     FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
   2488   }
   2489   return TRUE;
   2490 }
   2491 
   2492 FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
   2493     const std::vector<CPDF_FormField*>& fields,
   2494     FX_BOOL bIncludeOrExclude,
   2495     CFX_ByteTextBuf& textBuf) {
   2496   std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
   2497       m_pDocument->GetPath(), fields, bIncludeOrExclude));
   2498   return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
   2499 }
   2500 
   2501 #ifdef PDF_ENABLE_XFA
   2502 void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
   2503                                          FX_BOOL bSynchronizeElse) {
   2504   ASSERT(pFormField != NULL);
   2505 
   2506   int x = 0;
   2507   if (m_FieldSynchronizeMap.Lookup(pFormField, x))
   2508     return;
   2509 
   2510   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
   2511     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
   2512     ASSERT(pFormCtrl != NULL);
   2513 
   2514     ASSERT(m_pInterForm != NULL);
   2515     if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
   2516       pWidget->Synchronize(bSynchronizeElse);
   2517     }
   2518   }
   2519 }
   2520 #endif  // PDF_ENABLE_XFA
   2521 
   2522 CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
   2523     const CFX_WideString& sFileExt) {
   2524   CFX_WideString sFileName;
   2525   return L"";
   2526 }
   2527 
   2528 FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
   2529                                       FX_BOOL bUrlEncoded) {
   2530   if (sDestination.IsEmpty())
   2531     return FALSE;
   2532 
   2533   if (!m_pDocument || !m_pInterForm)
   2534     return FALSE;
   2535 
   2536   CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
   2537   CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
   2538   CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
   2539   if (!pFDFDoc)
   2540     return FALSE;
   2541 
   2542   CFX_ByteTextBuf FdfBuffer;
   2543   FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
   2544   delete pFDFDoc;
   2545   if (!bRet)
   2546     return FALSE;
   2547 
   2548   uint8_t* pBuffer = FdfBuffer.GetBuffer();
   2549   FX_STRSIZE nBufSize = FdfBuffer.GetLength();
   2550 
   2551   if (bUrlEncoded) {
   2552     if (!FDFToURLEncodedData(pBuffer, nBufSize))
   2553       return FALSE;
   2554   }
   2555 
   2556   pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
   2557 
   2558   if (bUrlEncoded) {
   2559     FX_Free(pBuffer);
   2560     pBuffer = NULL;
   2561   }
   2562 
   2563   return TRUE;
   2564 }
   2565 
   2566 FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
   2567   CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
   2568   if (!pFDF)
   2569     return FALSE;
   2570 
   2571   FX_BOOL bRet = pFDF->WriteBuf(textBuf);
   2572   delete pFDF;
   2573 
   2574   return bRet;
   2575 }
   2576 
   2577 FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
   2578   ASSERT(action);
   2579 
   2580   CPDF_Dictionary* pActionDict = action.GetDict();
   2581   if (!pActionDict->KeyExist("Fields"))
   2582     return m_pInterForm->ResetForm(true);
   2583 
   2584   CPDF_ActionFields af = action.GetWidgets();
   2585   FX_DWORD dwFlags = action.GetFlags();
   2586 
   2587   std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
   2588   std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
   2589   return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
   2590 }
   2591 
   2592 FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
   2593   return FALSE;
   2594 }
   2595 
   2596 std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
   2597     const std::vector<CPDF_Object*>& objects) const {
   2598   std::vector<CPDF_FormField*> fields;
   2599   for (CPDF_Object* pObject : objects) {
   2600     if (pObject && pObject->IsString()) {
   2601       CFX_WideString csName = pObject->GetUnicodeText();
   2602       CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
   2603       if (pField)
   2604         fields.push_back(pField);
   2605     }
   2606   }
   2607   return fields;
   2608 }
   2609 
   2610 int CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField,
   2611                                          CFX_WideString& csValue) {
   2612   CPDF_FormField* pFormField = (CPDF_FormField*)pField;
   2613   int nType = pFormField->GetFieldType();
   2614   if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
   2615     FX_BOOL bRC = TRUE;
   2616     OnKeyStrokeCommit(pFormField, csValue, bRC);
   2617     if (bRC) {
   2618       OnValidate(pFormField, csValue, bRC);
   2619       return bRC ? 1 : -1;
   2620     }
   2621     return -1;
   2622   }
   2623   return 0;
   2624 }
   2625 
   2626 int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField) {
   2627   CPDF_FormField* pFormField = (CPDF_FormField*)pField;
   2628 #ifdef PDF_ENABLE_XFA
   2629   SynchronizeField(pFormField, FALSE);
   2630 #endif  // PDF_ENABLE_XFA
   2631   int nType = pFormField->GetFieldType();
   2632   if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
   2633     OnCalculate(pFormField);
   2634     FX_BOOL bFormated = FALSE;
   2635     CFX_WideString sValue = OnFormat(pFormField, bFormated);
   2636     if (bFormated)
   2637       ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
   2638     else
   2639       ResetFieldAppearance(pFormField, NULL, TRUE);
   2640     UpdateField(pFormField);
   2641   }
   2642   return 0;
   2643 }
   2644 
   2645 int CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField,
   2646                                              CFX_WideString& csValue) {
   2647   CPDF_FormField* pFormField = (CPDF_FormField*)pField;
   2648   if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
   2649     return 0;
   2650 
   2651   FX_BOOL bRC = TRUE;
   2652   OnKeyStrokeCommit(pFormField, csValue, bRC);
   2653   if (!bRC)
   2654     return -1;
   2655 
   2656   OnValidate(pFormField, csValue, bRC);
   2657   if (!bRC)
   2658     return -1;
   2659 
   2660   return 1;
   2661 }
   2662 
   2663 int CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField) {
   2664   CPDF_FormField* pFormField = (CPDF_FormField*)pField;
   2665   if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX) {
   2666     OnCalculate(pFormField);
   2667     ResetFieldAppearance(pFormField, NULL, TRUE);
   2668     UpdateField(pFormField);
   2669   }
   2670   return 0;
   2671 }
   2672 
   2673 int CPDFSDK_InterForm::AfterCheckedStatusChange(
   2674     const CPDF_FormField* pField,
   2675     const CFX_ByteArray& statusArray) {
   2676   CPDF_FormField* pFormField = (CPDF_FormField*)pField;
   2677   int nType = pFormField->GetFieldType();
   2678   if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
   2679     OnCalculate(pFormField);
   2680     UpdateField(pFormField);
   2681   }
   2682   return 0;
   2683 }
   2684 
   2685 int CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm) {
   2686   return 0;
   2687 }
   2688 
   2689 int CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm) {
   2690   OnCalculate(nullptr);
   2691   return 0;
   2692 }
   2693 
   2694 int CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm) {
   2695   return 0;
   2696 }
   2697 
   2698 int CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm) {
   2699   OnCalculate(nullptr);
   2700   return 0;
   2701 }
   2702 
   2703 FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
   2704   if (nFieldType < 1 || nFieldType > kNumFieldTypes)
   2705     return FALSE;
   2706   return m_bNeedHightlight[nFieldType - 1];
   2707 }
   2708 
   2709 void CPDFSDK_InterForm::RemoveAllHighLight() {
   2710   for (int i = 0; i < kNumFieldTypes; ++i)
   2711     m_bNeedHightlight[i] = FALSE;
   2712 }
   2713 
   2714 void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
   2715   if (nFieldType < 0 || nFieldType > kNumFieldTypes)
   2716     return;
   2717   switch (nFieldType) {
   2718     case 0: {
   2719       for (int i = 0; i < kNumFieldTypes; ++i) {
   2720         m_aHighlightColor[i] = clr;
   2721         m_bNeedHightlight[i] = TRUE;
   2722       }
   2723       break;
   2724     }
   2725     default: {
   2726       m_aHighlightColor[nFieldType - 1] = clr;
   2727       m_bNeedHightlight[nFieldType - 1] = TRUE;
   2728       break;
   2729     }
   2730   }
   2731 }
   2732 
   2733 FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
   2734   if (nFieldType < 0 || nFieldType > kNumFieldTypes)
   2735     return FXSYS_RGB(255, 255, 255);
   2736   if (nFieldType == 0)
   2737     return m_aHighlightColor[0];
   2738   return m_aHighlightColor[nFieldType - 1];
   2739 }
   2740 
   2741 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
   2742                                      const CFX_ByteString& sType,
   2743                                      const CFX_ByteString& sSubType)
   2744     : m_pPageView(pPageView),
   2745       m_sType(sType),
   2746       m_sSubType(sSubType),
   2747       m_nTabs(BAI_STRUCTURE) {
   2748   CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
   2749   CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");
   2750 
   2751   if (sTabs == "R") {
   2752     m_nTabs = BAI_ROW;
   2753   } else if (sTabs == "C") {
   2754     m_nTabs = BAI_COLUMN;
   2755   } else {
   2756     m_nTabs = BAI_STRUCTURE;
   2757   }
   2758 
   2759   GenerateResults();
   2760 }
   2761 
   2762 CBA_AnnotIterator::~CBA_AnnotIterator() {
   2763   m_Annots.RemoveAll();
   2764 }
   2765 
   2766 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
   2767   if (m_Annots.GetSize() > 0)
   2768     return m_Annots[0];
   2769 
   2770   return NULL;
   2771 }
   2772 
   2773 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
   2774   if (m_Annots.GetSize() > 0)
   2775     return m_Annots[m_Annots.GetSize() - 1];
   2776 
   2777   return NULL;
   2778 }
   2779 
   2780 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
   2781   for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
   2782     if (m_Annots[i] == pAnnot)
   2783       return (i + 1 < sz) ? m_Annots[i + 1] : m_Annots[0];
   2784   }
   2785   return NULL;
   2786 }
   2787 
   2788 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
   2789   for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
   2790     if (m_Annots[i] == pAnnot)
   2791       return (i - 1 >= 0) ? m_Annots[i - 1] : m_Annots[sz - 1];
   2792   }
   2793   return NULL;
   2794 }
   2795 
   2796 int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
   2797   ASSERT(p1);
   2798   ASSERT(p2);
   2799 
   2800   CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
   2801   CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
   2802 
   2803   if (rcAnnot1.left < rcAnnot2.left)
   2804     return -1;
   2805   if (rcAnnot1.left > rcAnnot2.left)
   2806     return 1;
   2807   return 0;
   2808 }
   2809 
   2810 int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
   2811   ASSERT(p1);
   2812   ASSERT(p2);
   2813 
   2814   CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
   2815   CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
   2816 
   2817   if (rcAnnot1.top < rcAnnot2.top)
   2818     return -1;
   2819   if (rcAnnot1.top > rcAnnot2.top)
   2820     return 1;
   2821   return 0;
   2822 }
   2823 
   2824 void CBA_AnnotIterator::GenerateResults() {
   2825   switch (m_nTabs) {
   2826     case BAI_STRUCTURE: {
   2827       for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
   2828         CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
   2829         if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
   2830           m_Annots.Add(pAnnot);
   2831       }
   2832       break;
   2833     }
   2834     case BAI_ROW: {
   2835       CPDFSDK_SortAnnots sa;
   2836       for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
   2837         CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
   2838         if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
   2839           sa.Add(pAnnot);
   2840       }
   2841 
   2842       if (sa.GetSize() > 0)
   2843         sa.Sort(CBA_AnnotIterator::CompareByLeft);
   2844 
   2845       while (sa.GetSize() > 0) {
   2846         int nLeftTopIndex = -1;
   2847         FX_FLOAT fTop = 0.0f;
   2848 
   2849         for (int i = sa.GetSize() - 1; i >= 0; i--) {
   2850           CPDFSDK_Annot* pAnnot = sa.GetAt(i);
   2851           ASSERT(pAnnot);
   2852 
   2853           CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
   2854 
   2855           if (rcAnnot.top > fTop) {
   2856             nLeftTopIndex = i;
   2857             fTop = rcAnnot.top;
   2858           }
   2859         }
   2860 
   2861         if (nLeftTopIndex >= 0) {
   2862           CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
   2863           ASSERT(pLeftTopAnnot);
   2864 
   2865           CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
   2866 
   2867           m_Annots.Add(pLeftTopAnnot);
   2868           sa.RemoveAt(nLeftTopIndex);
   2869 
   2870           CFX_ArrayTemplate<int> aSelect;
   2871 
   2872           for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
   2873             CPDFSDK_Annot* pAnnot = sa.GetAt(i);
   2874             ASSERT(pAnnot);
   2875 
   2876             CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
   2877             FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
   2878             if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
   2879               aSelect.Add(i);
   2880           }
   2881 
   2882           for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
   2883             m_Annots.Add(sa[aSelect[i]]);
   2884 
   2885           for (int i = aSelect.GetSize() - 1; i >= 0; --i)
   2886               sa.RemoveAt(aSelect[i]);
   2887 
   2888           aSelect.RemoveAll();
   2889         }
   2890       }
   2891       sa.RemoveAll();
   2892       break;
   2893     }
   2894     case BAI_COLUMN: {
   2895       CPDFSDK_SortAnnots sa;
   2896       for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
   2897         CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
   2898         if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
   2899           sa.Add(pAnnot);
   2900       }
   2901 
   2902       if (sa.GetSize() > 0)
   2903         sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);
   2904 
   2905       while (sa.GetSize() > 0) {
   2906         int nLeftTopIndex = -1;
   2907         FX_FLOAT fLeft = -1.0f;
   2908 
   2909         for (int i = sa.GetSize() - 1; i >= 0; --i) {
   2910           CPDFSDK_Annot* pAnnot = sa.GetAt(i);
   2911           ASSERT(pAnnot);
   2912 
   2913           CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
   2914 
   2915           if (fLeft < 0) {
   2916             nLeftTopIndex = 0;
   2917             fLeft = rcAnnot.left;
   2918           } else if (rcAnnot.left < fLeft) {
   2919             nLeftTopIndex = i;
   2920             fLeft = rcAnnot.left;
   2921           }
   2922         }
   2923 
   2924         if (nLeftTopIndex >= 0) {
   2925           CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
   2926           ASSERT(pLeftTopAnnot);
   2927 
   2928           CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
   2929 
   2930           m_Annots.Add(pLeftTopAnnot);
   2931           sa.RemoveAt(nLeftTopIndex);
   2932 
   2933           CFX_ArrayTemplate<int> aSelect;
   2934           for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
   2935             CPDFSDK_Annot* pAnnot = sa.GetAt(i);
   2936             ASSERT(pAnnot);
   2937 
   2938             CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
   2939             FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
   2940             if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
   2941               aSelect.Add(i);
   2942           }
   2943 
   2944           for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
   2945             m_Annots.Add(sa[aSelect[i]]);
   2946 
   2947           for (int i = aSelect.GetSize() - 1; i >= 0; --i)
   2948             sa.RemoveAt(aSelect[i]);
   2949 
   2950           aSelect.RemoveAll();
   2951         }
   2952       }
   2953       sa.RemoveAll();
   2954       break;
   2955     }
   2956   }
   2957 }
   2958 
   2959 CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot) {
   2960   CPDF_Rect rcAnnot;
   2961   pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
   2962   return rcAnnot;
   2963 }
   2964