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