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