• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  static const int FPDFDOC_UTILS_MAXRECURSION = 32;
9  CFX_WideString	GetFullName(CPDF_Dictionary* pFieldDict);
10  void			InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument);
11  FX_DWORD		CountInterFormFonts(CPDF_Dictionary* pFormDict);
12  CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_DWORD index, CFX_ByteString& csNameTag);
13  CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csNameTag);
14  CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CFX_ByteString& csNameTag);
15  CPDF_Font*		GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag);
16  CPDF_Font*		GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag);
17  FX_BOOL			FindInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont, CFX_ByteString& csNameTag);
18  FX_BOOL			FindInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag);
19  void			AddInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont, CFX_ByteString& csNameTag);
20  CPDF_Font*		AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag);
21  CPDF_Font*		AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag);
22  void			RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont);
23  void			RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag);
24  CPDF_Font*		GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument);
25  void			SetDefaultInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont);
26  void			SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray);
27  FX_BOOL			NeedPDFEncodeForFieldFullName(const CFX_WideString& csFieldName);
28  FX_BOOL			NeedPDFEncodeForFieldTree(CPDF_Dictionary* pFieldDict, int nLevel = 0);
29  void			EncodeFieldName(const CFX_WideString& csName, CFX_ByteString& csT);
30  void			UpdateEncodeFieldName(CPDF_Dictionary* pFieldDict, int nLevel = 0);
GetFullName(CPDF_Dictionary * pFieldDict)31  CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict)
32  {
33      CFX_WideString full_name;
34      CPDF_Dictionary* pLevel = pFieldDict;
35      while (pLevel) {
36          CFX_WideString short_name = pLevel->GetUnicodeText("T");
37          if (short_name != L"") {
38              if (full_name == L"") {
39                  full_name = short_name;
40              } else {
41                  full_name = short_name + L"." + full_name;
42              }
43          }
44          pLevel = pLevel->GetDict("Parent");
45      }
46      return full_name;
47  }
HasFont()48  FX_BOOL CPDF_DefaultAppearance::HasFont()
49  {
50      if (m_csDA.IsEmpty()) {
51          return FALSE;
52      }
53      CPDF_SimpleParser syntax(m_csDA);
54      return syntax.FindTagParam("Tf", 2);
55  }
GetFontString()56  CFX_ByteString CPDF_DefaultAppearance::GetFontString()
57  {
58      CFX_ByteString csFont;
59      if (m_csDA.IsEmpty()) {
60          return csFont;
61      }
62      CPDF_SimpleParser syntax(m_csDA);
63      if (syntax.FindTagParam("Tf", 2)) {
64          csFont += (CFX_ByteString)syntax.GetWord();
65          csFont += " ";
66          csFont += (CFX_ByteString)syntax.GetWord();
67          csFont += " ";
68          csFont += (CFX_ByteString)syntax.GetWord();
69      }
70      return csFont;
71  }
GetFont(CFX_ByteString & csFontNameTag,FX_FLOAT & fFontSize)72  void CPDF_DefaultAppearance::GetFont(CFX_ByteString& csFontNameTag, FX_FLOAT& fFontSize)
73  {
74      csFontNameTag = "";
75      fFontSize = 0;
76      if (m_csDA.IsEmpty()) {
77          return;
78      }
79      CPDF_SimpleParser syntax(m_csDA);
80      if (syntax.FindTagParam("Tf", 2)) {
81          csFontNameTag = (CFX_ByteString)syntax.GetWord();
82          csFontNameTag.Delete(0, 1);
83          fFontSize = FX_atof((CFX_ByteString)syntax.GetWord());
84      }
85      csFontNameTag = PDF_NameDecode(csFontNameTag);
86  }
HasColor(FX_BOOL bStrokingOperation)87  FX_BOOL CPDF_DefaultAppearance::HasColor(FX_BOOL bStrokingOperation)
88  {
89      if (m_csDA.IsEmpty()) {
90          return FALSE;
91      }
92      CPDF_SimpleParser syntax(m_csDA);
93      if (syntax.FindTagParam(bStrokingOperation ? "G" : "g", 1)) {
94          return TRUE;
95      }
96      syntax.SetPos(0);
97      if (syntax.FindTagParam(bStrokingOperation ? "RG" : "rg", 3)) {
98          return TRUE;
99      }
100      syntax.SetPos(0);
101      return syntax.FindTagParam(bStrokingOperation ? "K" : "k", 4);
102  }
GetColorString(FX_BOOL bStrokingOperation)103  CFX_ByteString CPDF_DefaultAppearance::GetColorString(FX_BOOL bStrokingOperation)
104  {
105      CFX_ByteString csColor;
106      if (m_csDA.IsEmpty()) {
107          return csColor;
108      }
109      CPDF_SimpleParser syntax(m_csDA);
110      if (syntax.FindTagParam(bStrokingOperation ? "G" : "g", 1)) {
111          csColor += (CFX_ByteString)syntax.GetWord();
112          csColor += " ";
113          csColor += (CFX_ByteString)syntax.GetWord();
114          return csColor;
115      }
116      syntax.SetPos(0);
117      if (syntax.FindTagParam(bStrokingOperation ? "RG" : "rg", 3)) {
118          csColor += (CFX_ByteString)syntax.GetWord();
119          csColor += " ";
120          csColor += (CFX_ByteString)syntax.GetWord();
121          csColor += " ";
122          csColor += (CFX_ByteString)syntax.GetWord();
123          csColor += " ";
124          csColor += (CFX_ByteString)syntax.GetWord();
125          return csColor;
126      }
127      syntax.SetPos(0);
128      if (syntax.FindTagParam(bStrokingOperation ? "K" : "k", 4)) {
129          csColor += (CFX_ByteString)syntax.GetWord();
130          csColor += " ";
131          csColor += (CFX_ByteString)syntax.GetWord();
132          csColor += " ";
133          csColor += (CFX_ByteString)syntax.GetWord();
134          csColor += " ";
135          csColor += (CFX_ByteString)syntax.GetWord();
136          csColor += " ";
137          csColor += (CFX_ByteString)syntax.GetWord();
138      }
139      return csColor;
140  }
GetColor(int & iColorType,FX_FLOAT fc[4],FX_BOOL bStrokingOperation)141  void CPDF_DefaultAppearance::GetColor(int& iColorType, FX_FLOAT fc[4], FX_BOOL bStrokingOperation)
142  {
143      iColorType = COLORTYPE_TRANSPARENT;
144      for (int c = 0; c < 4; c ++) {
145          fc[c] = 0;
146      }
147      if (m_csDA.IsEmpty()) {
148          return;
149      }
150      CPDF_SimpleParser syntax(m_csDA);
151      if (syntax.FindTagParam(bStrokingOperation ? "G" : "g", 1)) {
152          iColorType = COLORTYPE_GRAY;
153          fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
154          return;
155      }
156      syntax.SetPos(0);
157      if (syntax.FindTagParam(bStrokingOperation ? "RG" : "rg", 3)) {
158          iColorType = COLORTYPE_RGB;
159          fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
160          fc[1] = FX_atof((CFX_ByteString)syntax.GetWord());
161          fc[2] = FX_atof((CFX_ByteString)syntax.GetWord());
162          return;
163      }
164      syntax.SetPos(0);
165      if (syntax.FindTagParam(bStrokingOperation ? "K" : "k", 4)) {
166          iColorType = COLORTYPE_CMYK;
167          fc[0] = FX_atof((CFX_ByteString)syntax.GetWord());
168          fc[1] = FX_atof((CFX_ByteString)syntax.GetWord());
169          fc[2] = FX_atof((CFX_ByteString)syntax.GetWord());
170          fc[3] = FX_atof((CFX_ByteString)syntax.GetWord());
171      }
172  }
GetColor(FX_ARGB & color,int & iColorType,FX_BOOL bStrokingOperation)173  void CPDF_DefaultAppearance::GetColor(FX_ARGB& color, int& iColorType, FX_BOOL bStrokingOperation)
174  {
175      color = 0;
176      iColorType = COLORTYPE_TRANSPARENT;
177      if (m_csDA.IsEmpty()) {
178          return;
179      }
180      CPDF_SimpleParser syntax(m_csDA);
181      if (syntax.FindTagParam(bStrokingOperation ? "G" : "g", 1)) {
182          iColorType = COLORTYPE_GRAY;
183          FX_FLOAT g = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
184          color = ArgbEncode(255, (int)g, (int)g, (int)g);
185          return;
186      }
187      syntax.SetPos(0);
188      if (syntax.FindTagParam(bStrokingOperation ? "RG" : "rg", 3)) {
189          iColorType = COLORTYPE_RGB;
190          FX_FLOAT r = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
191          FX_FLOAT g = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
192          FX_FLOAT b = FX_atof((CFX_ByteString)syntax.GetWord()) * 255 + 0.5f;
193          color = ArgbEncode(255, (int)r, (int)g, (int)b);
194          return;
195      }
196      syntax.SetPos(0);
197      if (syntax.FindTagParam(bStrokingOperation ? "K" : "k", 4)) {
198          iColorType = COLORTYPE_CMYK;
199          FX_FLOAT c = FX_atof((CFX_ByteString)syntax.GetWord());
200          FX_FLOAT m = FX_atof((CFX_ByteString)syntax.GetWord());
201          FX_FLOAT y = FX_atof((CFX_ByteString)syntax.GetWord());
202          FX_FLOAT k = FX_atof((CFX_ByteString)syntax.GetWord());
203          FX_FLOAT r = 1.0f - FX_MIN(1.0f, c + k);
204          FX_FLOAT g = 1.0f - FX_MIN(1.0f, m + k);
205          FX_FLOAT b = 1.0f - FX_MIN(1.0f, y + k);
206          color = ArgbEncode(255, (int)(r * 255 + 0.5f), (int)(g * 255 + 0.5f), (int)(b * 255 + 0.5f));
207      }
208  }
HasTextMatrix()209  FX_BOOL CPDF_DefaultAppearance::HasTextMatrix()
210  {
211      if (m_csDA.IsEmpty()) {
212          return FALSE;
213      }
214      CPDF_SimpleParser syntax(m_csDA);
215      return syntax.FindTagParam("Tm", 6);
216  }
GetTextMatrixString()217  CFX_ByteString CPDF_DefaultAppearance::GetTextMatrixString()
218  {
219      CFX_ByteString csTM;
220      if (m_csDA.IsEmpty()) {
221          return csTM;
222      }
223      CPDF_SimpleParser syntax(m_csDA);
224      if (syntax.FindTagParam("Tm", 6)) {
225          for (int i = 0; i < 6; i ++) {
226              csTM += (CFX_ByteString)syntax.GetWord();
227              csTM += " ";
228          }
229          csTM += (CFX_ByteString)syntax.GetWord();
230      }
231      return csTM;
232  }
GetTextMatrix()233  CFX_AffineMatrix CPDF_DefaultAppearance::GetTextMatrix()
234  {
235      CFX_AffineMatrix tm;
236      if (m_csDA.IsEmpty()) {
237          return tm;
238      }
239      CPDF_SimpleParser syntax(m_csDA);
240      if (syntax.FindTagParam("Tm", 6)) {
241          FX_FLOAT f[6];
242          for (int i = 0; i < 6; i ++) {
243              f[i] = FX_atof((CFX_ByteString)syntax.GetWord());
244          }
245          tm.Set(f[0], f[1], f[2], f[3], f[4], f[5]);
246      }
247      return tm;
248  }
InitInterFormDict(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument)249  void InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument)
250  {
251      if (pDocument == NULL) {
252          return;
253      }
254      if (pFormDict == NULL) {
255          pFormDict = CPDF_Dictionary::Create();
256          if (pFormDict == NULL) {
257              return;
258          }
259          FX_DWORD dwObjNum = pDocument->AddIndirectObject(pFormDict);
260          CPDF_Dictionary* pRoot = pDocument->GetRoot();
261          pRoot->SetAtReference("AcroForm", pDocument, dwObjNum);
262      }
263      CFX_ByteString csDA;
264      if (!pFormDict->KeyExist("DR")) {
265          CPDF_Font* pFont = NULL;
266          CFX_ByteString csBaseName, csDefault;
267          FX_BYTE charSet = CPDF_InterForm::GetNativeCharSet();
268          pFont = CPDF_InterForm::AddStandardFont(pDocument, "Helvetica");
269          if (pFont != NULL) {
270              AddInterFormFont(pFormDict, pDocument, pFont, csBaseName);
271              csDefault = csBaseName;
272          }
273          if (charSet != 0) {
274              CFX_ByteString csFontName = CPDF_InterForm::GetNativeFont(charSet, NULL);
275              if (pFont == NULL || csFontName != "Helvetica") {
276                  pFont = CPDF_InterForm::AddNativeFont(pDocument);
277                  if (pFont != NULL) {
278                      csBaseName = "";
279                      AddInterFormFont(pFormDict, pDocument, pFont, csBaseName);
280                      csDefault = csBaseName;
281                  }
282              }
283          }
284          if (pFont != NULL) {
285              csDA = "/" + PDF_NameEncode(csDefault) + " 0 Tf";
286          }
287      }
288      if (!csDA.IsEmpty()) {
289          csDA += " ";
290      }
291      csDA += "0 g";
292      if (!pFormDict->KeyExist("DA")) {
293          pFormDict->SetAtString("DA", csDA);
294      }
295  }
CountInterFormFonts(CPDF_Dictionary * pFormDict)296  FX_DWORD CountInterFormFonts(CPDF_Dictionary* pFormDict)
297  {
298      if (pFormDict == NULL) {
299          return 0;
300      }
301      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
302      if (pDR == NULL) {
303          return 0;
304      }
305      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
306      if (pFonts == NULL) {
307          return 0;
308      }
309      FX_DWORD dwCount = 0;
310      FX_POSITION pos = pFonts->GetStartPos();
311      while (pos) {
312          CPDF_Object* pObj = NULL;
313          CFX_ByteString csKey;
314          pObj = pFonts->GetNextElement(pos, csKey);
315          if (pObj == NULL) {
316              continue;
317          }
318          CPDF_Object* pDirect = pObj->GetDirect();
319          if (pDirect != NULL && pDirect->GetType() == PDFOBJ_DICTIONARY) {
320              if (((CPDF_Dictionary*)pDirect)->GetString("Type") == "Font") {
321                  dwCount ++;
322              }
323          }
324      }
325      return dwCount;
326  }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,FX_DWORD index,CFX_ByteString & csNameTag)327  CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_DWORD index, CFX_ByteString& csNameTag)
328  {
329      if (pFormDict == NULL) {
330          return NULL;
331      }
332      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
333      if (pDR == NULL) {
334          return NULL;
335      }
336      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
337      if (pFonts == NULL) {
338          return NULL;
339      }
340      FX_DWORD dwCount = 0;
341      FX_POSITION pos = pFonts->GetStartPos();
342      while (pos) {
343          CPDF_Object* pObj = NULL;
344          CFX_ByteString csKey;
345          pObj = pFonts->GetNextElement(pos, csKey);
346          if (pObj == NULL) {
347              continue;
348          }
349          CPDF_Object* pDirect = pObj->GetDirect();
350          if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
351              continue;
352          }
353          CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
354          if (pElement->GetString("Type") != "Font") {
355              continue;
356          }
357          if (dwCount == index) {
358              csNameTag = csKey;
359              return pDocument->LoadFont(pElement);
360          }
361          dwCount ++;
362      }
363      return NULL;
364  }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csNameTag)365  CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csNameTag)
366  {
367      CFX_ByteString csAlias = PDF_NameDecode(csNameTag);
368      if (pFormDict == NULL || csAlias.IsEmpty()) {
369          return NULL;
370      }
371      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
372      if (pDR == NULL) {
373          return NULL;
374      }
375      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
376      if (pFonts == NULL) {
377          return NULL;
378      }
379      CPDF_Dictionary* pElement = pFonts->GetDict(csAlias);
380      if (pElement == NULL) {
381          return NULL;
382      }
383      if (pElement->GetString("Type") == "Font") {
384          return pDocument->LoadFont(pElement);
385      }
386      return NULL;
387  }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csFontName,CFX_ByteString & csNameTag)388  CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CFX_ByteString& csNameTag)
389  {
390      if (pFormDict == NULL || csFontName.IsEmpty()) {
391          return NULL;
392      }
393      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
394      if (pDR == NULL) {
395          return NULL;
396      }
397      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
398      if (pFonts == NULL) {
399          return NULL;
400      }
401      FX_POSITION pos = pFonts->GetStartPos();
402      while (pos) {
403          CPDF_Object* pObj = NULL;
404          CFX_ByteString csKey;
405          pObj = pFonts->GetNextElement(pos, csKey);
406          if (pObj == NULL) {
407              continue;
408          }
409          CPDF_Object* pDirect = pObj->GetDirect();
410          if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
411              continue;
412          }
413          CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
414          if (pElement->GetString("Type") != "Font") {
415              continue;
416          }
417          CPDF_Font* pFind = pDocument->LoadFont(pElement);
418          if (pFind == NULL) {
419              continue;
420          }
421          CFX_ByteString csBaseFont;
422          csBaseFont = pFind->GetBaseFont();
423          csBaseFont.Remove(' ');
424          if (csBaseFont == csFontName) {
425              csNameTag = csKey;
426              return pFind;
427          }
428      }
429      return NULL;
430  }
GetNativeInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,FX_BYTE charSet,CFX_ByteString & csNameTag)431  CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag)
432  {
433      if (pFormDict == NULL) {
434          return NULL;
435      }
436      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
437      if (pDR == NULL) {
438          return NULL;
439      }
440      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
441      if (pFonts == NULL) {
442          return NULL;
443      }
444      FX_POSITION pos = pFonts->GetStartPos();
445      while (pos) {
446          CPDF_Object* pObj = NULL;
447          CFX_ByteString csKey;
448          pObj = pFonts->GetNextElement(pos, csKey);
449          if (pObj == NULL) {
450              continue;
451          }
452          CPDF_Object* pDirect = pObj->GetDirect();
453          if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
454              continue;
455          }
456          CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
457          if (pElement->GetString("Type") != "Font") {
458              continue;
459          }
460          CPDF_Font* pFind = pDocument->LoadFont(pElement);
461          if (pFind == NULL) {
462              continue;
463          }
464          CFX_SubstFont* pSubst = (CFX_SubstFont*)pFind->GetSubstFont();
465          if (pSubst == NULL) {
466              continue;
467          }
468          if (pSubst->m_Charset == (int)charSet) {
469              csNameTag = csKey;
470              return pFind;
471          }
472      }
473      return NULL;
474  }
GetNativeInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString & csNameTag)475  CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag)
476  {
477      csNameTag = "";
478      FX_BYTE charSet = CPDF_InterForm::GetNativeCharSet();
479      CFX_SubstFont* pSubst;
480      CPDF_Font* pFont = GetDefaultInterFormFont(pFormDict, pDocument);
481      if (pFont != NULL) {
482          pSubst = (CFX_SubstFont*)pFont->GetSubstFont();
483          if (pSubst != NULL && pSubst->m_Charset == (int)charSet) {
484              FindInterFormFont(pFormDict, pFont, csNameTag);
485              return pFont;
486          }
487      }
488      return GetNativeInterFormFont(pFormDict, pDocument, charSet, csNameTag);
489  }
FindInterFormFont(CPDF_Dictionary * pFormDict,const CPDF_Font * pFont,CFX_ByteString & csNameTag)490  FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont, CFX_ByteString& csNameTag)
491  {
492      if (pFormDict == NULL || pFont == NULL) {
493          return FALSE;
494      }
495      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
496      if (pDR == NULL) {
497          return FALSE;
498      }
499      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
500      if (pFonts == NULL) {
501          return FALSE;
502      }
503      FX_POSITION pos = pFonts->GetStartPos();
504      while (pos) {
505          CPDF_Object* pObj = NULL;
506          CFX_ByteString csKey;
507          pObj = pFonts->GetNextElement(pos, csKey);
508          if (pObj == NULL) {
509              continue;
510          }
511          CPDF_Object* pDirect = pObj->GetDirect();
512          if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
513              continue;
514          }
515          CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
516          if (pElement->GetString("Type") != "Font") {
517              continue;
518          }
519          if (pFont->GetFontDict() == pElement) {
520              csNameTag = csKey;
521              return TRUE;
522          }
523      }
524      return FALSE;
525  }
FindInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csFontName,CPDF_Font * & pFont,CFX_ByteString & csNameTag)526  FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag)
527  {
528      if (pFormDict == NULL) {
529          return FALSE;
530      }
531      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
532      if (pDR == NULL) {
533          return FALSE;
534      }
535      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
536      if (pFonts == NULL) {
537          return FALSE;
538      }
539      if (csFontName.GetLength() > 0) {
540          csFontName.Remove(' ');
541      }
542      FX_POSITION pos = pFonts->GetStartPos();
543      while (pos) {
544          CPDF_Object* pObj = NULL;
545          CFX_ByteString csKey, csTmp;
546          pObj = pFonts->GetNextElement(pos, csKey);
547          if (pObj == NULL) {
548              continue;
549          }
550          CPDF_Object* pDirect = pObj->GetDirect();
551          if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
552              continue;
553          }
554          CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
555          if (pElement->GetString("Type") != "Font") {
556              continue;
557          }
558          pFont = pDocument->LoadFont(pElement);
559          if (pFont == NULL) {
560              continue;
561          }
562          CFX_ByteString csBaseFont;
563          csBaseFont = pFont->GetBaseFont();
564          csBaseFont.Remove(' ');
565          if (csBaseFont == csFontName) {
566              csNameTag = csKey;
567              return TRUE;
568          }
569      }
570      return FALSE;
571  }
AddInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,const CPDF_Font * pFont,CFX_ByteString & csNameTag)572  void AddInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont, CFX_ByteString& csNameTag)
573  {
574      if (pFont == NULL) {
575          return;
576      }
577      if (pFormDict == NULL) {
578          InitInterFormDict(pFormDict, pDocument);
579      }
580      CFX_ByteString csTag;
581      if (FindInterFormFont(pFormDict, pFont, csTag)) {
582          csNameTag = csTag;
583          return;
584      }
585      if (pFormDict == NULL) {
586          InitInterFormDict(pFormDict, pDocument);
587      }
588      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
589      if (pDR == NULL) {
590          pDR = CPDF_Dictionary::Create();
591          if (pDR == NULL) {
592              return;
593          }
594          pFormDict->SetAt("DR", pDR);
595      }
596      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
597      if (pFonts == NULL) {
598          pFonts = CPDF_Dictionary::Create();
599          pDR->SetAt("Font", pFonts);
600      }
601      if (csNameTag.IsEmpty()) {
602          csNameTag = pFont->GetBaseFont();
603      }
604      csNameTag.Remove(' ');
605      csNameTag = CPDF_InterForm::GenerateNewResourceName(pDR, "Font", 4, csNameTag);
606      pFonts->SetAtReference(csNameTag, pDocument, pFont->GetFontDict());
607  }
AddNativeInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,FX_BYTE charSet,CFX_ByteString & csNameTag)608  CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag)
609  {
610      if (pFormDict == NULL) {
611          InitInterFormDict(pFormDict, pDocument);
612      }
613      CFX_ByteString csTemp;
614      CPDF_Font* pFont = GetNativeInterFormFont(pFormDict, pDocument, charSet, csTemp);
615      if (pFont != NULL) {
616          csNameTag = csTemp;
617          return pFont;
618      }
619      CFX_ByteString csFontName = CPDF_InterForm::GetNativeFont(charSet);
620      if (!csFontName.IsEmpty()) {
621          if (FindInterFormFont(pFormDict, pDocument, csFontName, pFont, csNameTag)) {
622              return pFont;
623          }
624      }
625      pFont = CPDF_InterForm::AddNativeFont(charSet, pDocument);
626      if (pFont != NULL) {
627          AddInterFormFont(pFormDict, pDocument, pFont, csNameTag);
628      }
629      return pFont;
630  }
AddNativeInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,CFX_ByteString & csNameTag)631  CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag)
632  {
633      FX_BYTE charSet = CPDF_InterForm::GetNativeCharSet();
634      return AddNativeInterFormFont(pFormDict, pDocument, charSet, csNameTag);
635  }
RemoveInterFormFont(CPDF_Dictionary * pFormDict,const CPDF_Font * pFont)636  void RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont)
637  {
638      if (pFormDict == NULL || pFont == NULL) {
639          return;
640      }
641      CFX_ByteString csTag;
642      if (!FindInterFormFont(pFormDict, pFont, csTag)) {
643          return;
644      }
645      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
646      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
647      pFonts->RemoveAt(csTag);
648  }
RemoveInterFormFont(CPDF_Dictionary * pFormDict,CFX_ByteString csNameTag)649  void RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag)
650  {
651      if (pFormDict == NULL || csNameTag.IsEmpty()) {
652          return;
653      }
654      CPDF_Dictionary* pDR = pFormDict->GetDict("DR");
655      if (pDR == NULL) {
656          return;
657      }
658      CPDF_Dictionary* pFonts = pDR->GetDict("Font");
659      if (pFonts == NULL) {
660          return;
661      }
662      pFonts->RemoveAt(csNameTag);
663  }
GetDefaultInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument)664  CPDF_Font* GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument)
665  {
666      if (pFormDict == NULL) {
667          return NULL;
668      }
669      CPDF_DefaultAppearance cDA = pFormDict->GetString("DA");
670      CFX_ByteString csFontNameTag;
671      FX_FLOAT fFontSize;
672      cDA.GetFont(csFontNameTag, fFontSize);
673      return GetInterFormFont(pFormDict, pDocument, csFontNameTag);
674  }
GetScaleMethod()675  CPDF_IconFit::ScaleMethod CPDF_IconFit::GetScaleMethod()
676  {
677      if (m_pDict == NULL) {
678          return Always;
679      }
680      CFX_ByteString csSW = m_pDict->GetString("SW", "A");
681      if (csSW == "B") {
682          return Bigger;
683      } else if (csSW == "S") {
684          return Smaller;
685      } else if (csSW == "N") {
686          return Never;
687      }
688      return Always;
689  }
IsProportionalScale()690  FX_BOOL CPDF_IconFit::IsProportionalScale()
691  {
692      if (m_pDict == NULL) {
693          return TRUE;
694      }
695      return m_pDict->GetString("S", "P") != "A";
696  }
GetIconPosition(FX_FLOAT & fLeft,FX_FLOAT & fBottom)697  void CPDF_IconFit::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom)
698  {
699      fLeft = fBottom = 0.5;
700      if (m_pDict == NULL) {
701          return;
702      }
703      CPDF_Array* pA = m_pDict->GetArray("A");
704      if (pA != NULL) {
705          FX_DWORD dwCount = pA->GetCount();
706          if (dwCount > 0) {
707              fLeft = pA->GetNumber(0);
708          }
709          if (dwCount > 1) {
710              fBottom = pA->GetNumber(1);
711          }
712      }
713  }
GetFittingBounds()714  FX_BOOL CPDF_IconFit::GetFittingBounds()
715  {
716      if (m_pDict == NULL) {
717          return FALSE;
718      }
719      return m_pDict->GetBoolean("FB");
720  }
SaveCheckedFieldStatus(CPDF_FormField * pField,CFX_ByteArray & statusArray)721  void SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray)
722  {
723      int iCount = pField->CountControls();
724      for (int i = 0; i < iCount; i ++) {
725          CPDF_FormControl* pControl = pField->GetControl(i);
726          if (pControl == NULL) {
727              continue;
728          }
729          statusArray.Add(pControl->IsChecked() ? 1 : 0);
730      }
731  }
FPDF_GetFieldAttr(CPDF_Dictionary * pFieldDict,const FX_CHAR * name,int nLevel)732  CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict, const FX_CHAR* name, int nLevel)
733  {
734      if (nLevel > FPDFDOC_UTILS_MAXRECURSION) {
735          return NULL;
736      }
737      if (pFieldDict == NULL) {
738          return NULL;
739      }
740      CPDF_Object* pAttr = pFieldDict->GetElementValue(name);
741      if (pAttr) {
742          return pAttr;
743      }
744      CPDF_Dictionary* pParent = pFieldDict->GetDict("Parent");
745      if (pParent == NULL) {
746          return NULL;
747      }
748      return FPDF_GetFieldAttr(pParent, name, nLevel + 1);
749  }
750