| // 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/page/cpdf_colorstate.h" |
| |
| #include "core/fpdfapi/page/cpdf_colorspace.h" |
| #include "core/fpdfapi/page/cpdf_pattern.h" |
| #include "core/fpdfapi/page/cpdf_tilingpattern.h" |
| #include "core/fxge/dib/fx_dib.h" |
| #include "third_party/base/check.h" |
| |
| CPDF_ColorState::CPDF_ColorState() = default; |
| |
| CPDF_ColorState::CPDF_ColorState(const CPDF_ColorState& that) |
| : m_Ref(that.m_Ref) {} |
| |
| CPDF_ColorState::~CPDF_ColorState() = default; |
| |
| void CPDF_ColorState::Emplace() { |
| m_Ref.Emplace(); |
| } |
| |
| void CPDF_ColorState::SetDefault() { |
| m_Ref.GetPrivateCopy()->SetDefault(); |
| } |
| |
| FX_COLORREF CPDF_ColorState::GetFillColorRef() const { |
| return m_Ref.GetObject()->m_FillColorRef; |
| } |
| |
| void CPDF_ColorState::SetFillColorRef(FX_COLORREF colorref) { |
| m_Ref.GetPrivateCopy()->m_FillColorRef = colorref; |
| } |
| |
| FX_COLORREF CPDF_ColorState::GetStrokeColorRef() const { |
| return m_Ref.GetObject()->m_StrokeColorRef; |
| } |
| |
| void CPDF_ColorState::SetStrokeColorRef(FX_COLORREF colorref) { |
| m_Ref.GetPrivateCopy()->m_StrokeColorRef = colorref; |
| } |
| |
| const CPDF_Color* CPDF_ColorState::GetFillColor() const { |
| const ColorData* pData = m_Ref.GetObject(); |
| return pData ? &pData->m_FillColor : nullptr; |
| } |
| |
| CPDF_Color* CPDF_ColorState::GetMutableFillColor() { |
| return &m_Ref.GetPrivateCopy()->m_FillColor; |
| } |
| |
| bool CPDF_ColorState::HasFillColor() const { |
| const CPDF_Color* pColor = GetFillColor(); |
| return pColor && !pColor->IsNull(); |
| } |
| |
| const CPDF_Color* CPDF_ColorState::GetStrokeColor() const { |
| const ColorData* pData = m_Ref.GetObject(); |
| return pData ? &pData->m_StrokeColor : nullptr; |
| } |
| |
| CPDF_Color* CPDF_ColorState::GetMutableStrokeColor() { |
| return &m_Ref.GetPrivateCopy()->m_StrokeColor; |
| } |
| |
| bool CPDF_ColorState::HasStrokeColor() const { |
| const CPDF_Color* pColor = GetStrokeColor(); |
| return pColor && !pColor->IsNull(); |
| } |
| |
| void CPDF_ColorState::SetFillColor(const RetainPtr<CPDF_ColorSpace>& pCS, |
| const std::vector<float>& values) { |
| ColorData* pData = m_Ref.GetPrivateCopy(); |
| SetColor(pCS, values, &pData->m_FillColor, &pData->m_FillColorRef); |
| } |
| |
| void CPDF_ColorState::SetStrokeColor(const RetainPtr<CPDF_ColorSpace>& pCS, |
| const std::vector<float>& values) { |
| ColorData* pData = m_Ref.GetPrivateCopy(); |
| SetColor(pCS, values, &pData->m_StrokeColor, &pData->m_StrokeColorRef); |
| } |
| |
| void CPDF_ColorState::SetFillPattern(const RetainPtr<CPDF_Pattern>& pPattern, |
| const std::vector<float>& values) { |
| ColorData* pData = m_Ref.GetPrivateCopy(); |
| SetPattern(pPattern, values, &pData->m_FillColor, &pData->m_FillColorRef); |
| } |
| |
| void CPDF_ColorState::SetStrokePattern(const RetainPtr<CPDF_Pattern>& pPattern, |
| const std::vector<float>& values) { |
| ColorData* pData = m_Ref.GetPrivateCopy(); |
| SetPattern(pPattern, values, &pData->m_StrokeColor, &pData->m_StrokeColorRef); |
| } |
| |
| void CPDF_ColorState::SetColor(const RetainPtr<CPDF_ColorSpace>& pCS, |
| const std::vector<float>& values, |
| CPDF_Color* color, |
| FX_COLORREF* colorref) { |
| DCHECK(color); |
| DCHECK(colorref); |
| |
| if (pCS) { |
| color->SetColorSpace(pCS); |
| } else if (color->IsNull()) { |
| color->SetColorSpace( |
| CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceGray)); |
| } |
| if (color->CountComponents() > values.size()) |
| return; |
| |
| if (!color->IsPattern()) |
| color->SetValueForNonPattern(values); |
| int R; |
| int G; |
| int B; |
| *colorref = color->GetRGB(&R, &G, &B) ? FXSYS_BGR(B, G, R) : 0xFFFFFFFF; |
| } |
| |
| void CPDF_ColorState::SetPattern(const RetainPtr<CPDF_Pattern>& pPattern, |
| const std::vector<float>& values, |
| CPDF_Color* color, |
| FX_COLORREF* colorref) { |
| DCHECK(color); |
| DCHECK(colorref); |
| |
| color->SetValueForPattern(pPattern, values); |
| int R; |
| int G; |
| int B; |
| bool ret = color->GetRGB(&R, &G, &B); |
| if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) { |
| if (!ret && pTilingPattern->colored()) { |
| *colorref = 0x00BFBFBF; |
| return; |
| } |
| } |
| *colorref = ret ? FXSYS_BGR(B, G, R) : 0xFFFFFFFF; |
| } |
| |
| CPDF_ColorState::ColorData::ColorData() = default; |
| |
| CPDF_ColorState::ColorData::ColorData(const ColorData& src) |
| : m_FillColorRef(src.m_FillColorRef), |
| m_StrokeColorRef(src.m_StrokeColorRef), |
| m_FillColor(src.m_FillColor), |
| m_StrokeColor(src.m_StrokeColor) {} |
| |
| CPDF_ColorState::ColorData::~ColorData() = default; |
| |
| void CPDF_ColorState::ColorData::SetDefault() { |
| m_FillColorRef = 0; |
| m_StrokeColorRef = 0; |
| m_FillColor.SetColorSpace( |
| CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceGray)); |
| m_StrokeColor.SetColorSpace( |
| CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceGray)); |
| } |
| |
| RetainPtr<CPDF_ColorState::ColorData> CPDF_ColorState::ColorData::Clone() |
| const { |
| return pdfium::MakeRetain<CPDF_ColorState::ColorData>(*this); |
| } |