Fix a few more warnings in chromium_code mode.
[pdfium.git] / core / src / fpdfapi / fpdf_page / fpdf_page_doc.cpp
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 }
150 void CPDF_DocPageData::Clear(FX_BOOL bRelease)
151 {
152     FX_POSITION pos;
153     FX_DWORD    nCount;
154     {
155         pos = m_PatternMap.GetStartPosition();
156         while (pos) {
157             CPDF_Object* ptObj;
158             CPDF_CountedObject<CPDF_Pattern*>* ptData;
159             m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
160             nCount = ptData->m_nCount;
161             if (bRelease || nCount < 2) {
162                 delete ptData->m_Obj;
163                 ptData->m_Obj = NULL;
164             }
165         }
166     }
167     {
168         pos = m_FontMap.GetStartPosition();
169         while (pos) {
170             CPDF_Dictionary* fontDict;
171             CPDF_CountedObject<CPDF_Font*>* fontData;
172             m_FontMap.GetNextAssoc(pos, fontDict, fontData);
173             nCount = fontData->m_nCount;
174             if (bRelease || nCount < 2) {
175                 delete fontData->m_Obj;
176                 fontData->m_Obj = NULL;
177             }
178         }
179     }
180     {
181         pos = m_ImageMap.GetStartPosition();
182         while (pos) {
183             FX_DWORD objNum;
184             CPDF_CountedObject<CPDF_Image*>* imageData;
185             m_ImageMap.GetNextAssoc(pos, objNum, imageData);
186             nCount = imageData->m_nCount;
187             if (bRelease || nCount < 2) {
188                 delete imageData->m_Obj;
189                 delete imageData;
190                 m_ImageMap.RemoveKey(objNum);
191             }
192         }
193     }
194     {
195         pos = m_ColorSpaceMap.GetStartPosition();
196         while (pos) {
197             CPDF_Object* csKey;
198             CPDF_CountedObject<CPDF_ColorSpace*>* csData;
199             m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
200             nCount = csData->m_nCount;
201             if (bRelease || nCount < 2) {
202                 csData->m_Obj->ReleaseCS();
203                 csData->m_Obj = NULL;
204             }
205         }
206     }
207     {
208         pos = m_IccProfileMap.GetStartPosition();
209         while (pos) {
210             CPDF_Stream* ipKey;
211             CPDF_CountedObject<CPDF_IccProfile*>* ipData;
212             m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData);
213             nCount = ipData->m_nCount;
214             if (bRelease || nCount < 2) {
215                 FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
216                 while (pos2) {
217                     CFX_ByteString bsKey;
218                     CPDF_Stream* pFindStream = NULL;
219                     m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream);
220                     if (ipKey == pFindStream) {
221                         m_HashProfileMap.RemoveKey(bsKey);
222                         break;
223                     }
224                 }
225                 delete ipData->m_Obj;
226                 delete ipData;
227                 m_IccProfileMap.RemoveKey(ipKey);
228             }
229         }
230     }
231     {
232         pos = m_FontFileMap.GetStartPosition();
233         while (pos) {
234             CPDF_Stream* ftKey;
235             CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
236             m_FontFileMap.GetNextAssoc(pos, ftKey, ftData);
237             nCount = ftData->m_nCount;
238             if (bRelease || nCount < 2) {
239                 delete ftData->m_Obj;
240                 delete ftData;
241                 m_FontFileMap.RemoveKey(ftKey);
242             }
243         }
244     }
245 }
246 CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly)
247 {
248     if (!pFontDict) {
249         return NULL;
250     }
251     if (findOnly) {
252         CPDF_CountedObject<CPDF_Font*>* fontData;
253         if (m_FontMap.Lookup(pFontDict, fontData)) {
254             if (!fontData->m_Obj) {
255                 return NULL;
256             }
257             fontData->m_nCount ++;
258             return fontData->m_Obj;
259         }
260         return NULL;
261     }
262     CPDF_CountedObject<CPDF_Font*>* fontData = NULL;
263     if (m_FontMap.Lookup(pFontDict, fontData)) {
264         if (fontData->m_Obj) {
265             fontData->m_nCount ++;
266             return fontData->m_Obj;
267         }
268     }
269     FX_BOOL bNew = FALSE;
270     if (!fontData) {
271         fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>;
272         bNew = TRUE;
273         if (!fontData) {
274             return NULL;
275         }
276     }
277     CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pFontDict);
278     if (!pFont) {
279         if (bNew) {
280             delete fontData;
281         }
282         return NULL;
283     }
284     fontData->m_nCount = 2;
285     fontData->m_Obj = pFont;
286     m_FontMap.SetAt(pFontDict, fontData);
287     return pFont;
288 }
289 CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding)
290 {
291     if (fontName.IsEmpty()) {
292         return NULL;
293     }
294     FX_POSITION pos = m_FontMap.GetStartPosition();
295     while (pos) {
296         CPDF_Dictionary* fontDict;
297         CPDF_CountedObject<CPDF_Font*>* fontData;
298         m_FontMap.GetNextAssoc(pos, fontDict, fontData);
299         CPDF_Font* pFont = fontData->m_Obj;
300         if (!pFont) {
301             continue;
302         }
303         if (pFont->GetBaseFont() != fontName) {
304             continue;
305         }
306         if (pFont->IsEmbedded()) {
307             continue;
308         }
309         if (pFont->GetFontType() != PDFFONT_TYPE1) {
310             continue;
311         }
312         if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) {
313             continue;
314         }
315         CPDF_Type1Font* pT1Font = pFont->GetType1Font();
316         if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) {
317             continue;
318         }
319         fontData->m_nCount ++;
320         return pFont;
321     }
322     CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
323     pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));
324     pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));
325     pDict->SetAtName(FX_BSTRC("BaseFont"), fontName);
326     if (pEncoding) {
327         pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize());
328     }
329     m_pPDFDoc->AddIndirectObject(pDict);
330     CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>;
331     if (!fontData) {
332         return NULL;
333     }
334     CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict);
335     if (!pFont) {
336         delete fontData;
337         return NULL;
338     }
339     fontData->m_nCount = 2;
340     fontData->m_Obj = pFont;
341     m_FontMap.SetAt(pDict, fontData);
342     return pFont;
343 }
344 void CPDF_DocPageData::ReleaseFont(CPDF_Dictionary* pFontDict)
345 {
346     if (!pFontDict) {
347         return;
348     }
349     CPDF_CountedObject<CPDF_Font*>* fontData;
350     if (!m_FontMap.Lookup(pFontDict, fontData)) {
351         return;
352     }
353     if (fontData->m_Obj && --fontData->m_nCount == 0) {
354         delete fontData->m_Obj;
355         fontData->m_Obj = NULL;
356     }
357 }
358 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources)
359 {
360     if (!pCSObj) {
361         return NULL;
362     }
363     if (pCSObj->GetType() == PDFOBJ_NAME) {
364         CFX_ByteString name = pCSObj->GetConstString();
365         CPDF_ColorSpace* pCS = _CSFromName(name);
366         if (!pCS && pResources) {
367             CPDF_Dictionary* pList = pResources->GetDict(FX_BSTRC("ColorSpace"));
368             if (pList) {
369                 pCSObj = pList->GetElementValue(name);
370                 return GetColorSpace(pCSObj, NULL);
371             }
372         }
373         if (pCS == NULL || pResources == NULL) {
374             return pCS;
375         }
376         CPDF_Dictionary* pColorSpaces = pResources->GetDict(FX_BSTRC("ColorSpace"));
377         if (pColorSpaces == NULL) {
378             return pCS;
379         }
380         CPDF_Object* pDefaultCS = NULL;
381         switch (pCS->GetFamily()) {
382             case PDFCS_DEVICERGB:
383                 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultRGB"));
384                 break;
385             case PDFCS_DEVICEGRAY:
386                 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultGray"));
387                 break;
388             case PDFCS_DEVICECMYK:
389                 pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultCMYK"));
390                 break;
391         }
392         if (pDefaultCS == NULL) {
393             return pCS;
394         }
395         return GetColorSpace(pDefaultCS, NULL);
396     }
397     if (pCSObj->GetType() != PDFOBJ_ARRAY) {
398         return NULL;
399     }
400     CPDF_Array* pArray = (CPDF_Array*)pCSObj;
401     if (pArray->GetCount() == 0) {
402         return NULL;
403     }
404     if (pArray->GetCount() == 1) {
405         return GetColorSpace(pArray->GetElementValue(0), pResources);
406     }
407     CPDF_CountedObject<CPDF_ColorSpace*>* csData = NULL;
408     if (m_ColorSpaceMap.Lookup(pCSObj, csData)) {
409         if (csData->m_Obj) {
410             csData->m_nCount++;
411             return csData->m_Obj;
412         }
413     }
414     FX_BOOL bNew = FALSE;
415     if (!csData) {
416         csData = FX_NEW CPDF_CountedObject<CPDF_ColorSpace*>;
417         if (!csData) {
418             return NULL;
419         }
420         bNew = TRUE;
421     }
422     CPDF_ColorSpace* pCS = CPDF_ColorSpace::Load(m_pPDFDoc, pArray);
423     if (!pCS) {
424         if (bNew) {
425             delete csData;
426         }
427         return NULL;
428     }
429     csData->m_nCount = 2;
430     csData->m_Obj = pCS;
431     m_ColorSpaceMap.SetAt(pCSObj, csData);
432     return pCS;
433 }
434 CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj)
435 {
436     if (!pCSObj) {
437         return NULL;
438     }
439     CPDF_CountedObject<CPDF_ColorSpace*>* csData;
440     if (!m_ColorSpaceMap.Lookup(pCSObj, csData)) {
441         return NULL;
442     }
443     if (!csData->m_Obj) {
444         return NULL;
445     }
446     csData->m_nCount ++;
447     return csData->m_Obj;
448 }
449 void CPDF_DocPageData::ReleaseColorSpace(CPDF_Object* pColorSpace)
450 {
451     if (!pColorSpace) {
452         return;
453     }
454     CPDF_CountedObject<CPDF_ColorSpace*>* csData;
455     if (!m_ColorSpaceMap.Lookup(pColorSpace, csData)) {
456         return;
457     }
458     if (csData->m_Obj && --csData->m_nCount == 0) {
459         csData->m_Obj->ReleaseCS();
460         csData->m_Obj = NULL;
461     }
462 }
463 CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix)
464 {
465     if (!pPatternObj) {
466         return NULL;
467     }
468     CPDF_CountedObject<CPDF_Pattern*>* ptData = NULL;
469     if (m_PatternMap.Lookup(pPatternObj, ptData)) {
470         if (ptData->m_Obj) {
471             ptData->m_nCount++;
472             return ptData->m_Obj;
473         }
474     }
475     FX_BOOL bNew = FALSE;
476     if (!ptData) {
477         ptData = FX_NEW CPDF_CountedObject<CPDF_Pattern*>;
478         bNew = TRUE;
479         if (!ptData) {
480             return NULL;
481         }
482     }
483     CPDF_Pattern* pPattern = NULL;
484     if (bShading) {
485         pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, bShading, matrix);
486     } else {
487         CPDF_Dictionary* pDict = pPatternObj ? pPatternObj->GetDict() : NULL;
488         if (pDict) {
489             int type = pDict->GetInteger(FX_BSTRC("PatternType"));
490             if (type == 1) {
491                 pPattern = FX_NEW CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix);
492             } else if (type == 2) {
493                 pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix);
494             }
495         }
496     }
497     if (!pPattern) {
498         if (bNew) {
499             delete ptData;
500         }
501         return NULL;
502     }
503     ptData->m_nCount = 2;
504     ptData->m_Obj = pPattern;
505     m_PatternMap.SetAt(pPatternObj, ptData);
506     return pPattern;
507 }
508 void CPDF_DocPageData::ReleasePattern(CPDF_Object* pPatternObj)
509 {
510     if (!pPatternObj) {
511         return;
512     }
513     CPDF_CountedObject<CPDF_Pattern*>* ptData;
514     if (!m_PatternMap.Lookup(pPatternObj, ptData)) {
515         return;
516     }
517     if (ptData->m_Obj && --ptData->m_nCount == 0) {
518         delete ptData->m_Obj;
519         ptData->m_Obj = NULL;
520     }
521 }
522 CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream)
523 {
524     if (!pImageStream) {
525         return NULL;
526     }
527     FX_DWORD dwImageObjNum = pImageStream->GetObjNum();
528     CPDF_CountedObject<CPDF_Image*>* imageData;
529     if (m_ImageMap.Lookup(dwImageObjNum, imageData)) {
530         imageData->m_nCount ++;
531         return imageData->m_Obj;
532     }
533     imageData = FX_NEW CPDF_CountedObject<CPDF_Image*>;
534     if (!imageData) {
535         return NULL;
536     }
537     CPDF_Image* pImage = FX_NEW CPDF_Image(m_pPDFDoc);
538     if (!pImage) {
539         delete imageData;
540         return NULL;
541     }
542     pImage->LoadImageF((CPDF_Stream*)pImageStream, FALSE);
543     imageData->m_nCount = 2;
544     imageData->m_Obj = pImage;
545     m_ImageMap.SetAt(dwImageObjNum, imageData);
546     return pImage;
547 }
548 void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream)
549 {
550     if (!pImageStream) {
551         return;
552     }
553     PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL);
554 }
555 CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents)
556 {
557     if (!pIccProfileStream) {
558         return NULL;
559     }
560     CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL;
561     if (m_IccProfileMap.Lookup(pIccProfileStream, ipData)) {
562         ipData->m_nCount++;
563         return ipData->m_Obj;
564     }
565     CPDF_StreamAcc stream;
566     stream.LoadAllData(pIccProfileStream, FALSE);
567     FX_BYTE digest[20];
568     CPDF_Stream* pCopiedStream = NULL;
569     CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest);
570     if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20), (void*&)pCopiedStream)) {
571         m_IccProfileMap.Lookup(pCopiedStream, ipData);
572         ipData->m_nCount++;
573         return ipData->m_Obj;
574     }
575     CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents);
576     if (!pProfile) {
577         return NULL;
578     }
579     ipData = FX_NEW CPDF_CountedObject<CPDF_IccProfile*>;
580     if (!ipData) {
581         delete pProfile;
582         return NULL;
583     }
584     ipData->m_nCount = 2;
585     ipData->m_Obj = pProfile;
586     m_IccProfileMap.SetAt(pIccProfileStream, ipData);
587     m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream);
588     return pProfile;
589 }
590 void CPDF_DocPageData::ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile)
591 {
592     if (!pIccProfileStream && !pIccProfile) {
593         return;
594     }
595     CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL;
596     if (m_IccProfileMap.Lookup(pIccProfileStream, ipData) && ipData->m_nCount < 2) {
597         FX_POSITION pos = m_HashProfileMap.GetStartPosition();
598         while (pos) {
599             CFX_ByteString key;
600             CPDF_Stream* pFindStream = NULL;
601             m_HashProfileMap.GetNextAssoc(pos, key, (void*&)pFindStream);
602             if (pIccProfileStream == pFindStream) {
603                 m_HashProfileMap.RemoveKey(key);
604                 break;
605             }
606         }
607     }
608     PDF_DocPageData_Release<CPDF_Stream*, CPDF_IccProfile*>(m_IccProfileMap, pIccProfileStream, pIccProfile);
609 }
610 CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(CPDF_Stream* pFontStream)
611 {
612     if (!pFontStream) {
613         return NULL;
614     }
615     CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
616     if (m_FontFileMap.Lookup(pFontStream, ftData)) {
617         ftData->m_nCount ++;
618         return ftData->m_Obj;
619     }
620     ftData = FX_NEW CPDF_CountedObject<CPDF_StreamAcc*>;
621     if (!ftData) {
622         return NULL;
623     }
624     CPDF_StreamAcc* pFontFile = FX_NEW CPDF_StreamAcc;
625     if (!pFontFile) {
626         delete ftData;
627         return NULL;
628     }
629     CPDF_Dictionary* pFontDict = pFontStream->GetDict();
630     FX_INT32 org_size = pFontDict->GetInteger(FX_BSTRC("Length1")) + pFontDict->GetInteger(FX_BSTRC("Length2")) + pFontDict->GetInteger(FX_BSTRC("Length3"));
631     if (org_size < 0) {
632         org_size = 0;
633     }
634     pFontFile->LoadAllData(pFontStream, FALSE, org_size);
635     ftData->m_nCount = 2;
636     ftData->m_Obj = pFontFile;
637     m_FontFileMap.SetAt(pFontStream, ftData);
638     return pFontFile;
639 }
640 void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce)
641 {
642     if (!pFontStream) {
643         return;
644     }
645     PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce);
646 }