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
GetFullName(CPDF_Dictionary * pFieldDict)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 }
HasFont()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 }
GetFontString()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 }
GetFont(CFX_ByteString & csFontNameTag,FX_FLOAT & fFontSize)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 }
HasColor(FX_BOOL bStrokingOperation)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 }
GetColorString(FX_BOOL bStrokingOperation)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 }
GetColor(int & iColorType,FX_FLOAT fc[4],FX_BOOL bStrokingOperation)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 }
GetColor(FX_ARGB & color,int & iColorType,FX_BOOL bStrokingOperation)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 }
HasTextMatrix()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 }
GetTextMatrixString()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 }
GetTextMatrix()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 }
InitInterFormDict(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument)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 FX_BYTE 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 }
CountInterFormFonts(CPDF_Dictionary * pFormDict)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 }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,FX_DWORD index,CFX_ByteString & csNameTag)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 }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csNameTag)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 }
GetInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csFontName,CFX_ByteString & csNameTag)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 }
GetNativeInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,FX_BYTE charSet,CFX_ByteString & csNameTag)412 CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE 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 }
GetNativeInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString & csNameTag)456 CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag)
457 {
458 csNameTag = "";
459 FX_BYTE 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 }
FindInterFormFont(CPDF_Dictionary * pFormDict,const CPDF_Font * pFont,CFX_ByteString & csNameTag)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 }
FindInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument,CFX_ByteString csFontName,CPDF_Font * & pFont,CFX_ByteString & csNameTag)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 }
AddInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,const CPDF_Font * pFont,CFX_ByteString & csNameTag)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 }
AddNativeInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,FX_BYTE charSet,CFX_ByteString & csNameTag)589 CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE 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 }
AddNativeInterFormFont(CPDF_Dictionary * & pFormDict,CPDF_Document * pDocument,CFX_ByteString & csNameTag)612 CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag)
613 {
614 FX_BYTE charSet = CPDF_InterForm::GetNativeCharSet();
615 return AddNativeInterFormFont(pFormDict, pDocument, charSet, csNameTag);
616 }
RemoveInterFormFont(CPDF_Dictionary * pFormDict,const CPDF_Font * pFont)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 }
RemoveInterFormFont(CPDF_Dictionary * pFormDict,CFX_ByteString csNameTag)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 }
GetDefaultInterFormFont(CPDF_Dictionary * pFormDict,CPDF_Document * pDocument)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 }
GetScaleMethod()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 }
IsProportionalScale()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 }
GetIconPosition(FX_FLOAT & fLeft,FX_FLOAT & fBottom)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 }
GetFittingBounds()695 FX_BOOL CPDF_IconFit::GetFittingBounds()
696 {
697 if (m_pDict == NULL) {
698 return FALSE;
699 }
700 return m_pDict->GetBoolean("FB");
701 }
SaveCheckedFieldStatus(CPDF_FormField * pField,CFX_ByteArray & statusArray)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 }
FPDF_GetFieldAttr(CPDF_Dictionary * pFieldDict,const FX_CHAR * name,int nLevel)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 }
731