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