• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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