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/fpdfapi/fpdf_page.h" 8 #include "../../../include/fpdfapi/fpdf_module.h" 9 #include "../../../include/fdrm/fx_crypt.h" 10 #include "../fpdf_font/font_int.h" 11 #include "pageint.h" 12 class CPDF_PageModule : public CPDF_PageModuleDef 13 { 14 public: 15 CPDF_PageModule() : m_StockGrayCS(PDFCS_DEVICEGRAY), m_StockRGBCS(PDFCS_DEVICERGB), 16 m_StockCMYKCS(PDFCS_DEVICECMYK) {} 17 virtual ~CPDF_PageModule() {} 18 virtual FX_BOOL Installed() 19 { 20 return TRUE; 21 } 22 virtual CPDF_DocPageData* CreateDocData(CPDF_Document* pDoc) 23 { 24 return FX_NEW CPDF_DocPageData(pDoc); 25 } 26 virtual void ReleaseDoc(CPDF_Document* pDoc); 27 virtual void ClearDoc(CPDF_Document* pDoc); 28 virtual CPDF_FontGlobals* GetFontGlobals() 29 { 30 return &m_FontGlobals; 31 } 32 virtual void ClearStockFont(CPDF_Document* pDoc) 33 { 34 m_FontGlobals.Clear(pDoc); 35 } 36 virtual CPDF_ColorSpace* GetStockCS(int family); 37 virtual void NotifyCJKAvailable(); 38 CPDF_FontGlobals m_FontGlobals; 39 CPDF_DeviceCS m_StockGrayCS; 40 CPDF_DeviceCS m_StockRGBCS; 41 CPDF_DeviceCS m_StockCMYKCS; 42 CPDF_PatternCS m_StockPatternCS; 43 }; 44 CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family) 45 { 46 if (family == PDFCS_DEVICEGRAY) { 47 return &m_StockGrayCS; 48 } 49 if (family == PDFCS_DEVICERGB) { 50 return &m_StockRGBCS; 51 } 52 if (family == PDFCS_DEVICECMYK) { 53 return &m_StockCMYKCS; 54 } 55 if (family == PDFCS_PATTERN) { 56 return &m_StockPatternCS; 57 } 58 return NULL; 59 } 60 void CPDF_ModuleMgr::InitPageModule() 61 { 62 if (m_pPageModule) { 63 delete m_pPageModule; 64 } 65 CPDF_PageModule* pPageModule = FX_NEW CPDF_PageModule; 66 m_pPageModule = pPageModule; 67 } 68 void CPDF_PageModule::ReleaseDoc(CPDF_Document* pDoc) 69 { 70 delete pDoc->GetPageData(); 71 } 72 void CPDF_PageModule::ClearDoc(CPDF_Document* pDoc) 73 { 74 pDoc->GetPageData()->Clear(FALSE); 75 } 76 void CPDF_PageModule::NotifyCJKAvailable() 77 { 78 m_FontGlobals.m_CMapManager.ReloadAll(); 79 } 80 CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) 81 { 82 if (!pFontDict) { 83 return NULL; 84 } 85 return GetValidatePageData()->GetFont(pFontDict, FALSE); 86 } 87 CPDF_Font* CPDF_Document::FindFont(CPDF_Dictionary* pFontDict) 88 { 89 if (!pFontDict) { 90 return NULL; 91 } 92 return GetValidatePageData()->GetFont(pFontDict, TRUE); 93 } 94 CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) 95 { 96 if (pStream == NULL) { 97 return NULL; 98 } 99 return GetValidatePageData()->GetFontFileStreamAcc(pStream); 100 } 101 CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name); 102 CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) 103 { 104 return GetValidatePageData()->GetColorSpace(pCSObj, pResources); 105 } 106 CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) 107 { 108 return GetValidatePageData()->GetPattern(pPatternObj, bShading, matrix); 109 } 110 CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents) 111 { 112 return GetValidatePageData()->GetIccProfile(pStream, nComponents); 113 } 114 CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) 115 { 116 if (!pObj) { 117 return NULL; 118 } 119 FXSYS_assert(pObj->GetObjNum()); 120 return GetValidatePageData()->GetImage(pObj); 121 } 122 void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj) 123 { 124 if (!pCSObj) { 125 return; 126 } 127 GetPageData()->ReleaseColorSpace(pCSObj); 128 } 129 CPDF_DocPageData::CPDF_DocPageData(CPDF_Document *pPDFDoc) 130 : m_pPDFDoc(pPDFDoc) 131 , m_FontMap() 132 , m_ColorSpaceMap() 133 , m_PatternMap() 134 , m_ImageMap() 135 , m_IccProfileMap() 136 , m_FontFileMap() 137 { 138 m_FontMap.InitHashTable(64); 139 m_ColorSpaceMap.InitHashTable(32); 140 m_PatternMap.InitHashTable(16); 141 m_ImageMap.InitHashTable(64); 142 m_IccProfileMap.InitHashTable(16); 143 m_FontFileMap.InitHashTable(32); 144 } 145 CPDF_DocPageData::~CPDF_DocPageData() 146 { 147 Clear(FALSE); 148 Clear(TRUE); 149 FX_POSITION pos = NULL; 150 } 151 void CPDF_DocPageData::Clear(FX_BOOL bRelease) 152 { 153 FX_POSITION pos; 154 FX_DWORD nCount; 155 { 156 pos = m_PatternMap.GetStartPosition(); 157 while (pos) { 158 CPDF_Object* ptObj; 159 CPDF_CountedObject<CPDF_Pattern*>* ptData; 160 m_PatternMap.GetNextAssoc(pos, ptObj, ptData); 161 nCount = ptData->m_nCount; 162 if (bRelease || nCount < 2) { 163 delete ptData->m_Obj; 164 ptData->m_Obj = NULL; 165 } 166 } 167 } 168 { 169 pos = m_FontMap.GetStartPosition(); 170 while (pos) { 171 CPDF_Dictionary* fontDict; 172 CPDF_CountedObject<CPDF_Font*>* fontData; 173 m_FontMap.GetNextAssoc(pos, fontDict, fontData); 174 nCount = fontData->m_nCount; 175 if (bRelease || nCount < 2) { 176 delete fontData->m_Obj; 177 fontData->m_Obj = NULL; 178 } 179 } 180 } 181 { 182 pos = m_ImageMap.GetStartPosition(); 183 while (pos) { 184 FX_DWORD objNum; 185 CPDF_CountedObject<CPDF_Image*>* imageData; 186 m_ImageMap.GetNextAssoc(pos, objNum, imageData); 187 nCount = imageData->m_nCount; 188 if (bRelease || nCount < 2) { 189 delete imageData->m_Obj; 190 delete imageData; 191 m_ImageMap.RemoveKey(objNum); 192 } 193 } 194 } 195 { 196 pos = m_ColorSpaceMap.GetStartPosition(); 197 while (pos) { 198 CPDF_Object* csKey; 199 CPDF_CountedObject<CPDF_ColorSpace*>* csData; 200 m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData); 201 nCount = csData->m_nCount; 202 if (bRelease || nCount < 2) { 203 csData->m_Obj->ReleaseCS(); 204 csData->m_Obj = NULL; 205 } 206 } 207 } 208 { 209 pos = m_IccProfileMap.GetStartPosition(); 210 while (pos) { 211 CPDF_Stream* ipKey; 212 CPDF_CountedObject<CPDF_IccProfile*>* ipData; 213 m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData); 214 nCount = ipData->m_nCount; 215 if (bRelease || nCount < 2) { 216 FX_POSITION pos2 = m_HashProfileMap.GetStartPosition(); 217 while (pos2) { 218 CFX_ByteString bsKey; 219 CPDF_Stream* pFindStream = NULL; 220 m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream); 221 if (ipKey == pFindStream) { 222 m_HashProfileMap.RemoveKey(bsKey); 223 break; 224 } 225 } 226 delete ipData->m_Obj; 227 delete ipData; 228 m_IccProfileMap.RemoveKey(ipKey); 229 } 230 } 231 } 232 { 233 pos = m_FontFileMap.GetStartPosition(); 234 while (pos) { 235 CPDF_Stream* ftKey; 236 CPDF_CountedObject<CPDF_StreamAcc*>* ftData; 237 m_FontFileMap.GetNextAssoc(pos, ftKey, ftData); 238 nCount = ftData->m_nCount; 239 if (bRelease || nCount < 2) { 240 delete ftData->m_Obj; 241 delete ftData; 242 m_FontFileMap.RemoveKey(ftKey); 243 } 244 } 245 } 246 } 247 CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly) 248 { 249 if (!pFontDict) { 250 return NULL; 251 } 252 if (findOnly) { 253 CPDF_CountedObject<CPDF_Font*>* fontData; 254 if (m_FontMap.Lookup(pFontDict, fontData)) { 255 if (!fontData->m_Obj) { 256 return NULL; 257 } 258 fontData->m_nCount ++; 259 return fontData->m_Obj; 260 } 261 return NULL; 262 } 263 CPDF_CountedObject<CPDF_Font*>* fontData = NULL; 264 if (m_FontMap.Lookup(pFontDict, fontData)) { 265 if (fontData->m_Obj) { 266 fontData->m_nCount ++; 267 return fontData->m_Obj; 268 } 269 } 270 FX_BOOL bNew = FALSE; 271 if (!fontData) { 272 fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; 273 bNew = TRUE; 274 if (!fontData) { 275 return NULL; 276 } 277 } 278 CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pFontDict); 279 if (!pFont) { 280 if (bNew) { 281 delete fontData; 282 } 283 return NULL; 284 } 285 fontData->m_nCount = 2; 286 fontData->m_Obj = pFont; 287 m_FontMap.SetAt(pFontDict, fontData); 288 return pFont; 289 } 290 CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding) 291 { 292 if (fontName.IsEmpty()) { 293 return NULL; 294 } 295 FX_POSITION pos = m_FontMap.GetStartPosition(); 296 while (pos) { 297 CPDF_Dictionary* fontDict; 298 CPDF_CountedObject<CPDF_Font*>* fontData; 299 m_FontMap.GetNextAssoc(pos, fontDict, fontData); 300 CPDF_Font* pFont = fontData->m_Obj; 301 if (!pFont) { 302 continue; 303 } 304 if (pFont->GetBaseFont() != fontName) { 305 continue; 306 } 307 if (pFont->IsEmbedded()) { 308 continue; 309 } 310 if (pFont->GetFontType() != PDFFONT_TYPE1) { 311 continue; 312 } 313 if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) { 314 continue; 315 } 316 CPDF_Type1Font* pT1Font = pFont->GetType1Font(); 317 if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) { 318 continue; 319 } 320 fontData->m_nCount ++; 321 return pFont; 322 } 323 CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; 324 pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); 325 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); 326 pDict->SetAtName(FX_BSTRC("BaseFont"), fontName); 327 if (pEncoding) { 328 pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize()); 329 } 330 m_pPDFDoc->AddIndirectObject(pDict); 331 CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; 332 if (!fontData) { 333 return NULL; 334 } 335 CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict); 336 if (!pFont) { 337 delete fontData; 338 return NULL; 339 } 340 fontData->m_nCount = 2; 341 fontData->m_Obj = pFont; 342 m_FontMap.SetAt(pDict, fontData); 343 return pFont; 344 } 345 void CPDF_DocPageData::ReleaseFont(CPDF_Dictionary* pFontDict) 346 { 347 if (!pFontDict) { 348 return; 349 } 350 CPDF_CountedObject<CPDF_Font*>* fontData; 351 if (!m_FontMap.Lookup(pFontDict, fontData)) { 352 return; 353 } 354 if (fontData->m_Obj && --fontData->m_nCount == 0) { 355 delete fontData->m_Obj; 356 fontData->m_Obj = NULL; 357 } 358 } 359 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) 360 { 361 if (!pCSObj) { 362 return NULL; 363 } 364 if (pCSObj->GetType() == PDFOBJ_NAME) { 365 CFX_ByteString name = pCSObj->GetConstString(); 366 CPDF_ColorSpace* pCS = _CSFromName(name); 367 if (!pCS && pResources) { 368 CPDF_Dictionary* pList = pResources->GetDict(FX_BSTRC("ColorSpace")); 369 if (pList) { 370 pCSObj = pList->GetElementValue(name); 371 return GetColorSpace(pCSObj, NULL); 372 } 373 } 374 if (pCS == NULL || pResources == NULL) { 375 return pCS; 376 } 377 CPDF_Dictionary* pColorSpaces = pResources->GetDict(FX_BSTRC("ColorSpace")); 378 if (pColorSpaces == NULL) { 379 return pCS; 380 } 381 CPDF_Object* pDefaultCS = NULL; 382 switch (pCS->GetFamily()) { 383 case PDFCS_DEVICERGB: 384 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultRGB")); 385 break; 386 case PDFCS_DEVICEGRAY: 387 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultGray")); 388 break; 389 case PDFCS_DEVICECMYK: 390 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultCMYK")); 391 break; 392 } 393 if (pDefaultCS == NULL) { 394 return pCS; 395 } 396 return GetColorSpace(pDefaultCS, NULL); 397 } 398 if (pCSObj->GetType() != PDFOBJ_ARRAY) { 399 return NULL; 400 } 401 CPDF_Array* pArray = (CPDF_Array*)pCSObj; 402 if (pArray->GetCount() == 0) { 403 return NULL; 404 } 405 if (pArray->GetCount() == 1) { 406 return GetColorSpace(pArray->GetElementValue(0), pResources); 407 } 408 CPDF_CountedObject<CPDF_ColorSpace*>* csData = NULL; 409 if (m_ColorSpaceMap.Lookup(pCSObj, csData)) { 410 if (csData->m_Obj) { 411 csData->m_nCount++; 412 return csData->m_Obj; 413 } 414 } 415 FX_BOOL bNew = FALSE; 416 if (!csData) { 417 csData = FX_NEW CPDF_CountedObject<CPDF_ColorSpace*>; 418 if (!csData) { 419 return NULL; 420 } 421 bNew = TRUE; 422 } 423 CPDF_ColorSpace* pCS = CPDF_ColorSpace::Load(m_pPDFDoc, pArray); 424 if (!pCS) { 425 if (bNew) { 426 delete csData; 427 } 428 return NULL; 429 } 430 csData->m_nCount = 2; 431 csData->m_Obj = pCS; 432 m_ColorSpaceMap.SetAt(pCSObj, csData); 433 return pCS; 434 } 435 CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) 436 { 437 if (!pCSObj) { 438 return NULL; 439 } 440 CPDF_CountedObject<CPDF_ColorSpace*>* csData; 441 if (!m_ColorSpaceMap.Lookup(pCSObj, csData)) { 442 return NULL; 443 } 444 if (!csData->m_Obj) { 445 return NULL; 446 } 447 csData->m_nCount ++; 448 return csData->m_Obj; 449 } 450 void CPDF_DocPageData::ReleaseColorSpace(CPDF_Object* pColorSpace) 451 { 452 if (!pColorSpace) { 453 return; 454 } 455 CPDF_CountedObject<CPDF_ColorSpace*>* csData; 456 if (!m_ColorSpaceMap.Lookup(pColorSpace, csData)) { 457 return; 458 } 459 if (csData->m_Obj && --csData->m_nCount == 0) { 460 csData->m_Obj->ReleaseCS(); 461 csData->m_Obj = NULL; 462 } 463 } 464 CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) 465 { 466 if (!pPatternObj) { 467 return NULL; 468 } 469 CPDF_CountedObject<CPDF_Pattern*>* ptData = NULL; 470 if (m_PatternMap.Lookup(pPatternObj, ptData)) { 471 if (ptData->m_Obj) { 472 ptData->m_nCount++; 473 return ptData->m_Obj; 474 } 475 } 476 FX_BOOL bNew = FALSE; 477 if (!ptData) { 478 ptData = FX_NEW CPDF_CountedObject<CPDF_Pattern*>; 479 bNew = TRUE; 480 if (!ptData) { 481 return NULL; 482 } 483 } 484 CPDF_Pattern* pPattern = NULL; 485 if (bShading) { 486 pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, bShading, matrix); 487 } else { 488 CPDF_Dictionary* pDict = pPatternObj->GetDict(); 489 if (pDict) { 490 int type = pDict->GetInteger(FX_BSTRC("PatternType")); 491 if (type == 1) { 492 pPattern = FX_NEW CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); 493 } else if (type == 2) { 494 pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); 495 } 496 } 497 } 498 if (!pPattern) { 499 if (bNew) { 500 delete ptData; 501 } 502 return NULL; 503 } 504 ptData->m_nCount = 2; 505 ptData->m_Obj = pPattern; 506 m_PatternMap.SetAt(pPatternObj, ptData); 507 return pPattern; 508 } 509 void CPDF_DocPageData::ReleasePattern(CPDF_Object* pPatternObj) 510 { 511 if (!pPatternObj) { 512 return; 513 } 514 CPDF_CountedObject<CPDF_Pattern*>* ptData; 515 if (!m_PatternMap.Lookup(pPatternObj, ptData)) { 516 return; 517 } 518 if (ptData->m_Obj && --ptData->m_nCount == 0) { 519 delete ptData->m_Obj; 520 ptData->m_Obj = NULL; 521 } 522 } 523 CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) 524 { 525 if (!pImageStream) { 526 return NULL; 527 } 528 FX_DWORD dwImageObjNum = pImageStream->GetObjNum(); 529 CPDF_CountedObject<CPDF_Image*>* imageData; 530 if (m_ImageMap.Lookup(dwImageObjNum, imageData)) { 531 imageData->m_nCount ++; 532 return imageData->m_Obj; 533 } 534 imageData = FX_NEW CPDF_CountedObject<CPDF_Image*>; 535 if (!imageData) { 536 return NULL; 537 } 538 CPDF_Image* pImage = FX_NEW CPDF_Image(m_pPDFDoc); 539 if (!pImage) { 540 delete imageData; 541 return NULL; 542 } 543 pImage->LoadImageF((CPDF_Stream*)pImageStream, FALSE); 544 imageData->m_nCount = 2; 545 imageData->m_Obj = pImage; 546 m_ImageMap.SetAt(dwImageObjNum, imageData); 547 return pImage; 548 } 549 void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream) 550 { 551 if (!pImageStream) { 552 return; 553 } 554 PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL); 555 } 556 CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents) 557 { 558 if (!pIccProfileStream) { 559 return NULL; 560 } 561 CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; 562 if (m_IccProfileMap.Lookup(pIccProfileStream, ipData)) { 563 ipData->m_nCount++; 564 return ipData->m_Obj; 565 } 566 CPDF_StreamAcc stream; 567 stream.LoadAllData(pIccProfileStream, FALSE); 568 FX_BYTE digest[20]; 569 CPDF_Stream* pCopiedStream = NULL; 570 CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); 571 if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20), (void*&)pCopiedStream)) { 572 m_IccProfileMap.Lookup(pCopiedStream, ipData); 573 ipData->m_nCount++; 574 return ipData->m_Obj; 575 } 576 CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents); 577 if (!pProfile) { 578 return NULL; 579 } 580 ipData = FX_NEW CPDF_CountedObject<CPDF_IccProfile*>; 581 if (!ipData) { 582 delete pProfile; 583 return NULL; 584 } 585 ipData->m_nCount = 2; 586 ipData->m_Obj = pProfile; 587 m_IccProfileMap.SetAt(pIccProfileStream, ipData); 588 m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream); 589 return pProfile; 590 } 591 void CPDF_DocPageData::ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile) 592 { 593 if (!pIccProfileStream && !pIccProfile) { 594 return; 595 } 596 CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; 597 if (m_IccProfileMap.Lookup(pIccProfileStream, ipData) && ipData->m_nCount < 2) { 598 FX_POSITION pos = m_HashProfileMap.GetStartPosition(); 599 while (pos) { 600 CFX_ByteString key; 601 CPDF_Stream* pFindStream = NULL; 602 m_HashProfileMap.GetNextAssoc(pos, key, (void*&)pFindStream); 603 if (pIccProfileStream == pFindStream) { 604 m_HashProfileMap.RemoveKey(key); 605 break; 606 } 607 } 608 } 609 PDF_DocPageData_Release<CPDF_Stream*, CPDF_IccProfile*>(m_IccProfileMap, pIccProfileStream, pIccProfile); 610 } 611 CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(CPDF_Stream* pFontStream) 612 { 613 if (!pFontStream) { 614 return NULL; 615 } 616 CPDF_CountedObject<CPDF_StreamAcc*>* ftData; 617 if (m_FontFileMap.Lookup(pFontStream, ftData)) { 618 ftData->m_nCount ++; 619 return ftData->m_Obj; 620 } 621 ftData = FX_NEW CPDF_CountedObject<CPDF_StreamAcc*>; 622 if (!ftData) { 623 return NULL; 624 } 625 CPDF_StreamAcc* pFontFile = FX_NEW CPDF_StreamAcc; 626 if (!pFontFile) { 627 delete ftData; 628 return NULL; 629 } 630 CPDF_Dictionary* pFontDict = pFontStream->GetDict(); 631 FX_INT32 org_size = pFontDict->GetInteger(FX_BSTRC("Length1")) + pFontDict->GetInteger(FX_BSTRC("Length2")) + pFontDict->GetInteger(FX_BSTRC("Length3")); 632 if (org_size < 0) { 633 org_size = 0; 634 } 635 pFontFile->LoadAllData(pFontStream, FALSE, org_size); 636 ftData->m_nCount = 2; 637 ftData->m_Obj = pFontFile; 638 m_FontFileMap.SetAt(pFontStream, ftData); 639 return pFontFile; 640 } 641 void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce) 642 { 643 if (!pFontStream) { 644 return; 645 } 646 PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce); 647 } 648