// 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_path.h"

CPDF_Path::CPDF_Path() = default;

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

CPDF_Path::~CPDF_Path() = default;

const std::vector<FX_PATHPOINT>& CPDF_Path::GetPoints() const {
  return m_Ref.GetObject()->GetPoints();
}

void CPDF_Path::ClosePath() {
  m_Ref.GetPrivateCopy()->ClosePath();
}

CFX_PointF CPDF_Path::GetPoint(int index) const {
  return m_Ref.GetObject()->GetPoint(index);
}

CFX_FloatRect CPDF_Path::GetBoundingBox() const {
  return m_Ref.GetObject()->GetBoundingBox();
}

CFX_FloatRect CPDF_Path::GetBoundingBox(float line_width,
                                        float miter_limit) const {
  return m_Ref.GetObject()->GetBoundingBox(line_width, miter_limit);
}

bool CPDF_Path::IsRect() const {
  return m_Ref.GetObject()->IsRect();
}

void CPDF_Path::Transform(const CFX_Matrix& matrix) {
  m_Ref.GetPrivateCopy()->Transform(matrix);
}

void CPDF_Path::Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix) {
  m_Ref.GetPrivateCopy()->Append(pData, pMatrix);
}

void CPDF_Path::AppendFloatRect(const CFX_FloatRect& rect) {
  m_Ref.GetPrivateCopy()->AppendFloatRect(rect);
}

void CPDF_Path::AppendRect(float left, float bottom, float right, float top) {
  m_Ref.GetPrivateCopy()->AppendRect(left, bottom, right, top);
}

void CPDF_Path::AppendPoint(const CFX_PointF& point, FXPT_TYPE type) {
  CFX_PathData data;
  data.AppendPoint(point, type);
  Append(&data, nullptr);
}

void CPDF_Path::AppendPointAndClose(const CFX_PointF& point, FXPT_TYPE type) {
  CFX_PathData data;
  data.AppendPointAndClose(point, type);
  Append(&data, nullptr);
}
