// 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_INCLUDE_FXGE_FX_GE_H_
#define CORE_INCLUDE_FXGE_FX_GE_H_

#include "fx_dib.h"
#include "fx_font.h"

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

class CFX_GEModule {
 public:
  static void Create(const char** pUserFontPaths);

  static void Use(CFX_GEModule* pMgr);

  static CFX_GEModule* Get();

  static void Destroy();

 public:
  CFX_FontCache* GetFontCache();
  CFX_FontMgr* GetFontMgr() { return m_pFontMgr; }
  void SetTextGamma(FX_FLOAT gammaValue);
  const uint8_t* GetTextGammaTable();

  void SetCodecModule(CCodec_ModuleMgr* pCodecModule) {
    m_pCodecModule = pCodecModule;
  }
  CCodec_ModuleMgr* GetCodecModule() { return m_pCodecModule; }
  FXFT_Library m_FTLibrary;
  void* GetPlatformData() { return m_pPlatformData; }

 protected:
  explicit CFX_GEModule(const char** pUserFontPaths);

  ~CFX_GEModule();
  void InitPlatform();
  void DestroyPlatform();

 private:
  uint8_t m_GammaValue[256];
  CFX_FontCache* m_pFontCache;
  CFX_FontMgr* m_pFontMgr;
  CCodec_ModuleMgr* m_pCodecModule;
  void* m_pPlatformData;
  const char** m_pUserFontPaths;
};
typedef struct {
  FX_FLOAT m_PointX;

  FX_FLOAT m_PointY;

  int m_Flag;
} FX_PATHPOINT;
#define FXPT_CLOSEFIGURE 0x01
#define FXPT_LINETO 0x02
#define FXPT_BEZIERTO 0x04
#define FXPT_MOVETO 0x06
#define FXPT_TYPE 0x06
#define FXFILL_ALTERNATE 1
#define FXFILL_WINDING 2
class CFX_ClipRgn {
 public:
  CFX_ClipRgn(int device_width, int device_height);

  CFX_ClipRgn(const FX_RECT& rect);

  CFX_ClipRgn(const CFX_ClipRgn& src);

  ~CFX_ClipRgn();

  typedef enum { RectI, MaskF } ClipType;

  void Reset(const FX_RECT& rect);

  ClipType GetType() const { return m_Type; }

  const FX_RECT& GetBox() const { return m_Box; }

  CFX_DIBitmapRef GetMask() const { return m_Mask; }

  void IntersectRect(const FX_RECT& rect);

  void IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask);

 protected:
  ClipType m_Type;

  FX_RECT m_Box;

  CFX_DIBitmapRef m_Mask;

  void IntersectMaskRect(FX_RECT rect, FX_RECT mask_box, CFX_DIBitmapRef Mask);
};
#define FX_GAMMA(value) (value)
#define FX_GAMMA_INVERSE(value) (value)
inline FX_ARGB ArgbGamma(FX_ARGB argb) {
  return argb;
}
inline FX_ARGB ArgbGammaInverse(FX_ARGB argb) {
  return argb;
}
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:
  CFX_GraphStateData();

  CFX_GraphStateData(const CFX_GraphStateData& src);

  ~CFX_GraphStateData();

  void Copy(const CFX_GraphStateData& src);

  void SetDashCount(int count);

  typedef enum { LineCapButt = 0, LineCapRound = 1, LineCapSquare = 2 } LineCap;
  LineCap m_LineCap;
  int m_DashCount;
  FX_FLOAT* m_DashArray;
  FX_FLOAT m_DashPhase;

  typedef enum {
    LineJoinMiter = 0,
    LineJoinRound = 1,
    LineJoinBevel = 2,
  } LineJoin;
  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_DITHER_BITS 8
#define FXDC_DISPLAY 1
#define FXDC_PRINTER 2
#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 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
typedef struct {
  FX_DWORD m_GlyphIndex;
  FX_FLOAT m_OriginX, m_OriginY;
  int m_FontCharWidth;
  FX_BOOL m_bGlyphAdjust;
  FX_FLOAT m_AdjustMatrix[4];
  FX_DWORD m_ExtGID;
  FX_BOOL m_bFontStyle;
} FXTEXT_CHARPOS;
class CFX_RenderDevice {
 public:
  CFX_RenderDevice();

  virtual ~CFX_RenderDevice();

  void SetDeviceDriver(IFX_RenderDeviceDriver* pDriver);

  IFX_RenderDeviceDriver* GetDeviceDriver() const { return m_pDeviceDriver; }

  FX_BOOL StartRendering();

  void EndRendering();

  void SaveState();

  void RestoreState(FX_BOOL bKeepSaved = FALSE);

  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,
                   FX_DWORD fill_color,
                   FX_DWORD stroke_color,
                   int fill_mode,
                   int alpha_flag = 0,
                   void* pIccTransform = NULL,
                   int blend_type = FXDIB_BLEND_NORMAL);

  FX_BOOL SetPixel(int x,
                   int y,
                   FX_DWORD color,
                   int alpha_flag = 0,
                   void* pIccTransform = NULL);

  FX_BOOL FillRect(const FX_RECT* pRect,
                   FX_DWORD color,
                   int alpha_flag = 0,
                   void* pIccTransform = NULL,
                   int blend_type = FXDIB_BLEND_NORMAL);

  FX_BOOL DrawCosmeticLine(FX_FLOAT x1,
                           FX_FLOAT y1,
                           FX_FLOAT x2,
                           FX_FLOAT y2,
                           FX_DWORD color,
                           int fill_mode = 0,
                           int alpha_flag = 0,
                           void* pIccTransform = NULL,
                           int blend_type = FXDIB_BLEND_NORMAL);

  FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap,
                    int left,
                    int top,
                    void* pIccTransform = NULL);

  CFX_DIBitmap* GetBackDrop();

  FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                    int left,
                    int top,
                    int blend_type = FXDIB_BLEND_NORMAL,
                    void* pIccTransform = NULL);

  FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap,
                        int left,
                        int top,
                        int dest_width,
                        int dest_height,
                        FX_DWORD flags = 0,
                        void* pIccTransform = NULL,
                        int blend_type = FXDIB_BLEND_NORMAL);

  FX_BOOL SetBitMask(const CFX_DIBSource* pBitmap,
                     int left,
                     int top,
                     FX_DWORD color,
                     int alpha_flag = 0,
                     void* pIccTransform = NULL);

  FX_BOOL StretchBitMask(const CFX_DIBSource* pBitmap,
                         int left,
                         int top,
                         int dest_width,
                         int dest_height,
                         FX_DWORD color,
                         FX_DWORD flags = 0,
                         int alpha_flag = 0,
                         void* pIccTransform = NULL);

  FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                      int bitmap_alpha,
                      FX_DWORD color,
                      const CFX_Matrix* pMatrix,
                      FX_DWORD flags,
                      void*& handle,
                      int alpha_flag = 0,
                      void* pIccTransform = NULL,
                      int blend_type = FXDIB_BLEND_NORMAL);

  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,
                         FX_DWORD fill_color,
                         FX_DWORD text_flags,
                         int alpha_flag = 0,
                         void* pIccTransform = NULL);

  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,
                       FX_DWORD fill_color,
                       FX_DWORD stroke_color,
                       CFX_PathData* pClippingPath,
                       int nFlag = 0,
                       int alpha_flag = 0,
                       void* pIccTransform = NULL,
                       int blend_type = FXDIB_BLEND_NORMAL);
  virtual void Begin() {}
  virtual void End() {}

 private:
  CFX_DIBitmap* m_pBitmap;

  int m_Width;

  int m_Height;

  int m_bpp;

  int m_RenderCaps;

  int m_DeviceClass;

  FX_RECT m_ClipBox;

 protected:
  IFX_RenderDeviceDriver* m_pDeviceDriver;

 private:
  void InitDeviceInfo();

  void UpdateClipBox();
};
class CFX_FxgeDevice : public CFX_RenderDevice {
 public:
  CFX_FxgeDevice();
  ~CFX_FxgeDevice() override;

  FX_BOOL Attach(CFX_DIBitmap* pBitmap,
                 int dither_bits = 0,
                 FX_BOOL bRgbByteOrder = FALSE,
                 CFX_DIBitmap* pOriDevice = NULL,
                 FX_BOOL bGroupKnockout = FALSE);

  FX_BOOL Create(int width,
                 int height,
                 FXDIB_Format format,
                 int dither_bits = 0,
                 CFX_DIBitmap* pOriDevice = NULL);

 protected:
  FX_BOOL m_bOwnedBitmap;
};
class CFX_SkiaDevice : public CFX_RenderDevice {
 public:
  CFX_SkiaDevice();
  ~CFX_SkiaDevice() override;

  FX_BOOL Attach(CFX_DIBitmap* pBitmap,
                 int dither_bits = 0,
                 FX_BOOL bRgbByteOrder = FALSE,
                 CFX_DIBitmap* pOriDevice = NULL,
                 FX_BOOL bGroupKnockout = FALSE);

  FX_BOOL Create(int width,
                 int height,
                 FXDIB_Format format,
                 int dither_bits = 0,
                 CFX_DIBitmap* pOriDevice = NULL);

 protected:
  FX_BOOL m_bOwnedBitmap;
};

class IFX_RenderDeviceDriver {
 public:
  static IFX_RenderDeviceDriver* CreateFxgeDriver(
      CFX_DIBitmap* pBitmap,
      FX_BOOL bRgbByteOrder = FALSE,
      CFX_DIBitmap* pOriDevice = NULL,
      FX_BOOL bGroupKnockout = FALSE);

  virtual ~IFX_RenderDeviceDriver() {}
  virtual void Begin() {}
  virtual void End() {}

  virtual int GetDeviceCaps(int caps_id) = 0;

  virtual CFX_Matrix GetCTM() const { return CFX_Matrix(); }

  virtual FX_BOOL IsPSPrintDriver() { return FALSE; }

  virtual FX_BOOL StartRendering() { return TRUE; }

  virtual void EndRendering() {}

  virtual void SaveState() = 0;

  virtual void RestoreState(FX_BOOL bKeepSaved = FALSE) = 0;

  virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
                                   const CFX_Matrix* pObject2Device,
                                   int fill_mode) = 0;

  virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
                                     const CFX_Matrix* pObject2Device,
                                     const CFX_GraphStateData* pGraphState) {
    return FALSE;
  }

  virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
                           const CFX_Matrix* pObject2Device,
                           const CFX_GraphStateData* pGraphState,
                           FX_DWORD fill_color,
                           FX_DWORD stroke_color,
                           int fill_mode,
                           int alpha_flag = 0,
                           void* pIccTransform = NULL,
                           int blend_type = FXDIB_BLEND_NORMAL) = 0;

  virtual FX_BOOL SetPixel(int x,
                           int y,
                           FX_DWORD color,
                           int alpha_flag = 0,
                           void* pIccTransform = NULL) {
    return FALSE;
  }

  virtual FX_BOOL FillRect(const FX_RECT* pRect,
                           FX_DWORD fill_color,
                           int alpha_flag = 0,
                           void* pIccTransform = NULL,
                           int blend_type = FXDIB_BLEND_NORMAL) {
    return FALSE;
  }

  virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1,
                                   FX_FLOAT y1,
                                   FX_FLOAT x2,
                                   FX_FLOAT y2,
                                   FX_DWORD color,
                                   int alpha_flag = 0,
                                   void* pIccTransform = NULL,
                                   int blend_type = FXDIB_BLEND_NORMAL) {
    return FALSE;
  }

  virtual FX_BOOL GetClipBox(FX_RECT* pRect) = 0;

  virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap,
                            int left,
                            int top,
                            void* pIccTransform = NULL,
                            FX_BOOL bDEdge = FALSE) {
    return FALSE;
  }
  virtual CFX_DIBitmap* GetBackDrop() { return NULL; }

  virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                            FX_DWORD color,
                            const FX_RECT* pSrcRect,
                            int dest_left,
                            int dest_top,
                            int blend_type,
                            int alpha_flag = 0,
                            void* pIccTransform = NULL) = 0;

  virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap,
                                FX_DWORD color,
                                int dest_left,
                                int dest_top,
                                int dest_width,
                                int dest_height,
                                const FX_RECT* pClipRect,
                                FX_DWORD flags,
                                int alpha_flag = 0,
                                void* pIccTransform = NULL,
                                int blend_type = FXDIB_BLEND_NORMAL) = 0;

  virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                              int bitmap_alpha,
                              FX_DWORD color,
                              const CFX_Matrix* pMatrix,
                              FX_DWORD flags,
                              void*& handle,
                              int alpha_flag = 0,
                              void* pIccTransform = NULL,
                              int blend_type = FXDIB_BLEND_NORMAL) = 0;

  virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause) {
    return FALSE;
  }

  virtual void CancelDIBits(void* handle) {}

  virtual FX_BOOL DrawDeviceText(int nChars,
                                 const FXTEXT_CHARPOS* pCharPos,
                                 CFX_Font* pFont,
                                 CFX_FontCache* pCache,
                                 const CFX_Matrix* pObject2Device,
                                 FX_FLOAT font_size,
                                 FX_DWORD color,
                                 int alpha_flag = 0,
                                 void* pIccTransform = NULL) {
    return FALSE;
  }

  virtual void* GetPlatformSurface() { return NULL; }

  virtual int GetDriverType() { return 0; }

  virtual void ClearDriver() {}
};

class IFX_PSOutput {
 public:
  virtual void Release() = 0;
  virtual void OutputPS(const FX_CHAR* string, int len) = 0;

 protected:
  virtual ~IFX_PSOutput() {}
};

class CPSFont;
class CFX_PSRenderer {
 public:
  CFX_PSRenderer();

  ~CFX_PSRenderer();

  void Init(IFX_PSOutput* pOutput,
            int ps_level,
            int width,
            int height,
            FX_BOOL bCmykOutput);
  FX_BOOL StartRendering();
  void EndRendering();

  void SaveState();

  void RestoreState(FX_BOOL bKeepSaved = FALSE);

  void SetClip_PathFill(const CFX_PathData* pPathData,
                        const CFX_Matrix* pObject2Device,
                        int fill_mode);

  void SetClip_PathStroke(const CFX_PathData* pPathData,
                          const CFX_Matrix* pObject2Device,
                          const CFX_GraphStateData* pGraphState);

  FX_RECT GetClipBox() { return m_ClipBox; }

  FX_BOOL DrawPath(const CFX_PathData* pPathData,
                   const CFX_Matrix* pObject2Device,
                   const CFX_GraphStateData* pGraphState,
                   FX_DWORD fill_color,
                   FX_DWORD stroke_color,
                   int fill_mode,
                   int alpha_flag = 0,
                   void* pIccTransform = NULL);

  FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                    FX_DWORD color,
                    int dest_left,
                    int dest_top,
                    int alpha_flag = 0,
                    void* pIccTransform = NULL);

  FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap,
                        FX_DWORD color,
                        int dest_left,
                        int dest_top,
                        int dest_width,
                        int dest_height,
                        FX_DWORD flags,
                        int alpha_flag = 0,
                        void* pIccTransform = NULL);

  FX_BOOL DrawDIBits(const CFX_DIBSource* pBitmap,
                     FX_DWORD color,
                     const CFX_Matrix* pMatrix,
                     FX_DWORD flags,
                     int alpha_flag = 0,
                     void* pIccTransform = NULL);

  FX_BOOL DrawText(int nChars,
                   const FXTEXT_CHARPOS* pCharPos,
                   CFX_Font* pFont,
                   CFX_FontCache* pCache,
                   const CFX_Matrix* pObject2Device,
                   FX_FLOAT font_size,
                   FX_DWORD color,
                   int alpha_flag = 0,
                   void* pIccTransform = NULL);

 private:
  IFX_PSOutput* m_pOutput;

  int m_PSLevel;

  CFX_GraphStateData m_CurGraphState;

  FX_BOOL m_bGraphStateSet;

  FX_BOOL m_bCmykOutput;

  FX_BOOL m_bColorSet;

  FX_DWORD m_LastColor;

  FX_RECT m_ClipBox;

  CFX_ArrayTemplate<CPSFont*> m_PSFontList;

  CFX_ArrayTemplate<FX_RECT> m_ClipBoxStack;
  FX_BOOL m_bInited;

  void OutputPath(const CFX_PathData* pPathData,
                  const CFX_Matrix* pObject2Device);

  void SetGraphState(const CFX_GraphStateData* pGraphState);

  void SetColor(FX_DWORD color, int alpha_flag, void* pIccTransform);

  void FindPSFontGlyph(CFX_FaceCache* pFaceCache,
                       CFX_Font* pFont,
                       const FXTEXT_CHARPOS& charpos,
                       int& ps_fontnum,
                       int& ps_glyphindex);

  void WritePSBinary(const uint8_t* data, int len);
};

#endif  // CORE_INCLUDE_FXGE_FX_GE_H_
