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