// 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_

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:
    virtual int		GetDeviceCaps(int caps_id);
    virtual void	SaveState()
    {
        SaveDC(m_hDC);
    }
    virtual void	RestoreState(FX_BOOL bKeepSaved = FALSE)
    {
        RestoreDC(m_hDC, -1);
        if (bKeepSaved) {
            SaveDC(m_hDC);
        }
    }
    virtual FX_BOOL	SetClip_PathFill(const CFX_PathData* pPathData,
                                     const CFX_AffineMatrix* pObject2Device,
                                     int fill_mode
                                    );
    virtual FX_BOOL	SetClip_PathStroke(const CFX_PathData* pPathData,
                                       const CFX_AffineMatrix* pObject2Device,
                                       const CFX_GraphStateData* pGraphState
                                      );
    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,
                             void* pIccTransform,
                             int	blend_type
                            );
    virtual FX_BOOL FillRect(const FX_RECT* pRect,
                             FX_DWORD fill_color,
                             int alpha_flag, void* pIccTransform, int blend_type);
    virtual 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);
    virtual void* GetClipRgn() ;
    virtual FX_BOOL SetClipRgn(void* pRgn) ;
    virtual FX_BOOL GetClipBox(FX_RECT* pRect);
    virtual FX_BOOL DeleteDeviceRgn(void* pRgn);
    virtual void	DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
    virtual void*	GetPlatformSurface()
    {
        return (void*)m_hDC;
    }
    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() {}
};
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:
    CPSOutput(HDC hDC);
    virtual ~CPSOutput();
    virtual void			Release()
    {
        delete this;
    }
    void Init();
    virtual void	OutputPS(const FX_CHAR* string, int len);
    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();
protected:
    virtual FX_BOOL IsPSPrintDriver()
    {
        return TRUE;
    }
    virtual int		GetDeviceCaps(int caps_id);
    virtual FX_BOOL	StartRendering();
    virtual void	EndRendering();
    virtual void	SaveState();
    virtual void	RestoreState(FX_BOOL bKeepSaved = FALSE);
    virtual FX_BOOL	SetClip_PathFill(const CFX_PathData* pPathData,
                                     const CFX_AffineMatrix* pObject2Device,
                                     int fill_mode
                                    );
    virtual FX_BOOL	SetClip_PathStroke(const CFX_PathData* pPathData,
                                       const CFX_AffineMatrix* pObject2Device,
                                       const CFX_GraphStateData* pGraphState
                                      );
    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,
                             void* pIccTransform,
                             int blend_type
                            );
    virtual FX_BOOL GetClipBox(FX_RECT* pRect);
    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);
    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, void* pIccTransform);
    virtual void*	GetPlatformSurface()
    {
        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_
