// 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 CORE_FXGE_INCLUDE_FX_GE_H_
#define CORE_FXGE_INCLUDE_FX_GE_H_

#include <memory>

#include "core/fxge/include/cfx_fontmgr.h"
#include "core/fxge/include/fx_dib.h"
#include "core/fxge/include/fx_font.h"

class CCodec_ModuleMgr;
class CFX_FaceCache;
class CFX_Font;
class CFX_FontCache;
class CFX_FontMgr;
class CPDF_ShadingPattern;
class IFX_RenderDeviceDriver;
class SkPictureRecorder;

class CFX_GEModule {
 public:
  static CFX_GEModule* Get();
  static void Destroy();

  void Init(const char** pUserFontPaths, CCodec_ModuleMgr* pCodecModule);
  CFX_FontCache* GetFontCache();
  CFX_FontMgr* GetFontMgr() { return m_pFontMgr.get(); }
  void SetTextGamma(FX_FLOAT gammaValue);
  const uint8_t* GetTextGammaTable() const;

  CCodec_ModuleMgr* GetCodecModule() { return m_pCodecModule; }
  void* GetPlatformData() { return m_pPlatformData; }

  FXFT_Library m_FTLibrary;

 private:
  CFX_GEModule();
  ~CFX_GEModule();

  void InitPlatform();
  void DestroyPlatform();

  uint8_t m_GammaValue[256];
  CFX_FontCache* m_pFontCache;
  std::unique_ptr<CFX_FontMgr> m_pFontMgr;
  CCodec_ModuleMgr* m_pCodecModule;
  void* m_pPlatformData;
  const char** m_pUserFontPaths;
};

struct FX_PATHPOINT {
  FX_FLOAT m_PointX;
  FX_FLOAT m_PointY;
  int m_Flag;
};

class CFX_ClipRgn {
 public:
  enum ClipType { RectI, MaskF };

  CFX_ClipRgn(int device_width, int device_height);
  explicit CFX_ClipRgn(const FX_RECT& rect);
  CFX_ClipRgn(const CFX_ClipRgn& src);
  ~CFX_ClipRgn();

  ClipType GetType() const { return m_Type; }
  const FX_RECT& GetBox() const { return m_Box; }
  CFX_DIBitmapRef GetMask() const { return m_Mask; }

  void Reset(const FX_RECT& rect);
  void IntersectRect(const FX_RECT& rect);
  void IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask);

 protected:
  void IntersectMaskRect(FX_RECT rect, FX_RECT mask_box, CFX_DIBitmapRef Mask);

  ClipType m_Type;
  FX_RECT m_Box;
  CFX_DIBitmapRef m_Mask;
};

class CFX_PathData {
 public:
  CFX_PathData();
  CFX_PathData(const CFX_PathData& src);
  ~CFX_PathData();

  int GetPointCount() const { return m_PointCount; }
  int GetFlag(int index) const { return m_pPoints[index].m_Flag; }
  FX_FLOAT GetPointX(int index) const { return m_pPoints[index].m_PointX; }
  FX_FLOAT GetPointY(int index) const { return m_pPoints[index].m_PointY; }
  FX_PATHPOINT* GetPoints() const { return m_pPoints; }

  void SetPointCount(int nPoints);
  void AllocPointCount(int nPoints);
  void AddPointCount(int addPoints);
  CFX_FloatRect GetBoundingBox() const;
  CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const;
  void Transform(const CFX_Matrix* pMatrix);
  FX_BOOL IsRect() const;
  FX_BOOL GetZeroAreaPath(CFX_PathData& NewPath,
                          CFX_Matrix* pMatrix,
                          FX_BOOL& bThin,
                          FX_BOOL bAdjust) const;
  FX_BOOL IsRect(const CFX_Matrix* pMatrix, CFX_FloatRect* rect) const;
  void Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix);
  void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top);
  void SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag);
  void TrimPoints(int nPoints);
  void Copy(const CFX_PathData& src);

 protected:
  friend class CPDF_Path;

  int m_PointCount;
  FX_PATHPOINT* m_pPoints;
  int m_AllocCount;
};

class CFX_GraphStateData {
 public:
  enum LineCap { LineCapButt = 0, LineCapRound = 1, LineCapSquare = 2 };

  CFX_GraphStateData();
  CFX_GraphStateData(const CFX_GraphStateData& src);
  ~CFX_GraphStateData();

  void Copy(const CFX_GraphStateData& src);
  void SetDashCount(int count);

  LineCap m_LineCap;
  int m_DashCount;
  FX_FLOAT* m_DashArray;
  FX_FLOAT m_DashPhase;

  enum LineJoin {
    LineJoinMiter = 0,
    LineJoinRound = 1,
    LineJoinBevel = 2,
  };
  LineJoin m_LineJoin;
  FX_FLOAT m_MiterLimit;
  FX_FLOAT m_LineWidth;
};

#define FXDC_DEVICE_CLASS 1
#define FXDC_PIXEL_WIDTH 2
#define FXDC_PIXEL_HEIGHT 3
#define FXDC_BITS_PIXEL 4
#define FXDC_HORZ_SIZE 5
#define FXDC_VERT_SIZE 6
#define FXDC_RENDER_CAPS 7
#define FXDC_DISPLAY 1
#define FXDC_PRINTER 2

#define FXPT_CLOSEFIGURE 0x01
#define FXPT_LINETO 0x02
#define FXPT_BEZIERTO 0x04
#define FXPT_MOVETO 0x06
#define FXPT_TYPE 0x06

#define FXRC_GET_BITS 0x01
#define FXRC_BIT_MASK 0x02
#define FXRC_ALPHA_MASK 0x04
#define FXRC_ALPHA_PATH 0x10
#define FXRC_ALPHA_IMAGE 0x20
#define FXRC_ALPHA_OUTPUT 0x40
#define FXRC_BLEND_MODE 0x80
#define FXRC_SOFT_CLIP 0x100
#define FXRC_CMYK_OUTPUT 0x200
#define FXRC_BITMASK_OUTPUT 0x400
#define FXRC_BYTEMASK_OUTPUT 0x800
#define FXRENDER_IMAGE_LOSSY 0x1000
#define FXRC_FILLSTROKE_PATH 0x2000
#define FXRC_SHADING 0x4000

#define FXFILL_ALTERNATE 1
#define FXFILL_WINDING 2
#define FXFILL_FULLCOVER 4
#define FXFILL_RECT_AA 8
#define FX_FILL_STROKE 16
#define FX_STROKE_ADJUST 32
#define FX_STROKE_TEXT_MODE 64
#define FX_FILL_TEXT_MODE 128
#define FX_ZEROAREA_FILL 256
#define FXFILL_NOPATHSMOOTH 512

#define FXTEXT_CLEARTYPE 0x01
#define FXTEXT_BGR_STRIPE 0x02
#define FXTEXT_PRINTGRAPHICTEXT 0x04
#define FXTEXT_NO_NATIVETEXT 0x08
#define FXTEXT_PRINTIMAGETEXT 0x10
#define FXTEXT_NOSMOOTH 0x20

struct FXTEXT_CHARPOS {
  uint32_t m_GlyphIndex;
  FX_FLOAT m_OriginX;
  FX_FLOAT m_OriginY;
  int m_FontCharWidth;
  FX_BOOL m_bGlyphAdjust;
  FX_FLOAT m_AdjustMatrix[4];
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  uint32_t m_ExtGID;
#endif
  bool m_bFontStyle;
};

class CFX_RenderDevice {
 public:
  CFX_RenderDevice();
  virtual ~CFX_RenderDevice();

  // Take ownership of |pDriver|.
  void SetDeviceDriver(std::unique_ptr<IFX_RenderDeviceDriver> pDriver);
  IFX_RenderDeviceDriver* GetDeviceDriver() const {
    return m_pDeviceDriver.get();
  }

  FX_BOOL StartRendering();
  void EndRendering();
  void SaveState();
  void RestoreState(bool bKeepSaved);

  int GetWidth() const { return m_Width; }
  int GetHeight() const { return m_Height; }
  int GetDeviceClass() const { return m_DeviceClass; }
  int GetBPP() const { return m_bpp; }
  int GetRenderCaps() const { return m_RenderCaps; }
  int GetDeviceCaps(int id) const;
  CFX_Matrix GetCTM() const;
  CFX_DIBitmap* GetBitmap() const { return m_pBitmap; }
  void SetBitmap(CFX_DIBitmap* pBitmap) { m_pBitmap = pBitmap; }
  FX_BOOL CreateCompatibleBitmap(CFX_DIBitmap* pDIB,
                                 int width,
                                 int height) const;
  const FX_RECT& GetClipBox() const { return m_ClipBox; }
  FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
                           const CFX_Matrix* pObject2Device,
                           int fill_mode);
  FX_BOOL SetClip_Rect(const FX_RECT& pRect);
  FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
                             const CFX_Matrix* pObject2Device,
                             const CFX_GraphStateData* pGraphState);
  FX_BOOL DrawPath(const CFX_PathData* pPathData,
                   const CFX_Matrix* pObject2Device,
                   const CFX_GraphStateData* pGraphState,
                   uint32_t fill_color,
                   uint32_t stroke_color,
                   int fill_mode) {
    return DrawPathWithBlend(pPathData, pObject2Device, pGraphState, fill_color,
                             stroke_color, fill_mode, FXDIB_BLEND_NORMAL);
  }
  FX_BOOL DrawPathWithBlend(const CFX_PathData* pPathData,
                            const CFX_Matrix* pObject2Device,
                            const CFX_GraphStateData* pGraphState,
                            uint32_t fill_color,
                            uint32_t stroke_color,
                            int fill_mode,
                            int blend_type);
  FX_BOOL SetPixel(int x, int y, uint32_t color);
  FX_BOOL FillRect(const FX_RECT* pRect, uint32_t color) {
    return FillRectWithBlend(pRect, color, FXDIB_BLEND_NORMAL);
  }
  FX_BOOL FillRectWithBlend(const FX_RECT* pRect,
                            uint32_t color,
                            int blend_type);
  FX_BOOL DrawCosmeticLine(FX_FLOAT x1,
                           FX_FLOAT y1,
                           FX_FLOAT x2,
                           FX_FLOAT y2,
                           uint32_t color) {
    return DrawCosmeticLineWithFillModeAndBlend(x1, y1, x2, y2, color, 0,
                                                FXDIB_BLEND_NORMAL);
  }
  FX_BOOL DrawCosmeticLineWithFillModeAndBlend(FX_FLOAT x1,
                                               FX_FLOAT y1,
                                               FX_FLOAT x2,
                                               FX_FLOAT y2,
                                               uint32_t color,
                                               int fill_mode,
                                               int blend_type);

  FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top);
  CFX_DIBitmap* GetBackDrop();
  FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, int left, int top) {
    return SetDIBitsWithBlend(pBitmap, left, top, FXDIB_BLEND_NORMAL);
  }
  FX_BOOL SetDIBitsWithBlend(const CFX_DIBSource* pBitmap,
                             int left,
                             int top,
                             int blend_type);
  FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap,
                        int left,
                        int top,
                        int dest_width,
                        int dest_height) {
    return StretchDIBitsWithFlagsAndBlend(pBitmap, left, top, dest_width,
                                          dest_height, 0, FXDIB_BLEND_NORMAL);
  }
  FX_BOOL StretchDIBitsWithFlagsAndBlend(const CFX_DIBSource* pBitmap,
                                         int left,
                                         int top,
                                         int dest_width,
                                         int dest_height,
                                         uint32_t flags,
                                         int blend_type);
  FX_BOOL SetBitMask(const CFX_DIBSource* pBitmap,
                     int left,
                     int top,
                     uint32_t color);
  FX_BOOL StretchBitMask(const CFX_DIBSource* pBitmap,
                         int left,
                         int top,
                         int dest_width,
                         int dest_height,
                         uint32_t color);
  FX_BOOL StretchBitMaskWithFlags(const CFX_DIBSource* pBitmap,
                                  int left,
                                  int top,
                                  int dest_width,
                                  int dest_height,
                                  uint32_t color,
                                  uint32_t flags);
  FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                      int bitmap_alpha,
                      uint32_t color,
                      const CFX_Matrix* pMatrix,
                      uint32_t flags,
                      void*& handle) {
    return StartDIBitsWithBlend(pBitmap, bitmap_alpha, color, pMatrix, flags,
                                handle, FXDIB_BLEND_NORMAL);
  }
  FX_BOOL StartDIBitsWithBlend(const CFX_DIBSource* pBitmap,
                               int bitmap_alpha,
                               uint32_t color,
                               const CFX_Matrix* pMatrix,
                               uint32_t flags,
                               void*& handle,
                               int blend_type);
  FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause);
  void CancelDIBits(void* handle);

  FX_BOOL DrawNormalText(int nChars,
                         const FXTEXT_CHARPOS* pCharPos,
                         CFX_Font* pFont,
                         CFX_FontCache* pCache,
                         FX_FLOAT font_size,
                         const CFX_Matrix* pText2Device,
                         uint32_t fill_color,
                         uint32_t text_flags);
  FX_BOOL DrawTextPath(int nChars,
                       const FXTEXT_CHARPOS* pCharPos,
                       CFX_Font* pFont,
                       CFX_FontCache* pCache,
                       FX_FLOAT font_size,
                       const CFX_Matrix* pText2User,
                       const CFX_Matrix* pUser2Device,
                       const CFX_GraphStateData* pGraphState,
                       uint32_t fill_color,
                       uint32_t stroke_color,
                       CFX_PathData* pClippingPath) {
    return DrawTextPathWithFlags(nChars, pCharPos, pFont, pCache, font_size,
                                 pText2User, pUser2Device, pGraphState,
                                 fill_color, stroke_color, pClippingPath, 0);
  }
  FX_BOOL DrawTextPathWithFlags(int nChars,
                                const FXTEXT_CHARPOS* pCharPos,
                                CFX_Font* pFont,
                                CFX_FontCache* pCache,
                                FX_FLOAT font_size,
                                const CFX_Matrix* pText2User,
                                const CFX_Matrix* pUser2Device,
                                const CFX_GraphStateData* pGraphState,
                                uint32_t fill_color,
                                uint32_t stroke_color,
                                CFX_PathData* pClippingPath,
                                int nFlag);

#ifdef _SKIA_SUPPORT_
  virtual void DebugVerifyBitmapIsPreMultiplied() const;
  void Flush();
#endif

 private:
  void InitDeviceInfo();
  void UpdateClipBox();
  FX_BOOL DrawFillStrokePath(const CFX_PathData* pPathData,
                             const CFX_Matrix* pObject2Device,
                             const CFX_GraphStateData* pGraphState,
                             uint32_t fill_color,
                             uint32_t stroke_color,
                             int fill_mode,
                             int blend_type);

  CFX_DIBitmap* m_pBitmap;
  int m_Width;
  int m_Height;
  int m_bpp;
  int m_RenderCaps;
  int m_DeviceClass;
  FX_RECT m_ClipBox;
  std::unique_ptr<IFX_RenderDeviceDriver> m_pDeviceDriver;
};

class CFX_FxgeDevice : public CFX_RenderDevice {
 public:
  CFX_FxgeDevice();
  ~CFX_FxgeDevice() override;

  bool Attach(CFX_DIBitmap* pBitmap,
              bool bRgbByteOrder,
              CFX_DIBitmap* pOriDevice,
              bool bGroupKnockout);
  bool Create(int width,
              int height,
              FXDIB_Format format,
              CFX_DIBitmap* pOriDevice);

#ifdef _SKIA_SUPPORT_
  bool AttachRecorder(SkPictureRecorder* recorder);
  SkPictureRecorder* CreateRecorder(int size_x, int size_y);
  void DebugVerifyBitmapIsPreMultiplied() const override;
#endif

 protected:
  bool m_bOwnedBitmap;
};

#endif  // CORE_FXGE_INCLUDE_FX_GE_H_
