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/cpdf_patterncs.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() = default;
16
CPDF_Color(const CPDF_Color & that)17 CPDF_Color::CPDF_Color(const CPDF_Color& that) {
18 *this = that;
19 }
20
21 CPDF_Color::~CPDF_Color() = default;
22
IsPattern() const23 bool CPDF_Color::IsPattern() const {
24 return m_pCS && IsPatternInternal();
25 }
26
IsPatternInternal() const27 bool CPDF_Color::IsPatternInternal() const {
28 return m_pCS->GetFamily() == PDFCS_PATTERN;
29 }
30
SetColorSpace(const RetainPtr<CPDF_ColorSpace> & pCS)31 void CPDF_Color::SetColorSpace(const RetainPtr<CPDF_ColorSpace>& pCS) {
32 m_pCS = pCS;
33 if (IsPatternInternal()) {
34 m_Buffer.clear();
35 m_pValue = pdfium::MakeUnique<PatternValue>();
36 } else {
37 m_Buffer = pCS->CreateBufAndSetDefaultColor();
38 m_pValue.reset();
39 }
40 }
41
SetValueForNonPattern(const std::vector<float> & values)42 void CPDF_Color::SetValueForNonPattern(const std::vector<float>& values) {
43 ASSERT(!IsPatternInternal());
44 ASSERT(m_pCS->CountComponents() <= values.size());
45 m_Buffer = values;
46 }
47
SetValueForPattern(const RetainPtr<CPDF_Pattern> & pPattern,const std::vector<float> & values)48 void CPDF_Color::SetValueForPattern(const RetainPtr<CPDF_Pattern>& pPattern,
49 const std::vector<float>& values) {
50 if (values.size() > kMaxPatternColorComps)
51 return;
52
53 if (!IsPattern())
54 SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN));
55
56 m_pValue->SetPattern(pPattern);
57 m_pValue->SetComps(values);
58 }
59
operator =(const CPDF_Color & that)60 CPDF_Color& CPDF_Color::operator=(const CPDF_Color& that) {
61 if (this == &that)
62 return *this;
63
64 m_Buffer = that.m_Buffer;
65 m_pValue = that.m_pValue ? pdfium::MakeUnique<PatternValue>(*that.m_pValue)
66 : nullptr;
67 m_pCS = that.m_pCS;
68 return *this;
69 }
70
CountComponents() const71 uint32_t CPDF_Color::CountComponents() const {
72 return m_pCS->CountComponents();
73 }
74
IsColorSpaceRGB() const75 bool CPDF_Color::IsColorSpaceRGB() const {
76 return m_pCS == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
77 }
78
GetRGB(int * R,int * G,int * B) const79 bool CPDF_Color::GetRGB(int* R, int* G, int* B) const {
80 float r = 0.0f;
81 float g = 0.0f;
82 float b = 0.0f;
83 bool result = false;
84 if (IsPatternInternal()) {
85 if (m_pValue) {
86 const CPDF_PatternCS* pPatternCS = m_pCS->AsPatternCS();
87 result = pPatternCS->GetPatternRGB(*m_pValue, &r, &g, &b);
88 }
89 } else {
90 if (!m_Buffer.empty())
91 result = m_pCS->GetRGB(m_Buffer.data(), &r, &g, &b);
92 }
93 if (!result)
94 return false;
95
96 *R = static_cast<int32_t>(r * 255 + 0.5f);
97 *G = static_cast<int32_t>(g * 255 + 0.5f);
98 *B = static_cast<int32_t>(b * 255 + 0.5f);
99 return true;
100 }
101
GetPattern() const102 CPDF_Pattern* CPDF_Color::GetPattern() const {
103 ASSERT(IsPattern());
104 return m_pValue ? m_pValue->GetPattern() : nullptr;
105 }
106