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" 8static const int FPDFDOC_UTILS_MAXRECURSION = 32; 9CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict); 10void InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument); 11FX_DWORD CountInterFormFonts(CPDF_Dictionary* pFormDict); 12CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_DWORD index, CFX_ByteString& csNameTag); 13CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csNameTag); 14CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CFX_ByteString& csNameTag); 15CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag); 16CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag); 17FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont, CFX_ByteString& csNameTag); 18FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag); 19void AddInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont, CFX_ByteString& csNameTag); 20CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag); 21CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag); 22void RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont); 23void RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag); 24CPDF_Font* GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument); 25void SetDefaultInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont); 26void SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray); 27FX_BOOL NeedPDFEncodeForFieldFullName(const CFX_WideString& csFieldName); 28FX_BOOL NeedPDFEncodeForFieldTree(CPDF_Dictionary* pFieldDict, int nLevel = 0); 29void EncodeFieldName(const CFX_WideString& csName, CFX_ByteString& csT); 30void UpdateEncodeFieldName(CPDF_Dictionary* pFieldDict, int nLevel = 0); 31CFX_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} 48FX_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} 56CFX_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} 72void 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} 87FX_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} 103CFX_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} 141void 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} 173void 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} 209FX_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} 217CFX_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} 233CFX_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} 249void 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} 296FX_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} 327CPDF_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} 365CPDF_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} 388CPDF_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} 431CPDF_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} 475CPDF_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} 490FX_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} 526FX_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} 572void 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} 608CPDF_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} 631CPDF_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} 636void 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} 649void 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} 664CPDF_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} 675CPDF_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} 690FX_BOOL CPDF_IconFit::IsProportionalScale() 691{ 692 if (m_pDict == NULL) { 693 return TRUE; 694 } 695 return m_pDict->GetString("S", "P") != "A"; 696} 697void 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} 714FX_BOOL CPDF_IconFit::GetFittingBounds() 715{ 716 if (m_pDict == NULL) { 717 return FALSE; 718 } 719 return m_pDict->GetBoolean("FB"); 720} 721void 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} 732CPDF_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