| 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 "core/fpdfapi/fpdf_page/pageint.h" | |
| 8 | |
| 9 #include <algorithm> | |
| 10 #include <set> | |
| 11 | |
| 12 #include "core/fdrm/crypto/fx_crypt.h" | |
| 13 #include "core/fpdfapi/cpdf_modulemgr.h" | |
| 14 #include "core/fpdfapi/font/cpdf_type1font.h" | |
| 15 #include "core/fpdfapi/font/font_int.h" | |
| 16 #include "core/fpdfapi/fpdf_page/cpdf_image.h" | |
| 17 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" | |
| 18 #include "core/fpdfapi/fpdf_page/cpdf_pattern.h" | |
| 19 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" | |
| 20 #include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" | |
| 21 #include "core/fpdfapi/fpdf_parser/cpdf_array.h" | |
| 22 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" | |
| 23 #include "core/fpdfapi/fpdf_parser/cpdf_document.h" | |
| 24 #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" | |
| 25 #include "third_party/base/stl_util.h" | |
| 26 | |
| 27 void CPDF_ModuleMgr::InitPageModule() { | |
| 28 m_pPageModule.reset(new CPDF_PageModule); | |
| 29 } | |
| 30 | |
| 31 CPDF_DocPageData::CPDF_DocPageData(CPDF_Document* pPDFDoc) | |
| 32 : m_pPDFDoc(pPDFDoc), m_bForceClear(FALSE) {} | |
| 33 | |
| 34 CPDF_DocPageData::~CPDF_DocPageData() { | |
| 35 Clear(FALSE); | |
| 36 Clear(TRUE); | |
| 37 | |
| 38 for (auto& it : m_PatternMap) | |
| 39 delete it.second; | |
| 40 m_PatternMap.clear(); | |
| 41 | |
| 42 for (auto& it : m_FontMap) | |
| 43 delete it.second; | |
| 44 m_FontMap.clear(); | |
| 45 | |
| 46 for (auto& it : m_ColorSpaceMap) | |
| 47 delete it.second; | |
| 48 m_ColorSpaceMap.clear(); | |
| 49 } | |
| 50 | |
| 51 void CPDF_DocPageData::Clear(FX_BOOL bForceRelease) { | |
| 52 m_bForceClear = bForceRelease; | |
| 53 | |
| 54 for (auto& it : m_PatternMap) { | |
| 55 CPDF_CountedPattern* ptData = it.second; | |
| 56 if (!ptData->get()) | |
| 57 continue; | |
| 58 | |
| 59 if (bForceRelease || ptData->use_count() < 2) | |
| 60 ptData->clear(); | |
| 61 } | |
| 62 | |
| 63 for (auto& it : m_FontMap) { | |
| 64 CPDF_CountedFont* fontData = it.second; | |
| 65 if (!fontData->get()) | |
| 66 continue; | |
| 67 | |
| 68 if (bForceRelease || fontData->use_count() < 2) { | |
| 69 fontData->clear(); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 for (auto& it : m_ColorSpaceMap) { | |
| 74 CPDF_CountedColorSpace* csData = it.second; | |
| 75 if (!csData->get()) | |
| 76 continue; | |
| 77 | |
| 78 if (bForceRelease || csData->use_count() < 2) { | |
| 79 csData->get()->Release(); | |
| 80 csData->reset(nullptr); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end();) { | |
| 85 auto curr_it = it++; | |
| 86 CPDF_CountedIccProfile* ipData = curr_it->second; | |
| 87 if (!ipData->get()) | |
| 88 continue; | |
| 89 | |
| 90 if (bForceRelease || ipData->use_count() < 2) { | |
| 91 for (auto hash_it = m_HashProfileMap.begin(); | |
| 92 hash_it != m_HashProfileMap.end(); ++hash_it) { | |
| 93 if (curr_it->first == hash_it->second) { | |
| 94 m_HashProfileMap.erase(hash_it); | |
| 95 break; | |
| 96 } | |
| 97 } | |
| 98 delete ipData->get(); | |
| 99 delete ipData; | |
| 100 m_IccProfileMap.erase(curr_it); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 for (auto it = m_FontFileMap.begin(); it != m_FontFileMap.end();) { | |
| 105 auto curr_it = it++; | |
| 106 CPDF_CountedStreamAcc* pCountedFont = curr_it->second; | |
| 107 if (!pCountedFont->get()) | |
| 108 continue; | |
| 109 | |
| 110 if (bForceRelease || pCountedFont->use_count() < 2) { | |
| 111 delete pCountedFont->get(); | |
| 112 delete pCountedFont; | |
| 113 m_FontFileMap.erase(curr_it); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 for (auto it = m_ImageMap.begin(); it != m_ImageMap.end();) { | |
| 118 auto curr_it = it++; | |
| 119 CPDF_CountedImage* pCountedImage = curr_it->second; | |
| 120 if (!pCountedImage->get()) | |
| 121 continue; | |
| 122 | |
| 123 if (bForceRelease || pCountedImage->use_count() < 2) { | |
| 124 delete pCountedImage->get(); | |
| 125 delete pCountedImage; | |
| 126 m_ImageMap.erase(curr_it); | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, | |
| 132 FX_BOOL findOnly) { | |
| 133 if (!pFontDict) | |
| 134 return nullptr; | |
| 135 | |
| 136 CPDF_CountedFont* pFontData = nullptr; | |
| 137 auto it = m_FontMap.find(pFontDict); | |
| 138 if (it != m_FontMap.end()) { | |
| 139 pFontData = it->second; | |
| 140 if (pFontData->get()) { | |
| 141 return pFontData->AddRef(); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 if (findOnly) | |
| 146 return nullptr; | |
| 147 | |
| 148 std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pFontDict); | |
| 149 if (!pFont) | |
| 150 return nullptr; | |
| 151 | |
| 152 if (pFontData) { | |
| 153 pFontData->reset(pFont.release()); | |
| 154 } else { | |
| 155 pFontData = new CPDF_CountedFont(pFont.release()); | |
| 156 m_FontMap[pFontDict] = pFontData; | |
| 157 } | |
| 158 return pFontData->AddRef(); | |
| 159 } | |
| 160 | |
| 161 CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, | |
| 162 CPDF_FontEncoding* pEncoding) { | |
| 163 if (fontName.IsEmpty()) | |
| 164 return nullptr; | |
| 165 | |
| 166 for (auto& it : m_FontMap) { | |
| 167 CPDF_CountedFont* fontData = it.second; | |
| 168 CPDF_Font* pFont = fontData->get(); | |
| 169 if (!pFont) | |
| 170 continue; | |
| 171 if (pFont->GetBaseFont() != fontName) | |
| 172 continue; | |
| 173 if (pFont->IsEmbedded()) | |
| 174 continue; | |
| 175 if (!pFont->IsType1Font()) | |
| 176 continue; | |
| 177 if (pFont->GetFontDict()->KeyExist("Widths")) | |
| 178 continue; | |
| 179 | |
| 180 CPDF_Type1Font* pT1Font = pFont->AsType1Font(); | |
| 181 if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) | |
| 182 continue; | |
| 183 | |
| 184 return fontData->AddRef(); | |
| 185 } | |
| 186 | |
| 187 CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool()); | |
| 188 pDict->SetNameFor("Type", "Font"); | |
| 189 pDict->SetNameFor("Subtype", "Type1"); | |
| 190 pDict->SetNameFor("BaseFont", fontName); | |
| 191 if (pEncoding) { | |
| 192 pDict->SetFor("Encoding", | |
| 193 pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); | |
| 194 } | |
| 195 m_pPDFDoc->AddIndirectObject(pDict); | |
| 196 std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pDict); | |
| 197 if (!pFont) | |
| 198 return nullptr; | |
| 199 | |
| 200 CPDF_CountedFont* fontData = new CPDF_CountedFont(pFont.release()); | |
| 201 m_FontMap[pDict] = fontData; | |
| 202 return fontData->AddRef(); | |
| 203 } | |
| 204 | |
| 205 void CPDF_DocPageData::ReleaseFont(const CPDF_Dictionary* pFontDict) { | |
| 206 if (!pFontDict) | |
| 207 return; | |
| 208 | |
| 209 auto it = m_FontMap.find(pFontDict); | |
| 210 if (it == m_FontMap.end()) | |
| 211 return; | |
| 212 | |
| 213 CPDF_CountedFont* pFontData = it->second; | |
| 214 if (!pFontData->get()) | |
| 215 return; | |
| 216 | |
| 217 pFontData->RemoveRef(); | |
| 218 if (pFontData->use_count() > 1) | |
| 219 return; | |
| 220 | |
| 221 // We have font data only in m_FontMap cache. Clean it. | |
| 222 pFontData->clear(); | |
| 223 } | |
| 224 | |
| 225 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace( | |
| 226 CPDF_Object* pCSObj, | |
| 227 const CPDF_Dictionary* pResources) { | |
| 228 std::set<CPDF_Object*> visited; | |
| 229 return GetColorSpaceImpl(pCSObj, pResources, &visited); | |
| 230 } | |
| 231 | |
| 232 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpaceImpl( | |
| 233 CPDF_Object* pCSObj, | |
| 234 const CPDF_Dictionary* pResources, | |
| 235 std::set<CPDF_Object*>* pVisited) { | |
| 236 if (!pCSObj) | |
| 237 return nullptr; | |
| 238 | |
| 239 if (pdfium::ContainsKey(*pVisited, pCSObj)) | |
| 240 return nullptr; | |
| 241 | |
| 242 if (pCSObj->IsName()) { | |
| 243 CFX_ByteString name = pCSObj->GetString(); | |
| 244 CPDF_ColorSpace* pCS = CPDF_ColorSpace::ColorspaceFromName(name); | |
| 245 if (!pCS && pResources) { | |
| 246 CPDF_Dictionary* pList = pResources->GetDictFor("ColorSpace"); | |
| 247 if (pList) { | |
| 248 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj); | |
| 249 return GetColorSpaceImpl(pList->GetDirectObjectFor(name), nullptr, | |
| 250 pVisited); | |
| 251 } | |
| 252 } | |
| 253 if (!pCS || !pResources) | |
| 254 return pCS; | |
| 255 | |
| 256 CPDF_Dictionary* pColorSpaces = pResources->GetDictFor("ColorSpace"); | |
| 257 if (!pColorSpaces) | |
| 258 return pCS; | |
| 259 | |
| 260 CPDF_Object* pDefaultCS = nullptr; | |
| 261 switch (pCS->GetFamily()) { | |
| 262 case PDFCS_DEVICERGB: | |
| 263 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB"); | |
| 264 break; | |
| 265 case PDFCS_DEVICEGRAY: | |
| 266 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultGray"); | |
| 267 break; | |
| 268 case PDFCS_DEVICECMYK: | |
| 269 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultCMYK"); | |
| 270 break; | |
| 271 } | |
| 272 if (!pDefaultCS) | |
| 273 return pCS; | |
| 274 | |
| 275 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj); | |
| 276 return GetColorSpaceImpl(pDefaultCS, nullptr, pVisited); | |
| 277 } | |
| 278 | |
| 279 CPDF_Array* pArray = pCSObj->AsArray(); | |
| 280 if (!pArray || pArray->IsEmpty()) | |
| 281 return nullptr; | |
| 282 | |
| 283 if (pArray->GetCount() == 1) { | |
| 284 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj); | |
| 285 return GetColorSpaceImpl(pArray->GetDirectObjectAt(0), pResources, | |
| 286 pVisited); | |
| 287 } | |
| 288 | |
| 289 CPDF_CountedColorSpace* csData = nullptr; | |
| 290 auto it = m_ColorSpaceMap.find(pCSObj); | |
| 291 if (it != m_ColorSpaceMap.end()) { | |
| 292 csData = it->second; | |
| 293 if (csData->get()) { | |
| 294 return csData->AddRef(); | |
| 295 } | |
| 296 } | |
| 297 | |
| 298 std::unique_ptr<CPDF_ColorSpace> pCS = | |
| 299 CPDF_ColorSpace::Load(m_pPDFDoc, pArray); | |
| 300 if (!pCS) | |
| 301 return nullptr; | |
| 302 | |
| 303 if (!csData) { | |
| 304 csData = new CPDF_CountedColorSpace(pCS.release()); | |
| 305 m_ColorSpaceMap[pCSObj] = csData; | |
| 306 } else { | |
| 307 csData->reset(pCS.release()); | |
| 308 } | |
| 309 return csData->AddRef(); | |
| 310 } | |
| 311 | |
| 312 CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) { | |
| 313 if (!pCSObj) | |
| 314 return nullptr; | |
| 315 | |
| 316 auto it = m_ColorSpaceMap.find(pCSObj); | |
| 317 if (it != m_ColorSpaceMap.end()) | |
| 318 return it->second->AddRef(); | |
| 319 | |
| 320 return nullptr; | |
| 321 } | |
| 322 | |
| 323 void CPDF_DocPageData::ReleaseColorSpace(const CPDF_Object* pColorSpace) { | |
| 324 if (!pColorSpace) | |
| 325 return; | |
| 326 | |
| 327 auto it = m_ColorSpaceMap.find(pColorSpace); | |
| 328 if (it == m_ColorSpaceMap.end()) | |
| 329 return; | |
| 330 | |
| 331 CPDF_CountedColorSpace* pCountedColorSpace = it->second; | |
| 332 if (!pCountedColorSpace->get()) | |
| 333 return; | |
| 334 | |
| 335 pCountedColorSpace->RemoveRef(); | |
| 336 if (pCountedColorSpace->use_count() > 1) | |
| 337 return; | |
| 338 | |
| 339 // We have item only in m_ColorSpaceMap cache. Clean it. | |
| 340 pCountedColorSpace->get()->Release(); | |
| 341 pCountedColorSpace->reset(nullptr); | |
| 342 } | |
| 343 | |
| 344 CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, | |
| 345 FX_BOOL bShading, | |
| 346 const CFX_Matrix& matrix) { | |
| 347 if (!pPatternObj) | |
| 348 return nullptr; | |
| 349 | |
| 350 CPDF_CountedPattern* ptData = nullptr; | |
| 351 auto it = m_PatternMap.find(pPatternObj); | |
| 352 if (it != m_PatternMap.end()) { | |
| 353 ptData = it->second; | |
| 354 if (ptData->get()) { | |
| 355 return ptData->AddRef(); | |
| 356 } | |
| 357 } | |
| 358 CPDF_Pattern* pPattern = nullptr; | |
| 359 if (bShading) { | |
| 360 pPattern = new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, TRUE, matrix); | |
| 361 } else { | |
| 362 CPDF_Dictionary* pDict = pPatternObj ? pPatternObj->GetDict() : nullptr; | |
| 363 if (pDict) { | |
| 364 int type = pDict->GetIntegerFor("PatternType"); | |
| 365 if (type == CPDF_Pattern::TILING) { | |
| 366 pPattern = new CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); | |
| 367 } else if (type == CPDF_Pattern::SHADING) { | |
| 368 pPattern = | |
| 369 new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); | |
| 370 } | |
| 371 } | |
| 372 } | |
| 373 if (!pPattern) | |
| 374 return nullptr; | |
| 375 | |
| 376 if (!ptData) { | |
| 377 ptData = new CPDF_CountedPattern(pPattern); | |
| 378 m_PatternMap[pPatternObj] = ptData; | |
| 379 } else { | |
| 380 ptData->reset(pPattern); | |
| 381 } | |
| 382 return ptData->AddRef(); | |
| 383 } | |
| 384 | |
| 385 void CPDF_DocPageData::ReleasePattern(const CPDF_Object* pPatternObj) { | |
| 386 if (!pPatternObj) | |
| 387 return; | |
| 388 | |
| 389 auto it = m_PatternMap.find(pPatternObj); | |
| 390 if (it == m_PatternMap.end()) | |
| 391 return; | |
| 392 | |
| 393 CPDF_CountedPattern* pPattern = it->second; | |
| 394 if (!pPattern->get()) | |
| 395 return; | |
| 396 | |
| 397 pPattern->RemoveRef(); | |
| 398 if (pPattern->use_count() > 1) | |
| 399 return; | |
| 400 | |
| 401 // We have item only in m_PatternMap cache. Clean it. | |
| 402 pPattern->clear(); | |
| 403 } | |
| 404 | |
| 405 CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) { | |
| 406 if (!pImageStream) | |
| 407 return nullptr; | |
| 408 | |
| 409 const uint32_t dwImageObjNum = pImageStream->GetObjNum(); | |
| 410 auto it = m_ImageMap.find(dwImageObjNum); | |
| 411 if (it != m_ImageMap.end()) | |
| 412 return it->second->AddRef(); | |
| 413 | |
| 414 CPDF_CountedImage* pCountedImage = new CPDF_CountedImage( | |
| 415 new CPDF_Image(m_pPDFDoc, pImageStream->AsStream(), false)); | |
| 416 m_ImageMap[dwImageObjNum] = pCountedImage; | |
| 417 return pCountedImage->AddRef(); | |
| 418 } | |
| 419 | |
| 420 void CPDF_DocPageData::ReleaseImage(const CPDF_Object* pImageStream) { | |
| 421 if (!pImageStream) | |
| 422 return; | |
| 423 | |
| 424 uint32_t dwObjNum = pImageStream->GetObjNum(); | |
| 425 if (!dwObjNum) | |
| 426 return; | |
| 427 | |
| 428 auto it = m_ImageMap.find(dwObjNum); | |
| 429 if (it == m_ImageMap.end()) | |
| 430 return; | |
| 431 | |
| 432 CPDF_CountedImage* pCountedImage = it->second; | |
| 433 if (!pCountedImage) | |
| 434 return; | |
| 435 | |
| 436 pCountedImage->RemoveRef(); | |
| 437 if (pCountedImage->use_count() > 1) | |
| 438 return; | |
| 439 | |
| 440 // We have item only in m_ImageMap cache. Clean it. | |
| 441 delete pCountedImage->get(); | |
| 442 delete pCountedImage; | |
| 443 m_ImageMap.erase(it); | |
| 444 } | |
| 445 | |
| 446 CPDF_IccProfile* CPDF_DocPageData::GetIccProfile( | |
| 447 CPDF_Stream* pIccProfileStream) { | |
| 448 if (!pIccProfileStream) | |
| 449 return nullptr; | |
| 450 | |
| 451 auto it = m_IccProfileMap.find(pIccProfileStream); | |
| 452 if (it != m_IccProfileMap.end()) | |
| 453 return it->second->AddRef(); | |
| 454 | |
| 455 CPDF_StreamAcc stream; | |
| 456 stream.LoadAllData(pIccProfileStream, FALSE); | |
| 457 uint8_t digest[20]; | |
| 458 CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); | |
| 459 CFX_ByteString bsDigest(digest, 20); | |
| 460 auto hash_it = m_HashProfileMap.find(bsDigest); | |
| 461 if (hash_it != m_HashProfileMap.end()) { | |
| 462 auto it_copied_stream = m_IccProfileMap.find(hash_it->second); | |
| 463 if (it_copied_stream != m_IccProfileMap.end()) | |
| 464 return it_copied_stream->second->AddRef(); | |
| 465 } | |
| 466 CPDF_IccProfile* pProfile = | |
| 467 new CPDF_IccProfile(stream.GetData(), stream.GetSize()); | |
| 468 CPDF_CountedIccProfile* ipData = new CPDF_CountedIccProfile(pProfile); | |
| 469 m_IccProfileMap[pIccProfileStream] = ipData; | |
| 470 m_HashProfileMap[bsDigest] = pIccProfileStream; | |
| 471 return ipData->AddRef(); | |
| 472 } | |
| 473 | |
| 474 void CPDF_DocPageData::ReleaseIccProfile(const CPDF_IccProfile* pIccProfile) { | |
| 475 ASSERT(pIccProfile); | |
| 476 | |
| 477 for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end(); ++it) { | |
| 478 CPDF_CountedIccProfile* profile = it->second; | |
| 479 if (profile->get() != pIccProfile) | |
| 480 continue; | |
| 481 | |
| 482 profile->RemoveRef(); | |
| 483 if (profile->use_count() > 1) | |
| 484 continue; | |
| 485 // We have item only in m_IccProfileMap cache. Clean it. | |
| 486 delete profile->get(); | |
| 487 delete profile; | |
| 488 m_IccProfileMap.erase(it); | |
| 489 return; | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc( | |
| 494 CPDF_Stream* pFontStream) { | |
| 495 ASSERT(pFontStream); | |
| 496 | |
| 497 auto it = m_FontFileMap.find(pFontStream); | |
| 498 if (it != m_FontFileMap.end()) | |
| 499 return it->second->AddRef(); | |
| 500 | |
| 501 CPDF_Dictionary* pFontDict = pFontStream->GetDict(); | |
| 502 int32_t org_size = pFontDict->GetIntegerFor("Length1") + | |
| 503 pFontDict->GetIntegerFor("Length2") + | |
| 504 pFontDict->GetIntegerFor("Length3"); | |
| 505 org_size = std::max(org_size, 0); | |
| 506 | |
| 507 CPDF_StreamAcc* pFontFile = new CPDF_StreamAcc; | |
| 508 pFontFile->LoadAllData(pFontStream, FALSE, org_size); | |
| 509 | |
| 510 CPDF_CountedStreamAcc* pCountedFont = new CPDF_CountedStreamAcc(pFontFile); | |
| 511 m_FontFileMap[pFontStream] = pCountedFont; | |
| 512 return pCountedFont->AddRef(); | |
| 513 } | |
| 514 | |
| 515 void CPDF_DocPageData::ReleaseFontFileStreamAcc( | |
| 516 const CPDF_Stream* pFontStream) { | |
| 517 if (!pFontStream) | |
| 518 return; | |
| 519 | |
| 520 auto it = m_FontFileMap.find(pFontStream); | |
| 521 if (it == m_FontFileMap.end()) | |
| 522 return; | |
| 523 | |
| 524 CPDF_CountedStreamAcc* pCountedStream = it->second; | |
| 525 if (!pCountedStream) | |
| 526 return; | |
| 527 | |
| 528 pCountedStream->RemoveRef(); | |
| 529 if (pCountedStream->use_count() > 1) | |
| 530 return; | |
| 531 | |
| 532 // We have item only in m_FontFileMap cache. Clean it. | |
| 533 delete pCountedStream->get(); | |
| 534 delete pCountedStream; | |
| 535 m_FontFileMap.erase(it); | |
| 536 } | |
| 537 | |
| 538 CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr( | |
| 539 CPDF_Object* pCSObj) const { | |
| 540 if (!pCSObj) | |
| 541 return nullptr; | |
| 542 | |
| 543 auto it = m_ColorSpaceMap.find(pCSObj); | |
| 544 return it != m_ColorSpaceMap.end() ? it->second : nullptr; | |
| 545 } | |
| 546 | |
| 547 CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr( | |
| 548 CPDF_Object* pPatternObj) const { | |
| 549 if (!pPatternObj) | |
| 550 return nullptr; | |
| 551 | |
| 552 auto it = m_PatternMap.find(pPatternObj); | |
| 553 return it != m_PatternMap.end() ? it->second : nullptr; | |
| 554 } | |
| OLD | NEW |