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
CPDF_GeneralState(const CPDF_GeneralState & that)74 CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that)
75 : m_Ref(that.m_Ref) {}
76
77 CPDF_GeneralState::~CPDF_GeneralState() = default;
78
SetRenderIntent(const ByteString & ri)79 void CPDF_GeneralState::SetRenderIntent(const ByteString& ri) {
80 m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri);
81 }
82
GetBlendMode() const83 ByteString CPDF_GeneralState::GetBlendMode() const {
84 switch (GetBlendType()) {
85 case BlendMode::kNormal:
86 return ByteString(pdfium::transparency::kNormal);
87 case BlendMode::kMultiply:
88 return ByteString(pdfium::transparency::kMultiply);
89 case BlendMode::kScreen:
90 return ByteString(pdfium::transparency::kScreen);
91 case BlendMode::kOverlay:
92 return ByteString(pdfium::transparency::kOverlay);
93 case BlendMode::kDarken:
94 return ByteString(pdfium::transparency::kDarken);
95 case BlendMode::kLighten:
96 return ByteString(pdfium::transparency::kLighten);
97 case BlendMode::kColorDodge:
98 return ByteString(pdfium::transparency::kColorDodge);
99 case BlendMode::kColorBurn:
100 return ByteString(pdfium::transparency::kColorBurn);
101 case BlendMode::kHardLight:
102 return ByteString(pdfium::transparency::kHardLight);
103 case BlendMode::kSoftLight:
104 return ByteString(pdfium::transparency::kSoftLight);
105 case BlendMode::kDifference:
106 return ByteString(pdfium::transparency::kDifference);
107 case BlendMode::kExclusion:
108 return ByteString(pdfium::transparency::kExclusion);
109 case BlendMode::kHue:
110 return ByteString(pdfium::transparency::kHue);
111 case BlendMode::kSaturation:
112 return ByteString(pdfium::transparency::kSaturation);
113 case BlendMode::kColor:
114 return ByteString(pdfium::transparency::kColor);
115 case BlendMode::kLuminosity:
116 return ByteString(pdfium::transparency::kLuminosity);
117 }
118 return ByteString(pdfium::transparency::kNormal);
119 }
120
GetBlendType() const121 BlendMode CPDF_GeneralState::GetBlendType() const {
122 const StateData* pData = m_Ref.GetObject();
123 return pData ? pData->m_BlendType : BlendMode::kNormal;
124 }
125
SetBlendType(BlendMode type)126 void CPDF_GeneralState::SetBlendType(BlendMode type) {
127 m_Ref.GetPrivateCopy()->m_BlendType = type;
128 }
129
GetFillAlpha() const130 float CPDF_GeneralState::GetFillAlpha() const {
131 const StateData* pData = m_Ref.GetObject();
132 return pData ? pData->m_FillAlpha : 1.0f;
133 }
134
SetFillAlpha(float alpha)135 void CPDF_GeneralState::SetFillAlpha(float alpha) {
136 m_Ref.GetPrivateCopy()->m_FillAlpha = alpha;
137 }
138
GetStrokeAlpha() const139 float CPDF_GeneralState::GetStrokeAlpha() const {
140 const StateData* pData = m_Ref.GetObject();
141 return pData ? pData->m_StrokeAlpha : 1.0f;
142 }
143
SetStrokeAlpha(float alpha)144 void CPDF_GeneralState::SetStrokeAlpha(float alpha) {
145 m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha;
146 }
147
GetSoftMask() const148 RetainPtr<const CPDF_Dictionary> CPDF_GeneralState::GetSoftMask() const {
149 const StateData* pData = m_Ref.GetObject();
150 return pData ? pData->m_pSoftMask : nullptr;
151 }
152
GetMutableSoftMask()153 RetainPtr<CPDF_Dictionary> CPDF_GeneralState::GetMutableSoftMask() {
154 const StateData* pData = m_Ref.GetObject();
155 return pData ? pData->m_pSoftMask : nullptr;
156 }
157
SetSoftMask(RetainPtr<CPDF_Dictionary> pDict)158 void CPDF_GeneralState::SetSoftMask(RetainPtr<CPDF_Dictionary> pDict) {
159 m_Ref.GetPrivateCopy()->m_pSoftMask = std::move(pDict);
160 }
161
GetTR() const162 RetainPtr<const CPDF_Object> CPDF_GeneralState::GetTR() const {
163 const StateData* pData = m_Ref.GetObject();
164 return pData ? pData->m_pTR : nullptr;
165 }
166
SetTR(RetainPtr<const CPDF_Object> pObject)167 void CPDF_GeneralState::SetTR(RetainPtr<const CPDF_Object> pObject) {
168 m_Ref.GetPrivateCopy()->m_pTR = std::move(pObject);
169 }
170
GetTransferFunc() const171 RetainPtr<CPDF_TransferFunc> CPDF_GeneralState::GetTransferFunc() const {
172 const StateData* pData = m_Ref.GetObject();
173 return pData ? pData->m_pTransferFunc : nullptr;
174 }
175
SetTransferFunc(RetainPtr<CPDF_TransferFunc> pFunc)176 void CPDF_GeneralState::SetTransferFunc(RetainPtr<CPDF_TransferFunc> pFunc) {
177 m_Ref.GetPrivateCopy()->m_pTransferFunc = std::move(pFunc);
178 }
179
SetBlendMode(const ByteString & mode)180 void CPDF_GeneralState::SetBlendMode(const ByteString& mode) {
181 StateData* pData = m_Ref.GetPrivateCopy();
182 pData->m_BlendMode = mode;
183 pData->m_BlendType = GetBlendTypeInternal(mode);
184 }
185
GetSMaskMatrix() const186 const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const {
187 const StateData* pData = m_Ref.GetObject();
188 return pData ? &pData->m_SMaskMatrix : nullptr;
189 }
190
SetSMaskMatrix(const CFX_Matrix & matrix)191 void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) {
192 m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix;
193 }
194
GetFillOP() const195 bool CPDF_GeneralState::GetFillOP() const {
196 const StateData* pData = m_Ref.GetObject();
197 return pData && pData->m_FillOP;
198 }
199
SetFillOP(bool op)200 void CPDF_GeneralState::SetFillOP(bool op) {
201 m_Ref.GetPrivateCopy()->m_FillOP = op;
202 }
203
SetStrokeOP(bool op)204 void CPDF_GeneralState::SetStrokeOP(bool op) {
205 m_Ref.GetPrivateCopy()->m_StrokeOP = op;
206 }
207
GetStrokeOP() const208 bool CPDF_GeneralState::GetStrokeOP() const {
209 const StateData* pData = m_Ref.GetObject();
210 return pData && pData->m_StrokeOP;
211 }
212
GetOPMode() const213 int CPDF_GeneralState::GetOPMode() const {
214 return m_Ref.GetObject()->m_OPMode;
215 }
216
SetOPMode(int mode)217 void CPDF_GeneralState::SetOPMode(int mode) {
218 m_Ref.GetPrivateCopy()->m_OPMode = mode;
219 }
220
SetBG(RetainPtr<const CPDF_Object> pObject)221 void CPDF_GeneralState::SetBG(RetainPtr<const CPDF_Object> pObject) {
222 m_Ref.GetPrivateCopy()->m_pBG = std::move(pObject);
223 }
224
SetUCR(RetainPtr<const CPDF_Object> pObject)225 void CPDF_GeneralState::SetUCR(RetainPtr<const CPDF_Object> pObject) {
226 m_Ref.GetPrivateCopy()->m_pUCR = std::move(pObject);
227 }
228
SetHT(RetainPtr<const CPDF_Object> pObject)229 void CPDF_GeneralState::SetHT(RetainPtr<const CPDF_Object> pObject) {
230 m_Ref.GetPrivateCopy()->m_pHT = std::move(pObject);
231 }
232
SetFlatness(float flatness)233 void CPDF_GeneralState::SetFlatness(float flatness) {
234 m_Ref.GetPrivateCopy()->m_Flatness = flatness;
235 }
236
SetSmoothness(float smoothness)237 void CPDF_GeneralState::SetSmoothness(float smoothness) {
238 m_Ref.GetPrivateCopy()->m_Smoothness = smoothness;
239 }
240
GetStrokeAdjust() const241 bool CPDF_GeneralState::GetStrokeAdjust() const {
242 const StateData* pData = m_Ref.GetObject();
243 return pData && pData->m_StrokeAdjust;
244 }
245
SetStrokeAdjust(bool adjust)246 void CPDF_GeneralState::SetStrokeAdjust(bool adjust) {
247 m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust;
248 }
249
SetAlphaSource(bool source)250 void CPDF_GeneralState::SetAlphaSource(bool source) {
251 m_Ref.GetPrivateCopy()->m_AlphaSource = source;
252 }
253
SetTextKnockout(bool knockout)254 void CPDF_GeneralState::SetTextKnockout(bool knockout) {
255 m_Ref.GetPrivateCopy()->m_TextKnockout = knockout;
256 }
257
SetMatrix(const CFX_Matrix & matrix)258 void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) {
259 m_Ref.GetPrivateCopy()->m_Matrix = matrix;
260 }
261
GetMutableMatrix()262 CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() {
263 return &m_Ref.GetPrivateCopy()->m_Matrix;
264 }
265
SetGraphicsResourceNames(std::vector<ByteString> names)266 void CPDF_GeneralState::SetGraphicsResourceNames(
267 std::vector<ByteString> names) {
268 m_Ref.GetPrivateCopy()->m_GraphicsResourceNames = std::move(names);
269 }
270
AppendGraphicsResourceName(ByteString name)271 void CPDF_GeneralState::AppendGraphicsResourceName(ByteString name) {
272 m_Ref.GetPrivateCopy()->m_GraphicsResourceNames.push_back(std::move(name));
273 }
274
GetGraphicsResourceNames() const275 pdfium::span<const ByteString> CPDF_GeneralState::GetGraphicsResourceNames()
276 const {
277 const StateData* data = m_Ref.GetObject();
278 if (!data) {
279 return {};
280 }
281 return data->m_GraphicsResourceNames;
282 }
283
284 CPDF_GeneralState::StateData::StateData() = default;
285
StateData(const StateData & that)286 CPDF_GeneralState::StateData::StateData(const StateData& that)
287 : m_BlendMode(that.m_BlendMode),
288 m_BlendType(that.m_BlendType),
289 m_pSoftMask(that.m_pSoftMask),
290 m_SMaskMatrix(that.m_SMaskMatrix),
291 m_StrokeAlpha(that.m_StrokeAlpha),
292 m_FillAlpha(that.m_FillAlpha),
293 m_pTR(that.m_pTR),
294 m_pTransferFunc(that.m_pTransferFunc),
295 m_Matrix(that.m_Matrix),
296 m_RenderIntent(that.m_RenderIntent),
297 m_StrokeAdjust(that.m_StrokeAdjust),
298 m_AlphaSource(that.m_AlphaSource),
299 m_TextKnockout(that.m_TextKnockout),
300 m_StrokeOP(that.m_StrokeOP),
301 m_FillOP(that.m_FillOP),
302 m_OPMode(that.m_OPMode),
303 m_pBG(that.m_pBG),
304 m_pUCR(that.m_pUCR),
305 m_pHT(that.m_pHT),
306 m_Flatness(that.m_Flatness),
307 m_Smoothness(that.m_Smoothness) {}
308
309 CPDF_GeneralState::StateData::~StateData() = default;
310
Clone() const311 RetainPtr<CPDF_GeneralState::StateData> CPDF_GeneralState::StateData::Clone()
312 const {
313 return pdfium::MakeRetain<CPDF_GeneralState::StateData>(*this);
314 }
315