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 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 653 FX_BOOL CPDF_IconFit::IsProportionalScale() { 654 if (!m_pDict) { 655 return TRUE; 656 } 657 return m_pDict->GetString("S", "P") != "A"; 658 } 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 } 675 FX_BOOL CPDF_IconFit::GetFittingBounds() { 676 if (!m_pDict) { 677 return FALSE; 678 } 679 return m_pDict->GetBoolean("FB"); 680 } 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 } 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