// 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_SRC_FXGE_WIN32_WIN32_INT_H_
#define CORE_SRC_FXGE_WIN32_WIN32_INT_H_

#include "../../../include/fxge/fx_ge.h"

struct WINDIB_Open_Args_;
class CGdiplusExt {
 public:
  CGdiplusExt();
  ~CGdiplusExt();
  void Load();
  FX_BOOL IsAvailable() { return m_hModule != NULL; }
  FX_BOOL StretchBitMask(HDC hDC,
                         BOOL bMonoDevice,
                         const CFX_DIBitmap* pBitmap,
                         int dest_left,
                         int dest_top,
                         int dest_width,
                         int dest_height,
                         FX_DWORD argb,
                         const FX_RECT* pClipRect,
                         int flags);
  FX_BOOL StretchDIBits(HDC hDC,
                        const CFX_DIBitmap* pBitmap,
                        int dest_left,
                        int dest_top,
                        int dest_width,
                        int dest_height,
                        const FX_RECT* pClipRect,
                        int flags);
  FX_BOOL DrawPath(HDC hDC,
                   const CFX_PathData* pPathData,
                   const CFX_AffineMatrix* pObject2Device,
                   const CFX_GraphStateData* pGraphState,
                   FX_DWORD fill_argb,
                   FX_DWORD stroke_argb,
                   int fill_mode);

  void* LoadMemFont(uint8_t* pData, FX_DWORD size);
  void DeleteMemFont(void* pFontCollection);
  FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics);
  void GdipDeleteGraphics(void* graphics);
  void GdipSetTextRenderingHint(void* graphics, int mode);
  void GdipSetPageUnit(void* graphics, FX_DWORD unit);
  void GdipSetWorldTransform(void* graphics, void* pMatrix);
  FX_BOOL GdipDrawDriverString(void* graphics,
                               unsigned short* text,
                               int length,
                               void* font,
                               void* brush,
                               void* positions,
                               int flags,
                               const void* matrix);
  void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush);
  void GdipDeleteBrush(void* pBrush);
  void GdipCreateMatrix(FX_FLOAT a,
                        FX_FLOAT b,
                        FX_FLOAT c,
                        FX_FLOAT d,
                        FX_FLOAT e,
                        FX_FLOAT f,
                        void** matrix);
  void GdipDeleteMatrix(void* matrix);
  FX_BOOL GdipCreateFontFamilyFromName(const FX_WCHAR* name,
                                       void* pFontCollection,
                                       void** pFamily);
  void GdipDeleteFontFamily(void* pFamily);
  FX_BOOL GdipCreateFontFromFamily(void* pFamily,
                                   FX_FLOAT font_size,
                                   int fontstyle,
                                   int flag,
                                   void** pFont);
  void* GdipCreateFontFromCollection(void* pFontCollection,
                                     FX_FLOAT font_size,
                                     int fontstyle);
  void GdipDeleteFont(void* pFont);
  FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void** bitmap);
  void GdipDisposeImage(void* bitmap);
  void GdipGetFontSize(void* pFont, FX_FLOAT* size);
  void* GdiAddFontMemResourceEx(void* pFontdata,
                                FX_DWORD size,
                                void* pdv,
                                FX_DWORD* num_face);
  FX_BOOL GdiRemoveFontMemResourceEx(void* handle);
  void* m_Functions[100];
  void* m_pGdiAddFontMemResourceEx;
  void* m_pGdiRemoveFontMemResourseEx;
  CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);

 protected:
  HMODULE m_hModule;
  HMODULE m_GdiModule;
};
#include "dwrite_int.h"
class CWin32Platform {
 public:
  FX_BOOL m_bHalfTone;
  CGdiplusExt m_GdiplusExt;
  CDWriteExt m_DWriteExt;
};

class CGdiDeviceDriver : public IFX_RenderDeviceDriver {
 protected:
  // IFX_RenderDeviceDriver
  int GetDeviceCaps(int caps_id) override;
  void SaveState() override { SaveDC(m_hDC); }
  void RestoreState(FX_BOOL bKeepSaved = FALSE) override {
    RestoreDC(m_hDC, -1);
    if (bKeepSaved) {
      SaveDC(m_hDC);
    }
  }
  FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
                           const CFX_AffineMatrix* pObject2Device,
                           int fill_mode) override;
  FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
                             const CFX_AffineMatrix* pObject2Device,
                             const CFX_GraphStateData* pGraphState) override;
  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,
                   void* pIccTransform,
                   int blend_type) override;
  FX_BOOL FillRect(const FX_RECT* pRect,
                   FX_DWORD fill_color,
                   int alpha_flag,
                   void* pIccTransform,
                   int blend_type) override;
  FX_BOOL DrawCosmeticLine(FX_FLOAT x1,
                           FX_FLOAT y1,
                           FX_FLOAT x2,
                           FX_FLOAT y2,
                           FX_DWORD color,
                           int alpha_flag,
                           void* pIccTransform,
                           int blend_type) override;
  FX_BOOL GetClipBox(FX_RECT* pRect) override;
  void* GetPlatformSurface() override { return (void*)m_hDC; }

  virtual void* GetClipRgn();
  virtual FX_BOOL SetClipRgn(void* pRgn);
  virtual FX_BOOL DeleteDeviceRgn(void* pRgn);
  virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);

  FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap,
                        const FX_RECT* pSrcRect,
                        int left,
                        int top,
                        void* pIccTransform);
  FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap,
                            int dest_left,
                            int dest_top,
                            int dest_width,
                            int dest_height,
                            FX_DWORD flags,
                            void* pIccTransform);
  FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap,
                             int dest_left,
                             int dest_top,
                             int dest_width,
                             int dest_height,
                             FX_DWORD bitmap_color,
                             FX_DWORD flags,
                             int alpha_flag,
                             void* pIccTransform);
  HDC m_hDC;
  int m_Width, m_Height, m_nBitsPerPixel;
  int m_DeviceClass, m_RenderCaps;
  CGdiDeviceDriver(HDC hDC, int device_class);
  ~CGdiDeviceDriver() override {}
};

class CGdiDisplayDriver : public CGdiDeviceDriver {
 public:
  CGdiDisplayDriver(HDC hDC);

 protected:
  virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap,
                            int left,
                            int top,
                            void* pIccTransform = NULL,
                            FX_BOOL bDEdge = FALSE);
  virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                            FX_DWORD color,
                            const FX_RECT* pSrcRect,
                            int left,
                            int top,
                            int blend_type,
                            int alpha_flag,
                            void* pIccTransform);
  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,
                                void* pIccTransform,
                                int blend_type);
  virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                              int bitmap_alpha,
                              FX_DWORD color,
                              const CFX_AffineMatrix* pMatrix,
                              FX_DWORD render_flags,
                              void*& handle,
                              int alpha_flag,
                              void* pIccTransform,
                              int blend_type) {
    return FALSE;
  }
  FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource,
                                FX_DWORD color,
                                int dest_left,
                                int dest_top,
                                int dest_width,
                                int dest_height,
                                const FX_RECT* pClipRect,
                                int render_flags,
                                int alpha_flag = 0,
                                void* pIccTransform = NULL,
                                int blend_type = FXDIB_BLEND_NORMAL);
};
class CGdiPrinterDriver : public CGdiDeviceDriver {
 public:
  CGdiPrinterDriver(HDC hDC);

 protected:
  virtual int GetDeviceCaps(int caps_id);
  virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                            FX_DWORD color,
                            const FX_RECT* pSrcRect,
                            int left,
                            int top,
                            int blend_type,
                            int alpha_flag,
                            void* pIccTransform);
  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,
                                void* pIccTransform,
                                int blend_type);
  virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                              int bitmap_alpha,
                              FX_DWORD color,
                              const CFX_AffineMatrix* pMatrix,
                              FX_DWORD render_flags,
                              void*& handle,
                              int alpha_flag,
                              void* pIccTransform,
                              int blend_type);
  int m_HorzSize, m_VertSize;
  FX_BOOL m_bSupportROP;
};

class CPSOutput : public IFX_PSOutput {
 public:
  explicit CPSOutput(HDC hDC);
  ~CPSOutput() override;

  // IFX_PSOutput
  void Release() override { delete this; }
  void OutputPS(const FX_CHAR* string, int len) override;

  void Init();

  HDC m_hDC;
  FX_CHAR* m_pBuf;
};

class CPSPrinterDriver : public IFX_RenderDeviceDriver {
 public:
  CPSPrinterDriver();
  FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput);
  ~CPSPrinterDriver() override;

 protected:
  // IFX_RenderDeviceDriver
  int GetDeviceCaps(int caps_id);
  FX_BOOL IsPSPrintDriver() override { return TRUE; }
  FX_BOOL StartRendering() override;
  void EndRendering() override;
  void SaveState() override;
  void RestoreState(FX_BOOL bKeepSaved = FALSE) override;
  FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
                           const CFX_AffineMatrix* pObject2Device,
                           int fill_mode) override;
  FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
                             const CFX_AffineMatrix* pObject2Device,
                             const CFX_GraphStateData* pGraphState) override;
  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,
                   void* pIccTransform,
                   int blend_type) override;
  FX_BOOL GetClipBox(FX_RECT* pRect) override;
  FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap,
                    FX_DWORD color,
                    const FX_RECT* pSrcRect,
                    int left,
                    int top,
                    int blend_type,
                    int alpha_flag,
                    void* pIccTransform) override;
  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,
                        void* pIccTransform,
                        int blend_type) override;
  FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap,
                      int bitmap_alpha,
                      FX_DWORD color,
                      const CFX_AffineMatrix* pMatrix,
                      FX_DWORD render_flags,
                      void*& handle,
                      int alpha_flag,
                      void* pIccTransform,
                      int blend_type) override;
  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,
                         void* pIccTransform) override;
  void* GetPlatformSurface() override { return (void*)m_hDC; }

  HDC m_hDC;
  FX_BOOL m_bCmykOutput;
  int m_Width, m_Height, m_nBitsPerPixel;
  int m_HorzSize, m_VertSize;
  CPSOutput* m_pPSOutput;
  CFX_PSRenderer m_PSRenderer;
};
void _Color2Argb(FX_ARGB& argb,
                 FX_DWORD color,
                 int alpha_flag,
                 void* pIccTransform);

#endif  // CORE_SRC_FXGE_WIN32_WIN32_INT_H_
