From 4d9df422c340b3bc33e044d3d94e1ff9582e1260 Mon Sep 17 00:00:00 2001 From: tsepez Date: Wed, 31 Aug 2016 10:26:38 -0700 Subject: Make CPDF_GraphState have a CPDF_GraphStateData instead of inheriting. Get callers out of the copy-before-write business, and let the class manage it instead. Review-Url: https://codereview.chromium.org/2292363002 --- BUILD.gn | 1 + core/fpdfapi/fpdf_page/cpdf_allstates.cpp | 18 ++++----- core/fpdfapi/fpdf_page/cpdf_graphstate.cpp | 61 +++++++++++++++++++++++++++++ core/fpdfapi/fpdf_page/cpdf_graphstate.h | 32 ++++++++++++++- core/fpdfapi/fpdf_page/cpdf_pathobject.cpp | 4 +- core/fpdfapi/fpdf_page/cpdf_textobject.cpp | 2 +- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 13 +++--- core/fpdfapi/fpdf_render/fpdf_render.cpp | 10 ++--- 8 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 core/fpdfapi/fpdf_page/cpdf_graphstate.cpp diff --git a/BUILD.gn b/BUILD.gn index 8efaf04793..b2f16b3ff1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -429,6 +429,7 @@ static_library("fpdfapi") { "core/fpdfapi/fpdf_page/cpdf_generalstatedata.cpp", "core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp", "core/fpdfapi/fpdf_page/cpdf_graphicstates.h", + "core/fpdfapi/fpdf_page/cpdf_graphstate.cpp", "core/fpdfapi/fpdf_page/cpdf_graphstate.h", "core/fpdfapi/fpdf_page/cpdf_image.cpp", "core/fpdfapi/fpdf_page/cpdf_imageobject.cpp", diff --git a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp index e01b379bed..acecafd01e 100644 --- a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp @@ -45,11 +45,7 @@ void CPDF_AllStates::Copy(const CPDF_AllStates& src) { void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale) { - CFX_GraphStateData* pData = m_GraphState.GetPrivateCopy(); - pData->m_DashPhase = phase * scale; - pData->SetDashCount(static_cast(pArray->GetCount())); - for (size_t i = 0; i < pArray->GetCount(); i++) - pData->m_DashArray[i] = pArray->GetNumberAt(i) * scale; + m_GraphState.SetLineDash(pArray, phase, scale); } void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, @@ -65,18 +61,18 @@ void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, uint32_t key = key_str.GetID(); switch (key) { case FXBSTR_ID('L', 'W', 0, 0): - m_GraphState.GetPrivateCopy()->m_LineWidth = pObject->GetNumber(); + m_GraphState.SetLineWidth(pObject->GetNumber()); break; case FXBSTR_ID('L', 'C', 0, 0): - m_GraphState.GetPrivateCopy()->m_LineCap = - (CFX_GraphStateData::LineCap)pObject->GetInteger(); + m_GraphState.SetLineCap( + static_cast(pObject->GetInteger())); break; case FXBSTR_ID('L', 'J', 0, 0): - m_GraphState.GetPrivateCopy()->m_LineJoin = - (CFX_GraphStateData::LineJoin)pObject->GetInteger(); + m_GraphState.SetLineJoin( + static_cast(pObject->GetInteger())); break; case FXBSTR_ID('M', 'L', 0, 0): - m_GraphState.GetPrivateCopy()->m_MiterLimit = pObject->GetNumber(); + m_GraphState.SetMiterLimit(pObject->GetNumber()); break; case FXBSTR_ID('D', 0, 0, 0): { CPDF_Array* pDash = pObject->AsArray(); diff --git a/core/fpdfapi/fpdf_page/cpdf_graphstate.cpp b/core/fpdfapi/fpdf_page/cpdf_graphstate.cpp new file mode 100644 index 0000000000..5a8dbe841a --- /dev/null +++ b/core/fpdfapi/fpdf_page/cpdf_graphstate.cpp @@ -0,0 +1,61 @@ +// 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/cpdf_graphstate.h" + +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" + +CPDF_GraphState::CPDF_GraphState() {} + +CPDF_GraphState::CPDF_GraphState(const CPDF_GraphState& that) + : m_Ref(that.m_Ref) {} + +CPDF_GraphState::~CPDF_GraphState() {} + +void CPDF_GraphState::Emplace() { + m_Ref.Emplace(); +} + +void CPDF_GraphState::SetLineDash(CPDF_Array* pArray, + FX_FLOAT phase, + FX_FLOAT scale) { + CFX_GraphStateData* pData = m_Ref.GetPrivateCopy(); + pData->m_DashPhase = phase * scale; + pData->SetDashCount(static_cast(pArray->GetCount())); + for (size_t i = 0; i < pArray->GetCount(); i++) + pData->m_DashArray[i] = pArray->GetNumberAt(i) * scale; +} + +FX_FLOAT CPDF_GraphState::GetLineWidth() const { + return m_Ref.GetObject()->m_LineWidth; +} + +void CPDF_GraphState::SetLineWidth(FX_FLOAT width) { + m_Ref.GetPrivateCopy()->m_LineWidth = width; +} + +CFX_GraphStateData::LineCap CPDF_GraphState::GetLineCap() const { + return m_Ref.GetObject()->m_LineCap; +} +void CPDF_GraphState::SetLineCap(CFX_GraphStateData::LineCap cap) { + m_Ref.GetPrivateCopy()->m_LineCap = cap; +} + +CFX_GraphStateData::LineJoin CPDF_GraphState::GetLineJoin() const { + return m_Ref.GetObject()->m_LineJoin; +} + +void CPDF_GraphState::SetLineJoin(CFX_GraphStateData::LineJoin join) { + m_Ref.GetPrivateCopy()->m_LineJoin = join; +} + +FX_FLOAT CPDF_GraphState::GetMiterLimit() const { + return m_Ref.GetObject()->m_MiterLimit; +} + +void CPDF_GraphState::SetMiterLimit(FX_FLOAT limit) { + m_Ref.GetPrivateCopy()->m_MiterLimit = limit; +} diff --git a/core/fpdfapi/fpdf_page/cpdf_graphstate.h b/core/fpdfapi/fpdf_page/cpdf_graphstate.h index 7748bb203d..c3e3880f3c 100644 --- a/core/fpdfapi/fpdf_page/cpdf_graphstate.h +++ b/core/fpdfapi/fpdf_page/cpdf_graphstate.h @@ -7,8 +7,38 @@ #ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHSTATE_H_ #define CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHSTATE_H_ +#include "core/fxcrt/include/cfx_count_ref.h" #include "core/fxge/include/cfx_graphstatedata.h" -class CPDF_GraphState : public CFX_CountRef {}; +class CPDF_Array; + +class CPDF_GraphState { + public: + CPDF_GraphState(); + CPDF_GraphState(const CPDF_GraphState& that); + ~CPDF_GraphState(); + + void Emplace(); + + void SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale); + + FX_FLOAT GetLineWidth() const; + void SetLineWidth(FX_FLOAT width); + + CFX_GraphStateData::LineCap GetLineCap() const; + void SetLineCap(CFX_GraphStateData::LineCap cap); + + CFX_GraphStateData::LineJoin GetLineJoin() const; + void SetLineJoin(CFX_GraphStateData::LineJoin join); + + FX_FLOAT GetMiterLimit() const; + void SetMiterLimit(FX_FLOAT limit); + + // FIXME(tsepez): remove when all GraphStateData usage gone. + const CFX_GraphStateData* GetObject() const { return m_Ref.GetObject(); } + + private: + CFX_CountRef m_Ref; +}; #endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHSTATE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp b/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp index 0055d6a133..946d934edb 100644 --- a/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp @@ -46,9 +46,9 @@ void CPDF_PathObject::CalcBoundingBox() { if (!m_Path) return; CFX_FloatRect rect; - FX_FLOAT width = m_GraphState.GetObject()->m_LineWidth; + FX_FLOAT width = m_GraphState.GetLineWidth(); if (m_bStroke && width != 0) { - rect = m_Path.GetBoundingBox(width, m_GraphState.GetObject()->m_MiterLimit); + rect = m_Path.GetBoundingBox(width, m_GraphState.GetMiterLimit()); } else { rect = m_Path.GetBoundingBox(); } diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp index f9e6bdaa76..1c6f37cad4 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp @@ -365,7 +365,7 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, m_Top = max_y; matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); if (TextRenderingModeIsStrokeMode(m_TextState.GetTextMode())) { - FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; + FX_FLOAT half_width = m_GraphState.GetLineWidth() / 2; m_Left -= half_width; m_Right += half_width; m_Top += half_width; diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 5560b9c20f..70e1d1aea6 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -881,13 +881,13 @@ void CPDF_StreamContentParser::Handle_SetFlat() { void CPDF_StreamContentParser::Handle_BeginImageData() {} void CPDF_StreamContentParser::Handle_SetLineJoin() { - m_pCurStates->m_GraphState.GetPrivateCopy()->m_LineJoin = - (CFX_GraphStateData::LineJoin)GetInteger(0); + m_pCurStates->m_GraphState.SetLineJoin( + static_cast(GetInteger(0))); } void CPDF_StreamContentParser::Handle_SetLineCap() { - m_pCurStates->m_GraphState.GetPrivateCopy()->m_LineCap = - (CFX_GraphStateData::LineCap)GetInteger(0); + m_pCurStates->m_GraphState.SetLineCap( + static_cast(GetInteger(0))); } void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() { @@ -930,7 +930,7 @@ void CPDF_StreamContentParser::Handle_MoveTo() { } void CPDF_StreamContentParser::Handle_SetMiterLimit() { - m_pCurStates->m_GraphState.GetPrivateCopy()->m_MiterLimit = GetNumber(0); + m_pCurStates->m_GraphState.SetMiterLimit(GetNumber(0)); } void CPDF_StreamContentParser::Handle_MarkPlace() {} @@ -1399,8 +1399,7 @@ void CPDF_StreamContentParser::Handle_CurveTo_23() { } void CPDF_StreamContentParser::Handle_SetLineWidth() { - FX_FLOAT width = GetNumber(0); - m_pCurStates->m_GraphState.GetPrivateCopy()->m_LineWidth = width; + m_pCurStates->m_GraphState.SetLineWidth(GetNumber(0)); } void CPDF_StreamContentParser::Handle_Clip() { diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp index f77e46d923..c36d7f4cd3 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp @@ -495,12 +495,12 @@ FX_BOOL CPDF_RenderStatus::ProcessPath(const CPDF_PathObject* pPathObj, if (m_pType3Char) FillType |= FX_FILL_TEXT_MODE; - CFX_GraphStateData graphState(*pPathObj->m_GraphState.GetObject()); + CPDF_GraphState graphState = pPathObj->m_GraphState; if (m_Options.m_Flags & RENDER_THINLINE) - graphState.m_LineWidth = 0; - return m_pDevice->DrawPathWithBlend(pPathObj->m_Path.GetObject(), - &path_matrix, &graphState, fill_argb, - stroke_argb, FillType, m_curBlend); + graphState.SetLineWidth(0); + return m_pDevice->DrawPathWithBlend( + pPathObj->m_Path.GetObject(), &path_matrix, graphState.GetObject(), + fill_argb, stroke_argb, FillType, m_curBlend); } CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const { -- cgit v1.2.3