Add new public APIs to find the z-order for links and widgets.
[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_pFormNotify = NULL;
240   m_bUpdated = FALSE;
241   m_pFieldTree = new CFieldTree;
242   CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
243   m_pFormDict = pRoot->GetDict("AcroForm");
244   if (m_pFormDict == NULL) {
245     return;
246   }
247   CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
248   if (pFields == NULL) {
249     return;
250   }
251   int count = pFields->GetCount();
252   for (int i = 0; i < count; i++) {
253     LoadField(pFields->GetDict(i));
254   }
255 }
256
257 CPDF_InterForm::~CPDF_InterForm() {
258   for (auto it : m_ControlMap)
259     delete it.second;
260   if (m_pFieldTree) {
261     int nCount = m_pFieldTree->m_Root.CountFields();
262     for (int i = 0; i < nCount; ++i) {
263       delete m_pFieldTree->m_Root.GetField(i);
264     }
265     delete m_pFieldTree;
266   }
267 }
268
269 FX_BOOL CPDF_InterForm::m_bUpdateAP = TRUE;
270 FX_BOOL CPDF_InterForm::UpdatingAPEnabled() {
271   return m_bUpdateAP;
272 }
273 void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP) {
274   m_bUpdateAP = bUpdateAP;
275 }
276 CFX_ByteString CPDF_InterForm::GenerateNewResourceName(
277     const CPDF_Dictionary* pResDict,
278     const FX_CHAR* csType,
279     int iMinLen,
280     const FX_CHAR* csPrefix) {
281   CFX_ByteString csStr = csPrefix;
282   CFX_ByteString csBType = csType;
283   if (csStr.IsEmpty()) {
284     if (csBType == "ExtGState") {
285       csStr = "GS";
286     } else if (csBType == "ColorSpace") {
287       csStr = "CS";
288     } else if (csBType == "Font") {
289       csStr = "ZiTi";
290     } else {
291       csStr = "Res";
292     }
293   }
294   CFX_ByteString csTmp = csStr;
295   int iCount = csStr.GetLength();
296   int m = 0;
297   if (iMinLen > 0) {
298     csTmp = "";
299     while (m < iMinLen && m < iCount) {
300       csTmp += csStr[m++];
301     }
302     while (m < iMinLen) {
303       csTmp += '0' + m % 10;
304       m++;
305     }
306   } else {
307     m = iCount;
308   }
309   if (pResDict == NULL) {
310     return csTmp;
311   }
312   CPDF_Dictionary* pDict = pResDict->GetDict(csType);
313   if (pDict == NULL) {
314     return csTmp;
315   }
316   int num = 0;
317   CFX_ByteString bsNum;
318   while (TRUE) {
319     if (!pDict->KeyExist(csTmp + bsNum)) {
320       return csTmp + bsNum;
321     }
322     if (m < iCount) {
323       csTmp += csStr[m++];
324     } else {
325       bsNum.Format("%d", num++);
326     }
327     m++;
328   }
329   return csTmp;
330 }
331 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
332 typedef struct _PDF_FONTDATA {
333   FX_BOOL bFind;
334   LOGFONTA lf;
335 } PDF_FONTDATA, FAR* LPDF_FONTDATA;
336 static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXA* lpelfe,
337                                       NEWTEXTMETRICEX* lpntme,
338                                       DWORD FontType,
339                                       LPARAM lParam) {
340   if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@') != NULL) {
341     return 1;
342   }
343   LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam;
344   memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA));
345   pData->bFind = TRUE;
346   return 0;
347 }
348 static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf) {
349   PDF_FONTDATA fd;
350   memset(&fd, 0, sizeof(PDF_FONTDATA));
351   HDC hDC = ::GetDC(NULL);
352   EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd,
353                       0);
354   ::ReleaseDC(NULL, hDC);
355   if (fd.bFind) {
356     memcpy(&lf, &fd.lf, sizeof(LOGFONTA));
357   }
358   return fd.bFind;
359 }
360 static FX_BOOL RetrieveSpecificFont(uint8_t charSet,
361                                     uint8_t pitchAndFamily,
362                                     LPCSTR pcsFontName,
363                                     LOGFONTA& lf) {
364   memset(&lf, 0, sizeof(LOGFONTA));
365   lf.lfCharSet = charSet;
366   lf.lfPitchAndFamily = pitchAndFamily;
367   if (pcsFontName != NULL) {
368     strcpy(lf.lfFaceName, pcsFontName);
369   }
370   return RetrieveSpecificFont(lf);
371 }
372 static FX_BOOL RetrieveStockFont(int iFontObject,
373                                  uint8_t charSet,
374                                  LOGFONTA& lf) {
375   HFONT hFont = (HFONT)::GetStockObject(iFontObject);
376   if (hFont != NULL) {
377     memset(&lf, 0, sizeof(LOGFONTA));
378     int iRet = ::GetObject(hFont, sizeof(LOGFONTA), &lf);
379     if (iRet > 0 && (lf.lfCharSet == charSet || charSet == 255)) {
380       return RetrieveSpecificFont(lf);
381     }
382   }
383   return FALSE;
384 }
385 #endif
386 CPDF_Font* CPDF_InterForm::AddSystemDefaultFont(
387     const CPDF_Document* pDocument) {
388   if (pDocument == NULL) {
389     return NULL;
390   }
391   CPDF_Font* pFont = NULL;
392 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
393   LOGFONTA lf;
394   FX_BOOL bRet;
395   bRet = RetrieveStockFont(DEFAULT_GUI_FONT, 255, lf);
396   if (!bRet) {
397     bRet = RetrieveStockFont(SYSTEM_FONT, 255, lf);
398   }
399   if (bRet) {
400     pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
401   }
402 #endif
403   return pFont;
404 }
405 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument,
406                                          CFX_ByteString csFontName,
407                                          uint8_t iCharSet) {
408   if (pDocument == NULL || csFontName.IsEmpty()) {
409     return NULL;
410   }
411 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
412   if (iCharSet == 1) {
413     iCharSet = GetNativeCharSet();
414   }
415   HFONT hFont = ::CreateFontA(
416       0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
417       DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
418   if (hFont != NULL) {
419     LOGFONTA lf;
420     memset(&lf, 0, sizeof(LOGFONTA));
421     ::GetObjectA(hFont, sizeof(LOGFONTA), &lf);
422     ::DeleteObject(hFont);
423     if (strlen(lf.lfFaceName) > 0) {
424       return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
425     }
426   }
427 #endif
428   return NULL;
429 }
430 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument,
431                                          CFX_WideString csFontName,
432                                          uint8_t iCharSet) {
433   if (pDocument == NULL || csFontName.IsEmpty()) {
434     return NULL;
435   }
436 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
437   if (iCharSet == 1) {
438     iCharSet = GetNativeCharSet();
439   }
440   HFONT hFont = ::CreateFontW(
441       0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
442       DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
443   if (hFont != NULL) {
444     LOGFONTA lf;
445     memset(&lf, 0, sizeof(LOGFONTA));
446     ::GetObject(hFont, sizeof(LOGFONTA), &lf);
447     ::DeleteObject(hFont);
448     if (strlen(lf.lfFaceName) > 0) {
449       return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
450     }
451   }
452 #endif
453   return NULL;
454 }
455 CPDF_Font* CPDF_InterForm::AddStandardFont(const CPDF_Document* pDocument,
456                                            CFX_ByteString csFontName) {
457   if (pDocument == NULL || csFontName.IsEmpty()) {
458     return NULL;
459   }
460   CPDF_Font* pFont = NULL;
461   if (csFontName == "ZapfDingbats") {
462     pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, NULL);
463   } else {
464     CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI);
465     pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, &encoding);
466   }
467   return pFont;
468 }
469 CFX_ByteString CPDF_InterForm::GetNativeFont(uint8_t charSet, void* pLogFont) {
470   CFX_ByteString csFontName;
471 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
472   LOGFONTA lf;
473   FX_BOOL bRet;
474   if (charSet == ANSI_CHARSET) {
475     csFontName = "Helvetica";
476     return csFontName;
477   }
478   bRet = FALSE;
479   if (charSet == SHIFTJIS_CHARSET) {
480     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
481                                 "MS Mincho", lf);
482   } else if (charSet == GB2312_CHARSET) {
483     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "SimSun",
484                                 lf);
485   } else if (charSet == CHINESEBIG5_CHARSET) {
486     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MingLiU",
487                                 lf);
488   }
489   if (!bRet) {
490     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
491                                 "Arial Unicode MS", lf);
492   }
493   if (!bRet) {
494     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
495                                 "Microsoft Sans Serif", lf);
496   }
497   if (!bRet) {
498     bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, NULL, lf);
499   }
500   if (bRet) {
501     if (pLogFont != NULL) {
502       memcpy(pLogFont, &lf, sizeof(LOGFONTA));
503     }
504     csFontName = lf.lfFaceName;
505     return csFontName;
506   }
507 #endif
508   return csFontName;
509 }
510 CFX_ByteString CPDF_InterForm::GetNativeFont(void* pLogFont) {
511 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
512   uint8_t charSet = GetNativeCharSet();
513   return GetNativeFont(charSet, pLogFont);
514 #else
515   return CFX_ByteString();
516 #endif
517 }
518 uint8_t CPDF_InterForm::GetNativeCharSet() {
519 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
520   uint8_t charSet = ANSI_CHARSET;
521   UINT iCodePage = ::GetACP();
522   switch (iCodePage) {
523     case 932:
524       charSet = SHIFTJIS_CHARSET;
525       break;
526     case 936:
527       charSet = GB2312_CHARSET;
528       break;
529     case 950:
530       charSet = CHINESEBIG5_CHARSET;
531       break;
532     case 1252:
533       charSet = ANSI_CHARSET;
534       break;
535     case 874:
536       charSet = THAI_CHARSET;
537       break;
538     case 949:
539       charSet = HANGUL_CHARSET;
540       break;
541     case 1200:
542       charSet = ANSI_CHARSET;
543       break;
544     case 1250:
545       charSet = EASTEUROPE_CHARSET;
546       break;
547     case 1251:
548       charSet = RUSSIAN_CHARSET;
549       break;
550     case 1253:
551       charSet = GREEK_CHARSET;
552       break;
553     case 1254:
554       charSet = TURKISH_CHARSET;
555       break;
556     case 1255:
557       charSet = HEBREW_CHARSET;
558       break;
559     case 1256:
560       charSet = ARABIC_CHARSET;
561       break;
562     case 1257:
563       charSet = BALTIC_CHARSET;
564       break;
565     case 1258:
566       charSet = VIETNAMESE_CHARSET;
567       break;
568     case 1361:
569       charSet = JOHAB_CHARSET;
570       break;
571   }
572   return charSet;
573 #else
574   return 0;
575 #endif
576 }
577 CPDF_Font* CPDF_InterForm::AddNativeFont(uint8_t charSet,
578                                          const CPDF_Document* pDocument) {
579   if (pDocument == NULL) {
580     return NULL;
581   }
582   CPDF_Font* pFont = NULL;
583 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
584   LOGFONTA lf;
585   CFX_ByteString csFontName = GetNativeFont(charSet, &lf);
586   if (!csFontName.IsEmpty()) {
587     if (csFontName == "Helvetica") {
588       pFont = AddStandardFont(pDocument, csFontName);
589     } else {
590       pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
591     }
592   }
593 #endif
594   return pFont;
595 }
596 CPDF_Font* CPDF_InterForm::AddNativeFont(const CPDF_Document* pDocument) {
597   if (pDocument == NULL) {
598     return NULL;
599   }
600   CPDF_Font* pFont = NULL;
601   uint8_t charSet = GetNativeCharSet();
602   pFont = AddNativeFont(charSet, pDocument);
603   return pFont;
604 }
605 FX_BOOL CPDF_InterForm::ValidateFieldName(
606     CFX_WideString& csNewFieldName,
607     int iType,
608     const CPDF_FormField* pExcludedField,
609     const CPDF_FormControl* pExcludedControl) {
610   if (csNewFieldName.IsEmpty()) {
611     return FALSE;
612   }
613   int iPos = 0;
614   int iLength = csNewFieldName.GetLength();
615   CFX_WideString csSub;
616   while (TRUE) {
617     while (iPos < iLength &&
618            (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) {
619       iPos++;
620     }
621     if (iPos < iLength && !csSub.IsEmpty()) {
622       csSub += L'.';
623     }
624     while (iPos < iLength && csNewFieldName[iPos] != L'.') {
625       csSub += csNewFieldName[iPos++];
626     }
627     for (int i = csSub.GetLength() - 1; i > -1; i--) {
628       if (csSub[i] == L' ' || csSub[i] == L'.') {
629         csSub.SetAt(i, L'\0');
630       } else {
631         break;
632       }
633     }
634     FX_DWORD dwCount = m_pFieldTree->m_Root.CountFields();
635     for (FX_DWORD m = 0; m < dwCount; m++) {
636       CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m);
637       if (pField == NULL) {
638         continue;
639       }
640       if (pField == pExcludedField) {
641         if (pExcludedControl != NULL) {
642           if (pField->CountControls() < 2) {
643             continue;
644           }
645         } else {
646           continue;
647         }
648       }
649       CFX_WideString csFullName = pField->GetFullName();
650       int iRet = CompareFieldName(csSub, csFullName);
651       if (iRet == 1) {
652         if (pField->GetFieldType() != iType) {
653           return FALSE;
654         }
655       } else if (iRet == 2 && csSub == csNewFieldName) {
656         if (csFullName[iPos] == L'.') {
657           return FALSE;
658         }
659       } else if (iRet == 3 && csSub == csNewFieldName) {
660         if (csNewFieldName[csFullName.GetLength()] == L'.') {
661           return FALSE;
662         }
663       }
664     }
665     if (iPos >= iLength) {
666       break;
667     }
668   }
669   if (csSub.IsEmpty()) {
670     return FALSE;
671   }
672   csNewFieldName = csSub;
673   return TRUE;
674 }
675 FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName,
676                                           int iType) {
677   return ValidateFieldName(csNewFieldName, iType, NULL, NULL);
678 }
679 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField,
680                                           CFX_WideString& csNewFieldName) {
681   if (pField == NULL || csNewFieldName.IsEmpty()) {
682     return FALSE;
683   }
684   return ValidateFieldName(
685       csNewFieldName, ((CPDF_FormField*)pField)->GetFieldType(), pField, NULL);
686 }
687 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl,
688                                           CFX_WideString& csNewFieldName) {
689   if (pControl == NULL || csNewFieldName.IsEmpty()) {
690     return FALSE;
691   }
692   CPDF_FormField* pField = ((CPDF_FormControl*)pControl)->GetField();
693   return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField,
694                            pControl);
695 }
696 int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1,
697                                      const CFX_ByteString& name2) {
698   const FX_CHAR* ptr1 = name1;
699   const FX_CHAR* ptr2 = name2;
700   if (name1.GetLength() == name2.GetLength()) {
701     return name1 == name2 ? 1 : 0;
702   }
703   int i = 0;
704   while (ptr1[i] == ptr2[i]) {
705     i++;
706   }
707   if (i == name1.GetLength()) {
708     return 2;
709   }
710   if (i == name2.GetLength()) {
711     return 3;
712   }
713   return 0;
714 }
715 int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1,
716                                      const CFX_WideString& name2) {
717   const FX_WCHAR* ptr1 = name1.c_str();
718   const FX_WCHAR* ptr2 = name2.c_str();
719   if (name1.GetLength() == name2.GetLength()) {
720     return name1 == name2 ? 1 : 0;
721   }
722   int i = 0;
723   while (ptr1[i] == ptr2[i]) {
724     i++;
725   }
726   if (i == name1.GetLength()) {
727     return 2;
728   }
729   if (i == name2.GetLength()) {
730     return 3;
731   }
732   return 0;
733 }
734 FX_DWORD CPDF_InterForm::CountFields(const CFX_WideString& csFieldName) {
735   if (csFieldName.IsEmpty()) {
736     return (FX_DWORD)m_pFieldTree->m_Root.CountFields();
737   }
738   CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName);
739   if (pNode == NULL) {
740     return 0;
741   }
742   return pNode->CountFields();
743 }
744 CPDF_FormField* CPDF_InterForm::GetField(FX_DWORD index,
745                                          const CFX_WideString& csFieldName) {
746   if (csFieldName == L"") {
747     return m_pFieldTree->m_Root.GetField(index);
748   }
749   CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName);
750   if (pNode == NULL) {
751     return NULL;
752   }
753   return pNode->GetField(index);
754 }
755 void CPDF_InterForm::GetAllFieldNames(CFX_WideStringArray& allFieldNames) {
756   allFieldNames.RemoveAll();
757   int nCount = m_pFieldTree->m_Root.CountFields();
758   for (int i = 0; i < nCount; i++) {
759     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
760     if (pField) {
761       CFX_WideString full_name = GetFullName(pField->GetFieldDict());
762       allFieldNames.Add(full_name);
763     }
764   }
765 }
766 FX_BOOL CPDF_InterForm::IsValidFormField(const void* pField) {
767   if (pField == NULL) {
768     return FALSE;
769   }
770   int nCount = m_pFieldTree->m_Root.CountFields();
771   for (int i = 0; i < nCount; i++) {
772     CPDF_FormField* pFormField = m_pFieldTree->m_Root.GetField(i);
773     if (pField == pFormField) {
774       return TRUE;
775     }
776   }
777   return FALSE;
778 }
779 CPDF_FormField* CPDF_InterForm::GetFieldByDict(
780     CPDF_Dictionary* pFieldDict) const {
781   if (pFieldDict == NULL) {
782     return NULL;
783   }
784   CFX_WideString csWName = GetFullName(pFieldDict);
785   return m_pFieldTree->GetField(csWName);
786 }
787
788 CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage,
789                                                     FX_FLOAT pdf_x,
790                                                     FX_FLOAT pdf_y,
791                                                     int* z_order) const {
792   CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
793   if (!pAnnotList)
794     return nullptr;
795
796   for (FX_DWORD i = pAnnotList->GetCount(); i > 0; --i) {
797     FX_DWORD annot_index = i - 1;
798     CPDF_Dictionary* pAnnot = pAnnotList->GetDict(annot_index);
799     if (!pAnnot)
800       continue;
801
802     const auto it = m_ControlMap.find(pAnnot);
803     if (it == m_ControlMap.end())
804       continue;
805
806     CPDF_FormControl* pControl = it->second;
807     CFX_FloatRect rect = pControl->GetRect();
808     if (!rect.Contains(pdf_x, pdf_y))
809       continue;
810
811     if (z_order)
812       *z_order = annot_index;
813     return pControl;
814   }
815   return nullptr;
816 }
817
818 CPDF_FormControl* CPDF_InterForm::GetControlByDict(
819     CPDF_Dictionary* pWidgetDict) const {
820   const auto it = m_ControlMap.find(pWidgetDict);
821   return it != m_ControlMap.end() ? it->second : nullptr;
822 }
823
824 FX_BOOL CPDF_InterForm::NeedConstructAP() {
825   if (m_pFormDict == NULL) {
826     return FALSE;
827   }
828   return m_pFormDict->GetBoolean("NeedAppearances");
829 }
830 void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) {
831   if (m_pFormDict == NULL) {
832     InitInterFormDict(m_pFormDict, m_pDocument);
833   }
834   m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP);
835   m_bGenerateAP = bNeedAP;
836 }
837 int CPDF_InterForm::CountFieldsInCalculationOrder() {
838   if (m_pFormDict == NULL) {
839     return 0;
840   }
841   CPDF_Array* pArray = m_pFormDict->GetArray("CO");
842   if (pArray == NULL) {
843     return 0;
844   }
845   return pArray->GetCount();
846 }
847 CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index) {
848   if (m_pFormDict == NULL || index < 0) {
849     return NULL;
850   }
851   CPDF_Array* pArray = m_pFormDict->GetArray("CO");
852   if (pArray == NULL) {
853     return NULL;
854   }
855   CPDF_Object* pElement = pArray->GetElementValue(index);
856   if (pElement != NULL && pElement->GetType() == PDFOBJ_DICTIONARY) {
857     return GetFieldByDict((CPDF_Dictionary*)pElement);
858   }
859   return NULL;
860 }
861 int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField) {
862   if (m_pFormDict == NULL || pField == NULL) {
863     return -1;
864   }
865   CPDF_Array* pArray = m_pFormDict->GetArray("CO");
866   if (pArray == NULL) {
867     return -1;
868   }
869   for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
870     CPDF_Object* pElement = pArray->GetElementValue(i);
871     if (pElement == pField->m_pDict) {
872       return i;
873     }
874   }
875   return -1;
876 }
877 FX_DWORD CPDF_InterForm::CountFormFonts() {
878   return CountInterFormFonts(m_pFormDict);
879 }
880 CPDF_Font* CPDF_InterForm::GetFormFont(FX_DWORD index,
881                                        CFX_ByteString& csNameTag) {
882   return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag);
883 }
884 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag) {
885   return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag);
886 }
887 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName,
888                                        CFX_ByteString& csNameTag) {
889   return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag);
890 }
891 CPDF_Font* CPDF_InterForm::GetNativeFormFont(uint8_t charSet,
892                                              CFX_ByteString& csNameTag) {
893   return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
894 }
895 CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag) {
896   return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
897 }
898 FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont,
899                                      CFX_ByteString& csNameTag) {
900   return FindInterFormFont(m_pFormDict, pFont, csNameTag);
901 }
902 FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName,
903                                      CPDF_Font*& pFont,
904                                      CFX_ByteString& csNameTag) {
905   return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont,
906                            csNameTag);
907 }
908 void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont,
909                                  CFX_ByteString& csNameTag) {
910   AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag);
911   m_bUpdated = TRUE;
912 }
913 CPDF_Font* CPDF_InterForm::AddNativeFormFont(uint8_t charSet,
914                                              CFX_ByteString& csNameTag) {
915   m_bUpdated = TRUE;
916   return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
917 }
918 CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag) {
919   m_bUpdated = TRUE;
920   return AddNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
921 }
922 void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont) {
923   m_bUpdated = TRUE;
924   RemoveInterFormFont(m_pFormDict, pFont);
925 }
926 void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag) {
927   m_bUpdated = TRUE;
928   RemoveInterFormFont(m_pFormDict, csNameTag);
929 }
930 CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance() {
931   CFX_ByteString csDA;
932   if (m_pFormDict == NULL) {
933     return csDA;
934   }
935   csDA = m_pFormDict->GetString("DA");
936   return csDA;
937 }
938 CPDF_Font* CPDF_InterForm::GetDefaultFormFont() {
939   return GetDefaultInterFormFont(m_pFormDict, m_pDocument);
940 }
941 int CPDF_InterForm::GetFormAlignment() {
942   if (m_pFormDict == NULL) {
943     return 0;
944   }
945   return m_pFormDict->GetInteger("Q", 0);
946 }
947 FX_BOOL CPDF_InterForm::ResetForm(const CFX_PtrArray& fields,
948                                   FX_BOOL bIncludeOrExclude,
949                                   FX_BOOL bNotify) {
950   if (bNotify && m_pFormNotify != NULL) {
951     int iRet = m_pFormNotify->BeforeFormReset(this);
952     if (iRet < 0) {
953       return FALSE;
954     }
955   }
956   int nCount = m_pFieldTree->m_Root.CountFields();
957   for (int i = 0; i < nCount; i++) {
958     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
959     if (pField == NULL) {
960       continue;
961     }
962     FX_BOOL bFind = FALSE;
963     int iCount = fields.GetSize();
964     for (int i = 0; i < iCount; i++) {
965       if (pField == (CPDF_FormField*)fields[i]) {
966         bFind = TRUE;
967         break;
968       }
969     }
970     if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
971       pField->ResetField(bNotify);
972     }
973   }
974   if (bNotify && m_pFormNotify != NULL) {
975     m_pFormNotify->AfterFormReset(this);
976   }
977   return TRUE;
978 }
979 FX_BOOL CPDF_InterForm::ResetForm(FX_BOOL bNotify) {
980   if (bNotify && m_pFormNotify != NULL) {
981     int iRet = m_pFormNotify->BeforeFormReset(this);
982     if (iRet < 0) {
983       return FALSE;
984     }
985   }
986   int nCount = m_pFieldTree->m_Root.CountFields();
987   for (int i = 0; i < nCount; i++) {
988     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
989     if (pField == NULL) {
990       continue;
991     }
992     pField->ResetField(bNotify);
993   }
994   if (bNotify && m_pFormNotify != NULL) {
995     m_pFormNotify->AfterFormReset(this);
996   }
997   return TRUE;
998 }
999 void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) {
1000   if (nLevel > nMaxRecursion) {
1001     return;
1002   }
1003   if (pFieldDict == NULL) {
1004     return;
1005   }
1006   FX_DWORD dwParentObjNum = pFieldDict->GetObjNum();
1007   CPDF_Array* pKids = pFieldDict->GetArray("Kids");
1008   if (!pKids) {
1009     AddTerminalField(pFieldDict);
1010     return;
1011   }
1012   CPDF_Dictionary* pFirstKid = pKids->GetDict(0);
1013   if (pFirstKid == NULL) {
1014     return;
1015   }
1016   if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) {
1017     for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
1018       CPDF_Dictionary* pChildDict = pKids->GetDict(i);
1019       if (pChildDict) {
1020         if (pChildDict->GetObjNum() != dwParentObjNum) {
1021           LoadField(pChildDict, nLevel + 1);
1022         }
1023       }
1024     }
1025   } else {
1026     AddTerminalField(pFieldDict);
1027   }
1028 }
1029 FX_BOOL CPDF_InterForm::HasXFAForm() const {
1030   return m_pFormDict && m_pFormDict->GetArray(FX_BSTRC("XFA")) != NULL;
1031 }
1032 void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage) {
1033   ASSERT(pPage != NULL);
1034   CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
1035   if (pPageDict == NULL) {
1036     return;
1037   }
1038   CPDF_Array* pAnnots = pPageDict->GetArray(FX_BSTRC("Annots"));
1039   if (pAnnots == NULL) {
1040     return;
1041   }
1042   int iAnnotCount = pAnnots->GetCount();
1043   for (int i = 0; i < iAnnotCount; i++) {
1044     CPDF_Dictionary* pAnnot = pAnnots->GetDict(i);
1045     if (pAnnot != NULL && pAnnot->GetString(FX_BSTRC("Subtype")) == "Widget") {
1046       LoadField(pAnnot);
1047     }
1048   }
1049 }
1050 CPDF_FormField* CPDF_InterForm::AddTerminalField(
1051     const CPDF_Dictionary* pFieldDict) {
1052   if (!pFieldDict->KeyExist(FX_BSTRC("T"))) {
1053     return NULL;
1054   }
1055   CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFieldDict;
1056   CFX_WideString csWName = GetFullName(pDict);
1057   if (csWName.IsEmpty()) {
1058     return NULL;
1059   }
1060   CPDF_FormField* pField = NULL;
1061   pField = m_pFieldTree->GetField(csWName);
1062   if (pField == NULL) {
1063     CPDF_Dictionary* pParent = (CPDF_Dictionary*)pFieldDict;
1064     if (!pFieldDict->KeyExist(FX_BSTRC("T")) &&
1065         pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) {
1066       pParent = pFieldDict->GetDict(FX_BSTRC("Parent"));
1067       if (!pParent) {
1068         pParent = (CPDF_Dictionary*)pFieldDict;
1069       }
1070     }
1071     if (pParent && pParent != pFieldDict &&
1072         !pParent->KeyExist(FX_BSTRC("FT"))) {
1073       if (pFieldDict->KeyExist(FX_BSTRC("FT"))) {
1074         CPDF_Object* pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT"));
1075         if (pFTValue) {
1076           pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone());
1077         }
1078       }
1079       if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) {
1080         CPDF_Object* pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff"));
1081         if (pFfValue) {
1082           pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone());
1083         }
1084       }
1085     }
1086     pField = new CPDF_FormField(this, pParent);
1087     CPDF_Object* pTObj = pDict->GetElement("T");
1088     if (pTObj && pTObj->GetType() == PDFOBJ_REFERENCE) {
1089       CPDF_Object* pClone = pTObj->Clone(TRUE);
1090       if (pClone) {
1091         pDict->SetAt("T", pClone);
1092       } else {
1093         pDict->SetAtName("T", "");
1094       }
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(
1118     const CPDF_FormField* pField,
1119     const CPDF_Dictionary* pWidgetDict) {
1120   const auto it = m_ControlMap.find(pWidgetDict);
1121   if (it != m_ControlMap.end())
1122     return it->second;
1123
1124   CPDF_FormControl* pControl = new CPDF_FormControl(
1125       (CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict);
1126   m_ControlMap[pWidgetDict] = pControl;
1127   ((CPDF_FormField*)pField)->m_ControlList.Add(pControl);
1128   return pControl;
1129 }
1130 CPDF_FormField* CPDF_InterForm::CheckRequiredFields(
1131     const CFX_PtrArray* fields,
1132     FX_BOOL bIncludeOrExclude) const {
1133   int nCount = m_pFieldTree->m_Root.CountFields();
1134   for (int i = 0; i < nCount; i++) {
1135     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
1136     if (pField == NULL) {
1137       continue;
1138     }
1139     int32_t iType = pField->GetType();
1140     if (iType == CPDF_FormField::PushButton ||
1141         iType == CPDF_FormField::CheckBox || iType == CPDF_FormField::ListBox) {
1142       continue;
1143     }
1144     FX_DWORD dwFlags = pField->GetFieldFlags();
1145     if (dwFlags & 0x04) {
1146       continue;
1147     }
1148     FX_BOOL bFind = TRUE;
1149     if (fields != NULL) {
1150       bFind = fields->Find(pField, 0) >= 0;
1151     }
1152     if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
1153       CPDF_Dictionary* pFieldDict = pField->m_pDict;
1154       if ((dwFlags & 0x02) != 0 && pFieldDict->GetString("V").IsEmpty()) {
1155         return pField;
1156       }
1157     }
1158   }
1159   return NULL;
1160 }
1161 CFDF_Document* CPDF_InterForm::ExportToFDF(const CFX_WideStringC& pdf_path,
1162                                            FX_BOOL bSimpleFileSpec) const {
1163   CFX_PtrArray fields;
1164   int nCount = m_pFieldTree->m_Root.CountFields();
1165   for (int i = 0; i < nCount; i++) {
1166     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
1167     fields.Add(pField);
1168   }
1169   return ExportToFDF(pdf_path, fields, TRUE, bSimpleFileSpec);
1170 }
1171 CFX_WideString FILESPEC_EncodeFileName(const CFX_WideStringC& filepath);
1172 CFDF_Document* CPDF_InterForm::ExportToFDF(const CFX_WideStringC& pdf_path,
1173                                            CFX_PtrArray& fields,
1174                                            FX_BOOL bIncludeOrExclude,
1175                                            FX_BOOL bSimpleFileSpec) const {
1176   CFDF_Document* pDoc = CFDF_Document::CreateNewDoc();
1177   if (pDoc == NULL) {
1178     return NULL;
1179   }
1180   CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF");
1181   if (!pdf_path.IsEmpty()) {
1182     if (bSimpleFileSpec) {
1183       CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path);
1184       pMainDict->SetAtString(FX_BSTRC("F"),
1185                              CFX_ByteString::FromUnicode(wsFilePath));
1186       pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath));
1187     } else {
1188       CPDF_FileSpec filespec;
1189       filespec.SetFileName(pdf_path);
1190       pMainDict->SetAt("F", (CPDF_Object*)filespec);
1191     }
1192   }
1193   CPDF_Array* pFields = CPDF_Array::Create();
1194   if (pFields == NULL) {
1195     return NULL;
1196   }
1197   pMainDict->SetAt("Fields", pFields);
1198   int nCount = m_pFieldTree->m_Root.CountFields();
1199   for (int i = 0; i < nCount; i++) {
1200     CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
1201     if (pField == NULL || pField->GetType() == CPDF_FormField::PushButton) {
1202       continue;
1203     }
1204     FX_DWORD dwFlags = pField->GetFieldFlags();
1205     if (dwFlags & 0x04) {
1206       continue;
1207     }
1208     FX_BOOL bFind = fields.Find(pField, 0) >= 0;
1209     if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
1210       if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) {
1211         continue;
1212       }
1213       CFX_WideString fullname = GetFullName(pField->GetFieldDict());
1214       CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create();
1215       if (pFieldDict == NULL) {
1216         return NULL;
1217       }
1218       CPDF_String* pString = CPDF_String::Create(fullname);
1219       if (pString == NULL) {
1220         pFieldDict->Release();
1221         return NULL;
1222       }
1223       pFieldDict->SetAt("T", pString);
1224       if (pField->GetType() == CPDF_FormField::CheckBox ||
1225           pField->GetType() == CPDF_FormField::RadioButton) {
1226         CFX_WideString csExport = pField->GetCheckValue(FALSE);
1227         CFX_ByteString csBExport = PDF_EncodeText(csExport);
1228         CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
1229         if (pOpt == NULL) {
1230           pFieldDict->SetAtName("V", csBExport);
1231         } else {
1232           pFieldDict->SetAtString("V", csBExport);
1233         }
1234       } else {
1235         CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
1236         if (pV != NULL) {
1237           pFieldDict->SetAt("V", pV->Clone(TRUE));
1238         }
1239       }
1240       pFields->Add(pFieldDict);
1241     }
1242   }
1243   return pDoc;
1244 }
1245 const struct _SupportFieldEncoding {
1246   const FX_CHAR* m_name;
1247   int32_t m_codePage;
1248 } g_fieldEncoding[] = {
1249     {"BigFive", 950},
1250     {"GBK", 936},
1251     {"Shift-JIS", 932},
1252     {"UHC", 949},
1253 };
1254 static void FPDFDOC_FDF_GetFieldValue(CPDF_Dictionary* pFieldDict,
1255                                       CFX_WideString& csValue,
1256                                       CFX_ByteString& bsEncoding) {
1257   ASSERT(pFieldDict != NULL);
1258   CFX_ByteString csBValue = pFieldDict->GetString("V");
1259   int32_t iCount = sizeof(g_fieldEncoding) / sizeof(g_fieldEncoding[0]);
1260   int32_t i = 0;
1261   for (; i < iCount; ++i)
1262     if (bsEncoding == g_fieldEncoding[i].m_name) {
1263       break;
1264     }
1265   if (i < iCount) {
1266     CFX_CharMap* pCharMap =
1267         CFX_CharMap::GetDefaultMapper(g_fieldEncoding[i].m_codePage);
1268     FXSYS_assert(pCharMap != NULL);
1269     csValue.ConvertFrom(csBValue, pCharMap);
1270     return;
1271   }
1272   CFX_ByteString csTemp = csBValue.Left(2);
1273   if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF") {
1274     csValue = PDF_DecodeText(csBValue);
1275   } else {
1276     csValue = CFX_WideString::FromLocal(csBValue);
1277   }
1278 }
1279 void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict,
1280                                      const CFX_WideString& parent_name,
1281                                      FX_BOOL bNotify,
1282                                      int nLevel) {
1283   CFX_WideString name;
1284   if (!parent_name.IsEmpty()) {
1285     name = parent_name + L".";
1286   }
1287   name += pFieldDict->GetUnicodeText("T");
1288   CPDF_Array* pKids = pFieldDict->GetArray("Kids");
1289   if (pKids) {
1290     for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
1291       CPDF_Dictionary* pKid = pKids->GetDict(i);
1292       if (pKid == NULL) {
1293         continue;
1294       }
1295       if (nLevel <= nMaxRecursion) {
1296         FDF_ImportField(pKid, name, bNotify, nLevel + 1);
1297       }
1298     }
1299     return;
1300   }
1301   if (!pFieldDict->KeyExist("V")) {
1302     return;
1303   }
1304   CPDF_FormField* pField = m_pFieldTree->GetField(name);
1305   if (pField == NULL) {
1306     return;
1307   }
1308   CFX_WideString csWValue;
1309   FPDFDOC_FDF_GetFieldValue(pFieldDict, csWValue, m_bsEncoding);
1310   int iType = pField->GetFieldType();
1311   if (bNotify && m_pFormNotify != NULL) {
1312     int iRet = 0;
1313     if (iType == FIELDTYPE_LISTBOX) {
1314       iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue);
1315     } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
1316       iRet = m_pFormNotify->BeforeValueChange(pField, csWValue);
1317     }
1318     if (iRet < 0) {
1319       return;
1320     }
1321   }
1322   CFX_ByteArray statusArray;
1323   if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
1324     SaveCheckedFieldStatus(pField, statusArray);
1325   }
1326   pField->SetValue(csWValue);
1327   CPDF_FormField::Type eType = pField->GetType();
1328   if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) &&
1329       pFieldDict->KeyExist("Opt")) {
1330     pField->m_pDict->SetAt("Opt",
1331                            pFieldDict->GetElementValue("Opt")->Clone(TRUE));
1332   }
1333   if (bNotify && m_pFormNotify != NULL) {
1334     if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
1335       m_pFormNotify->AfterCheckedStatusChange(pField, statusArray);
1336     } else if (iType == FIELDTYPE_LISTBOX) {
1337       m_pFormNotify->AfterSelectionChange(pField);
1338     } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
1339       m_pFormNotify->AfterValueChange(pField);
1340     }
1341   }
1342   if (CPDF_InterForm::m_bUpdateAP) {
1343     pField->UpdateAP(NULL);
1344   }
1345 }
1346 FX_BOOL CPDF_InterForm::ImportFromFDF(const CFDF_Document* pFDF,
1347                                       FX_BOOL bNotify) {
1348   if (pFDF == NULL) {
1349     return FALSE;
1350   }
1351   CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
1352   if (pMainDict == NULL) {
1353     return FALSE;
1354   }
1355   CPDF_Array* pFields = pMainDict->GetArray("Fields");
1356   if (pFields == NULL) {
1357     return FALSE;
1358   }
1359   m_bsEncoding = pMainDict->GetString(FX_BSTRC("Encoding"));
1360   if (bNotify && m_pFormNotify != NULL) {
1361     int iRet = m_pFormNotify->BeforeFormImportData(this);
1362     if (iRet < 0) {
1363       return FALSE;
1364     }
1365   }
1366   for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
1367     CPDF_Dictionary* pField = pFields->GetDict(i);
1368     if (pField == NULL) {
1369       continue;
1370     }
1371     FDF_ImportField(pField, L"", bNotify);
1372   }
1373   if (bNotify && m_pFormNotify != NULL) {
1374     m_pFormNotify->AfterFormImportData(this);
1375   }
1376   return TRUE;
1377 }
1378 void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) {
1379   m_pFormNotify = (CPDF_FormNotify*)pNotify;
1380 }