Home | History | Annotate | Download | only in page
      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