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