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/page/cpdf_shadingpattern.h" 8 9 #include <algorithm> 10 11 #include "core/fpdfapi/page/cpdf_docpagedata.h" 12 #include "core/fpdfapi/page/pageint.h" 13 #include "core/fpdfapi/parser/cpdf_array.h" 14 #include "core/fpdfapi/parser/cpdf_dictionary.h" 15 #include "core/fpdfapi/parser/cpdf_document.h" 16 #include "core/fpdfapi/parser/cpdf_object.h" 17 #include "core/fpdfapi/parser/cpdf_stream.h" 18 19 namespace { 20 21 ShadingType ToShadingType(int type) { 22 return (type > static_cast<int>(kInvalidShading) && 23 type < static_cast<int>(kMaxShading)) 24 ? static_cast<ShadingType>(type) 25 : kInvalidShading; 26 } 27 28 } // namespace 29 30 CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, 31 CPDF_Object* pPatternObj, 32 bool bShading, 33 const CFX_Matrix& parentMatrix) 34 : CPDF_Pattern(SHADING, 35 pDoc, 36 bShading ? nullptr : pPatternObj, 37 parentMatrix), 38 m_ShadingType(kInvalidShading), 39 m_bShadingObj(bShading), 40 m_pShadingObj(pPatternObj), 41 m_pCS(nullptr), 42 m_pCountedCS(nullptr) { 43 if (!bShading) { 44 CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); 45 m_Pattern2Form = pDict->GetMatrixFor("Matrix"); 46 m_pShadingObj = pDict->GetDirectObjectFor("Shading"); 47 m_Pattern2Form.Concat(parentMatrix); 48 } 49 } 50 51 CPDF_ShadingPattern::~CPDF_ShadingPattern() { 52 CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : nullptr; 53 if (pCS && m_pDocument) 54 m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); 55 } 56 57 CPDF_TilingPattern* CPDF_ShadingPattern::AsTilingPattern() { 58 return nullptr; 59 } 60 61 CPDF_ShadingPattern* CPDF_ShadingPattern::AsShadingPattern() { 62 return this; 63 } 64 65 bool CPDF_ShadingPattern::Load() { 66 if (m_ShadingType != kInvalidShading) 67 return true; 68 69 CPDF_Dictionary* pShadingDict = 70 m_pShadingObj ? m_pShadingObj->GetDict() : nullptr; 71 if (!pShadingDict) 72 return false; 73 74 m_pFunctions.clear(); 75 CPDF_Object* pFunc = pShadingDict->GetDirectObjectFor("Function"); 76 if (pFunc) { 77 if (CPDF_Array* pArray = pFunc->AsArray()) { 78 m_pFunctions.resize(std::min<size_t>(pArray->GetCount(), 4)); 79 for (size_t i = 0; i < m_pFunctions.size(); ++i) 80 m_pFunctions[i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i)); 81 } else { 82 m_pFunctions.push_back(CPDF_Function::Load(pFunc)); 83 } 84 } 85 CPDF_Object* pCSObj = pShadingDict->GetDirectObjectFor("ColorSpace"); 86 if (!pCSObj) 87 return false; 88 89 CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); 90 m_pCS = pDocPageData->GetColorSpace(pCSObj, nullptr); 91 if (m_pCS) 92 m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray()); 93 94 m_ShadingType = ToShadingType(pShadingDict->GetIntegerFor("ShadingType")); 95 96 // We expect to have a stream if our shading type is a mesh. 97 if (IsMeshShading() && !ToStream(m_pShadingObj)) 98 return false; 99 100 return true; 101 } 102