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