Home | History | Annotate | Download | only in fpdfdoc
      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 "../../include/fpdfdoc/fpdf_doc.h"
      8 #include "../../include/fxcrt/fx_xml.h"
      9 #include "doc_utils.h"
     10 
     11 const int nMaxRecursion = 32;
     12 
     13 class _CFieldNameExtractor
     14 {
     15 public:
     16     _CFieldNameExtractor(const CFX_WideString& full_name)
     17     {
     18         m_pStart = full_name.c_str();
     19         m_pEnd = m_pStart + full_name.GetLength();
     20         m_pCur = m_pStart;
     21     }
     22     void GetNext(FX_LPCWSTR &pSubName, FX_STRSIZE& size)
     23     {
     24         pSubName = m_pCur;
     25         while (m_pCur < m_pEnd && m_pCur[0] != L'.') {
     26             m_pCur++;
     27         }
     28         size = (FX_STRSIZE)(m_pCur - pSubName);
     29         if (m_pCur < m_pEnd && m_pCur[0] == L'.') {
     30             m_pCur++;
     31         }
     32     }
     33 protected:
     34     FX_LPCWSTR m_pStart;
     35     FX_LPCWSTR m_pEnd;
     36     FX_LPCWSTR m_pCur;
     37 };
     38 class CFieldTree
     39 {
     40 public:
     41     struct _Node  {
     42         _Node *parent;
     43         CFX_PtrArray children;
     44         CFX_WideString short_name;
     45         CPDF_FormField *field_ptr;
     46         int CountFields(int nLevel = 0)
     47         {
     48             if (nLevel > nMaxRecursion) {
     49                 return 0;
     50             }
     51             if (field_ptr) {
     52                 return 1;
     53             }
     54             int count = 0;
     55             for (int i = 0; i < children.GetSize(); i ++) {
     56                 count += ((_Node *)children.GetAt(i))->CountFields(nLevel + 1);
     57             }
     58             return count;
     59         }
     60         CPDF_FormField* GetField(int* fields_to_go)
     61         {
     62             if (field_ptr) {
     63                 if (*fields_to_go == 0) {
     64                     return field_ptr;
     65                 }
     66                 --*fields_to_go;
     67                 return NULL;
     68             }
     69             for (int i = 0; i < children.GetSize(); i++) {
     70                 _Node *pNode = (_Node *)children.GetAt(i);
     71                 CPDF_FormField* pField = pNode->GetField(fields_to_go);
     72                 if (pField) {
     73                     return pField;
     74                 }
     75             }
     76             return NULL;
     77         }
     78         CPDF_FormField* GetField(int index)
     79         {
     80             int fields_to_go = index;
     81             return GetField(&fields_to_go);
     82         }
     83     };
     84     CFieldTree();
     85     ~CFieldTree();
     86     void SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr);
     87     CPDF_FormField *GetField(const CFX_WideString &full_name);
     88     CPDF_FormField *RemoveField(const CFX_WideString &full_name);
     89     void RemoveAll();
     90     _Node *FindNode(const CFX_WideString &full_name);
     91     _Node * AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr);
     92     void RemoveNode(_Node *pNode, int nLevel = 0);
     93     _Node *_Lookup(_Node *pParent, const CFX_WideString &short_name);
     94     _Node m_Root;
     95 };
     96 CFieldTree::CFieldTree()
     97 {
     98     m_Root.parent = NULL;
     99     m_Root.field_ptr = NULL;
    100 }
    101 CFieldTree::~CFieldTree()
    102 {
    103     RemoveAll();
    104 }
    105 CFieldTree::_Node *CFieldTree::AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr)
    106 {
    107     if (pParent == NULL) {
    108         return NULL;
    109     }
    110     _Node* pNode = new _Node;
    111     pNode->parent = pParent;
    112     pNode->short_name = short_name;
    113     pNode->field_ptr = field_ptr;
    114     pParent->children.Add(pNode);
    115     return pNode;
    116 }
    117 void CFieldTree::RemoveNode(_Node *pNode, int nLevel)
    118 {
    119     if (pNode == NULL) {
    120         return ;
    121     }
    122     if (nLevel > nMaxRecursion) {
    123         delete pNode;
    124         return ;
    125     }
    126     CFX_PtrArray& ptr_array = pNode->children;
    127     for (int i = 0; i < ptr_array.GetSize(); i ++) {
    128         _Node *pChild = (_Node *)ptr_array[i];
    129         RemoveNode(pChild, nLevel + 1);
    130     }
    131     delete pNode;
    132 }
    133 CFieldTree::_Node *CFieldTree::_Lookup(_Node *pParent, const CFX_WideString &short_name)
    134 {
    135     if (pParent == NULL) {
    136         return NULL;
    137     }
    138     CFX_PtrArray& ptr_array = pParent->children;
    139     for (int i = 0; i < ptr_array.GetSize(); i ++) {
    140         _Node *pNode = (_Node *)ptr_array[i];
    141         if (pNode->short_name.GetLength() == short_name.GetLength() &&
    142                 FXSYS_memcmp32(pNode->short_name.c_str(), short_name.c_str(), short_name.GetLength()*sizeof(FX_WCHAR)) == 0) {
    143             return pNode;
    144         }
    145     }
    146     return NULL;
    147 }
    148 void CFieldTree::RemoveAll()
    149 {
    150     CFX_PtrArray& ptr_array = m_Root.children;
    151     for (int i = 0; i < ptr_array.GetSize(); i ++) {
    152         _Node *pNode = (_Node *)ptr_array[i];
    153         RemoveNode(pNode);
    154     }
    155 }
    156 void CFieldTree::SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr)
    157 {
    158     if (full_name == L"") {
    159         return;
    160     }
    161     _CFieldNameExtractor name_extractor(full_name);
    162     FX_LPCWSTR pName;
    163     FX_STRSIZE nLength;
    164     name_extractor.GetNext(pName, nLength);
    165     _Node *pNode = &m_Root, *pLast = NULL;
    166     while (nLength > 0) {
    167         pLast = pNode;
    168         CFX_WideString name = CFX_WideString(pName, nLength);
    169         pNode = _Lookup(pLast, name);
    170         if (pNode == NULL) {
    171             pNode = AddChild(pLast, name, NULL);
    172         }
    173         name_extractor.GetNext(pName, nLength);
    174     }
    175     if (pNode != &m_Root) {
    176         pNode->field_ptr = field_ptr;
    177     }
    178 }
    179 CPDF_FormField *CFieldTree::GetField(const CFX_WideString &full_name)
    180 {
    181     if (full_name == L"") {
    182         return NULL;
    183     }
    184     _CFieldNameExtractor name_extractor(full_name);
    185     FX_LPCWSTR pName;
    186     FX_STRSIZE nLength;
    187     name_extractor.GetNext(pName, nLength);
    188     _Node *pNode = &m_Root, *pLast = NULL;
    189     while (nLength > 0 && pNode) {
    190         pLast = pNode;
    191         CFX_WideString name = CFX_WideString(pName, nLength);
    192         pNode = _Lookup(pLast, name);
    193         name_extractor.GetNext(pName, nLength);
    194     }
    195     return pNode ? pNode->field_ptr : NULL;
    196 }
    197 CPDF_FormField *CFieldTree::RemoveField(const CFX_WideString & full_name)
    198 {
    199     if (full_name == L"") {
    200         return NULL;
    201     }
    202     _CFieldNameExtractor name_extractor(full_name);
    203     FX_LPCWSTR pName;
    204     FX_STRSIZE nLength;
    205     name_extractor.GetNext(pName, nLength);
    206     _Node *pNode = &m_Root, *pLast = NULL;
    207     while (nLength > 0 && pNode) {
    208         pLast = pNode;
    209         CFX_WideString name = CFX_WideString(pName, nLength);
    210         pNode = _Lookup(pLast, name);
    211         name_extractor.GetNext(pName, nLength);
    212     }
    213     if (pNode && pNode != &m_Root) {
    214         CFX_PtrArray& ptr_array = pLast->children;
    215         for (int i = 0; i < ptr_array.GetSize(); i ++) {
    216             if (pNode == (_Node *)ptr_array[i]) {
    217                 ptr_array.RemoveAt(i);
    218                 break;
    219             }
    220         }
    221         CPDF_FormField *pField = pNode->field_ptr;
    222         RemoveNode(pNode);
    223         return pField;
    224     }
    225     return NULL;
    226 }
    227 CFieldTree::_Node *CFieldTree::FindNode(const CFX_WideString& full_name)
    228 {
    229     if (full_name == L"") {
    230         return NULL;
    231     }
    232     _CFieldNameExtractor name_extractor(full_name);
    233     FX_LPCWSTR pName;
    234     FX_STRSIZE nLength;
    235     name_extractor.GetNext(pName, nLength);
    236     _Node *pNode = &m_Root, *pLast = NULL;
    237     while (nLength > 0 && pNode) {
    238         pLast = pNode;
    239         CFX_WideString name = CFX_WideString(pName, nLength);
    240         pNode = _Lookup(pLast, name);
    241         name_extractor.GetNext(pName, nLength);
    242     }
    243     return pNode;
    244 }
    245 CPDF_InterForm::CPDF_InterForm(CPDF_Document* pDocument, FX_BOOL bGenerateAP) : CFX_PrivateData()
    246 {
    247     m_pDocument = pDocument;
    248     m_bGenerateAP = bGenerateAP;
    249     m_pFormNotify = NULL;
    250     m_bUpdated = FALSE;
    251     m_pFieldTree = new CFieldTree;
    252     CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
    253     m_pFormDict = pRoot->GetDict("AcroForm");
    254     if (m_pFormDict == NULL) {
    255         return;
    256     }
    257     CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
    258     if (pFields == NULL) {
    259         return;
    260     }
    261     int count = pFields->GetCount();
    262     for (int i = 0; i < count; i ++) {
    263         LoadField(pFields->GetDict(i));
    264     }
    265 }
    266 CPDF_InterForm::~CPDF_InterForm()
    267 {
    268     FX_POSITION pos = m_ControlMap.GetStartPosition();
    269     while (pos) {
    270         FX_LPVOID key, value;
    271         m_ControlMap.GetNextAssoc(pos, key, value);
    272         delete (CPDF_FormControl*)value;
    273     }
    274     if (m_pFieldTree != NULL) {
    275         int nCount = m_pFieldTree->m_Root.CountFields();
    276         for (int i = 0; i < nCount; i++) {
    277             CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i);
    278             delete pField;
    279         }
    280         delete m_pFieldTree;
    281     }
    282 }
    283 FX_BOOL	CPDF_InterForm::m_bUpdateAP = TRUE;
    284 FX_BOOL CPDF_InterForm::UpdatingAPEnabled()
    285 {
    286     return m_bUpdateAP;
    287 }
    288 void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP)
    289 {
    290     m_bUpdateAP = bUpdateAP;
    291 }
    292 CFX_ByteString CPDF_InterForm::GenerateNewResourceName(const CPDF_Dictionary* pResDict, FX_LPCSTR csType, int iMinLen, FX_LPCSTR csPrefix)
    293 {
    294     CFX_ByteString csStr = csPrefix;
    295     CFX_ByteString csBType = csType;
    296     if (csStr.IsEmpty()) {
    297         if (csBType == "ExtGState") {
    298             csStr = "GS";
    299         } else if (csBType == "ColorSpace") {
    300             csStr = "CS";
    301         } else if (csBType == "Font") {
    302             csStr = "ZiTi";
    303         } else {
    304             csStr = "Res";
    305         }
    306     }
    307     CFX_ByteString csTmp = csStr;
    308     int iCount = csStr.GetLength();
    309     int m = 0;
    310     if (iMinLen > 0) {
    311         csTmp = "";
    312         while (m < iMinLen && m < iCount) {
    313             csTmp += csStr[m ++];
    314         }
    315         while (m < iMinLen) {
    316             csTmp += '0' + m % 10;
    317             m ++;
    318         }
    319     } else {
    320         m = iCount;
    321     }
    322     if (pResDict == NULL) {
    323         return csTmp;
    324     }
    325     CPDF_Dictionary* pDict = pResDict->GetDict(csType);
    326     if (pDict == NULL) {
    327         return csTmp;
    328     }
    329     int num = 0;
    330     CFX_ByteString bsNum;
    331     while (TRUE) {
    332         if (!pDict->KeyExist(csTmp + bsNum)) {
    333             return csTmp + bsNum;
    334         }
    335         if (m < iCount) {
    336             csTmp += csStr[m ++];
    337         } else {
    338             bsNum.Format("%d", num++);
    339         }
    340         m ++;
    341     }
    342     return csTmp;
    343 }
    344 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    345 typedef struct _PDF_FONTDATA {
    346     FX_BOOL		bFind;
    347     LOGFONTA	lf;
    348 } PDF_FONTDATA, FAR* LPDF_FONTDATA;
    349 static int CALLBACK EnumFontFamExProc(	ENUMLOGFONTEXA *lpelfe,
    350                                         NEWTEXTMETRICEX *lpntme,
    351                                         DWORD FontType,
    352                                         LPARAM lParam
    353                                      )
    354 {
    355     if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@') != NULL) {
    356         return 1;
    357     } else {
    358         LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam;
    359         memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA));
    360         pData->bFind = TRUE;
    361         return 0;
    362     }
    363 }
    364 static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf)
    365 {
    366     PDF_FONTDATA fd;
    367     memset(&fd, 0, sizeof(PDF_FONTDATA));
    368     HDC hDC = ::GetDC(NULL);
    369     EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd, 0);
    370     ::ReleaseDC(NULL, hDC);
    371     if (fd.bFind) {
    372         memcpy(&lf, &fd.lf, sizeof(LOGFONTA));
    373     }
    374     return fd.bFind;
    375 }
    376 static FX_BOOL RetrieveSpecificFont(FX_BYTE charSet, FX_BYTE pitchAndFamily, LPCSTR pcsFontName, LOGFONTA& lf)
    377 {
    378     memset(&lf, 0, sizeof(LOGFONTA));
    379     lf.lfCharSet = charSet;
    380     lf.lfPitchAndFamily = pitchAndFamily;
    381     if (pcsFontName != NULL) {
    382         strcpy(lf.lfFaceName, pcsFontName);
    383     }
    384     return RetrieveSpecificFont(lf);
    385 }
    386 static FX_BOOL RetrieveStockFont(int iFontObject, FX_BYTE charSet, LOGFONTA& lf)
    387 {
    388     HFONT hFont = (HFONT)::GetStockObject(iFontObject);
    389     if (hFont != NULL) {
    390         memset(&lf, 0, sizeof(LOGFONTA));
    391         int iRet = ::GetObject(hFont, sizeof(LOGFONTA), &lf);
    392         if (iRet > 0 && (lf.lfCharSet == charSet || charSet == 255)) {
    393             return RetrieveSpecificFont(lf);
    394         }
    395     }
    396     return FALSE;
    397 }
    398 #endif
    399 CPDF_Font* CPDF_InterForm::AddSystemDefaultFont(const CPDF_Document* pDocument)
    400 {
    401     if (pDocument == NULL) {
    402         return NULL;
    403     }
    404     CPDF_Font* pFont = NULL;
    405 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    406     LOGFONTA lf;
    407     FX_BOOL bRet;
    408     bRet = RetrieveStockFont(DEFAULT_GUI_FONT, 255, lf);
    409     if (!bRet) {
    410         bRet = RetrieveStockFont(SYSTEM_FONT, 255, lf);
    411     }
    412     if (bRet) {
    413         pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    414     }
    415 #endif
    416     return pFont;
    417 }
    418 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_ByteString csFontName, FX_BYTE iCharSet)
    419 {
    420     if (pDocument == NULL || csFontName.IsEmpty()) {
    421         return NULL;
    422     }
    423 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    424     if (iCharSet == 1) {
    425         iCharSet = GetNativeCharSet();
    426     }
    427     HFONT hFont = ::CreateFontA(0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
    428     if (hFont != NULL) {
    429         LOGFONTA lf;
    430         memset(&lf, 0, sizeof(LOGFONTA));
    431         ::GetObjectA(hFont, sizeof(LOGFONTA), &lf);
    432         ::DeleteObject(hFont);
    433         if (strlen(lf.lfFaceName) > 0) {
    434             return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    435         }
    436     }
    437 #endif
    438     return NULL;
    439 }
    440 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_WideString csFontName, FX_BYTE iCharSet)
    441 {
    442     if (pDocument == NULL || csFontName.IsEmpty()) {
    443         return NULL;
    444     }
    445 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    446     if (iCharSet == 1) {
    447         iCharSet = GetNativeCharSet();
    448     }
    449     HFONT hFont = ::CreateFontW(0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
    450     if (hFont != NULL) {
    451         LOGFONTA lf;
    452         memset(&lf, 0, sizeof(LOGFONTA));
    453         ::GetObject(hFont, sizeof(LOGFONTA), &lf);
    454         ::DeleteObject(hFont);
    455         if (strlen(lf.lfFaceName) > 0) {
    456             return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    457         }
    458     }
    459 #endif
    460     return NULL;
    461 }
    462 CPDF_Font* CPDF_InterForm::AddStandardFont(const CPDF_Document* pDocument, CFX_ByteString csFontName)
    463 {
    464     if (pDocument == NULL || csFontName.IsEmpty()) {
    465         return NULL;
    466     }
    467     CPDF_Font* pFont = NULL;
    468     if (csFontName == "ZapfDingbats") {
    469         pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, NULL);
    470     } else {
    471         CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI);
    472         pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, &encoding);
    473     }
    474     return pFont;
    475 }
    476 CFX_ByteString CPDF_InterForm::GetNativeFont(FX_BYTE charSet, FX_LPVOID pLogFont)
    477 {
    478     CFX_ByteString csFontName;
    479 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    480     LOGFONTA lf;
    481     FX_BOOL bRet;
    482     if (charSet == ANSI_CHARSET) {
    483         csFontName = "Helvetica";
    484         return csFontName;
    485     }
    486     bRet = FALSE;
    487     if (charSet == SHIFTJIS_CHARSET) {
    488         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MS Mincho", lf);
    489     } else if (charSet == GB2312_CHARSET) {
    490         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "SimSun", lf);
    491     } else if (charSet == CHINESEBIG5_CHARSET) {
    492         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MingLiU", lf);
    493     }
    494     if (!bRet) {
    495         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Arial Unicode MS", lf);
    496     }
    497     if (!bRet) {
    498         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Microsoft Sans Serif", lf);
    499     }
    500     if (!bRet) {
    501         bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, NULL, lf);
    502     }
    503     if (bRet) {
    504         if (pLogFont != NULL) {
    505             memcpy(pLogFont, &lf, sizeof(LOGFONTA));
    506         }
    507         csFontName = lf.lfFaceName;
    508         return csFontName;
    509     }
    510 #endif
    511     return csFontName;
    512 }
    513 CFX_ByteString CPDF_InterForm::GetNativeFont(FX_LPVOID pLogFont)
    514 {
    515 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    516     FX_BYTE charSet = GetNativeCharSet();
    517     return GetNativeFont(charSet, pLogFont);
    518 #else
    519     return CFX_ByteString();
    520 #endif
    521 }
    522 FX_BYTE CPDF_InterForm::GetNativeCharSet()
    523 {
    524 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    525     FX_BYTE charSet = ANSI_CHARSET;
    526     UINT iCodePage = ::GetACP();
    527     switch (iCodePage) {
    528         case 932:
    529             charSet = SHIFTJIS_CHARSET;
    530             break;
    531         case 936:
    532             charSet = GB2312_CHARSET;
    533             break;
    534         case 950:
    535             charSet = CHINESEBIG5_CHARSET;
    536             break;
    537         case 1252:
    538             charSet = ANSI_CHARSET;
    539             break;
    540         case 874:
    541             charSet = THAI_CHARSET;
    542             break;
    543         case 949:
    544             charSet = HANGUL_CHARSET;
    545             break;
    546         case 1200:
    547             charSet = ANSI_CHARSET;
    548             break;
    549         case 1250:
    550             charSet = EASTEUROPE_CHARSET;
    551             break;
    552         case 1251:
    553             charSet = RUSSIAN_CHARSET;
    554             break;
    555         case 1253:
    556             charSet = GREEK_CHARSET;
    557             break;
    558         case 1254:
    559             charSet = TURKISH_CHARSET;
    560             break;
    561         case 1255:
    562             charSet = HEBREW_CHARSET;
    563             break;
    564         case 1256:
    565             charSet = ARABIC_CHARSET;
    566             break;
    567         case 1257:
    568             charSet = BALTIC_CHARSET;
    569             break;
    570         case 1258:
    571             charSet = VIETNAMESE_CHARSET;
    572             break;
    573         case 1361:
    574             charSet = JOHAB_CHARSET;
    575             break;
    576     }
    577     return charSet;
    578 #else
    579     return 0;
    580 #endif
    581 }
    582 CPDF_Font* CPDF_InterForm::AddNativeFont(FX_BYTE charSet, const CPDF_Document* pDocument)
    583 {
    584     if (pDocument == NULL) {
    585         return NULL;
    586     }
    587     CPDF_Font* pFont = NULL;
    588 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    589     LOGFONTA lf;
    590     CFX_ByteString csFontName = GetNativeFont(charSet, &lf);
    591     if (!csFontName.IsEmpty()) {
    592         if (csFontName == "Helvetica") {
    593             pFont = AddStandardFont(pDocument, csFontName);
    594         } else {
    595             pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    596         }
    597     }
    598 #endif
    599     return pFont;
    600 }
    601 CPDF_Font* CPDF_InterForm::AddNativeFont(const CPDF_Document* pDocument)
    602 {
    603     if (pDocument == NULL) {
    604         return NULL;
    605     }
    606     CPDF_Font* pFont = NULL;
    607     FX_BYTE charSet = GetNativeCharSet();
    608     pFont = AddNativeFont(charSet, pDocument);
    609     return pFont;
    610 }
    611 FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType, const CPDF_FormField* pExcludedField, const CPDF_FormControl* pExcludedControl)
    612 {
    613     if (csNewFieldName.IsEmpty()) {
    614         return FALSE;
    615     }
    616     int iPos = 0;
    617     int iLength = csNewFieldName.GetLength();
    618     CFX_WideString csSub;
    619     while (TRUE) {
    620         while (iPos < iLength && (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) {
    621             iPos ++;
    622         }
    623         if (iPos < iLength && !csSub.IsEmpty()) {
    624             csSub += L'.';
    625         }
    626         while (iPos < iLength && csNewFieldName[iPos] != L'.') {
    627             csSub += csNewFieldName[iPos ++];
    628         }
    629         for (int i = csSub.GetLength() - 1; i > -1; i --) {
    630             if (csSub[i] == L' ' || csSub[i] == L'.') {
    631                 csSub.SetAt(i, L'\0');
    632             } else {
    633                 break;
    634             }
    635         }
    636         FX_DWORD dwCount = m_pFieldTree->m_Root.CountFields();
    637         for (FX_DWORD m = 0; m < dwCount; m ++) {
    638             CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m);
    639             if (pField == NULL) {
    640                 continue;
    641             }
    642             if (pField == pExcludedField) {
    643                 if (pExcludedControl != NULL) {
    644                     if (pField->CountControls() < 2) {
    645                         continue;
    646                     }
    647                 } else {
    648                     continue;
    649                 }
    650             }
    651             CFX_WideString csFullName = pField->GetFullName();
    652             int iRet = CompareFieldName(csSub, csFullName);
    653             if (iRet == 1) {
    654                 if (pField->GetFieldType() != iType) {
    655                     return FALSE;
    656                 }
    657             } else if (iRet == 2 && csSub == csNewFieldName) {
    658                 if (csFullName[iPos] == L'.') {
    659                     return FALSE;
    660                 }
    661             } else if (iRet == 3 && csSub == csNewFieldName) {
    662                 if (csNewFieldName[csFullName.GetLength()] == L'.') {
    663                     return FALSE;
    664                 }
    665             }
    666         }
    667         if (iPos >= iLength) {
    668             break;
    669         }
    670     }
    671     if (csSub.IsEmpty()) {
    672         return FALSE;
    673     }
    674     csNewFieldName = csSub;
    675     return TRUE;
    676 }
    677 FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType)
    678 {
    679     return ValidateFieldName(csNewFieldName, iType, NULL, NULL);
    680 }
    681 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField, CFX_WideString& csNewFieldName)
    682 {
    683     if (pField == NULL || csNewFieldName.IsEmpty()) {
    684         return FALSE;
    685     }
    686     return ValidateFieldName(csNewFieldName, ((CPDF_FormField*)pField)->GetFieldType(), pField, NULL);
    687 }
    688 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl, CFX_WideString& csNewFieldName)
    689 {
    690     if (pControl == NULL || csNewFieldName.IsEmpty()) {
    691         return FALSE;
    692     }
    693     CPDF_FormField* pField = ((CPDF_FormControl*)pControl)->GetField();
    694     return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField, pControl);
    695 }
    696 int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1, const CFX_ByteString& name2)
    697 {
    698     FX_LPCSTR ptr1 = name1, ptr2 = name2;
    699     if (name1.GetLength() != name2.GetLength()) {
    700         int i = 0;
    701         while (ptr1[i] == ptr2[i]) {
    702             i ++;
    703         }
    704         if (i == name1.GetLength()) {
    705             return 2;
    706         }
    707         if (i == name2.GetLength()) {
    708             return 3;
    709         }
    710         return 0;
    711     } else {
    712         return name1 == name2 ? 1 : 0;
    713     }
    714 }
    715 int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1, const CFX_WideString& name2)
    716 {
    717     FX_LPCWSTR ptr1 = name1.c_str();
    718     FX_LPCWSTR ptr2 = name2.c_str();
    719     if (name1.GetLength() != name2.GetLength()) {
    720         int i = 0;
    721         while (ptr1[i] == ptr2[i]) {
    722             i ++;
    723         }
    724         if (i == name1.GetLength()) {
    725             return 2;
    726         }
    727         if (i == name2.GetLength()) {
    728             return 3;
    729         }
    730         return 0;
    731     } else {
    732         return name1 == name2 ? 1 : 0;
    733     }
    734 }
    735 FX_DWORD CPDF_InterForm::CountFields(const CFX_WideString &csFieldName)
    736 {
    737     if (csFieldName.IsEmpty()) {
    738         return (FX_DWORD)m_pFieldTree->m_Root.CountFields();
    739     }
    740     CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName);
    741     if (pNode == NULL) {
    742         return 0;
    743     }
    744     return pNode->CountFields();
    745 }
    746 CPDF_FormField* CPDF_InterForm::GetField(FX_DWORD index, const CFX_WideString &csFieldName)
    747 {
    748     if (csFieldName == L"") {
    749         return m_pFieldTree->m_Root.GetField(index);
    750     }
    751     CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName);
    752     if (pNode == NULL) {
    753         return NULL;
    754     }
    755     return pNode->GetField(index);
    756 }
    757 void CPDF_InterForm::GetAllFieldNames(CFX_WideStringArray& allFieldNames)
    758 {
    759     allFieldNames.RemoveAll();
    760     int nCount = m_pFieldTree->m_Root.CountFields();
    761     for (int i = 0; i < nCount; i ++) {
    762         CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i);
    763         if (pField) {
    764             CFX_WideString full_name = GetFullName(pField->GetFieldDict());
    765             allFieldNames.Add(full_name);
    766         }
    767     }
    768 }
    769 FX_BOOL CPDF_InterForm::IsValidFormField(const void* pField)
    770 {
    771     if (pField == NULL) {
    772         return FALSE;
    773     }
    774     int nCount = m_pFieldTree->m_Root.CountFields();
    775     for (int i = 0; i < nCount; i++) {
    776         CPDF_FormField *pFormField = m_pFieldTree->m_Root.GetField(i);
    777         if (pField == pFormField) {
    778             return TRUE;
    779         }
    780     }
    781     return FALSE;
    782 }
    783 CPDF_FormField* CPDF_InterForm::GetFieldByDict(CPDF_Dictionary* pFieldDict) const
    784 {
    785     if (pFieldDict == NULL) {
    786         return NULL;
    787     }
    788     CFX_WideString csWName = GetFullName(pFieldDict);
    789     return m_pFieldTree->GetField(csWName);
    790 }
    791 FX_DWORD CPDF_InterForm::CountControls(CFX_WideString csFieldName)
    792 {
    793     if (csFieldName.IsEmpty()) {
    794         return (FX_DWORD)m_ControlMap.GetCount();
    795     }
    796     CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName);
    797     if (pField == NULL) {
    798         return 0;
    799     }
    800     return pField->m_ControlList.GetSize();
    801 }
    802 CPDF_FormControl* CPDF_InterForm::GetControl(FX_DWORD index, CFX_WideString csFieldName)
    803 {
    804     CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName);
    805     if (pField == NULL) {
    806         return NULL;
    807     }
    808     if (index < (FX_DWORD)pField->m_ControlList.GetSize()) {
    809         return (CPDF_FormControl *)pField->m_ControlList.GetAt(index);
    810     }
    811     return NULL;
    812 }
    813 FX_BOOL CPDF_InterForm::IsValidFormControl(const void* pControl)
    814 {
    815     if (pControl == NULL) {
    816         return FALSE;
    817     }
    818     FX_POSITION pos = m_ControlMap.GetStartPosition();
    819     while (pos) {
    820         CPDF_Dictionary* pWidgetDict = NULL;
    821         void* pFormControl = NULL;
    822         m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, pFormControl);
    823         if (pControl == pFormControl) {
    824             return TRUE;
    825         }
    826     }
    827     return FALSE;
    828 }
    829 int CPDF_InterForm::CountPageControls(CPDF_Page* pPage) const
    830 {
    831     CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    832     if (pAnnotList == NULL) {
    833         return 0;
    834     }
    835     int count = 0;
    836     for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) {
    837         CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
    838         if (pAnnot == NULL) {
    839             continue;
    840         }
    841         CPDF_FormControl* pControl;
    842         if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
    843             continue;
    844         }
    845         count ++;
    846     }
    847     return count;
    848 }
    849 CPDF_FormControl* CPDF_InterForm::GetPageControl(CPDF_Page* pPage, int index) const
    850 {
    851     CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    852     if (pAnnotList == NULL) {
    853         return NULL;
    854     }
    855     int count = 0;
    856     for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) {
    857         CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
    858         if (pAnnot == NULL) {
    859             continue;
    860         }
    861         CPDF_FormControl* pControl;
    862         if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
    863             continue;
    864         }
    865         if (index == count) {
    866             return pControl;
    867         }
    868         count ++;
    869     }
    870     return NULL;
    871 }
    872 CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLOAT pdf_y) const
    873 {
    874     CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    875     if (pAnnotList == NULL) {
    876         return NULL;
    877     }
    878     for (FX_DWORD i = pAnnotList->GetCount(); i > 0; i --) {
    879         CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i - 1);
    880         if (pAnnot == NULL) {
    881             continue;
    882         }
    883         CPDF_FormControl* pControl;
    884         if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
    885             continue;
    886         }
    887         CFX_FloatRect rect = pControl->GetRect();
    888         if (rect.Contains(pdf_x, pdf_y)) {
    889             return pControl;
    890         }
    891     }
    892     return NULL;
    893 }
    894 CPDF_FormControl* CPDF_InterForm::GetControlByDict(CPDF_Dictionary* pWidgetDict) const
    895 {
    896     CPDF_FormControl* pControl = NULL;
    897     m_ControlMap.Lookup(pWidgetDict, (FX_LPVOID&)pControl);
    898     return pControl;
    899 }
    900 FX_DWORD CPDF_InterForm::CountInternalFields(const CFX_WideString& csFieldName) const
    901 {
    902     if (m_pFormDict == NULL) {
    903         return 0;
    904     }
    905     CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
    906     if (pArray == NULL) {
    907         return 0;
    908     }
    909     if (csFieldName.IsEmpty()) {
    910         return pArray->GetCount();
    911     } else {
    912         int iLength = csFieldName.GetLength();
    913         int iPos = 0;
    914         CPDF_Dictionary* pDict = NULL;
    915         while (pArray != NULL) {
    916             CFX_WideString csSub;
    917             if (iPos < iLength && csFieldName[iPos] == L'.') {
    918                 iPos ++;
    919             }
    920             while (iPos < iLength && csFieldName[iPos] != L'.') {
    921                 csSub += csFieldName[iPos ++];
    922             }
    923             int iCount = pArray->GetCount();
    924             FX_BOOL bFind = FALSE;
    925             for (int i = 0; i < iCount; i ++) {
    926                 pDict = pArray->GetDict(i);
    927                 if (pDict == NULL) {
    928                     continue;
    929                 }
    930                 CFX_WideString csT = pDict->GetUnicodeText("T");
    931                 if (csT == csSub) {
    932                     bFind = TRUE;
    933                     break;
    934                 }
    935             }
    936             if (!bFind) {
    937                 return 0;
    938             }
    939             if (iPos >= iLength) {
    940                 break;
    941             }
    942             pArray = pDict->GetArray("Kids");
    943         }
    944         if (pDict == NULL) {
    945             return 0;
    946         } else {
    947             pArray = pDict->GetArray("Kids");
    948             if (pArray == NULL) {
    949                 return 1;
    950             } else {
    951                 return pArray->GetCount();
    952             }
    953         }
    954     }
    955 }
    956 CPDF_Dictionary* CPDF_InterForm::GetInternalField(FX_DWORD index, const CFX_WideString& csFieldName) const
    957 {
    958     if (m_pFormDict == NULL) {
    959         return NULL;
    960     }
    961     CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
    962     if (pArray == NULL) {
    963         return 0;
    964     }
    965     if (csFieldName.IsEmpty()) {
    966         return pArray->GetDict(index);
    967     } else {
    968         int iLength = csFieldName.GetLength();
    969         int iPos = 0;
    970         CPDF_Dictionary* pDict = NULL;
    971         while (pArray != NULL) {
    972             CFX_WideString csSub;
    973             if (iPos < iLength && csFieldName[iPos] == L'.') {
    974                 iPos ++;
    975             }
    976             while (iPos < iLength && csFieldName[iPos] != L'.') {
    977                 csSub += csFieldName[iPos ++];
    978             }
    979             int iCount = pArray->GetCount();
    980             FX_BOOL bFind = FALSE;
    981             for (int i = 0; i < iCount; i ++) {
    982                 pDict = pArray->GetDict(i);
    983                 if (pDict == NULL) {
    984                     continue;
    985                 }
    986                 CFX_WideString csT = pDict->GetUnicodeText("T");
    987                 if (csT == csSub) {
    988                     bFind = TRUE;
    989                     break;
    990                 }
    991             }
    992             if (!bFind) {
    993                 return NULL;
    994             }
    995             if (iPos >= iLength) {
    996                 break;
    997             }
    998             pArray = pDict->GetArray("Kids");
    999         }
   1000         if (pDict == NULL) {
   1001             return NULL;
   1002         } else {
   1003             pArray = pDict->GetArray("Kids");
   1004             if (pArray == NULL) {
   1005                 return pDict;
   1006             } else {
   1007                 return pArray->GetDict(index);
   1008             }
   1009         }
   1010     }
   1011 }
   1012 FX_BOOL CPDF_InterForm::NeedConstructAP()
   1013 {
   1014     if (m_pFormDict == NULL) {
   1015         return FALSE;
   1016     }
   1017     return m_pFormDict->GetBoolean("NeedAppearances");
   1018 }
   1019 void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP)
   1020 {
   1021     if (m_pFormDict == NULL) {
   1022         InitInterFormDict(m_pFormDict, m_pDocument);
   1023     }
   1024     m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP);
   1025     m_bGenerateAP = bNeedAP;
   1026 }
   1027 int CPDF_InterForm::CountFieldsInCalculationOrder()
   1028 {
   1029     if (m_pFormDict == NULL) {
   1030         return 0;
   1031     }
   1032     CPDF_Array* pArray = m_pFormDict->GetArray("CO");
   1033     if (pArray == NULL) {
   1034         return 0;
   1035     }
   1036     return pArray->GetCount();
   1037 }
   1038 CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index)
   1039 {
   1040     if (m_pFormDict == NULL || index < 0) {
   1041         return NULL;
   1042     }
   1043     CPDF_Array* pArray = m_pFormDict->GetArray("CO");
   1044     if (pArray == NULL) {
   1045         return NULL;
   1046     }
   1047     CPDF_Object* pElement = pArray->GetElementValue(index);
   1048     if (pElement != NULL && pElement->GetType() == PDFOBJ_DICTIONARY) {
   1049         return GetFieldByDict((CPDF_Dictionary*)pElement);
   1050     }
   1051     return NULL;
   1052 }
   1053 int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField)
   1054 {
   1055     if (m_pFormDict == NULL || pField == NULL) {
   1056         return -1;
   1057     }
   1058     CPDF_Array* pArray = m_pFormDict->GetArray("CO");
   1059     if (pArray == NULL) {
   1060         return -1;
   1061     }
   1062     for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
   1063         CPDF_Object* pElement = pArray->GetElementValue(i);
   1064         if (pElement == pField->m_pDict) {
   1065             return i;
   1066         }
   1067     }
   1068     return -1;
   1069 }
   1070 FX_DWORD CPDF_InterForm::CountFormFonts()
   1071 {
   1072     return CountInterFormFonts(m_pFormDict);
   1073 }
   1074 CPDF_Font* CPDF_InterForm::GetFormFont(FX_DWORD index, CFX_ByteString& csNameTag)
   1075 {
   1076     return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag);
   1077 }
   1078 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag)
   1079 {
   1080     return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag);
   1081 }
   1082 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName, CFX_ByteString& csNameTag)
   1083 {
   1084     return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag);
   1085 }
   1086 CPDF_Font* CPDF_InterForm::GetNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag)
   1087 {
   1088     return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
   1089 }
   1090 CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag)
   1091 {
   1092     return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
   1093 }
   1094 FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag)
   1095 {
   1096     return FindInterFormFont(m_pFormDict, pFont, csNameTag);
   1097 }
   1098 FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag)
   1099 {
   1100     return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont, csNameTag);
   1101 }
   1102 void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag)
   1103 {
   1104     AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag);
   1105     m_bUpdated = TRUE;
   1106 }
   1107 CPDF_Font* CPDF_InterForm::AddNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag)
   1108 {
   1109     m_bUpdated = TRUE;
   1110     return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
   1111 }
   1112 CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag)
   1113 {
   1114     m_bUpdated = TRUE;
   1115     return AddNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
   1116 }
   1117 void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont)
   1118 {
   1119     m_bUpdated = TRUE;
   1120     RemoveInterFormFont(m_pFormDict, pFont);
   1121 }
   1122 void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag)
   1123 {
   1124     m_bUpdated = TRUE;
   1125     RemoveInterFormFont(m_pFormDict, csNameTag);
   1126 }
   1127 CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance()
   1128 {
   1129     CFX_ByteString csDA;
   1130     if (m_pFormDict == NULL) {
   1131         return csDA;
   1132     }
   1133     csDA = m_pFormDict->GetString("DA");
   1134     return csDA;
   1135 }
   1136 CPDF_Font* CPDF_InterForm::GetDefaultFormFont()
   1137 {
   1138     return GetDefaultInterFormFont(m_pFormDict, m_pDocument);
   1139 }
   1140 int CPDF_InterForm::GetFormAlignment()
   1141 {
   1142     if (m_pFormDict == NULL) {
   1143         return 0;
   1144     }
   1145     return m_pFormDict->GetInteger("Q", 0);
   1146 }
   1147 FX_BOOL CPDF_InterForm::ResetForm(const CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bNotify)
   1148 {
   1149     if (bNotify && m_pFormNotify != NULL) {
   1150         int iRet = m_pFormNotify->BeforeFormReset(this);
   1151         if (iRet < 0) {
   1152             return FALSE;
   1153         }
   1154     }
   1155     int nCount = m_pFieldTree->m_Root.CountFields();
   1156     for (int i = 0; i < nCount; i++) {
   1157         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
   1158         if (pField == NULL) {
   1159             continue;
   1160         }
   1161         FX_BOOL bFind = FALSE;
   1162         int iCount = fields.GetSize();
   1163         for (int i = 0; i < iCount; i ++) {
   1164             if (pField == (CPDF_FormField*)fields[i]) {
   1165                 bFind = TRUE;
   1166                 break;
   1167             }
   1168         }
   1169         if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
   1170             pField->ResetField(bNotify);
   1171         }
   1172     }
   1173     if (bNotify && m_pFormNotify != NULL) {
   1174         m_pFormNotify->AfterFormReset(this);
   1175     }
   1176     return TRUE;
   1177 }
   1178 FX_BOOL CPDF_InterForm::ResetForm(FX_BOOL bNotify)
   1179 {
   1180     if (bNotify && m_pFormNotify != NULL) {
   1181         int iRet = m_pFormNotify->BeforeFormReset(this);
   1182         if (iRet < 0) {
   1183             return FALSE;
   1184         }
   1185     }
   1186     int nCount = m_pFieldTree->m_Root.CountFields();
   1187     for (int i = 0; i < nCount; i++) {
   1188         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
   1189         if (pField == NULL) {
   1190             continue;
   1191         }
   1192         pField->ResetField(bNotify);
   1193     }
   1194     if (bNotify && m_pFormNotify != NULL) {
   1195         m_pFormNotify->AfterFormReset(this);
   1196     }
   1197     return TRUE;
   1198 }
   1199 void CPDF_InterForm::ReloadForm()
   1200 {
   1201     FX_POSITION pos = m_ControlMap.GetStartPosition();
   1202     while (pos) {
   1203         CPDF_Dictionary* pWidgetDict;
   1204         CPDF_FormControl* pControl;
   1205         m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, (FX_LPVOID&)pControl);
   1206         delete pControl;
   1207     }
   1208     m_ControlMap.RemoveAll();
   1209     int nCount = m_pFieldTree->m_Root.CountFields();
   1210     for (int k = 0; k < nCount; k ++) {
   1211         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(k);
   1212         delete pField;
   1213     }
   1214     m_pFieldTree->RemoveAll();
   1215     if (m_pFormDict == NULL) {
   1216         return;
   1217     }
   1218     CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
   1219     if (pFields == NULL) {
   1220         return;
   1221     }
   1222     int iCount = pFields->GetCount();
   1223     for (int i = 0; i < iCount; i ++) {
   1224         LoadField(pFields->GetDict(i));
   1225     }
   1226 }
   1227 void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel)
   1228 {
   1229     if (nLevel > nMaxRecursion) {
   1230         return;
   1231     }
   1232     if (pFieldDict == NULL) {
   1233         return;
   1234     }
   1235     FX_DWORD dwParentObjNum = pFieldDict->GetObjNum();
   1236     CPDF_Array* pKids = pFieldDict->GetArray("Kids");
   1237     if (!pKids) {
   1238         AddTerminalField(pFieldDict);
   1239         return;
   1240     }
   1241     CPDF_Dictionary* pFirstKid = pKids->GetDict(0);
   1242     if (pFirstKid == NULL) {
   1243         return;
   1244     }
   1245     if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) {
   1246         for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
   1247             CPDF_Dictionary * pChildDict = pKids->GetDict(i);
   1248             if (pChildDict) {
   1249                 if (pChildDict->GetObjNum() != dwParentObjNum) {
   1250                     LoadField(pChildDict, nLevel + 1);
   1251                 }
   1252             }
   1253         }
   1254     } else {
   1255         AddTerminalField(pFieldDict);
   1256     }
   1257 }
   1258 FX_BOOL CPDF_InterForm::HasXFAForm() const
   1259 {
   1260     return m_pFormDict && m_pFormDict->GetArray(FX_BSTRC("XFA")) != NULL;
   1261 }
   1262 void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage)
   1263 {
   1264     ASSERT(pPage != NULL);
   1265     CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
   1266     if (pPageDict == NULL) {
   1267         return;
   1268     }
   1269     CPDF_Array* pAnnots = pPageDict->GetArray(FX_BSTRC("Annots"));
   1270     if (pAnnots == NULL) {
   1271         return;
   1272     }
   1273     int iAnnotCount = pAnnots->GetCount();
   1274     for (int i = 0; i < iAnnotCount; i++) {
   1275         CPDF_Dictionary* pAnnot = pAnnots->GetDict(i);
   1276         if (pAnnot != NULL && pAnnot->GetString(FX_BSTRC("Subtype")) == "Widget") {
   1277             LoadField(pAnnot);
   1278         }
   1279     }
   1280 }
   1281 CPDF_FormField* CPDF_InterForm::AddTerminalField(const CPDF_Dictionary* pFieldDict)
   1282 {
   1283     if (!pFieldDict->KeyExist(FX_BSTRC("T"))) {
   1284         return NULL;
   1285     }
   1286     CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFieldDict;
   1287     CFX_WideString csWName = GetFullName(pDict);
   1288     if (csWName.IsEmpty()) {
   1289         return NULL;
   1290     }
   1291     CPDF_FormField* pField = NULL;
   1292     pField = m_pFieldTree->GetField(csWName);
   1293     if (pField == NULL) {
   1294         CPDF_Dictionary *pParent = (CPDF_Dictionary*)pFieldDict;
   1295         if (!pFieldDict->KeyExist(FX_BSTR("T")) &&
   1296                 pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) {
   1297             pParent = pFieldDict->GetDict(FX_BSTRC("Parent"));
   1298             if (!pParent) {
   1299                 pParent = (CPDF_Dictionary*)pFieldDict;
   1300             }
   1301         }
   1302         if (pParent && pParent != pFieldDict && !pParent->KeyExist(FX_BSTRC("FT"))) {
   1303             if (pFieldDict->KeyExist(FX_BSTRC("FT"))) {
   1304                 CPDF_Object *pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT"));
   1305                 if (pFTValue) {
   1306                     pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone());
   1307                 }
   1308             }
   1309             if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) {
   1310                 CPDF_Object *pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff"));
   1311                 if (pFfValue) {
   1312                     pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone());
   1313                 }
   1314             }
   1315         }
   1316         pField = new CPDF_FormField(this, pParent);
   1317         CPDF_Object* pTObj = pDict->GetElement("T");
   1318         if (pTObj && pTObj->GetType() == PDFOBJ_REFERENCE) {
   1319             CPDF_Object* pClone = pTObj->Clone(TRUE);
   1320             if (pClone) {
   1321                 pDict->SetAt("T", pClone);
   1322             } else {
   1323                 pDict->SetAtName("T", "");
   1324             }
   1325         }
   1326         m_pFieldTree->SetField(csWName, pField);
   1327     }
   1328     CPDF_Array* pKids = pFieldDict->GetArray("Kids");
   1329     if (pKids == NULL) {
   1330         if (pFieldDict->GetString("Subtype") == "Widget") {
   1331             AddControl(pField, pFieldDict);
   1332         }
   1333     } else {
   1334         for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
   1335             CPDF_Dictionary* pKid = pKids->GetDict(i);
   1336             if (pKid == NULL) {
   1337                 continue;
   1338             }
   1339             if (pKid->GetString("Subtype") != "Widget") {
   1340                 continue;
   1341             }
   1342             AddControl(pField, pKid);
   1343         }
   1344     }
   1345     return pField;
   1346 }
   1347 CPDF_FormControl* CPDF_InterForm::AddControl(const CPDF_FormField* pField, const CPDF_Dictionary* pWidgetDict)
   1348 {
   1349     void *rValue = NULL;
   1350     if (m_ControlMap.Lookup((CPDF_Dictionary*)pWidgetDict, rValue)) {
   1351         return (CPDF_FormControl*)rValue;
   1352     }
   1353     CPDF_FormControl* pControl = new CPDF_FormControl((CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict);
   1354     m_ControlMap.SetAt((CPDF_Dictionary*)pWidgetDict, pControl);
   1355     ((CPDF_FormField*)pField)->m_ControlList.Add(pControl);
   1356     return pControl;
   1357 }
   1358 CPDF_FormField* CPDF_InterForm::CheckRequiredFields(const CFX_PtrArray *fields, FX_BOOL bIncludeOrExclude) const
   1359 {
   1360     int nCount = m_pFieldTree->m_Root.CountFields();
   1361     for (int i = 0; i < nCount; i++) {
   1362         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
   1363         if (pField == NULL) {
   1364             continue;
   1365         }
   1366         FX_INT32 iType = pField->GetType();
   1367         if (iType == CPDF_FormField::PushButton || iType == CPDF_FormField::CheckBox || iType == CPDF_FormField::ListBox) {
   1368             continue;
   1369         }
   1370         FX_DWORD dwFlags = pField->GetFieldFlags();
   1371         if (dwFlags & 0x04) {
   1372             continue;
   1373         }
   1374         FX_BOOL bFind = TRUE;
   1375         if (fields != NULL) {
   1376             bFind = fields->Find(pField, 0) >= 0;
   1377         }
   1378         if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
   1379             CPDF_Dictionary *pFieldDict = pField->m_pDict;
   1380             if ((dwFlags & 0x02) != 0 && pFieldDict->GetString("V").IsEmpty()) {
   1381                 return pField;
   1382             }
   1383         }
   1384     }
   1385     return NULL;
   1386 }
   1387 CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, FX_BOOL bSimpleFileSpec) const
   1388 {
   1389     CFX_PtrArray fields;
   1390     int nCount = m_pFieldTree->m_Root.CountFields();
   1391     for (int i = 0; i < nCount; i ++) {
   1392         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
   1393         fields.Add(pField);
   1394     }
   1395     return ExportToFDF(pdf_path, fields, TRUE, bSimpleFileSpec);
   1396 }
   1397 CFX_WideString FILESPEC_EncodeFileName(FX_WSTR filepath);
   1398 CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bSimpleFileSpec) const
   1399 {
   1400     CFDF_Document* pDoc = CFDF_Document::CreateNewDoc();
   1401     if (pDoc == NULL) {
   1402         return NULL;
   1403     }
   1404     CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF");
   1405     if (!pdf_path.IsEmpty()) {
   1406         if (bSimpleFileSpec) {
   1407             CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path);
   1408             pMainDict->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(wsFilePath));
   1409             pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath));
   1410         } else {
   1411             CPDF_FileSpec filespec;
   1412             filespec.SetFileName(pdf_path);
   1413             pMainDict->SetAt("F", (CPDF_Object*)filespec);
   1414         }
   1415     }
   1416     CPDF_Array* pFields = CPDF_Array::Create();
   1417     if (pFields == NULL) {
   1418         return NULL;
   1419     }
   1420     pMainDict->SetAt("Fields", pFields);
   1421     int nCount = m_pFieldTree->m_Root.CountFields();
   1422     for (int i = 0; i < nCount; i ++) {
   1423         CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
   1424         if (pField == NULL || pField->GetType() == CPDF_FormField::PushButton) {
   1425             continue;
   1426         }
   1427         FX_DWORD dwFlags = pField->GetFieldFlags();
   1428         if (dwFlags & 0x04) {
   1429             continue;
   1430         }
   1431         FX_BOOL bFind = fields.Find(pField, 0) >= 0;
   1432         if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
   1433             if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) {
   1434                 continue;
   1435             }
   1436             CFX_WideString fullname = GetFullName(pField->GetFieldDict());
   1437             CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create();
   1438             if (pFieldDict == NULL) {
   1439                 return NULL;
   1440             }
   1441             CPDF_String* pString = CPDF_String::Create(fullname);
   1442             if (pString == NULL) {
   1443                 pFieldDict->Release();
   1444                 return NULL;
   1445             }
   1446             pFieldDict->SetAt("T", pString);
   1447             if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) {
   1448                 CFX_WideString csExport = pField->GetCheckValue(FALSE);
   1449                 CFX_ByteString csBExport = PDF_EncodeText(csExport);
   1450                 CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
   1451                 if (pOpt == NULL) {
   1452                     pFieldDict->SetAtName("V", csBExport);
   1453                 } else {
   1454                     pFieldDict->SetAtString("V", csBExport);
   1455                 }
   1456             } else {
   1457                 CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
   1458                 if (pV != NULL) {
   1459                     pFieldDict->SetAt("V", pV->Clone(TRUE));
   1460                 }
   1461             }
   1462             pFields->Add(pFieldDict);
   1463         }
   1464     }
   1465     return pDoc;
   1466 }
   1467 const struct _SupportFieldEncoding {
   1468     FX_LPCSTR m_name;
   1469     FX_INT32 m_codePage;
   1470 } g_fieldEncoding[] = {
   1471     { "BigFive", 950 },
   1472     { "GBK", 936 },
   1473     { "Shift-JIS", 932 },
   1474     { "UHC", 949 },
   1475 };
   1476 static void FPDFDOC_FDF_GetFieldValue(CPDF_Dictionary *pFieldDict, CFX_WideString &csValue, CFX_ByteString &bsEncoding)
   1477 {
   1478     ASSERT(pFieldDict != NULL);
   1479     CFX_ByteString csBValue = pFieldDict->GetString("V");
   1480     FX_INT32 iCount = sizeof(g_fieldEncoding) / sizeof(g_fieldEncoding[0]);
   1481     FX_INT32 i = 0;
   1482     for (; i < iCount; ++i)
   1483         if (bsEncoding == g_fieldEncoding[i].m_name) {
   1484             break;
   1485         }
   1486     if (i < iCount) {
   1487         CFX_CharMap *pCharMap = CFX_CharMap::GetDefaultMapper(g_fieldEncoding[i].m_codePage);
   1488         FXSYS_assert(pCharMap != NULL);
   1489         csValue.ConvertFrom(csBValue, pCharMap);
   1490         return;
   1491     }
   1492     CFX_ByteString csTemp = csBValue.Left(2);
   1493     if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF") {
   1494         csValue = PDF_DecodeText(csBValue);
   1495     } else {
   1496         csValue = CFX_WideString::FromLocal(csBValue);
   1497     }
   1498 }
   1499 void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, const CFX_WideString& parent_name, FX_BOOL bNotify, int nLevel)
   1500 {
   1501     CFX_WideString name;
   1502     if (!parent_name.IsEmpty()) {
   1503         name = parent_name + L".";
   1504     }
   1505     name += pFieldDict->GetUnicodeText("T");
   1506     CPDF_Array* pKids = pFieldDict->GetArray("Kids");
   1507     if (pKids) {
   1508         for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
   1509             CPDF_Dictionary* pKid = pKids->GetDict(i);
   1510             if (pKid == NULL) {
   1511                 continue;
   1512             }
   1513             if (nLevel <= nMaxRecursion) {
   1514                 FDF_ImportField(pKid, name, bNotify, nLevel + 1);
   1515             }
   1516         }
   1517         return;
   1518     }
   1519     if (!pFieldDict->KeyExist("V")) {
   1520         return;
   1521     }
   1522     CPDF_FormField* pField = m_pFieldTree->GetField(name);
   1523     if (pField == NULL) {
   1524         return;
   1525     }
   1526     CFX_WideString csWValue;
   1527     FPDFDOC_FDF_GetFieldValue(pFieldDict, csWValue, m_bsEncoding);
   1528     int iType = pField->GetFieldType();
   1529     if (bNotify && m_pFormNotify != NULL) {
   1530         int iRet = 0;
   1531         if (iType == FIELDTYPE_LISTBOX) {
   1532             iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue);
   1533         } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
   1534             iRet = m_pFormNotify->BeforeValueChange(pField, csWValue);
   1535         }
   1536         if (iRet < 0) {
   1537             return;
   1538         }
   1539     }
   1540     CFX_ByteArray statusArray;
   1541     if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
   1542         SaveCheckedFieldStatus(pField, statusArray);
   1543     }
   1544     pField->SetValue(csWValue);
   1545     CPDF_FormField::Type eType = pField->GetType();
   1546     if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) && pFieldDict->KeyExist("Opt")) {
   1547         pField->m_pDict->SetAt("Opt", pFieldDict->GetElementValue("Opt")->Clone(TRUE));
   1548     }
   1549     if (bNotify && m_pFormNotify != NULL) {
   1550         if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
   1551             m_pFormNotify->AfterCheckedStatusChange(pField, statusArray);
   1552         } else if (iType == FIELDTYPE_LISTBOX) {
   1553             m_pFormNotify->AfterSelectionChange(pField);
   1554         } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
   1555             m_pFormNotify->AfterValueChange(pField);
   1556         }
   1557     }
   1558     if (CPDF_InterForm::m_bUpdateAP) {
   1559         pField->UpdateAP(NULL);
   1560     }
   1561 }
   1562 FX_BOOL CPDF_InterForm::ImportFromFDF(const CFDF_Document* pFDF, FX_BOOL bNotify)
   1563 {
   1564     if (pFDF == NULL) {
   1565         return FALSE;
   1566     }
   1567     CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
   1568     if (pMainDict == NULL) {
   1569         return FALSE;
   1570     }
   1571     CPDF_Array* pFields = pMainDict->GetArray("Fields");
   1572     if (pFields == NULL) {
   1573         return FALSE;
   1574     }
   1575     m_bsEncoding = pMainDict->GetString(FX_BSTRC("Encoding"));
   1576     if (bNotify && m_pFormNotify != NULL) {
   1577         int iRet = m_pFormNotify->BeforeFormImportData(this);
   1578         if (iRet < 0) {
   1579             return FALSE;
   1580         }
   1581     }
   1582     for (FX_DWORD i = 0; i < pFields->GetCount(); i ++) {
   1583         CPDF_Dictionary* pField = pFields->GetDict(i);
   1584         if (pField == NULL) {
   1585             continue;
   1586         }
   1587         FDF_ImportField(pField, L"", bNotify);
   1588     }
   1589     if (bNotify && m_pFormNotify != NULL) {
   1590         m_pFormNotify->AfterFormImportData(this);
   1591     }
   1592     return TRUE;
   1593 }
   1594 void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify)
   1595 {
   1596     m_pFormNotify = (CPDF_FormNotify*)pNotify;
   1597 }
   1598 int CPDF_InterForm::GetPageWithWidget(int iCurPage, FX_BOOL bNext)
   1599 {
   1600     if (iCurPage < 0) {
   1601         return -1;
   1602     }
   1603     int iPageCount = m_pDocument->GetPageCount();
   1604     if (iCurPage >= iPageCount) {
   1605         return -1;
   1606     }
   1607     int iNewPage = iCurPage;
   1608     do {
   1609         iNewPage += bNext ? 1 : -1;
   1610         if (iNewPage >= iPageCount) {
   1611             iNewPage = 0;
   1612         }
   1613         if (iNewPage < 0) {
   1614             iNewPage = iPageCount - 1;
   1615         }
   1616         if (iNewPage == iCurPage) {
   1617             break;
   1618         }
   1619         CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iNewPage);
   1620         if (pPageDict == NULL) {
   1621             continue;
   1622         }
   1623         CPDF_Array* pAnnots = pPageDict->GetArray("Annots");
   1624         if (pAnnots == NULL) {
   1625             continue;
   1626         }
   1627         FX_DWORD dwCount = pAnnots->GetCount();
   1628         for (FX_DWORD i = 0; i < dwCount; i ++) {
   1629             CPDF_Object* pAnnotDict = pAnnots->GetElementValue(i);
   1630             if (pAnnotDict == NULL) {
   1631                 continue;
   1632             }
   1633             CPDF_FormControl* pControl = NULL;
   1634             if (m_ControlMap.Lookup(pAnnotDict, (void*&)pControl)) {
   1635                 return iNewPage;
   1636             }
   1637         }
   1638     } while (TRUE);
   1639     return -1;
   1640 }
   1641