// 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_ClipRgn;
class CFX_PathData;
class CFX_GraphStateData;
class CFX_Font;
class CFX_FontMgr;
class CFX_FontCache;
class CFX_FaceCache;
class CFX_RenderDevice;
class IFX_RenderDeviceDriver;
class CCodec_ModuleMgr;
class IFXG_PaintModuleMgr;

class CFX_GEModule {
 public:
  static void Create();

  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:
  CFX_GEModule();

  ~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;
};
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_AffineMatrix* pMatrix);

  FX_BOOL IsRect() const;

  FX_BOOL GetZeroAreaPath(CFX_PathData& NewPath,
                          CFX_AffineMatrix* pMatrix,
                          FX_BOOL& bThin,
                          FX_BOOL bAdjust) const;

  FX_BOOL IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* rect) const;

  void Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* 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_AffineMatrix* pObject2Device,
                           int fill_mode);

  FX_BOOL SetClip_Rect(const FX_RECT* pRect);

  FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
                             const CFX_AffineMatrix* pObject2Device,
                             const CFX_GraphStateData* pGraphState);

  FX_BOOL DrawPath(const CFX_PathData* pPathData,
                   const CFX_AffineMatrix* 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_AffineMatrix* 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_AffineMatrix* 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_AffineMatrix* pText2User,
                       const CFX_AffineMatrix* 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();

  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();

  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_AffineMatrix* pObject2Device,
                                   int fill_mode) = 0;

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

  virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
                           const CFX_AffineMatrix* 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_AffineMatrix* 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_AffineMatrix* 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:
  ~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_AffineMatrix* pObject2Device,
                        int fill_mode);

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

  FX_RECT GetClipBox() { return m_ClipBox; }

  FX_BOOL DrawPath(const CFX_PathData* pPathData,
                   const CFX_AffineMatrix* 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_AffineMatrix* 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_AffineMatrix* 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_AffineMatrix* 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_
