| // Copyright 2014 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #include "../../../include/fpdfapi/fpdf_page.h" | |
| #include "../../../include/fpdfapi/fpdf_module.h" | |
| #include "../../../include/fdrm/fx_crypt.h" | |
| #include "../fpdf_font/font_int.h" | |
| #include "pageint.h" | |
| class CPDF_PageModule : public CPDF_PageModuleDef | |
| { | |
| public: | |
| CPDF_PageModule() : m_StockGrayCS(PDFCS_DEVICEGRAY), m_StockRGBCS(PDFCS_DEVICERGB), | |
| m_StockCMYKCS(PDFCS_DEVICECMYK) {} | |
| virtual ~CPDF_PageModule() {} | |
| virtual FX_BOOL Installed() | |
| { | |
| return TRUE; | |
| } | |
| virtual CPDF_DocPageData* CreateDocData(CPDF_Document* pDoc) | |
| { | |
| return FX_NEW CPDF_DocPageData(pDoc); | |
| } | |
| virtual void ReleaseDoc(CPDF_Document* pDoc); | |
| virtual void ClearDoc(CPDF_Document* pDoc); | |
| virtual CPDF_FontGlobals* GetFontGlobals() | |
| { | |
| return &m_FontGlobals; | |
| } | |
| virtual void ClearStockFont(CPDF_Document* pDoc) | |
| { | |
| m_FontGlobals.Clear(pDoc); | |
| } | |
| virtual CPDF_ColorSpace* GetStockCS(int family); | |
| virtual void NotifyCJKAvailable(); | |
| CPDF_FontGlobals m_FontGlobals; | |
| CPDF_DeviceCS m_StockGrayCS; | |
| CPDF_DeviceCS m_StockRGBCS; | |
| CPDF_DeviceCS m_StockCMYKCS; | |
| CPDF_PatternCS m_StockPatternCS; | |
| }; | |
| CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family) | |
| { | |
| if (family == PDFCS_DEVICEGRAY) { | |
| return &m_StockGrayCS; | |
| } | |
| if (family == PDFCS_DEVICERGB) { | |
| return &m_StockRGBCS; | |
| } | |
| if (family == PDFCS_DEVICECMYK) { | |
| return &m_StockCMYKCS; | |
| } | |
| if (family == PDFCS_PATTERN) { | |
| return &m_StockPatternCS; | |
| } | |
| return NULL; | |
| } | |
| void CPDF_ModuleMgr::InitPageModule() | |
| { | |
| if (m_pPageModule) { | |
| delete m_pPageModule; | |
| } | |
| CPDF_PageModule* pPageModule = FX_NEW CPDF_PageModule; | |
| m_pPageModule = pPageModule; | |
| } | |
| void CPDF_PageModule::ReleaseDoc(CPDF_Document* pDoc) | |
| { | |
| delete pDoc->GetPageData(); | |
| } | |
| void CPDF_PageModule::ClearDoc(CPDF_Document* pDoc) | |
| { | |
| pDoc->GetPageData()->Clear(FALSE); | |
| } | |
| void CPDF_PageModule::NotifyCJKAvailable() | |
| { | |
| m_FontGlobals.m_CMapManager.ReloadAll(); | |
| } | |
| CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) | |
| { | |
| if (!pFontDict) { | |
| return NULL; | |
| } | |
| return GetValidatePageData()->GetFont(pFontDict, FALSE); | |
| } | |
| CPDF_Font* CPDF_Document::FindFont(CPDF_Dictionary* pFontDict) | |
| { | |
| if (!pFontDict) { | |
| return NULL; | |
| } | |
| return GetValidatePageData()->GetFont(pFontDict, TRUE); | |
| } | |
| CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) | |
| { | |
| if (pStream == NULL) { | |
| return NULL; | |
| } | |
| return GetValidatePageData()->GetFontFileStreamAcc(pStream); | |
| } | |
| CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name); | |
| CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) | |
| { | |
| return GetValidatePageData()->GetColorSpace(pCSObj, pResources); | |
| } | |
| CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) | |
| { | |
| return GetValidatePageData()->GetPattern(pPatternObj, bShading, matrix); | |
| } | |
| CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents) | |
| { | |
| return GetValidatePageData()->GetIccProfile(pStream, nComponents); | |
| } | |
| CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) | |
| { | |
| if (!pObj) { | |
| return NULL; | |
| } | |
| FXSYS_assert(pObj->GetObjNum()); | |
| return GetValidatePageData()->GetImage(pObj); | |
| } | |
| void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj) | |
| { | |
| if (!pCSObj) { | |
| return; | |
| } | |
| GetPageData()->ReleaseColorSpace(pCSObj); | |
| } | |
| CPDF_DocPageData::CPDF_DocPageData(CPDF_Document *pPDFDoc) | |
| : m_pPDFDoc(pPDFDoc) | |
| , m_FontMap() | |
| , m_ColorSpaceMap() | |
| , m_PatternMap() | |
| , m_ImageMap() | |
| , m_IccProfileMap() | |
| , m_FontFileMap() | |
| { | |
| m_FontMap.InitHashTable(64); | |
| m_ColorSpaceMap.InitHashTable(32); | |
| m_PatternMap.InitHashTable(16); | |
| m_ImageMap.InitHashTable(64); | |
| m_IccProfileMap.InitHashTable(16); | |
| m_FontFileMap.InitHashTable(32); | |
| } | |
| CPDF_DocPageData::~CPDF_DocPageData() | |
| { | |
| Clear(FALSE); | |
| Clear(TRUE); | |
| FX_POSITION pos = NULL; | |
| } | |
| void CPDF_DocPageData::Clear(FX_BOOL bRelease) | |
| { | |
| FX_POSITION pos; | |
| FX_DWORD nCount; | |
| { | |
| pos = m_PatternMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Object* ptObj; | |
| CPDF_CountedObject<CPDF_Pattern*>* ptData; | |
| m_PatternMap.GetNextAssoc(pos, ptObj, ptData); | |
| nCount = ptData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| delete ptData->m_Obj; | |
| ptData->m_Obj = NULL; | |
| } | |
| } | |
| } | |
| { | |
| pos = m_FontMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Dictionary* fontDict; | |
| CPDF_CountedObject<CPDF_Font*>* fontData; | |
| m_FontMap.GetNextAssoc(pos, fontDict, fontData); | |
| nCount = fontData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| delete fontData->m_Obj; | |
| fontData->m_Obj = NULL; | |
| } | |
| } | |
| } | |
| { | |
| pos = m_ImageMap.GetStartPosition(); | |
| while (pos) { | |
| FX_DWORD objNum; | |
| CPDF_CountedObject<CPDF_Image*>* imageData; | |
| m_ImageMap.GetNextAssoc(pos, objNum, imageData); | |
| nCount = imageData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| delete imageData->m_Obj; | |
| delete imageData; | |
| m_ImageMap.RemoveKey(objNum); | |
| } | |
| } | |
| } | |
| { | |
| pos = m_ColorSpaceMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Object* csKey; | |
| CPDF_CountedObject<CPDF_ColorSpace*>* csData; | |
| m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData); | |
| nCount = csData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| csData->m_Obj->ReleaseCS(); | |
| csData->m_Obj = NULL; | |
| } | |
| } | |
| } | |
| { | |
| pos = m_IccProfileMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Stream* ipKey; | |
| CPDF_CountedObject<CPDF_IccProfile*>* ipData; | |
| m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData); | |
| nCount = ipData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| FX_POSITION pos2 = m_HashProfileMap.GetStartPosition(); | |
| while (pos2) { | |
| CFX_ByteString bsKey; | |
| CPDF_Stream* pFindStream = NULL; | |
| m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream); | |
| if (ipKey == pFindStream) { | |
| m_HashProfileMap.RemoveKey(bsKey); | |
| break; | |
| } | |
| } | |
| delete ipData->m_Obj; | |
| delete ipData; | |
| m_IccProfileMap.RemoveKey(ipKey); | |
| } | |
| } | |
| } | |
| { | |
| pos = m_FontFileMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Stream* ftKey; | |
| CPDF_CountedObject<CPDF_StreamAcc*>* ftData; | |
| m_FontFileMap.GetNextAssoc(pos, ftKey, ftData); | |
| nCount = ftData->m_nCount; | |
| if (bRelease || nCount < 2) { | |
| delete ftData->m_Obj; | |
| delete ftData; | |
| m_FontFileMap.RemoveKey(ftKey); | |
| } | |
| } | |
| } | |
| } | |
| CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly) | |
| { | |
| if (!pFontDict) { | |
| return NULL; | |
| } | |
| if (findOnly) { | |
| CPDF_CountedObject<CPDF_Font*>* fontData; | |
| if (m_FontMap.Lookup(pFontDict, fontData)) { | |
| if (!fontData->m_Obj) { | |
| return NULL; | |
| } | |
| fontData->m_nCount ++; | |
| return fontData->m_Obj; | |
| } | |
| return NULL; | |
| } | |
| CPDF_CountedObject<CPDF_Font*>* fontData = NULL; | |
| if (m_FontMap.Lookup(pFontDict, fontData)) { | |
| if (fontData->m_Obj) { | |
| fontData->m_nCount ++; | |
| return fontData->m_Obj; | |
| } | |
| } | |
| FX_BOOL bNew = FALSE; | |
| if (!fontData) { | |
| fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; | |
| bNew = TRUE; | |
| if (!fontData) { | |
| return NULL; | |
| } | |
| } | |
| CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pFontDict); | |
| if (!pFont) { | |
| if (bNew) { | |
| delete fontData; | |
| } | |
| return NULL; | |
| } | |
| fontData->m_nCount = 2; | |
| fontData->m_Obj = pFont; | |
| m_FontMap.SetAt(pFontDict, fontData); | |
| return pFont; | |
| } | |
| CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding) | |
| { | |
| if (fontName.IsEmpty()) { | |
| return NULL; | |
| } | |
| FX_POSITION pos = m_FontMap.GetStartPosition(); | |
| while (pos) { | |
| CPDF_Dictionary* fontDict; | |
| CPDF_CountedObject<CPDF_Font*>* fontData; | |
| m_FontMap.GetNextAssoc(pos, fontDict, fontData); | |
| CPDF_Font* pFont = fontData->m_Obj; | |
| if (!pFont) { | |
| continue; | |
| } | |
| if (pFont->GetBaseFont() != fontName) { | |
| continue; | |
| } | |
| if (pFont->IsEmbedded()) { | |
| continue; | |
| } | |
| if (pFont->GetFontType() != PDFFONT_TYPE1) { | |
| continue; | |
| } | |
| if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) { | |
| continue; | |
| } | |
| CPDF_Type1Font* pT1Font = pFont->GetType1Font(); | |
| if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) { | |
| continue; | |
| } | |
| fontData->m_nCount ++; | |
| return pFont; | |
| } | |
| CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; | |
| pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); | |
| pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); | |
| pDict->SetAtName(FX_BSTRC("BaseFont"), fontName); | |
| if (pEncoding) { | |
| pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize()); | |
| } | |
| m_pPDFDoc->AddIndirectObject(pDict); | |
| CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; | |
| if (!fontData) { | |
| return NULL; | |
| } | |
| CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict); | |
| if (!pFont) { | |
| delete fontData; | |
| return NULL; | |
| } | |
| fontData->m_nCount = 2; | |
| fontData->m_Obj = pFont; | |
| m_FontMap.SetAt(pDict, fontData); | |
| return pFont; | |
| } | |
| void CPDF_DocPageData::ReleaseFont(CPDF_Dictionary* pFontDict) | |
| { | |
| if (!pFontDict) { | |
| return; | |
| } | |
| CPDF_CountedObject<CPDF_Font*>* fontData; | |
| if (!m_FontMap.Lookup(pFontDict, fontData)) { | |
| return; | |
| } | |
| if (fontData->m_Obj && --fontData->m_nCount == 0) { | |
| delete fontData->m_Obj; | |
| fontData->m_Obj = NULL; | |
| } | |
| } | |
| CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) | |
| { | |
| if (!pCSObj) { | |
| return NULL; | |
| } | |
| if (pCSObj->GetType() == PDFOBJ_NAME) { | |
| CFX_ByteString name = pCSObj->GetConstString(); | |
| CPDF_ColorSpace* pCS = _CSFromName(name); | |
| if (!pCS && pResources) { | |
| CPDF_Dictionary* pList = pResources->GetDict(FX_BSTRC("ColorSpace")); | |
| if (pList) { | |
| pCSObj = pList->GetElementValue(name); | |
| return GetColorSpace(pCSObj, NULL); | |
| } | |
| } | |
| if (pCS == NULL || pResources == NULL) { | |
| return pCS; | |
| } | |
| CPDF_Dictionary* pColorSpaces = pResources->GetDict(FX_BSTRC("ColorSpace")); | |
| if (pColorSpaces == NULL) { | |
| return pCS; | |
| } | |
| CPDF_Object* pDefaultCS = NULL; | |
| switch (pCS->GetFamily()) { | |
| case PDFCS_DEVICERGB: | |
| pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultRGB")); | |
| break; | |
| case PDFCS_DEVICEGRAY: | |
| pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultGray")); | |
| break; | |
| case PDFCS_DEVICECMYK: | |
| pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultCMYK")); | |
| break; | |
| } | |
| if (pDefaultCS == NULL) { | |
| return pCS; | |
| } | |
| return GetColorSpace(pDefaultCS, NULL); | |
| } | |
| if (pCSObj->GetType() != PDFOBJ_ARRAY) { | |
| return NULL; | |
| } | |
| CPDF_Array* pArray = (CPDF_Array*)pCSObj; | |
| if (pArray->GetCount() == 0) { | |
| return NULL; | |
| } | |
| if (pArray->GetCount() == 1) { | |
| return GetColorSpace(pArray->GetElementValue(0), pResources); | |
| } | |
| CPDF_CountedObject<CPDF_ColorSpace*>* csData = NULL; | |
| if (m_ColorSpaceMap.Lookup(pCSObj, csData)) { | |
| if (csData->m_Obj) { | |
| csData->m_nCount++; | |
| return csData->m_Obj; | |
| } | |
| } | |
| FX_BOOL bNew = FALSE; | |
| if (!csData) { | |
| csData = FX_NEW CPDF_CountedObject<CPDF_ColorSpace*>; | |
| if (!csData) { | |
| return NULL; | |
| } | |
| bNew = TRUE; | |
| } | |
| CPDF_ColorSpace* pCS = CPDF_ColorSpace::Load(m_pPDFDoc, pArray); | |
| if (!pCS) { | |
| if (bNew) { | |
| delete csData; | |
| } | |
| return NULL; | |
| } | |
| csData->m_nCount = 2; | |
| csData->m_Obj = pCS; | |
| m_ColorSpaceMap.SetAt(pCSObj, csData); | |
| return pCS; | |
| } | |
| CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) | |
| { | |
| if (!pCSObj) { | |
| return NULL; | |
| } | |
| CPDF_CountedObject<CPDF_ColorSpace*>* csData; | |
| if (!m_ColorSpaceMap.Lookup(pCSObj, csData)) { | |
| return NULL; | |
| } | |
| if (!csData->m_Obj) { | |
| return NULL; | |
| } | |
| csData->m_nCount ++; | |
| return csData->m_Obj; | |
| } | |
| void CPDF_DocPageData::ReleaseColorSpace(CPDF_Object* pColorSpace) | |
| { | |
| if (!pColorSpace) { | |
| return; | |
| } | |
| CPDF_CountedObject<CPDF_ColorSpace*>* csData; | |
| if (!m_ColorSpaceMap.Lookup(pColorSpace, csData)) { | |
| return; | |
| } | |
| if (csData->m_Obj && --csData->m_nCount == 0) { | |
| csData->m_Obj->ReleaseCS(); | |
| csData->m_Obj = NULL; | |
| } | |
| } | |
| CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) | |
| { | |
| if (!pPatternObj) { | |
| return NULL; | |
| } | |
| CPDF_CountedObject<CPDF_Pattern*>* ptData = NULL; | |
| if (m_PatternMap.Lookup(pPatternObj, ptData)) { | |
| if (ptData->m_Obj) { | |
| ptData->m_nCount++; | |
| return ptData->m_Obj; | |
| } | |
| } | |
| FX_BOOL bNew = FALSE; | |
| if (!ptData) { | |
| ptData = FX_NEW CPDF_CountedObject<CPDF_Pattern*>; | |
| bNew = TRUE; | |
| if (!ptData) { | |
| return NULL; | |
| } | |
| } | |
| CPDF_Pattern* pPattern = NULL; | |
| if (bShading) { | |
| pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, bShading, matrix); | |
| } else { | |
| CPDF_Dictionary* pDict = pPatternObj->GetDict(); | |
| if (pDict) { | |
| int type = pDict->GetInteger(FX_BSTRC("PatternType")); | |
| if (type == 1) { | |
| pPattern = FX_NEW CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); | |
| } else if (type == 2) { | |
| pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); | |
| } | |
| } | |
| } | |
| if (!pPattern) { | |
| if (bNew) { | |
| delete ptData; | |
| } | |
| return NULL; | |
| } | |
| ptData->m_nCount = 2; | |
| ptData->m_Obj = pPattern; | |
| m_PatternMap.SetAt(pPatternObj, ptData); | |
| return pPattern; | |
| } | |
| void CPDF_DocPageData::ReleasePattern(CPDF_Object* pPatternObj) | |
| { | |
| if (!pPatternObj) { | |
| return; | |
| } | |
| CPDF_CountedObject<CPDF_Pattern*>* ptData; | |
| if (!m_PatternMap.Lookup(pPatternObj, ptData)) { | |
| return; | |
| } | |
| if (ptData->m_Obj && --ptData->m_nCount == 0) { | |
| delete ptData->m_Obj; | |
| ptData->m_Obj = NULL; | |
| } | |
| } | |
| CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) | |
| { | |
| if (!pImageStream) { | |
| return NULL; | |
| } | |
| FX_DWORD dwImageObjNum = pImageStream->GetObjNum(); | |
| CPDF_CountedObject<CPDF_Image*>* imageData; | |
| if (m_ImageMap.Lookup(dwImageObjNum, imageData)) { | |
| imageData->m_nCount ++; | |
| return imageData->m_Obj; | |
| } | |
| imageData = FX_NEW CPDF_CountedObject<CPDF_Image*>; | |
| if (!imageData) { | |
| return NULL; | |
| } | |
| CPDF_Image* pImage = FX_NEW CPDF_Image(m_pPDFDoc); | |
| if (!pImage) { | |
| delete imageData; | |
| return NULL; | |
| } | |
| pImage->LoadImageF((CPDF_Stream*)pImageStream, FALSE); | |
| imageData->m_nCount = 2; | |
| imageData->m_Obj = pImage; | |
| m_ImageMap.SetAt(dwImageObjNum, imageData); | |
| return pImage; | |
| } | |
| void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream) | |
| { | |
| if (!pImageStream) { | |
| return; | |
| } | |
| PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL); | |
| } | |
| CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents) | |
| { | |
| if (!pIccProfileStream) { | |
| return NULL; | |
| } | |
| CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; | |
| if (m_IccProfileMap.Lookup(pIccProfileStream, ipData)) { | |
| ipData->m_nCount++; | |
| return ipData->m_Obj; | |
| } | |
| CPDF_StreamAcc stream; | |
| stream.LoadAllData(pIccProfileStream, FALSE); | |
| FX_BYTE digest[20]; | |
| CPDF_Stream* pCopiedStream = NULL; | |
| CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); | |
| if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20), (void*&)pCopiedStream)) { | |
| m_IccProfileMap.Lookup(pCopiedStream, ipData); | |
| ipData->m_nCount++; | |
| return ipData->m_Obj; | |
| } | |
| CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents); | |
| if (!pProfile) { | |
| return NULL; | |
| } | |
| ipData = FX_NEW CPDF_CountedObject<CPDF_IccProfile*>; | |
| if (!ipData) { | |
| delete pProfile; | |
| return NULL; | |
| } | |
| ipData->m_nCount = 2; | |
| ipData->m_Obj = pProfile; | |
| m_IccProfileMap.SetAt(pIccProfileStream, ipData); | |
| m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream); | |
| return pProfile; | |
| } | |
| void CPDF_DocPageData::ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile) | |
| { | |
| if (!pIccProfileStream && !pIccProfile) { | |
| return; | |
| } | |
| CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; | |
| if (m_IccProfileMap.Lookup(pIccProfileStream, ipData) && ipData->m_nCount < 2) { | |
| FX_POSITION pos = m_HashProfileMap.GetStartPosition(); | |
| while (pos) { | |
| CFX_ByteString key; | |
| CPDF_Stream* pFindStream = NULL; | |
| m_HashProfileMap.GetNextAssoc(pos, key, (void*&)pFindStream); | |
| if (pIccProfileStream == pFindStream) { | |
| m_HashProfileMap.RemoveKey(key); | |
| break; | |
| } | |
| } | |
| } | |
| PDF_DocPageData_Release<CPDF_Stream*, CPDF_IccProfile*>(m_IccProfileMap, pIccProfileStream, pIccProfile); | |
| } | |
| CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(CPDF_Stream* pFontStream) | |
| { | |
| if (!pFontStream) { | |
| return NULL; | |
| } | |
| CPDF_CountedObject<CPDF_StreamAcc*>* ftData; | |
| if (m_FontFileMap.Lookup(pFontStream, ftData)) { | |
| ftData->m_nCount ++; | |
| return ftData->m_Obj; | |
| } | |
| ftData = FX_NEW CPDF_CountedObject<CPDF_StreamAcc*>; | |
| if (!ftData) { | |
| return NULL; | |
| } | |
| CPDF_StreamAcc* pFontFile = FX_NEW CPDF_StreamAcc; | |
| if (!pFontFile) { | |
| delete ftData; | |
| return NULL; | |
| } | |
| CPDF_Dictionary* pFontDict = pFontStream->GetDict(); | |
| FX_INT32 org_size = pFontDict->GetInteger(FX_BSTRC("Length1")) + pFontDict->GetInteger(FX_BSTRC("Length2")) + pFontDict->GetInteger(FX_BSTRC("Length3")); | |
| if (org_size < 0) { | |
| org_size = 0; | |
| } | |
| pFontFile->LoadAllData(pFontStream, FALSE, org_size); | |
| ftData->m_nCount = 2; | |
| ftData->m_Obj = pFontFile; | |
| m_FontFileMap.SetAt(pFontStream, ftData); | |
| return pFontFile; | |
| } | |
| void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce) | |
| { | |
| if (!pFontStream) { | |
| return; | |
| } | |
| PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce); | |
| } |