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:
CPDF_PageModule()15 CPDF_PageModule() : m_StockGrayCS(PDFCS_DEVICEGRAY), m_StockRGBCS(PDFCS_DEVICERGB),
16 m_StockCMYKCS(PDFCS_DEVICECMYK) {}
~CPDF_PageModule()17 virtual ~CPDF_PageModule() {}
Installed()18 virtual FX_BOOL Installed()
19 {
20 return TRUE;
21 }
CreateDocData(CPDF_Document * pDoc)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);
GetFontGlobals()28 virtual CPDF_FontGlobals* GetFontGlobals()
29 {
30 return &m_FontGlobals;
31 }
ClearStockFont(CPDF_Document * pDoc)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 };
GetStockCS(int family)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 }
InitPageModule()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 }
ReleaseDoc(CPDF_Document * pDoc)68 void CPDF_PageModule::ReleaseDoc(CPDF_Document* pDoc)
69 {
70 delete pDoc->GetPageData();
71 }
ClearDoc(CPDF_Document * pDoc)72 void CPDF_PageModule::ClearDoc(CPDF_Document* pDoc)
73 {
74 pDoc->GetPageData()->Clear(FALSE);
75 }
NotifyCJKAvailable()76 void CPDF_PageModule::NotifyCJKAvailable()
77 {
78 m_FontGlobals.m_CMapManager.ReloadAll();
79 }
LoadFont(CPDF_Dictionary * pFontDict)80 CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict)
81 {
82 if (!pFontDict) {
83 return NULL;
84 }
85 return GetValidatePageData()->GetFont(pFontDict, FALSE);
86 }
FindFont(CPDF_Dictionary * pFontDict)87 CPDF_Font* CPDF_Document::FindFont(CPDF_Dictionary* pFontDict)
88 {
89 if (!pFontDict) {
90 return NULL;
91 }
92 return GetValidatePageData()->GetFont(pFontDict, TRUE);
93 }
LoadFontFile(CPDF_Stream * pStream)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);
LoadColorSpace(CPDF_Object * pCSObj,CPDF_Dictionary * pResources)102 CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources)
103 {
104 return GetValidatePageData()->GetColorSpace(pCSObj, pResources);
105 }
LoadPattern(CPDF_Object * pPatternObj,FX_BOOL bShading,const CFX_AffineMatrix * matrix)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 }
LoadIccProfile(CPDF_Stream * pStream,int nComponents)110 CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents)
111 {
112 return GetValidatePageData()->GetIccProfile(pStream, nComponents);
113 }
LoadImageF(CPDF_Object * pObj)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 }
RemoveColorSpaceFromPageData(CPDF_Object * pCSObj)122 void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj)
123 {
124 if (!pCSObj) {
125 return;
126 }
127 GetPageData()->ReleaseColorSpace(pCSObj);
128 }
CPDF_DocPageData(CPDF_Document * pPDFDoc)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 }
~CPDF_DocPageData()145 CPDF_DocPageData::~CPDF_DocPageData()
146 {
147 Clear(FALSE);
148 Clear(TRUE);
149 FX_POSITION pos = NULL;
150 }
Clear(FX_BOOL bRelease)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 }
GetFont(CPDF_Dictionary * pFontDict,FX_BOOL findOnly)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 }
GetStandardFont(FX_BSTR fontName,CPDF_FontEncoding * pEncoding)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 }
ReleaseFont(CPDF_Dictionary * pFontDict)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 }
GetColorSpace(CPDF_Object * pCSObj,CPDF_Dictionary * pResources)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 }
GetCopiedColorSpace(CPDF_Object * pCSObj)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 }
ReleaseColorSpace(CPDF_Object * pColorSpace)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 }
GetPattern(CPDF_Object * pPatternObj,FX_BOOL bShading,const CFX_AffineMatrix * matrix)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 }
ReleasePattern(CPDF_Object * pPatternObj)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 }
GetImage(CPDF_Object * pImageStream)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 }
ReleaseImage(CPDF_Object * pImageStream)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 }
GetIccProfile(CPDF_Stream * pIccProfileStream,FX_INT32 nComponents)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 }
ReleaseIccProfile(CPDF_Stream * pIccProfileStream,CPDF_IccProfile * pIccProfile)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 }
GetFontFileStreamAcc(CPDF_Stream * pFontStream)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 }
ReleaseFontFileStreamAcc(CPDF_Stream * pFontStream,FX_BOOL bForce)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