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 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