1 // Copyright 2016 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/render/cpdf_docrenderdata.h" 8 9 #include <memory> 10 11 #include "core/fpdfapi/font/cpdf_type3font.h" 12 #include "core/fpdfapi/page/cpdf_function.h" 13 #include "core/fpdfapi/parser/cpdf_array.h" 14 #include "core/fpdfapi/parser/cpdf_document.h" 15 #include "core/fpdfapi/render/cpdf_dibsource.h" 16 #include "core/fpdfapi/render/cpdf_transferfunc.h" 17 #include "core/fpdfapi/render/cpdf_type3cache.h" 18 19 namespace { 20 21 const int kMaxOutputs = 16; 22 23 } // namespace 24 CPDF_DocRenderData(CPDF_Document * pPDFDoc)25CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc) 26 : m_pPDFDoc(pPDFDoc) {} 27 ~CPDF_DocRenderData()28CPDF_DocRenderData::~CPDF_DocRenderData() { 29 Clear(true); 30 } 31 Clear(bool bRelease)32void CPDF_DocRenderData::Clear(bool bRelease) { 33 for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) { 34 auto curr_it = it++; 35 if (bRelease || curr_it->second->HasOneRef()) { 36 m_Type3FaceMap.erase(curr_it); 37 } 38 } 39 40 for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) { 41 auto curr_it = it++; 42 if (bRelease || curr_it->second->HasOneRef()) 43 m_TransferFuncMap.erase(curr_it); 44 } 45 } 46 GetCachedType3(CPDF_Type3Font * pFont)47RetainPtr<CPDF_Type3Cache> CPDF_DocRenderData::GetCachedType3( 48 CPDF_Type3Font* pFont) { 49 auto it = m_Type3FaceMap.find(pFont); 50 if (it != m_Type3FaceMap.end()) 51 return it->second; 52 53 auto pCache = pdfium::MakeRetain<CPDF_Type3Cache>(pFont); 54 m_Type3FaceMap[pFont] = pCache; 55 return pCache; 56 } 57 MaybePurgeCachedType3(CPDF_Type3Font * pFont)58void CPDF_DocRenderData::MaybePurgeCachedType3(CPDF_Type3Font* pFont) { 59 auto it = m_Type3FaceMap.find(pFont); 60 if (it != m_Type3FaceMap.end() && it->second->HasOneRef()) 61 m_Type3FaceMap.erase(it); 62 } 63 GetTransferFunc(CPDF_Object * pObj)64RetainPtr<CPDF_TransferFunc> CPDF_DocRenderData::GetTransferFunc( 65 CPDF_Object* pObj) { 66 if (!pObj) 67 return nullptr; 68 69 auto it = m_TransferFuncMap.find(pObj); 70 if (it != m_TransferFuncMap.end()) 71 return it->second; 72 73 std::unique_ptr<CPDF_Function> pFuncs[3]; 74 bool bUniTransfer = true; 75 bool bIdentity = true; 76 if (CPDF_Array* pArray = pObj->AsArray()) { 77 bUniTransfer = false; 78 if (pArray->GetCount() < 3) 79 return nullptr; 80 81 for (uint32_t i = 0; i < 3; ++i) { 82 pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i)); 83 if (!pFuncs[2 - i]) 84 return nullptr; 85 } 86 } else { 87 pFuncs[0] = CPDF_Function::Load(pObj); 88 if (!pFuncs[0]) 89 return nullptr; 90 } 91 auto pTransfer = pdfium::MakeRetain<CPDF_TransferFunc>(m_pPDFDoc.Get()); 92 m_TransferFuncMap[pObj] = pTransfer; 93 94 float input; 95 int noutput; 96 float output[kMaxOutputs]; 97 memset(output, 0, sizeof(output)); 98 for (int v = 0; v < 256; ++v) { 99 input = (float)v / 255.0f; 100 if (bUniTransfer) { 101 if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) 102 pFuncs[0]->Call(&input, 1, output, &noutput); 103 int o = FXSYS_round(output[0] * 255); 104 if (o != v) 105 bIdentity = false; 106 for (int i = 0; i < 3; ++i) 107 pTransfer->GetSamples()[i * 256 + v] = o; 108 continue; 109 } 110 for (int i = 0; i < 3; ++i) { 111 if (!pFuncs[i] || pFuncs[i]->CountOutputs() > kMaxOutputs) { 112 pTransfer->GetSamples()[i * 256 + v] = v; 113 continue; 114 } 115 pFuncs[i]->Call(&input, 1, output, &noutput); 116 int o = FXSYS_round(output[0] * 255); 117 if (o != v) 118 bIdentity = false; 119 pTransfer->GetSamples()[i * 256 + v] = o; 120 } 121 } 122 123 pTransfer->SetIdentity(bIdentity); 124 return pTransfer; 125 } 126 MaybePurgeTransferFunc(CPDF_Object * pObj)127void CPDF_DocRenderData::MaybePurgeTransferFunc(CPDF_Object* pObj) { 128 auto it = m_TransferFuncMap.find(pObj); 129 if (it != m_TransferFuncMap.end() && it->second->HasOneRef()) 130 m_TransferFuncMap.erase(it); 131 } 132