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