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