| Index: core/fpdfapi/render/cpdf_docrenderdata.cpp
|
| diff --git a/core/fpdfapi/render/cpdf_docrenderdata.cpp b/core/fpdfapi/render/cpdf_docrenderdata.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9a1691711b41aed9f568d66583ea25d4c166d054
|
| --- /dev/null
|
| +++ b/core/fpdfapi/render/cpdf_docrenderdata.cpp
|
| @@ -0,0 +1,153 @@
|
| +// Copyright 2016 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 "core/fpdfapi/render/cpdf_docrenderdata.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "core/fpdfapi/font/cpdf_type3font.h"
|
| +#include "core/fpdfapi/page/pageint.h"
|
| +#include "core/fpdfapi/parser/cpdf_array.h"
|
| +#include "core/fpdfapi/parser/cpdf_document.h"
|
| +#include "core/fpdfapi/render/cpdf_type3cache.h"
|
| +#include "core/fpdfapi/render/render_int.h"
|
| +
|
| +namespace {
|
| +
|
| +const int kMaxOutputs = 16;
|
| +
|
| +} // namespace
|
| +
|
| +CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc)
|
| + : m_pPDFDoc(pPDFDoc) {}
|
| +
|
| +CPDF_DocRenderData::~CPDF_DocRenderData() {
|
| + Clear(true);
|
| +}
|
| +
|
| +void CPDF_DocRenderData::Clear(bool bRelease) {
|
| + for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) {
|
| + auto curr_it = it++;
|
| + CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second;
|
| + if (bRelease || cache->use_count() < 2) {
|
| + delete cache->get();
|
| + delete cache;
|
| + m_Type3FaceMap.erase(curr_it);
|
| + }
|
| + }
|
| +
|
| + for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) {
|
| + auto curr_it = it++;
|
| + CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second;
|
| + if (bRelease || value->use_count() < 2) {
|
| + delete value->get();
|
| + delete value;
|
| + m_TransferFuncMap.erase(curr_it);
|
| + }
|
| + }
|
| +}
|
| +
|
| +CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) {
|
| + CPDF_CountedObject<CPDF_Type3Cache>* pCache;
|
| + auto it = m_Type3FaceMap.find(pFont);
|
| + if (it == m_Type3FaceMap.end()) {
|
| + CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont);
|
| + pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3);
|
| + m_Type3FaceMap[pFont] = pCache;
|
| + } else {
|
| + pCache = it->second;
|
| + }
|
| + return pCache->AddRef();
|
| +}
|
| +
|
| +void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) {
|
| + auto it = m_Type3FaceMap.find(pFont);
|
| + if (it != m_Type3FaceMap.end()) {
|
| + it->second->RemoveRef();
|
| + if (it->second->use_count() < 2) {
|
| + delete it->second->get();
|
| + delete it->second;
|
| + m_Type3FaceMap.erase(it);
|
| + }
|
| + }
|
| +}
|
| +
|
| +CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) {
|
| + if (!pObj)
|
| + return nullptr;
|
| +
|
| + auto it = m_TransferFuncMap.find(pObj);
|
| + if (it != m_TransferFuncMap.end()) {
|
| + CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second;
|
| + return pTransferCounter->AddRef();
|
| + }
|
| +
|
| + std::unique_ptr<CPDF_Function> pFuncs[3];
|
| + bool bUniTransfer = true;
|
| + bool bIdentity = true;
|
| + if (CPDF_Array* pArray = pObj->AsArray()) {
|
| + bUniTransfer = false;
|
| + if (pArray->GetCount() < 3)
|
| + return nullptr;
|
| +
|
| + for (uint32_t i = 0; i < 3; ++i) {
|
| + pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i));
|
| + if (!pFuncs[2 - i])
|
| + return nullptr;
|
| + }
|
| + } else {
|
| + pFuncs[0] = CPDF_Function::Load(pObj);
|
| + if (!pFuncs[0])
|
| + return nullptr;
|
| + }
|
| + CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc(m_pPDFDoc);
|
| + CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter =
|
| + new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer);
|
| + m_TransferFuncMap[pObj] = pTransferCounter;
|
| + FX_FLOAT output[kMaxOutputs];
|
| + FXSYS_memset(output, 0, sizeof(output));
|
| + FX_FLOAT input;
|
| + int noutput;
|
| + for (int v = 0; v < 256; ++v) {
|
| + input = (FX_FLOAT)v / 255.0f;
|
| + if (bUniTransfer) {
|
| + if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs)
|
| + pFuncs[0]->Call(&input, 1, output, noutput);
|
| + int o = FXSYS_round(output[0] * 255);
|
| + if (o != v)
|
| + bIdentity = false;
|
| + for (int i = 0; i < 3; ++i)
|
| + pTransfer->m_Samples[i * 256 + v] = o;
|
| + continue;
|
| + }
|
| + for (int i = 0; i < 3; ++i) {
|
| + if (!pFuncs[i] || pFuncs[i]->CountOutputs() > kMaxOutputs) {
|
| + pTransfer->m_Samples[i * 256 + v] = v;
|
| + continue;
|
| + }
|
| + pFuncs[i]->Call(&input, 1, output, noutput);
|
| + int o = FXSYS_round(output[0] * 255);
|
| + if (o != v)
|
| + bIdentity = false;
|
| + pTransfer->m_Samples[i * 256 + v] = o;
|
| + }
|
| + }
|
| +
|
| + pTransfer->m_bIdentity = bIdentity;
|
| + return pTransferCounter->AddRef();
|
| +}
|
| +
|
| +void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) {
|
| + auto it = m_TransferFuncMap.find(pObj);
|
| + if (it != m_TransferFuncMap.end()) {
|
| + it->second->RemoveRef();
|
| + if (it->second->use_count() < 2) {
|
| + delete it->second->get();
|
| + delete it->second;
|
| + m_TransferFuncMap.erase(it);
|
| + }
|
| + }
|
| +}
|
|
|