1 // Copyright 2016 The PDFium Authors
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_generalstate.h"
8
9 #include <utility>
10
11 #include "core/fpdfapi/page/cpdf_transferfunc.h"
12 #include "core/fpdfapi/parser/cpdf_dictionary.h"
13 #include "core/fpdfapi/parser/cpdf_object.h"
14
15 namespace {
16
RI_StringToId(const ByteString & ri)17 int RI_StringToId(const ByteString& ri) {
18 uint32_t id = ri.GetID();
19 if (id == FXBSTR_ID('A', 'b', 's', 'o'))
20 return 1;
21
22 if (id == FXBSTR_ID('S', 'a', 't', 'u'))
23 return 2;
24
25 if (id == FXBSTR_ID('P', 'e', 'r', 'c'))
26 return 3;
27
28 return 0;
29 }
30
GetBlendTypeInternal(const ByteString & mode)31 BlendMode GetBlendTypeInternal(const ByteString& mode) {
32 switch (mode.GetID()) {
33 case FXBSTR_ID('N', 'o', 'r', 'm'):
34 case FXBSTR_ID('C', 'o', 'm', 'p'):
35 return BlendMode::kNormal;
36 case FXBSTR_ID('M', 'u', 'l', 't'):
37 return BlendMode::kMultiply;
38 case FXBSTR_ID('S', 'c', 'r', 'e'):
39 return BlendMode::kScreen;
40 case FXBSTR_ID('O', 'v', 'e', 'r'):
41 return BlendMode::kOverlay;
42 case FXBSTR_ID('D', 'a', 'r', 'k'):
43 return BlendMode::kDarken;
44 case FXBSTR_ID('L', 'i', 'g', 'h'):
45 return BlendMode::kLighten;
46 case FXBSTR_ID('C', 'o', 'l', 'o'):
47 if (mode.GetLength() == 10)
48 return BlendMode::kColorDodge;
49 if (mode.GetLength() == 9)
50 return BlendMode::kColorBurn;
51 return BlendMode::kColor;
52 case FXBSTR_ID('H', 'a', 'r', 'd'):
53 return BlendMode::kHardLight;
54 case FXBSTR_ID('S', 'o', 'f', 't'):
55 return BlendMode::kSoftLight;
56 case FXBSTR_ID('D', 'i', 'f', 'f'):
57 return BlendMode::kDifference;
58 case FXBSTR_ID('E', 'x', 'c', 'l'):
59 return BlendMode::kExclusion;
60 case FXBSTR_ID('H', 'u', 'e', 0):
61 return BlendMode::kHue;
62 case FXBSTR_ID('S', 'a', 't', 'u'):
63 return BlendMode::kSaturation;
64 case FXBSTR_ID('L', 'u', 'm', 'i'):
65 return BlendMode::kLuminosity;
66 }
67 return BlendMode::kNormal;
68 }
69
70 } // namespace
71
72 CPDF_GeneralState::CPDF_GeneralState() = default;
73
74 CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that) = default;
75
76 CPDF_GeneralState::~CPDF_GeneralState() = default;
77
SetRenderIntent(const ByteString & ri)78 void CPDF_GeneralState::SetRenderIntent(const ByteString& ri) {
79 m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri);
80 }
81
GetBlendMode() const82 ByteString CPDF_GeneralState::GetBlendMode() const {
83 switch (GetBlendType()) {
84 case BlendMode::kNormal:
85 return ByteString(pdfium::transparency::kNormal);
86 case BlendMode::kMultiply:
87 return ByteString(pdfium::transparency::kMultiply);
88 case BlendMode::kScreen:
89 return ByteString(pdfium::transparency::kScreen);
90 case BlendMode::kOverlay:
91 return ByteString(pdfium::transparency::kOverlay);
92 case BlendMode::kDarken:
93 return ByteString(pdfium::transparency::kDarken);
94 case BlendMode::kLighten:
95 return ByteString(pdfium::transparency::kLighten);
96 case BlendMode::kColorDodge:
97 return ByteString(pdfium::transparency::kColorDodge);
98 case BlendMode::kColorBurn:
99 return ByteString(pdfium::transparency::kColorBurn);
100 case BlendMode::kHardLight:
101 return ByteString(pdfium::transparency::kHardLight);
102 case BlendMode::kSoftLight:
103 return ByteString(pdfium::transparency::kSoftLight);
104 case BlendMode::kDifference:
105 return ByteString(pdfium::transparency::kDifference);
106 case BlendMode::kExclusion:
107 return ByteString(pdfium::transparency::kExclusion);
108 case BlendMode::kHue:
109 return ByteString(pdfium::transparency::kHue);
110 case BlendMode::kSaturation:
111 return ByteString(pdfium::transparency::kSaturation);
112 case BlendMode::kColor:
113 return ByteString(pdfium::transparency::kColor);
114 case BlendMode::kLuminosity:
115 return ByteString(pdfium::transparency::kLuminosity);
116 }
117 return ByteString(pdfium::transparency::kNormal);
118 }
119
GetBlendType() const120 BlendMode CPDF_GeneralState::GetBlendType() const {
121 const StateData* pData = m_Ref.GetObject();
122 return pData ? pData->m_BlendType : BlendMode::kNormal;
123 }
124
SetBlendType(BlendMode type)125 void CPDF_GeneralState::SetBlendType(BlendMode type) {
126 if (GetBlendType() != type) {
127 m_Ref.GetPrivateCopy()->m_BlendType = type;
128 }
129 }
130
GetFillAlpha() const131 float CPDF_GeneralState::GetFillAlpha() const {
132 const StateData* pData = m_Ref.GetObject();
133 return pData ? pData->m_FillAlpha : 1.0f;
134 }
135
SetFillAlpha(float alpha)136 void CPDF_GeneralState::SetFillAlpha(float alpha) {
137 if (GetFillAlpha() != alpha) {
138 m_Ref.GetPrivateCopy()->m_FillAlpha = alpha;
139 }
140 }
141
GetStrokeAlpha() const142 float CPDF_GeneralState::GetStrokeAlpha() const {
143 const StateData* pData = m_Ref.GetObject();
144 return pData ? pData->m_StrokeAlpha : 1.0f;
145 }
146
SetStrokeAlpha(float alpha)147 void CPDF_GeneralState::SetStrokeAlpha(float alpha) {
148 if (GetStrokeAlpha() != alpha) {
149 m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha;
150 }
151 }
152
GetSoftMask() const153 RetainPtr<const CPDF_Dictionary> CPDF_GeneralState::GetSoftMask() const {
154 const StateData* pData = m_Ref.GetObject();
155 return pData ? pData->m_pSoftMask : nullptr;
156 }
157
GetMutableSoftMask()158 RetainPtr<CPDF_Dictionary> CPDF_GeneralState::GetMutableSoftMask() {
159 const StateData* pData = m_Ref.GetObject();
160 return pData ? pData->m_pSoftMask : nullptr;
161 }
162
SetSoftMask(RetainPtr<CPDF_Dictionary> pDict)163 void CPDF_GeneralState::SetSoftMask(RetainPtr<CPDF_Dictionary> pDict) {
164 m_Ref.GetPrivateCopy()->m_pSoftMask = std::move(pDict);
165 }
166
GetTR() const167 RetainPtr<const CPDF_Object> CPDF_GeneralState::GetTR() const {
168 const StateData* pData = m_Ref.GetObject();
169 return pData ? pData->m_pTR : nullptr;
170 }
171
SetTR(RetainPtr<const CPDF_Object> pObject)172 void CPDF_GeneralState::SetTR(RetainPtr<const CPDF_Object> pObject) {
173 m_Ref.GetPrivateCopy()->m_pTR = std::move(pObject);
174 }
175
GetTransferFunc() const176 RetainPtr<CPDF_TransferFunc> CPDF_GeneralState::GetTransferFunc() const {
177 const StateData* pData = m_Ref.GetObject();
178 return pData ? pData->m_pTransferFunc : nullptr;
179 }
180
SetTransferFunc(RetainPtr<CPDF_TransferFunc> pFunc)181 void CPDF_GeneralState::SetTransferFunc(RetainPtr<CPDF_TransferFunc> pFunc) {
182 m_Ref.GetPrivateCopy()->m_pTransferFunc = std::move(pFunc);
183 }
184
SetBlendMode(const ByteString & mode)185 void CPDF_GeneralState::SetBlendMode(const ByteString& mode) {
186 StateData* pData = m_Ref.GetPrivateCopy();
187 pData->m_BlendMode = mode;
188 pData->m_BlendType = GetBlendTypeInternal(mode);
189 }
190
GetSMaskMatrix() const191 const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const {
192 const StateData* pData = m_Ref.GetObject();
193 return pData ? &pData->m_SMaskMatrix : nullptr;
194 }
195
SetSMaskMatrix(const CFX_Matrix & matrix)196 void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) {
197 m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix;
198 }
199
GetFillOP() const200 bool CPDF_GeneralState::GetFillOP() const {
201 const StateData* pData = m_Ref.GetObject();
202 return pData && pData->m_FillOP;
203 }
204
SetFillOP(bool op)205 void CPDF_GeneralState::SetFillOP(bool op) {
206 m_Ref.GetPrivateCopy()->m_FillOP = op;
207 }
208
SetStrokeOP(bool op)209 void CPDF_GeneralState::SetStrokeOP(bool op) {
210 m_Ref.GetPrivateCopy()->m_StrokeOP = op;
211 }
212
GetStrokeOP() const213 bool CPDF_GeneralState::GetStrokeOP() const {
214 const StateData* pData = m_Ref.GetObject();
215 return pData && pData->m_StrokeOP;
216 }
217
GetOPMode() const218 int CPDF_GeneralState::GetOPMode() const {
219 return m_Ref.GetObject()->m_OPMode;
220 }
221
SetOPMode(int mode)222 void CPDF_GeneralState::SetOPMode(int mode) {
223 m_Ref.GetPrivateCopy()->m_OPMode = mode;
224 }
225
SetBG(RetainPtr<const CPDF_Object> pObject)226 void CPDF_GeneralState::SetBG(RetainPtr<const CPDF_Object> pObject) {
227 m_Ref.GetPrivateCopy()->m_pBG = std::move(pObject);
228 }
229
SetUCR(RetainPtr<const CPDF_Object> pObject)230 void CPDF_GeneralState::SetUCR(RetainPtr<const CPDF_Object> pObject) {
231 m_Ref.GetPrivateCopy()->m_pUCR = std::move(pObject);
232 }
233
SetHT(RetainPtr<const CPDF_Object> pObject)234 void CPDF_GeneralState::SetHT(RetainPtr<const CPDF_Object> pObject) {
235 m_Ref.GetPrivateCopy()->m_pHT = std::move(pObject);
236 }
237
SetFlatness(float flatness)238 void CPDF_GeneralState::SetFlatness(float flatness) {
239 m_Ref.GetPrivateCopy()->m_Flatness = flatness;
240 }
241
SetSmoothness(float smoothness)242 void CPDF_GeneralState::SetSmoothness(float smoothness) {
243 m_Ref.GetPrivateCopy()->m_Smoothness = smoothness;
244 }
245
GetStrokeAdjust() const246 bool CPDF_GeneralState::GetStrokeAdjust() const {
247 const StateData* pData = m_Ref.GetObject();
248 return pData && pData->m_StrokeAdjust;
249 }
250
SetStrokeAdjust(bool adjust)251 void CPDF_GeneralState::SetStrokeAdjust(bool adjust) {
252 m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust;
253 }
254
SetAlphaSource(bool source)255 void CPDF_GeneralState::SetAlphaSource(bool source) {
256 m_Ref.GetPrivateCopy()->m_AlphaSource = source;
257 }
258
SetTextKnockout(bool knockout)259 void CPDF_GeneralState::SetTextKnockout(bool knockout) {
260 m_Ref.GetPrivateCopy()->m_TextKnockout = knockout;
261 }
262
SetGraphicsResourceNames(std::vector<ByteString> names)263 void CPDF_GeneralState::SetGraphicsResourceNames(
264 std::vector<ByteString> names) {
265 m_Ref.GetPrivateCopy()->m_GraphicsResourceNames = std::move(names);
266 }
267
AppendGraphicsResourceName(ByteString name)268 void CPDF_GeneralState::AppendGraphicsResourceName(ByteString name) {
269 m_Ref.GetPrivateCopy()->m_GraphicsResourceNames.push_back(std::move(name));
270 }
271
GetGraphicsResourceNames() const272 pdfium::span<const ByteString> CPDF_GeneralState::GetGraphicsResourceNames()
273 const {
274 const StateData* data = m_Ref.GetObject();
275 if (!data) {
276 return {};
277 }
278 return data->m_GraphicsResourceNames;
279 }
280
281 CPDF_GeneralState::StateData::StateData() = default;
282
StateData(const StateData & that)283 CPDF_GeneralState::StateData::StateData(const StateData& that)
284 : m_BlendMode(that.m_BlendMode),
285 m_BlendType(that.m_BlendType),
286 m_pSoftMask(that.m_pSoftMask),
287 m_SMaskMatrix(that.m_SMaskMatrix),
288 m_StrokeAlpha(that.m_StrokeAlpha),
289 m_FillAlpha(that.m_FillAlpha),
290 m_pTR(that.m_pTR),
291 m_pTransferFunc(that.m_pTransferFunc),
292 m_RenderIntent(that.m_RenderIntent),
293 m_StrokeAdjust(that.m_StrokeAdjust),
294 m_AlphaSource(that.m_AlphaSource),
295 m_TextKnockout(that.m_TextKnockout),
296 m_StrokeOP(that.m_StrokeOP),
297 m_FillOP(that.m_FillOP),
298 m_OPMode(that.m_OPMode),
299 m_pBG(that.m_pBG),
300 m_pUCR(that.m_pUCR),
301 m_pHT(that.m_pHT),
302 m_Flatness(that.m_Flatness),
303 m_Smoothness(that.m_Smoothness) {}
304
305 CPDF_GeneralState::StateData::~StateData() = default;
306
Clone() const307 RetainPtr<CPDF_GeneralState::StateData> CPDF_GeneralState::StateData::Clone()
308 const {
309 return pdfium::MakeRetain<CPDF_GeneralState::StateData>(*this);
310 }
311