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_color.h" 8 9 #include "core/fpdfapi/page/cpdf_docpagedata.h" 10 #include "core/fpdfapi/page/pageint.h" 11 #include "core/fpdfapi/parser/cpdf_array.h" 12 #include "core/fpdfapi/parser/cpdf_document.h" 13 #include "core/fxcrt/fx_system.h" 14 15 CPDF_Color::CPDF_Color() : m_pCS(nullptr), m_pBuffer(nullptr) {} 16 17 CPDF_Color::~CPDF_Color() { 18 ReleaseBuffer(); 19 ReleaseColorSpace(); 20 } 21 22 bool CPDF_Color::IsPattern() const { 23 return m_pCS && m_pCS->GetFamily() == PDFCS_PATTERN; 24 } 25 26 void CPDF_Color::ReleaseBuffer() { 27 if (!m_pBuffer) 28 return; 29 30 if (m_pCS->GetFamily() == PDFCS_PATTERN) { 31 PatternValue* pvalue = (PatternValue*)m_pBuffer; 32 CPDF_Pattern* pPattern = 33 pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : nullptr; 34 if (pPattern && pPattern->document()) { 35 CPDF_DocPageData* pPageData = pPattern->document()->GetPageData(); 36 if (pPageData) 37 pPageData->ReleasePattern(pPattern->pattern_obj()); 38 } 39 } 40 FX_Free(m_pBuffer); 41 m_pBuffer = nullptr; 42 } 43 44 void CPDF_Color::ReleaseColorSpace() { 45 if (m_pCS && m_pCS->m_pDocument) { 46 m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray()); 47 m_pCS = nullptr; 48 } 49 } 50 51 void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) { 52 if (m_pCS == pCS) { 53 if (!m_pBuffer) 54 m_pBuffer = pCS->CreateBuf(); 55 56 ReleaseColorSpace(); 57 m_pCS = pCS; 58 return; 59 } 60 ReleaseBuffer(); 61 ReleaseColorSpace(); 62 63 m_pCS = pCS; 64 if (m_pCS) { 65 m_pBuffer = pCS->CreateBuf(); 66 pCS->GetDefaultColor(m_pBuffer); 67 } 68 } 69 70 void CPDF_Color::SetValue(FX_FLOAT* comps) { 71 if (!m_pBuffer) 72 return; 73 if (m_pCS->GetFamily() != PDFCS_PATTERN) 74 FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT)); 75 } 76 77 void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) { 78 if (ncomps > MAX_PATTERN_COLORCOMPS) 79 return; 80 81 if (!IsPattern()) { 82 FX_Free(m_pBuffer); 83 m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); 84 m_pBuffer = m_pCS->CreateBuf(); 85 } 86 87 CPDF_DocPageData* pDocPageData = nullptr; 88 PatternValue* pvalue = (PatternValue*)m_pBuffer; 89 if (pvalue->m_pPattern && pvalue->m_pPattern->document()) { 90 pDocPageData = pvalue->m_pPattern->document()->GetPageData(); 91 if (pDocPageData) 92 pDocPageData->ReleasePattern(pvalue->m_pPattern->pattern_obj()); 93 } 94 pvalue->m_nComps = ncomps; 95 pvalue->m_pPattern = pPattern; 96 if (ncomps) 97 FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT)); 98 99 pvalue->m_pCountedPattern = nullptr; 100 if (pPattern && pPattern->document()) { 101 if (!pDocPageData) 102 pDocPageData = pPattern->document()->GetPageData(); 103 104 pvalue->m_pCountedPattern = 105 pDocPageData->FindPatternPtr(pPattern->pattern_obj()); 106 } 107 } 108 109 void CPDF_Color::Copy(const CPDF_Color* pSrc) { 110 ReleaseBuffer(); 111 ReleaseColorSpace(); 112 113 m_pCS = pSrc->m_pCS; 114 if (m_pCS && m_pCS->m_pDocument) { 115 CPDF_Array* pArray = m_pCS->GetArray(); 116 if (pArray) 117 m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray); 118 } 119 if (!m_pCS) 120 return; 121 122 m_pBuffer = m_pCS->CreateBuf(); 123 FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize()); 124 if (m_pCS->GetFamily() != PDFCS_PATTERN) 125 return; 126 127 PatternValue* pValue = reinterpret_cast<PatternValue*>(m_pBuffer); 128 CPDF_Pattern* pPattern = pValue->m_pPattern; 129 if (pPattern && pPattern->document()) { 130 pValue->m_pPattern = pPattern->document()->GetPageData()->GetPattern( 131 pPattern->pattern_obj(), false, pPattern->parent_matrix()); 132 } 133 } 134 135 bool CPDF_Color::GetRGB(int& R, int& G, int& B) const { 136 if (!m_pCS || !m_pBuffer) 137 return false; 138 139 FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; 140 if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) 141 return false; 142 143 R = (int32_t)(r * 255 + 0.5f); 144 G = (int32_t)(g * 255 + 0.5f); 145 B = (int32_t)(b * 255 + 0.5f); 146 return true; 147 } 148 149 CPDF_Pattern* CPDF_Color::GetPattern() const { 150 if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) 151 return nullptr; 152 153 PatternValue* pvalue = (PatternValue*)m_pBuffer; 154 return pvalue->m_pPattern; 155 } 156