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