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_colorstate.h"
8
9 #include "core/fpdfapi/page/cpdf_colorspace.h"
10 #include "core/fpdfapi/page/cpdf_pattern.h"
11 #include "core/fpdfapi/page/cpdf_tilingpattern.h"
12 #include "core/fxge/fx_dib.h"
13
CPDF_ColorState()14 CPDF_ColorState::CPDF_ColorState() {}
15
CPDF_ColorState(const CPDF_ColorState & that)16 CPDF_ColorState::CPDF_ColorState(const CPDF_ColorState& that)
17 : m_Ref(that.m_Ref) {}
18
~CPDF_ColorState()19 CPDF_ColorState::~CPDF_ColorState() {}
20
Emplace()21 void CPDF_ColorState::Emplace() {
22 m_Ref.Emplace();
23 }
24
SetDefault()25 void CPDF_ColorState::SetDefault() {
26 m_Ref.GetPrivateCopy()->SetDefault();
27 }
28
GetFillColorRef() const29 FX_COLORREF CPDF_ColorState::GetFillColorRef() const {
30 return m_Ref.GetObject()->m_FillColorRef;
31 }
32
SetFillColorRef(FX_COLORREF colorref)33 void CPDF_ColorState::SetFillColorRef(FX_COLORREF colorref) {
34 m_Ref.GetPrivateCopy()->m_FillColorRef = colorref;
35 }
36
GetStrokeColorRef() const37 FX_COLORREF CPDF_ColorState::GetStrokeColorRef() const {
38 return m_Ref.GetObject()->m_StrokeColorRef;
39 }
40
SetStrokeColorRef(FX_COLORREF colorref)41 void CPDF_ColorState::SetStrokeColorRef(FX_COLORREF colorref) {
42 m_Ref.GetPrivateCopy()->m_StrokeColorRef = colorref;
43 }
44
GetFillColor() const45 const CPDF_Color* CPDF_ColorState::GetFillColor() const {
46 const ColorData* pData = m_Ref.GetObject();
47 return pData ? &pData->m_FillColor : nullptr;
48 }
49
GetMutableFillColor()50 CPDF_Color* CPDF_ColorState::GetMutableFillColor() {
51 return &m_Ref.GetPrivateCopy()->m_FillColor;
52 }
53
HasFillColor() const54 bool CPDF_ColorState::HasFillColor() const {
55 const CPDF_Color* pColor = GetFillColor();
56 return pColor && !pColor->IsNull();
57 }
58
GetStrokeColor() const59 const CPDF_Color* CPDF_ColorState::GetStrokeColor() const {
60 const ColorData* pData = m_Ref.GetObject();
61 return pData ? &pData->m_StrokeColor : nullptr;
62 }
63
GetMutableStrokeColor()64 CPDF_Color* CPDF_ColorState::GetMutableStrokeColor() {
65 return &m_Ref.GetPrivateCopy()->m_StrokeColor;
66 }
67
HasStrokeColor() const68 bool CPDF_ColorState::HasStrokeColor() const {
69 const CPDF_Color* pColor = GetStrokeColor();
70 return pColor && !pColor->IsNull();
71 }
72
SetFillColor(const RetainPtr<CPDF_ColorSpace> & pCS,const std::vector<float> & values)73 void CPDF_ColorState::SetFillColor(const RetainPtr<CPDF_ColorSpace>& pCS,
74 const std::vector<float>& values) {
75 ColorData* pData = m_Ref.GetPrivateCopy();
76 SetColor(pCS, values, &pData->m_FillColor, &pData->m_FillColorRef);
77 }
78
SetStrokeColor(const RetainPtr<CPDF_ColorSpace> & pCS,const std::vector<float> & values)79 void CPDF_ColorState::SetStrokeColor(const RetainPtr<CPDF_ColorSpace>& pCS,
80 const std::vector<float>& values) {
81 ColorData* pData = m_Ref.GetPrivateCopy();
82 SetColor(pCS, values, &pData->m_StrokeColor, &pData->m_StrokeColorRef);
83 }
84
SetFillPattern(const RetainPtr<CPDF_Pattern> & pPattern,const std::vector<float> & values)85 void CPDF_ColorState::SetFillPattern(const RetainPtr<CPDF_Pattern>& pPattern,
86 const std::vector<float>& values) {
87 ColorData* pData = m_Ref.GetPrivateCopy();
88 SetPattern(pPattern, values, &pData->m_FillColor, &pData->m_FillColorRef);
89 }
90
SetStrokePattern(const RetainPtr<CPDF_Pattern> & pPattern,const std::vector<float> & values)91 void CPDF_ColorState::SetStrokePattern(const RetainPtr<CPDF_Pattern>& pPattern,
92 const std::vector<float>& values) {
93 ColorData* pData = m_Ref.GetPrivateCopy();
94 SetPattern(pPattern, values, &pData->m_StrokeColor, &pData->m_StrokeColorRef);
95 }
96
SetColor(const RetainPtr<CPDF_ColorSpace> & pCS,const std::vector<float> & values,CPDF_Color * color,FX_COLORREF * colorref)97 void CPDF_ColorState::SetColor(const RetainPtr<CPDF_ColorSpace>& pCS,
98 const std::vector<float>& values,
99 CPDF_Color* color,
100 FX_COLORREF* colorref) {
101 ASSERT(color);
102 ASSERT(colorref);
103
104 if (pCS)
105 color->SetColorSpace(pCS);
106 else if (color->IsNull())
107 color->SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
108
109 if (color->CountComponents() > values.size())
110 return;
111
112 if (!color->IsPattern())
113 color->SetValueForNonPattern(values);
114 int R;
115 int G;
116 int B;
117 *colorref = color->GetRGB(&R, &G, &B) ? FXSYS_BGR(B, G, R) : 0xFFFFFFFF;
118 }
119
SetPattern(const RetainPtr<CPDF_Pattern> & pPattern,const std::vector<float> & values,CPDF_Color * color,FX_COLORREF * colorref)120 void CPDF_ColorState::SetPattern(const RetainPtr<CPDF_Pattern>& pPattern,
121 const std::vector<float>& values,
122 CPDF_Color* color,
123 FX_COLORREF* colorref) {
124 ASSERT(color);
125 ASSERT(colorref);
126
127 color->SetValueForPattern(pPattern, values);
128 int R;
129 int G;
130 int B;
131 bool ret = color->GetRGB(&R, &G, &B);
132 if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) {
133 if (!ret && pTilingPattern->colored()) {
134 *colorref = 0x00BFBFBF;
135 return;
136 }
137 }
138 *colorref = ret ? FXSYS_BGR(B, G, R) : 0xFFFFFFFF;
139 }
140
141 CPDF_ColorState::ColorData::ColorData() = default;
142
ColorData(const ColorData & src)143 CPDF_ColorState::ColorData::ColorData(const ColorData& src)
144 : m_FillColorRef(src.m_FillColorRef),
145 m_StrokeColorRef(src.m_StrokeColorRef),
146 m_FillColor(src.m_FillColor),
147 m_StrokeColor(src.m_StrokeColor) {}
148
149 CPDF_ColorState::ColorData::~ColorData() = default;
150
SetDefault()151 void CPDF_ColorState::ColorData::SetDefault() {
152 m_FillColorRef = 0;
153 m_StrokeColorRef = 0;
154 m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
155 m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
156 }
157
Clone() const158 RetainPtr<CPDF_ColorState::ColorData> CPDF_ColorState::ColorData::Clone()
159 const {
160 return pdfium::MakeRetain<CPDF_ColorState::ColorData>(*this);
161 }
162