Home | History | Annotate | Download | only in page
      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