// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/fpdf_page/include/cpdf_generalstate.h"

#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_render/render_int.h"

namespace {

int RI_StringToId(const CFX_ByteString& ri) {
  uint32_t id = ri.GetID();
  if (id == FXBSTR_ID('A', 'b', 's', 'o'))
    return 1;

  if (id == FXBSTR_ID('S', 'a', 't', 'u'))
    return 2;

  if (id == FXBSTR_ID('P', 'e', 'r', 'c'))
    return 3;

  return 0;
}

int GetBlendTypeInternal(const CFX_ByteString& mode) {
  switch (mode.GetID()) {
    case FXBSTR_ID('N', 'o', 'r', 'm'):
    case FXBSTR_ID('C', 'o', 'm', 'p'):
      return FXDIB_BLEND_NORMAL;
    case FXBSTR_ID('M', 'u', 'l', 't'):
      return FXDIB_BLEND_MULTIPLY;
    case FXBSTR_ID('S', 'c', 'r', 'e'):
      return FXDIB_BLEND_SCREEN;
    case FXBSTR_ID('O', 'v', 'e', 'r'):
      return FXDIB_BLEND_OVERLAY;
    case FXBSTR_ID('D', 'a', 'r', 'k'):
      return FXDIB_BLEND_DARKEN;
    case FXBSTR_ID('L', 'i', 'g', 'h'):
      return FXDIB_BLEND_LIGHTEN;
    case FXBSTR_ID('C', 'o', 'l', 'o'):
      if (mode.GetLength() == 10)
        return FXDIB_BLEND_COLORDODGE;
      if (mode.GetLength() == 9)
        return FXDIB_BLEND_COLORBURN;
      return FXDIB_BLEND_COLOR;
    case FXBSTR_ID('H', 'a', 'r', 'd'):
      return FXDIB_BLEND_HARDLIGHT;
    case FXBSTR_ID('S', 'o', 'f', 't'):
      return FXDIB_BLEND_SOFTLIGHT;
    case FXBSTR_ID('D', 'i', 'f', 'f'):
      return FXDIB_BLEND_DIFFERENCE;
    case FXBSTR_ID('E', 'x', 'c', 'l'):
      return FXDIB_BLEND_EXCLUSION;
    case FXBSTR_ID('H', 'u', 'e', 0):
      return FXDIB_BLEND_HUE;
    case FXBSTR_ID('S', 'a', 't', 'u'):
      return FXDIB_BLEND_SATURATION;
    case FXBSTR_ID('L', 'u', 'm', 'i'):
      return FXDIB_BLEND_LUMINOSITY;
  }
  return FXDIB_BLEND_NORMAL;
}

}  // namespace

CPDF_GeneralState::CPDF_GeneralState() {}

CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that)
    : m_Ref(that.m_Ref) {}

CPDF_GeneralState::~CPDF_GeneralState() {}

void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) {
  m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri);
}

int CPDF_GeneralState::GetBlendType() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL;
}

void CPDF_GeneralState::SetBlendType(int type) {
  m_Ref.GetPrivateCopy()->m_BlendType = type;
}

FX_FLOAT CPDF_GeneralState::GetFillAlpha() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_FillAlpha : 1.0f;
}

void CPDF_GeneralState::SetFillAlpha(FX_FLOAT alpha) {
  m_Ref.GetPrivateCopy()->m_FillAlpha = alpha;
}

FX_FLOAT CPDF_GeneralState::GetStrokeAlpha() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_StrokeAlpha : 1.0f;
}

void CPDF_GeneralState::SetStrokeAlpha(FX_FLOAT alpha) {
  m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha;
}

CPDF_Object* CPDF_GeneralState::GetSoftMask() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_pSoftMask : nullptr;
}

void CPDF_GeneralState::SetSoftMask(CPDF_Object* pObject) {
  m_Ref.GetPrivateCopy()->m_pSoftMask = pObject;
}

CPDF_Object* CPDF_GeneralState::GetTR() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_pTR : nullptr;
}

void CPDF_GeneralState::SetTR(CPDF_Object* pObject) {
  m_Ref.GetPrivateCopy()->m_pTR = pObject;
}

CPDF_TransferFunc* CPDF_GeneralState::GetTransferFunc() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? pData->m_pTransferFunc : nullptr;
}

void CPDF_GeneralState::SetTransferFunc(CPDF_TransferFunc* pFunc) {
  m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc;
}

void CPDF_GeneralState::SetBlendMode(const CFX_ByteString& mode) {
  StateData* pData = m_Ref.GetPrivateCopy();
  pData->m_BlendMode = mode;
  pData->m_BlendType = GetBlendTypeInternal(mode);
}

const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const {
  const StateData* pData = m_Ref.GetObject();
  return pData ? &pData->m_SMaskMatrix : nullptr;
}

void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) {
  m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix;
}

bool CPDF_GeneralState::GetFillOP() const {
  const StateData* pData = m_Ref.GetObject();
  return pData && pData->m_FillOP;
}

void CPDF_GeneralState::SetFillOP(bool op) {
  m_Ref.GetPrivateCopy()->m_FillOP = op;
}

void CPDF_GeneralState::SetStrokeOP(bool op) {
  m_Ref.GetPrivateCopy()->m_StrokeOP = op;
}

bool CPDF_GeneralState::GetStrokeOP() const {
  const StateData* pData = m_Ref.GetObject();
  return pData && pData->m_StrokeOP;
}

int CPDF_GeneralState::GetOPMode() const {
  return m_Ref.GetObject()->m_OPMode;
}

void CPDF_GeneralState::SetOPMode(int mode) {
  m_Ref.GetPrivateCopy()->m_OPMode = mode;
}

void CPDF_GeneralState::SetBG(CPDF_Object* pObject) {
  m_Ref.GetPrivateCopy()->m_pBG = pObject;
}

void CPDF_GeneralState::SetUCR(CPDF_Object* pObject) {
  m_Ref.GetPrivateCopy()->m_pUCR = pObject;
}

void CPDF_GeneralState::SetHT(CPDF_Object* pObject) {
  m_Ref.GetPrivateCopy()->m_pHT = pObject;
}

void CPDF_GeneralState::SetFlatness(FX_FLOAT flatness) {
  m_Ref.GetPrivateCopy()->m_Flatness = flatness;
}

void CPDF_GeneralState::SetSmoothness(FX_FLOAT smoothness) {
  m_Ref.GetPrivateCopy()->m_Smoothness = smoothness;
}

bool CPDF_GeneralState::GetStrokeAdjust() const {
  const StateData* pData = m_Ref.GetObject();
  return pData && pData->m_StrokeAdjust;
}

void CPDF_GeneralState::SetStrokeAdjust(bool adjust) {
  m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust;
}

void CPDF_GeneralState::SetAlphaSource(bool source) {
  m_Ref.GetPrivateCopy()->m_AlphaSource = source;
}

void CPDF_GeneralState::SetTextKnockout(bool knockout) {
  m_Ref.GetPrivateCopy()->m_TextKnockout = knockout;
}

void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) {
  m_Ref.GetPrivateCopy()->m_Matrix = matrix;
}

CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() {
  return &m_Ref.GetPrivateCopy()->m_Matrix;
}

CPDF_GeneralState::StateData::StateData()
    : m_BlendMode("Normal"),
      m_BlendType(0),
      m_pSoftMask(nullptr),
      m_StrokeAlpha(1.0),
      m_FillAlpha(1.0f),
      m_pTR(nullptr),
      m_pTransferFunc(nullptr),
      m_RenderIntent(0),
      m_StrokeAdjust(false),
      m_AlphaSource(false),
      m_TextKnockout(false),
      m_StrokeOP(false),
      m_FillOP(false),
      m_OPMode(0),
      m_pBG(nullptr),
      m_pUCR(nullptr),
      m_pHT(nullptr),
      m_Flatness(1.0f),
      m_Smoothness(0.0f) {
  m_SMaskMatrix.SetIdentity();
  m_Matrix.SetIdentity();
}

CPDF_GeneralState::StateData::StateData(const StateData& that)
    : m_BlendMode(that.m_BlendMode),
      m_BlendType(that.m_BlendType),
      m_pSoftMask(that.m_pSoftMask),
      m_StrokeAlpha(that.m_StrokeAlpha),
      m_FillAlpha(that.m_FillAlpha),
      m_pTR(that.m_pTR),
      m_pTransferFunc(that.m_pTransferFunc),
      m_RenderIntent(that.m_RenderIntent),
      m_StrokeAdjust(that.m_StrokeAdjust),
      m_AlphaSource(that.m_AlphaSource),
      m_TextKnockout(that.m_TextKnockout),
      m_StrokeOP(that.m_StrokeOP),
      m_FillOP(that.m_FillOP),
      m_OPMode(that.m_OPMode),
      m_pBG(that.m_pBG),
      m_pUCR(that.m_pUCR),
      m_pHT(that.m_pHT),
      m_Flatness(that.m_Flatness),
      m_Smoothness(that.m_Smoothness) {
  m_Matrix = that.m_Matrix;
  m_SMaskMatrix = that.m_SMaskMatrix;

  if (that.m_pTransferFunc && that.m_pTransferFunc->m_pPDFDoc) {
    CPDF_DocRenderData* pDocCache =
        that.m_pTransferFunc->m_pPDFDoc->GetRenderData();
    if (pDocCache)
      m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
  }
}

CPDF_GeneralState::StateData::~StateData() {
  if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
    CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
    if (pDocCache)
      pDocCache->ReleaseTransferFunc(m_pTR);
  }
}
