// Copyright 2014 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

#ifndef XFA_FDE_CFDE_RENDERDEVICE_H_
#define XFA_FDE_CFDE_RENDERDEVICE_H_

#include <vector>

#include "core/fxge/cfx_renderdevice.h"
#include "xfa/fgas/font/cfgas_gefont.h"

class CFDE_Brush;
class CFDE_Path;
class CFDE_Pen;
class CFX_GraphStateData;

class CFDE_RenderDevice {
 public:
  explicit CFDE_RenderDevice(CFX_RenderDevice* pDevice);
  ~CFDE_RenderDevice();

  int32_t GetWidth() const;
  int32_t GetHeight() const;
  void SaveState();
  void RestoreState();
  bool SetClipPath(const CFDE_Path* pClip);
  CFDE_Path* GetClipPath() const;
  bool SetClipRect(const CFX_RectF& rtClip);
  const CFX_RectF& GetClipRect();

  float GetDpiX() const;
  float GetDpiY() const;

  bool DrawImage(const CFX_RetainPtr<CFX_DIBSource>& pDib,
                 const CFX_RectF* pSrcRect,
                 const CFX_RectF& dstRect,
                 const CFX_Matrix* pImgMatrix = nullptr,
                 const CFX_Matrix* pDevMatrix = nullptr);
  bool DrawString(CFDE_Brush* pBrush,
                  const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                  const FXTEXT_CHARPOS* pCharPos,
                  int32_t iCount,
                  float fFontSize,
                  const CFX_Matrix* pMatrix = nullptr);
  bool DrawBezier(CFDE_Pen* pPen,
                  float fPenWidth,
                  const CFX_PointF& pt1,
                  const CFX_PointF& pt2,
                  const CFX_PointF& pt3,
                  const CFX_PointF& pt4,
                  const CFX_Matrix* pMatrix = nullptr);
  bool DrawCurve(CFDE_Pen* pPen,
                 float fPenWidth,
                 const std::vector<CFX_PointF>& points,
                 bool bClosed,
                 float fTension = 0.5f,
                 const CFX_Matrix* pMatrix = nullptr);
  bool DrawEllipse(CFDE_Pen* pPen,
                   float fPenWidth,
                   const CFX_RectF& rect,
                   const CFX_Matrix* pMatrix = nullptr);
  bool DrawLines(CFDE_Pen* pPen,
                 float fPenWidth,
                 const std::vector<CFX_PointF>& points,
                 const CFX_Matrix* pMatrix = nullptr);
  bool DrawLine(CFDE_Pen* pPen,
                float fPenWidth,
                const CFX_PointF& pt1,
                const CFX_PointF& pt2,
                const CFX_Matrix* pMatrix = nullptr);
  bool DrawPath(CFDE_Pen* pPen,
                float fPenWidth,
                const CFDE_Path* pPath,
                const CFX_Matrix* pMatrix = nullptr);
  bool DrawPolygon(CFDE_Pen* pPen,
                   float fPenWidth,
                   const std::vector<CFX_PointF>& points,
                   const CFX_Matrix* pMatrix = nullptr);
  bool DrawRectangle(CFDE_Pen* pPen,
                     float fPenWidth,
                     const CFX_RectF& rect,
                     const CFX_Matrix* pMatrix = nullptr);
  bool FillClosedCurve(CFDE_Brush* pBrush,
                       const std::vector<CFX_PointF>& points,
                       float fTension = 0.5f,
                       const CFX_Matrix* pMatrix = nullptr);
  bool FillEllipse(CFDE_Brush* pBrush,
                   const CFX_RectF& rect,
                   const CFX_Matrix* pMatrix = nullptr);
  bool FillPath(CFDE_Brush* pBrush,
                const CFDE_Path* pPath,
                const CFX_Matrix* pMatrix = nullptr);
  bool FillPolygon(CFDE_Brush* pBrush,
                   const std::vector<CFX_PointF>& points,
                   const CFX_Matrix* pMatrix = nullptr);
  bool FillRectangle(CFDE_Brush* pBrush,
                     const CFX_RectF& rect,
                     const CFX_Matrix* pMatrix = nullptr);

  bool DrawSolidString(CFDE_Brush* pBrush,
                       const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                       const FXTEXT_CHARPOS* pCharPos,
                       int32_t iCount,
                       float fFontSize,
                       const CFX_Matrix* pMatrix);
  bool DrawStringPath(CFDE_Brush* pBrush,
                      const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                      const FXTEXT_CHARPOS* pCharPos,
                      int32_t iCount,
                      float fFontSize,
                      const CFX_Matrix* pMatrix);

 protected:
  bool CreatePen(CFDE_Pen* pPen,
                 float fPenWidth,
                 CFX_GraphStateData& graphState);

  CFX_RenderDevice* const m_pDevice;
  CFX_RectF m_rtClip;
  int32_t m_iCharCount;
};

#endif  // XFA_FDE_CFDE_RENDERDEVICE_H_
