OLD | NEW |
(Empty) | |
| 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/pageint.h" |
| 13 #include "core/fpdfapi/parser/cpdf_array.h" |
| 14 #include "core/fpdfapi/parser/cpdf_document.h" |
| 15 #include "core/fpdfapi/render/cpdf_type3cache.h" |
| 16 #include "core/fpdfapi/render/render_int.h" |
| 17 |
| 18 namespace { |
| 19 |
| 20 const int kMaxOutputs = 16; |
| 21 |
| 22 } // namespace |
| 23 |
| 24 CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc) |
| 25 : m_pPDFDoc(pPDFDoc) {} |
| 26 |
| 27 CPDF_DocRenderData::~CPDF_DocRenderData() { |
| 28 Clear(true); |
| 29 } |
| 30 |
| 31 void CPDF_DocRenderData::Clear(bool bRelease) { |
| 32 for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) { |
| 33 auto curr_it = it++; |
| 34 CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second; |
| 35 if (bRelease || cache->use_count() < 2) { |
| 36 delete cache->get(); |
| 37 delete cache; |
| 38 m_Type3FaceMap.erase(curr_it); |
| 39 } |
| 40 } |
| 41 |
| 42 for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) { |
| 43 auto curr_it = it++; |
| 44 CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second; |
| 45 if (bRelease || value->use_count() < 2) { |
| 46 delete value->get(); |
| 47 delete value; |
| 48 m_TransferFuncMap.erase(curr_it); |
| 49 } |
| 50 } |
| 51 } |
| 52 |
| 53 CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) { |
| 54 CPDF_CountedObject<CPDF_Type3Cache>* pCache; |
| 55 auto it = m_Type3FaceMap.find(pFont); |
| 56 if (it == m_Type3FaceMap.end()) { |
| 57 CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont); |
| 58 pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3); |
| 59 m_Type3FaceMap[pFont] = pCache; |
| 60 } else { |
| 61 pCache = it->second; |
| 62 } |
| 63 return pCache->AddRef(); |
| 64 } |
| 65 |
| 66 void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) { |
| 67 auto it = m_Type3FaceMap.find(pFont); |
| 68 if (it != m_Type3FaceMap.end()) { |
| 69 it->second->RemoveRef(); |
| 70 if (it->second->use_count() < 2) { |
| 71 delete it->second->get(); |
| 72 delete it->second; |
| 73 m_Type3FaceMap.erase(it); |
| 74 } |
| 75 } |
| 76 } |
| 77 |
| 78 CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) { |
| 79 if (!pObj) |
| 80 return nullptr; |
| 81 |
| 82 auto it = m_TransferFuncMap.find(pObj); |
| 83 if (it != m_TransferFuncMap.end()) { |
| 84 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second; |
| 85 return pTransferCounter->AddRef(); |
| 86 } |
| 87 |
| 88 std::unique_ptr<CPDF_Function> pFuncs[3]; |
| 89 bool bUniTransfer = true; |
| 90 bool bIdentity = true; |
| 91 if (CPDF_Array* pArray = pObj->AsArray()) { |
| 92 bUniTransfer = false; |
| 93 if (pArray->GetCount() < 3) |
| 94 return nullptr; |
| 95 |
| 96 for (uint32_t i = 0; i < 3; ++i) { |
| 97 pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i)); |
| 98 if (!pFuncs[2 - i]) |
| 99 return nullptr; |
| 100 } |
| 101 } else { |
| 102 pFuncs[0] = CPDF_Function::Load(pObj); |
| 103 if (!pFuncs[0]) |
| 104 return nullptr; |
| 105 } |
| 106 CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc(m_pPDFDoc); |
| 107 CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = |
| 108 new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer); |
| 109 m_TransferFuncMap[pObj] = pTransferCounter; |
| 110 FX_FLOAT output[kMaxOutputs]; |
| 111 FXSYS_memset(output, 0, sizeof(output)); |
| 112 FX_FLOAT input; |
| 113 int noutput; |
| 114 for (int v = 0; v < 256; ++v) { |
| 115 input = (FX_FLOAT)v / 255.0f; |
| 116 if (bUniTransfer) { |
| 117 if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) |
| 118 pFuncs[0]->Call(&input, 1, output, noutput); |
| 119 int o = FXSYS_round(output[0] * 255); |
| 120 if (o != v) |
| 121 bIdentity = false; |
| 122 for (int i = 0; i < 3; ++i) |
| 123 pTransfer->m_Samples[i * 256 + v] = o; |
| 124 continue; |
| 125 } |
| 126 for (int i = 0; i < 3; ++i) { |
| 127 if (!pFuncs[i] || pFuncs[i]->CountOutputs() > kMaxOutputs) { |
| 128 pTransfer->m_Samples[i * 256 + v] = v; |
| 129 continue; |
| 130 } |
| 131 pFuncs[i]->Call(&input, 1, output, noutput); |
| 132 int o = FXSYS_round(output[0] * 255); |
| 133 if (o != v) |
| 134 bIdentity = false; |
| 135 pTransfer->m_Samples[i * 256 + v] = o; |
| 136 } |
| 137 } |
| 138 |
| 139 pTransfer->m_bIdentity = bIdentity; |
| 140 return pTransferCounter->AddRef(); |
| 141 } |
| 142 |
| 143 void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) { |
| 144 auto it = m_TransferFuncMap.find(pObj); |
| 145 if (it != m_TransferFuncMap.end()) { |
| 146 it->second->RemoveRef(); |
| 147 if (it->second->use_count() < 2) { |
| 148 delete it->second->get(); |
| 149 delete it->second; |
| 150 m_TransferFuncMap.erase(it); |
| 151 } |
| 152 } |
| 153 } |
OLD | NEW |