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 CFX_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 CFX_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 CFX_ByteString& ri) { 79 m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri); 80 } 81 82 int CPDF_GeneralState::GetBlendType() const { 83 const StateData* pData = m_Ref.GetObject(); 84 return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL; 85 } 86 87 void CPDF_GeneralState::SetBlendType(int type) { 88 m_Ref.GetPrivateCopy()->m_BlendType = type; 89 } 90 91 FX_FLOAT CPDF_GeneralState::GetFillAlpha() const { 92 const StateData* pData = m_Ref.GetObject(); 93 return pData ? pData->m_FillAlpha : 1.0f; 94 } 95 96 void CPDF_GeneralState::SetFillAlpha(FX_FLOAT alpha) { 97 m_Ref.GetPrivateCopy()->m_FillAlpha = alpha; 98 } 99 100 FX_FLOAT CPDF_GeneralState::GetStrokeAlpha() const { 101 const StateData* pData = m_Ref.GetObject(); 102 return pData ? pData->m_StrokeAlpha : 1.0f; 103 } 104 105 void CPDF_GeneralState::SetStrokeAlpha(FX_FLOAT alpha) { 106 m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha; 107 } 108 109 CPDF_Object* CPDF_GeneralState::GetSoftMask() const { 110 const StateData* pData = m_Ref.GetObject(); 111 return pData ? pData->m_pSoftMask : nullptr; 112 } 113 114 void CPDF_GeneralState::SetSoftMask(CPDF_Object* pObject) { 115 m_Ref.GetPrivateCopy()->m_pSoftMask = pObject; 116 } 117 118 CPDF_Object* CPDF_GeneralState::GetTR() const { 119 const StateData* pData = m_Ref.GetObject(); 120 return pData ? pData->m_pTR : nullptr; 121 } 122 123 void CPDF_GeneralState::SetTR(CPDF_Object* pObject) { 124 m_Ref.GetPrivateCopy()->m_pTR = pObject; 125 } 126 127 CPDF_TransferFunc* CPDF_GeneralState::GetTransferFunc() const { 128 const StateData* pData = m_Ref.GetObject(); 129 return pData ? pData->m_pTransferFunc : nullptr; 130 } 131 132 void CPDF_GeneralState::SetTransferFunc(CPDF_TransferFunc* pFunc) { 133 m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc; 134 } 135 136 void CPDF_GeneralState::SetBlendMode(const CFX_ByteString& mode) { 137 StateData* pData = m_Ref.GetPrivateCopy(); 138 pData->m_BlendMode = mode; 139 pData->m_BlendType = GetBlendTypeInternal(mode); 140 } 141 142 const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const { 143 const StateData* pData = m_Ref.GetObject(); 144 return pData ? &pData->m_SMaskMatrix : nullptr; 145 } 146 147 void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) { 148 m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix; 149 } 150 151 bool CPDF_GeneralState::GetFillOP() const { 152 const StateData* pData = m_Ref.GetObject(); 153 return pData && pData->m_FillOP; 154 } 155 156 void CPDF_GeneralState::SetFillOP(bool op) { 157 m_Ref.GetPrivateCopy()->m_FillOP = op; 158 } 159 160 void CPDF_GeneralState::SetStrokeOP(bool op) { 161 m_Ref.GetPrivateCopy()->m_StrokeOP = op; 162 } 163 164 bool CPDF_GeneralState::GetStrokeOP() const { 165 const StateData* pData = m_Ref.GetObject(); 166 return pData && pData->m_StrokeOP; 167 } 168 169 int CPDF_GeneralState::GetOPMode() const { 170 return m_Ref.GetObject()->m_OPMode; 171 } 172 173 void CPDF_GeneralState::SetOPMode(int mode) { 174 m_Ref.GetPrivateCopy()->m_OPMode = mode; 175 } 176 177 void CPDF_GeneralState::SetBG(CPDF_Object* pObject) { 178 m_Ref.GetPrivateCopy()->m_pBG = pObject; 179 } 180 181 void CPDF_GeneralState::SetUCR(CPDF_Object* pObject) { 182 m_Ref.GetPrivateCopy()->m_pUCR = pObject; 183 } 184 185 void CPDF_GeneralState::SetHT(CPDF_Object* pObject) { 186 m_Ref.GetPrivateCopy()->m_pHT = pObject; 187 } 188 189 void CPDF_GeneralState::SetFlatness(FX_FLOAT flatness) { 190 m_Ref.GetPrivateCopy()->m_Flatness = flatness; 191 } 192 193 void CPDF_GeneralState::SetSmoothness(FX_FLOAT smoothness) { 194 m_Ref.GetPrivateCopy()->m_Smoothness = smoothness; 195 } 196 197 bool CPDF_GeneralState::GetStrokeAdjust() const { 198 const StateData* pData = m_Ref.GetObject(); 199 return pData && pData->m_StrokeAdjust; 200 } 201 202 void CPDF_GeneralState::SetStrokeAdjust(bool adjust) { 203 m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust; 204 } 205 206 void CPDF_GeneralState::SetAlphaSource(bool source) { 207 m_Ref.GetPrivateCopy()->m_AlphaSource = source; 208 } 209 210 void CPDF_GeneralState::SetTextKnockout(bool knockout) { 211 m_Ref.GetPrivateCopy()->m_TextKnockout = knockout; 212 } 213 214 void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) { 215 m_Ref.GetPrivateCopy()->m_Matrix = matrix; 216 } 217 218 CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() { 219 return &m_Ref.GetPrivateCopy()->m_Matrix; 220 } 221 222 CPDF_GeneralState::StateData::StateData() 223 : m_BlendMode("Normal"), 224 m_BlendType(0), 225 m_pSoftMask(nullptr), 226 m_StrokeAlpha(1.0), 227 m_FillAlpha(1.0f), 228 m_pTR(nullptr), 229 m_pTransferFunc(nullptr), 230 m_RenderIntent(0), 231 m_StrokeAdjust(false), 232 m_AlphaSource(false), 233 m_TextKnockout(false), 234 m_StrokeOP(false), 235 m_FillOP(false), 236 m_OPMode(0), 237 m_pBG(nullptr), 238 m_pUCR(nullptr), 239 m_pHT(nullptr), 240 m_Flatness(1.0f), 241 m_Smoothness(0.0f) { 242 m_SMaskMatrix.SetIdentity(); 243 m_Matrix.SetIdentity(); 244 } 245 246 CPDF_GeneralState::StateData::StateData(const StateData& that) 247 : m_BlendMode(that.m_BlendMode), 248 m_BlendType(that.m_BlendType), 249 m_pSoftMask(that.m_pSoftMask), 250 m_StrokeAlpha(that.m_StrokeAlpha), 251 m_FillAlpha(that.m_FillAlpha), 252 m_pTR(that.m_pTR), 253 m_pTransferFunc(that.m_pTransferFunc), 254 m_RenderIntent(that.m_RenderIntent), 255 m_StrokeAdjust(that.m_StrokeAdjust), 256 m_AlphaSource(that.m_AlphaSource), 257 m_TextKnockout(that.m_TextKnockout), 258 m_StrokeOP(that.m_StrokeOP), 259 m_FillOP(that.m_FillOP), 260 m_OPMode(that.m_OPMode), 261 m_pBG(that.m_pBG), 262 m_pUCR(that.m_pUCR), 263 m_pHT(that.m_pHT), 264 m_Flatness(that.m_Flatness), 265 m_Smoothness(that.m_Smoothness) { 266 m_Matrix = that.m_Matrix; 267 m_SMaskMatrix = that.m_SMaskMatrix; 268 269 if (that.m_pTransferFunc && that.m_pTransferFunc->m_pPDFDoc) { 270 CPDF_DocRenderData* pDocCache = 271 that.m_pTransferFunc->m_pPDFDoc->GetRenderData(); 272 if (pDocCache) 273 m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR); 274 } 275 } 276 277 CPDF_GeneralState::StateData::~StateData() { 278 if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) { 279 CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData(); 280 if (pDocCache) 281 pDocCache->ReleaseTransferFunc(m_pTR); 282 } 283 } 284