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/parser/cpdf_document.h" 10 #include "core/fpdfapi/render/cpdf_dibsource.h" 11 #include "core/fpdfapi/render/cpdf_docrenderdata.h" 12 #include "core/fpdfapi/render/cpdf_transferfunc.h" 13 14 namespace { 15 16 int RI_StringToId(const ByteString& ri) { 17 uint32_t id = ri.GetID(); 18 if (id == FXBSTR_ID('A', 'b', 's', 'o')) 19 return 1; 20 21 if (id == FXBSTR_ID('S', 'a', 't', 'u')) 22 return 2; 23 24 if (id == FXBSTR_ID('P', 'e', 'r', 'c')) 25 return 3; 26 27 return 0; 28 } 29 30 int GetBlendTypeInternal(const ByteString& mode) { 31 switch (mode.GetID()) { 32 case FXBSTR_ID('N', 'o', 'r', 'm'): 33 case FXBSTR_ID('C', 'o', 'm', 'p'): 34 return FXDIB_BLEND_NORMAL; 35 case FXBSTR_ID('M', 'u', 'l', 't'): 36 return FXDIB_BLEND_MULTIPLY; 37 case FXBSTR_ID('S', 'c', 'r', 'e'): 38 return FXDIB_BLEND_SCREEN; 39 case FXBSTR_ID('O', 'v', 'e', 'r'): 40 return FXDIB_BLEND_OVERLAY; 41 case FXBSTR_ID('D', 'a', 'r', 'k'): 42 return FXDIB_BLEND_DARKEN; 43 case FXBSTR_ID('L', 'i', 'g', 'h'): 44 return FXDIB_BLEND_LIGHTEN; 45 case FXBSTR_ID('C', 'o', 'l', 'o'): 46 if (mode.GetLength() == 10) 47 return FXDIB_BLEND_COLORDODGE; 48 if (mode.GetLength() == 9) 49 return FXDIB_BLEND_COLORBURN; 50 return FXDIB_BLEND_COLOR; 51 case FXBSTR_ID('H', 'a', 'r', 'd'): 52 return FXDIB_BLEND_HARDLIGHT; 53 case FXBSTR_ID('S', 'o', 'f', 't'): 54 return FXDIB_BLEND_SOFTLIGHT; 55 case FXBSTR_ID('D', 'i', 'f', 'f'): 56 return FXDIB_BLEND_DIFFERENCE; 57 case FXBSTR_ID('E', 'x', 'c', 'l'): 58 return FXDIB_BLEND_EXCLUSION; 59 case FXBSTR_ID('H', 'u', 'e', 0): 60 return FXDIB_BLEND_HUE; 61 case FXBSTR_ID('S', 'a', 't', 'u'): 62 return FXDIB_BLEND_SATURATION; 63 case FXBSTR_ID('L', 'u', 'm', 'i'): 64 return FXDIB_BLEND_LUMINOSITY; 65 } 66 return FXDIB_BLEND_NORMAL; 67 } 68 69 } // namespace 70 71 CPDF_GeneralState::CPDF_GeneralState() {} 72 73 CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that) 74 : m_Ref(that.m_Ref) {} 75 76 CPDF_GeneralState::~CPDF_GeneralState() {} 77 78 void CPDF_GeneralState::SetRenderIntent(const ByteString& ri) { 79 m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri); 80 } 81 ByteString CPDF_GeneralState::GetBlendMode() const { 82 switch (GetBlendType()) { 83 case FXDIB_BLEND_NORMAL: 84 return ByteString("Normal"); 85 case FXDIB_BLEND_MULTIPLY: 86 return ByteString("Multiply"); 87 case FXDIB_BLEND_SCREEN: 88 return ByteString("Screen"); 89 case FXDIB_BLEND_OVERLAY: 90 return ByteString("Overlay"); 91 case FXDIB_BLEND_DARKEN: 92 return ByteString("Darken"); 93 case FXDIB_BLEND_LIGHTEN: 94 return ByteString("Lighten"); 95 case FXDIB_BLEND_COLORDODGE: 96 return ByteString("ColorDodge"); 97 case FXDIB_BLEND_COLORBURN: 98 return ByteString("ColorBurn"); 99 case FXDIB_BLEND_HARDLIGHT: 100 return ByteString("HardLight"); 101 case FXDIB_BLEND_SOFTLIGHT: 102 return ByteString("SoftLight"); 103 case FXDIB_BLEND_DIFFERENCE: 104 return ByteString("Difference"); 105 case FXDIB_BLEND_EXCLUSION: 106 return ByteString("Exclusion"); 107 case FXDIB_BLEND_HUE: 108 return ByteString("Hue"); 109 case FXDIB_BLEND_SATURATION: 110 return ByteString("Saturation"); 111 case FXDIB_BLEND_COLOR: 112 return ByteString("Color"); 113 case FXDIB_BLEND_LUMINOSITY: 114 return ByteString("Luminosity"); 115 } 116 return ByteString("Normal"); 117 } 118 119 int CPDF_GeneralState::GetBlendType() const { 120 const StateData* pData = m_Ref.GetObject(); 121 return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL; 122 } 123 124 void CPDF_GeneralState::SetBlendType(int type) { 125 m_Ref.GetPrivateCopy()->m_BlendType = type; 126 } 127 128 float CPDF_GeneralState::GetFillAlpha() const { 129 const StateData* pData = m_Ref.GetObject(); 130 return pData ? pData->m_FillAlpha : 1.0f; 131 } 132 133 void CPDF_GeneralState::SetFillAlpha(float alpha) { 134 m_Ref.GetPrivateCopy()->m_FillAlpha = alpha; 135 } 136 137 float CPDF_GeneralState::GetStrokeAlpha() const { 138 const StateData* pData = m_Ref.GetObject(); 139 return pData ? pData->m_StrokeAlpha : 1.0f; 140 } 141 142 void CPDF_GeneralState::SetStrokeAlpha(float alpha) { 143 m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha; 144 } 145 146 CPDF_Object* CPDF_GeneralState::GetSoftMask() const { 147 const StateData* pData = m_Ref.GetObject(); 148 return pData ? pData->m_pSoftMask.Get() : nullptr; 149 } 150 151 void CPDF_GeneralState::SetSoftMask(CPDF_Object* pObject) { 152 m_Ref.GetPrivateCopy()->m_pSoftMask = pObject; 153 } 154 155 CPDF_Object* CPDF_GeneralState::GetTR() const { 156 const StateData* pData = m_Ref.GetObject(); 157 return pData ? pData->m_pTR.Get() : nullptr; 158 } 159 160 void CPDF_GeneralState::SetTR(CPDF_Object* pObject) { 161 m_Ref.GetPrivateCopy()->m_pTR = pObject; 162 } 163 164 RetainPtr<CPDF_TransferFunc> CPDF_GeneralState::GetTransferFunc() const { 165 const StateData* pData = m_Ref.GetObject(); 166 return pData ? pData->m_pTransferFunc : nullptr; 167 } 168 169 void CPDF_GeneralState::SetTransferFunc( 170 const RetainPtr<CPDF_TransferFunc>& pFunc) { 171 m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc; 172 } 173 174 void CPDF_GeneralState::SetBlendMode(const ByteString& mode) { 175 StateData* pData = m_Ref.GetPrivateCopy(); 176 pData->m_BlendMode = mode; 177 pData->m_BlendType = GetBlendTypeInternal(mode); 178 } 179 180 const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const { 181 const StateData* pData = m_Ref.GetObject(); 182 return pData ? &pData->m_SMaskMatrix : nullptr; 183 } 184 185 void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) { 186 m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix; 187 } 188 189 bool CPDF_GeneralState::GetFillOP() const { 190 const StateData* pData = m_Ref.GetObject(); 191 return pData && pData->m_FillOP; 192 } 193 194 void CPDF_GeneralState::SetFillOP(bool op) { 195 m_Ref.GetPrivateCopy()->m_FillOP = op; 196 } 197 198 void CPDF_GeneralState::SetStrokeOP(bool op) { 199 m_Ref.GetPrivateCopy()->m_StrokeOP = op; 200 } 201 202 bool CPDF_GeneralState::GetStrokeOP() const { 203 const StateData* pData = m_Ref.GetObject(); 204 return pData && pData->m_StrokeOP; 205 } 206 207 int CPDF_GeneralState::GetOPMode() const { 208 return m_Ref.GetObject()->m_OPMode; 209 } 210 211 void CPDF_GeneralState::SetOPMode(int mode) { 212 m_Ref.GetPrivateCopy()->m_OPMode = mode; 213 } 214 215 void CPDF_GeneralState::SetBG(CPDF_Object* pObject) { 216 m_Ref.GetPrivateCopy()->m_pBG = pObject; 217 } 218 219 void CPDF_GeneralState::SetUCR(CPDF_Object* pObject) { 220 m_Ref.GetPrivateCopy()->m_pUCR = pObject; 221 } 222 223 void CPDF_GeneralState::SetHT(CPDF_Object* pObject) { 224 m_Ref.GetPrivateCopy()->m_pHT = pObject; 225 } 226 227 void CPDF_GeneralState::SetFlatness(float flatness) { 228 m_Ref.GetPrivateCopy()->m_Flatness = flatness; 229 } 230 231 void CPDF_GeneralState::SetSmoothness(float smoothness) { 232 m_Ref.GetPrivateCopy()->m_Smoothness = smoothness; 233 } 234 235 bool CPDF_GeneralState::GetStrokeAdjust() const { 236 const StateData* pData = m_Ref.GetObject(); 237 return pData && pData->m_StrokeAdjust; 238 } 239 240 void CPDF_GeneralState::SetStrokeAdjust(bool adjust) { 241 m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust; 242 } 243 244 void CPDF_GeneralState::SetAlphaSource(bool source) { 245 m_Ref.GetPrivateCopy()->m_AlphaSource = source; 246 } 247 248 void CPDF_GeneralState::SetTextKnockout(bool knockout) { 249 m_Ref.GetPrivateCopy()->m_TextKnockout = knockout; 250 } 251 252 void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) { 253 m_Ref.GetPrivateCopy()->m_Matrix = matrix; 254 } 255 256 CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() { 257 return &m_Ref.GetPrivateCopy()->m_Matrix; 258 } 259 260 CPDF_GeneralState::StateData::StateData() 261 : m_BlendMode("Normal"), 262 m_BlendType(0), 263 m_pSoftMask(nullptr), 264 m_StrokeAlpha(1.0), 265 m_FillAlpha(1.0f), 266 m_pTR(nullptr), 267 m_pTransferFunc(nullptr), 268 m_RenderIntent(0), 269 m_StrokeAdjust(false), 270 m_AlphaSource(false), 271 m_TextKnockout(false), 272 m_StrokeOP(false), 273 m_FillOP(false), 274 m_OPMode(0), 275 m_pBG(nullptr), 276 m_pUCR(nullptr), 277 m_pHT(nullptr), 278 m_Flatness(1.0f), 279 m_Smoothness(0.0f) { 280 m_SMaskMatrix.SetIdentity(); 281 m_Matrix.SetIdentity(); 282 } 283 284 CPDF_GeneralState::StateData::StateData(const StateData& that) 285 : m_BlendMode(that.m_BlendMode), 286 m_BlendType(that.m_BlendType), 287 m_pSoftMask(that.m_pSoftMask), 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 m_Matrix = that.m_Matrix; 305 m_SMaskMatrix = that.m_SMaskMatrix; 306 307 if (that.m_pTransferFunc && that.m_pTransferFunc->GetDocument()) { 308 CPDF_DocRenderData* pDocCache = 309 that.m_pTransferFunc->GetDocument()->GetRenderData(); 310 if (pDocCache) 311 m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR.Get()); 312 } 313 } 314 315 CPDF_GeneralState::StateData::~StateData() { 316 if (m_pTransferFunc && m_pTransferFunc->GetDocument()) { 317 CPDF_DocRenderData* pDocCache = 318 m_pTransferFunc->GetDocument()->GetRenderData(); 319 if (pDocCache) { 320 m_pTransferFunc.Reset(); // Give up our reference first. 321 pDocCache->MaybePurgeTransferFunc(m_pTR.Get()); 322 } 323 } 324 } 325