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

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

#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
#include <crtdbg.h>

#include "../../../include/fxcodec/fx_codec.h"
#include "../../../include/fxge/fx_freetype.h"
#include "../../../include/fxge/fx_ge_win32.h"
#include "../agg/include/fx_agg_driver.h"
#include "../dib/dib_int.h"
#include "../ge/text_int.h"
#include "dwrite_int.h"
#include "win32_int.h"

class CWin32FontInfo final : public IFX_SystemFontInfo
{
public:
    CWin32FontInfo();
    ~CWin32FontInfo();
    virtual void		Release();
    virtual	FX_BOOL		EnumFontList(CFX_FontMapper* pMapper);
    virtual void*		MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* face, int& iExact);
    virtual void*		GetFont(const FX_CHAR* face)
    {
        return NULL;
    }
    virtual FX_DWORD	GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size);
    virtual void		DeleteFont(void* hFont);
    virtual	FX_BOOL		GetFaceName(void* hFont, CFX_ByteString& name);
    virtual FX_BOOL		GetFontCharset(void* hFont, int& charset);
    FX_BOOL				IsOpenTypeFromDiv(const LOGFONTA *plf);
    FX_BOOL				IsSupportFontFormDiv(const LOGFONTA* plf);
    void				AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType);
    void				GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
    void				GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family);
    CFX_ByteString		FindFont(const CFX_ByteString& name);
    HDC					m_hDC;
    CFX_FontMapper*		m_pMapper;
    CFX_ByteString		m_LastFamily;
    CFX_ByteString		m_KaiTi, m_FangSong;
};
CWin32FontInfo::CWin32FontInfo()
{
    m_hDC = CreateCompatibleDC(NULL);
}
CWin32FontInfo::~CWin32FontInfo()
{
    m_pMapper = NULL;
}
void CWin32FontInfo::Release()
{
    DeleteDC(m_hDC);
    delete this;
}
#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4)
FX_BOOL CWin32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf)
{
    HFONT hFont = CreateFontIndirectA(plf);
    FX_BOOL ret = FALSE;
    FX_DWORD font_size  = GetFontData(hFont, 0, NULL, 0);
    if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
        FX_DWORD lVersion = 0;
        GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD));
        lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 |
                   ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVersion >> 24));
        if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
                lVersion == 0x00010000 ||
                lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
                lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
                lVersion == 0x00020000) {
            ret = TRUE;
        }
    }
    DeleteFont(hFont);
    return ret;
}
FX_BOOL CWin32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf)
{
    HFONT hFont = CreateFontIndirectA(plf);
    FX_BOOL ret = FALSE;
    FX_DWORD font_size  = GetFontData(hFont, 0, NULL, 0);
    if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
        FX_DWORD lVersion = 0;
        GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD));
        lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 |
                   ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVersion >> 24));
        if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
                lVersion == 0x00010000 ||
                lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
                lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
                lVersion == 0x00020000) {
            ret = TRUE;
        } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
                   (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
            ret = TRUE;
        }
    }
    DeleteFont(hFont);
    return ret;
}
void CWin32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
{
    CFX_ByteString name(plf->lfFaceName, -1);
    if (name[0] == '@') {
        return;
    }
    if (name == m_LastFamily) {
        m_pMapper->AddInstalledFont(name, plf->lfCharSet);
        return;
    }
    if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
        return;
    }
    if (!(FontType & TRUETYPE_FONTTYPE)) {
        if (!IsSupportFontFormDiv(plf)) {
            return;
        }
    }
    m_pMapper->AddInstalledFont(name, plf->lfCharSet);
    m_LastFamily = name;
}
static int CALLBACK FontEnumProc(
    const LOGFONTA *plf,
    const TEXTMETRICA *lpntme,
    FX_DWORD FontType,
    LPARAM lParam
)
{
    CWin32FontInfo* pFontInfo = (CWin32FontInfo*)lParam;
    if (pFontInfo->m_pMapper->GetFontEnumerator()) {
        pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
    }
    pFontInfo->AddInstalledFont(plf, FontType);
    return 1;
}
FX_BOOL CWin32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
{
    m_pMapper = pMapper;
    LOGFONTA lf;
    FXSYS_memset(&lf, 0, sizeof(LOGFONTA));
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfFaceName[0] = 0;
    lf.lfPitchAndFamily = 0;
    EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (uintptr_t)this, 0);
    if (pMapper->GetFontEnumerator()) {
        pMapper->GetFontEnumerator()->Finish();
    }
    return TRUE;
}
static const struct {
    const FX_CHAR*	m_pFaceName;
    const FX_CHAR*	m_pVariantName;
}
VariantNames[] = {
    {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
};
static const struct {
    const FX_CHAR*	m_pName;
    const FX_CHAR*	m_pWinName;
    FX_BOOL		m_bBold;
    FX_BOOL		m_bItalic;
}
Base14Substs[] = {
    {"Courier", "Courier New", FALSE, FALSE},
    {"Courier-Bold", "Courier New", TRUE, FALSE},
    {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
    {"Courier-Oblique", "Courier New", FALSE, TRUE},
    {"Helvetica", "Arial", FALSE, FALSE},
    {"Helvetica-Bold", "Arial", TRUE, FALSE},
    {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
    {"Helvetica-Oblique", "Arial", FALSE, TRUE},
    {"Times-Roman", "Times New Roman", FALSE, FALSE},
    {"Times-Bold", "Times New Roman", TRUE, FALSE},
    {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
    {"Times-Italic", "Times New Roman", FALSE, TRUE},
};
CFX_ByteString CWin32FontInfo::FindFont(const CFX_ByteString& name)
{
    if (m_pMapper == NULL) {
        return name;
    }
    int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
    for (int i = 0; i < nFonts; i ++) {
        CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
        if (thisname[0] == ' ') {
            if (thisname.Mid(1, name.GetLength()) == name) {
                return m_pMapper->m_InstalledTTFonts[i + 1];
            }
        } else if (thisname.Left(name.GetLength()) == name) {
            return m_pMapper->m_InstalledTTFonts[i];
        }
    }
    return CFX_ByteString();
}
struct _FontNameMap {
    const FX_CHAR*	m_pSubFontName;
    const FX_CHAR*	m_pSrcFontName;
};
const _FontNameMap g_JpFontNameMap[] = {
    {"MS Mincho", "Heiseimin-W3"},
    {"MS Gothic", "Jun101-Light"},
};
extern "C" {
    static int compareString(const void* key, const void* element)
    {
        return FXSYS_stricmp((const FX_CHAR*)key, ((_FontNameMap*)element)->m_pSrcFontName);
    }
}
FX_BOOL _GetSubFontName(CFX_ByteString& name)
{
    int size = sizeof g_JpFontNameMap;
    void* pFontnameMap = (void*)g_JpFontNameMap;
    _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch(name.c_str(), pFontnameMap,
                          size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString);
    if (found == NULL) {
        return FALSE;
    }
    name = found->m_pSubFontName;
    return TRUE;
}
void CWin32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family)
{
    if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
        if (m_KaiTi.IsEmpty()) {
            m_KaiTi = FindFont("KaiTi");
            if (m_KaiTi.IsEmpty()) {
                m_KaiTi = "SimSun";
            }
        }
        face = m_KaiTi;
    } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
        if (m_FangSong.IsEmpty()) {
            m_FangSong = FindFont("FangSong");
            if (m_FangSong.IsEmpty()) {
                m_FangSong = "SimSun";
            }
        }
        face = m_FangSong;
    } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
        face = "SimSun";
    } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
        face = "SimHei";
    } else if (!(picth_family & FF_ROMAN) && weight > 550) {
        face = "SimHei";
    } else {
        face = "SimSun";
    }
}
void CWin32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
{
    if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
        if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
            face = "MS PGothic";
        } else if (face.Find("UI Gothic") >= 0) {
            face = "MS UI Gothic";
        } else {
            if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
                face = "MS PGothic";
            } else {
                face = "MS Gothic";
            }
        }
        return;
    }
    if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
        if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
            face = "MS PMincho";
        } else {
            face = "MS Mincho";
        }
        return;
    }
    if (_GetSubFontName(face)) {
        return;
    }
    if (!(picth_family & FF_ROMAN) && weight > 400) {
        face = "MS PGothic";
    } else {
        face = "MS PMincho";
    }
}
void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* cstr_face, int& iExact)
{
    CFX_ByteString face = cstr_face;
    int iBaseFont;
    for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
        if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
            face = Base14Substs[iBaseFont].m_pWinName;
            weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL;
            bItalic = Base14Substs[iBaseFont].m_bItalic;
            iExact = TRUE;
            break;
        }
    if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
        charset = DEFAULT_CHARSET;
    }
    int subst_pitch_family = pitch_family;
    switch (charset) {
        case SHIFTJIS_CHARSET:
            subst_pitch_family = FF_ROMAN;
            break;
        case CHINESEBIG5_CHARSET:
        case HANGUL_CHARSET:
        case GB2312_CHARSET:
            subst_pitch_family = 0;
            break;
    }
    HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
                                0, 0, subst_pitch_family, face);
    char facebuf[100];
    HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
    int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
    ::SelectObject(m_hDC, hOldFont);
    if (face.EqualNoCase(facebuf)) {
        return hFont;
    }
    int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
    for (int i = 0; i < iCount; ++i) {
        if (face == VariantNames[i].m_pFaceName) {
            CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
            const unsigned short* pName = (const unsigned short*)VariantNames[i].m_pVariantName;
            FX_STRSIZE len = CFX_WideString::WStringLength(pName);
            CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len);
            if (wsFace == wsName) {
                return hFont;
            }
        }
    }
    ::DeleteObject(hFont);
    if (charset == DEFAULT_CHARSET) {
        return NULL;
    }
    switch (charset) {
        case SHIFTJIS_CHARSET:
            GetJapanesePreference(face, weight, pitch_family);
            break;
        case GB2312_CHARSET:
            GetGBPreference(face, weight, pitch_family);
            break;
        case HANGUL_CHARSET:
            face = "Gulim";
            break;
        case CHINESEBIG5_CHARSET:
            if (face.Find("MSung") >= 0) {
                face = "MingLiU";
            } else {
                face = "PMingLiU";
            }
            break;
    }
    hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
                          0, 0, subst_pitch_family, face);
    return hFont;
}
void CWin32FontInfo::DeleteFont(void* hFont)
{
    ::DeleteObject(hFont);
}
FX_DWORD CWin32FontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size)
{
    HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
    table = FXDWORD_FROM_MSBFIRST(table);
    size = ::GetFontData(m_hDC, table, 0, buffer, size);
    ::SelectObject(m_hDC, hOldFont);
    if (size == GDI_ERROR) {
        return 0;
    }
    return size;
}
FX_BOOL CWin32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
{
    char facebuf[100];
    HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
    int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
    ::SelectObject(m_hDC, hOldFont);
    if (ret == 0) {
        return FALSE;
    }
    name = facebuf;
    return TRUE;
}
FX_BOOL CWin32FontInfo::GetFontCharset(void* hFont, int& charset)
{
    TEXTMETRIC tm;
    HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
    ::GetTextMetrics(m_hDC, &tm);
    ::SelectObject(m_hDC, hOldFont);
    charset = tm.tmCharSet;
    return TRUE;
}
IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
{
    return new CWin32FontInfo;
}
void CFX_GEModule::InitPlatform()
{
    CWin32Platform* pPlatformData = new CWin32Platform;
    OSVERSIONINFO ver;
    ver.dwOSVersionInfoSize = sizeof(ver);
    GetVersionEx(&ver);
    pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
    pPlatformData->m_GdiplusExt.Load();
    m_pPlatformData = pPlatformData;
    m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
}
void CFX_GEModule::DestroyPlatform()
{
    delete (CWin32Platform*)m_pPlatformData;
    m_pPlatformData = NULL;
}
CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class)
{
    m_hDC = hDC;
    m_DeviceClass = device_class;
    CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
    SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR);
    if (GetObjectType(m_hDC) == OBJ_MEMDC) {
        HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL);
        hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
        BITMAP bitmap;
        GetObject(hBitmap, sizeof bitmap, &bitmap);
        m_nBitsPerPixel = bitmap.bmBitsPixel;
        m_Width = bitmap.bmWidth;
        m_Height = abs(bitmap.bmHeight);
        hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
        DeleteObject(hBitmap);
    } else {
        m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
        m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
        m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
    }
    if (m_DeviceClass != FXDC_DISPLAY) {
        m_RenderCaps = FXRC_BIT_MASK;
    } else {
        m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK;
    }
}
int CGdiDeviceDriver::GetDeviceCaps(int caps_id)
{
    switch (caps_id) {
        case FXDC_DEVICE_CLASS:
            return m_DeviceClass;
        case FXDC_PIXEL_WIDTH:
            return m_Width;
        case FXDC_PIXEL_HEIGHT:
            return m_Height;
        case FXDC_BITS_PIXEL:
            return m_nBitsPerPixel;
        case FXDC_RENDER_CAPS:
            return m_RenderCaps;
    }
    return 0;
}
void* CGdiDeviceDriver::GetClipRgn()
{
    HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
    if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
        DeleteObject(hClipRgn);
        hClipRgn = NULL;
    }
    return (void*)hClipRgn;
}
FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform)
{
    if (m_DeviceClass == FXDC_PRINTER) {
        CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
        if (pBitmap == NULL) {
            return FALSE;
        }
        if ((pBitmap->IsCmykImage() || pIccTransform) &&
                !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
            return FALSE;
        }
        int width = pSrcRect->Width(), height = pSrcRect->Height();
        int pitch = pBitmap->GetPitch();
        LPBYTE pBuffer = pBitmap->GetBuffer();
        CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
        ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1;
        FX_RECT dst_rect(0, 0, width, height);
        dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
        int dst_width = dst_rect.Width();
        int dst_height = dst_rect.Height();
        ::StretchDIBits(m_hDC, left, top, dst_width, dst_height,
            0, 0, dst_width, dst_height, pBuffer, (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS, SRCCOPY);
        delete pBitmap;
    } else {
        CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
        if ((pBitmap->IsCmykImage() || pIccTransform) &&
                (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) {
            return FALSE;
        }
        int width = pSrcRect->Width(), height = pSrcRect->Height();
        int pitch = pBitmap->GetPitch();
        LPBYTE pBuffer = pBitmap->GetBuffer();
        CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
        ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom,
            0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS);
        if (pBitmap != pBitmap1) {
            delete pBitmap;
        }
    }
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
        int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
{
    CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
    if (pBitmap == NULL || dest_width == 0  || dest_height == 0) {
        return FALSE;
    }
    if ((pBitmap->IsCmykImage() || pIccTransform) &&
            !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
        return FALSE;
    }
    CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
    if ((int64_t)abs(dest_width) * abs(dest_height) < (int64_t)pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 ||
            (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) {
        SetStretchBltMode(m_hDC, HALFTONE);
    } else {
        SetStretchBltMode(m_hDC, COLORONCOLOR);
    }
    CFX_DIBitmap* pToStrechBitmap = pBitmap;
    bool del = false;
    if (m_DeviceClass == FXDC_PRINTER && ((int64_t)pBitmap->GetWidth() * pBitmap->GetHeight() > (int64_t)abs(dest_width) * abs(dest_height))) {
        pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height);
        del = true;
    }
    CFX_ByteString toStrechBitmapInfo = CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap);
    ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
                    0, 0, pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(), pToStrechBitmap->GetBuffer(),
                    (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS, SRCCOPY);
    if (del) {
        delete pToStrechBitmap;
    }
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
        int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
        int alpha_flag, void* pIccTransform)
{
    CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
    if (pBitmap == NULL || dest_width == 0  || dest_height == 0) {
        return FALSE;
    }
    _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransform);
    int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
    struct {
        BITMAPINFOHEADER	bmiHeader;
        FX_DWORD			bmiColors[2];
    } bmi;
    FXSYS_memset(&bmi.bmiHeader, 0, sizeof (BITMAPINFOHEADER));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biBitCount = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biHeight = -height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biWidth = width;
    if (m_nBitsPerPixel != 1) {
        SetStretchBltMode(m_hDC, HALFTONE);
    }
    bmi.bmiColors[0] = 0xffffff;
    bmi.bmiColors[1] = 0;

    HBRUSH hPattern = CreateSolidBrush(bitmap_color & 0xffffff);
    HBRUSH hOld = (HBRUSH)SelectObject(m_hDC, hPattern);


    // In PDF, when image mask is 1, use device bitmap; when mask is 0, use brush bitmap.
    // A complete list of the boolen operations is as follows:

    /* P(bitmap_color)    S(ImageMask)    D(DeviceBitmap)    Result
     *        0                 0                0              0
     *        0                 0                1              0
     *        0                 1                0              0
     *        0                 1                1              1
     *        1                 0                0              1
     *        1                 0                1              1
     *        1                 1                0              0
     *        1                 1                1              1
     */
    // The boolen codes is B8. Based on http://msdn.microsoft.com/en-us/library/aa932106.aspx, the ROP3 code is 0xB8074A

    ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
                    0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, 0xB8074A);

    SelectObject(m_hDC, hOld);
    DeleteObject(hPattern);

    return TRUE;
}
FX_BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
{
    return ::GetClipBox(m_hDC, (RECT*)pRect);
}
FX_BOOL CGdiDeviceDriver::SetClipRgn(void* hRgn)
{
    ::SelectClipRgn(m_hDC, (HRGN)hRgn);
    return TRUE;
}
static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb)
{
    FX_FLOAT width;
    FX_FLOAT scale = 1.f;
    if (pMatrix)
        scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
                FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
    if (pGraphState) {
        width = scale * pGraphState->m_LineWidth;
    } else {
        width = 1.0f;
    }
    FX_DWORD PenStyle = PS_GEOMETRIC;
    if (width < 1) {
        width = 1;
    }
    if(pGraphState->m_DashCount) {
        PenStyle |= PS_USERSTYLE;
    } else {
        PenStyle |= PS_SOLID;
    }
    switch(pGraphState->m_LineCap) {
        case 0:
            PenStyle |= PS_ENDCAP_FLAT;
            break;
        case 1:
            PenStyle |= PS_ENDCAP_ROUND;
            break;
        case 2:
            PenStyle |= PS_ENDCAP_SQUARE;
            break;
    }
    switch(pGraphState->m_LineJoin) {
        case 0:
            PenStyle |= PS_JOIN_MITER;
            break;
        case 1:
            PenStyle |= PS_JOIN_ROUND;
            break;
        case 2:
            PenStyle |= PS_JOIN_BEVEL;
            break;
    }
    int a;
    FX_COLORREF rgb;
    ArgbDecode(argb, a, rgb);
    LOGBRUSH lb;
    lb.lbColor = rgb;
    lb.lbStyle = BS_SOLID;
    lb.lbHatch = 0;
    FX_DWORD* pDash = NULL;
    if (pGraphState->m_DashCount) {
        pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
        for (int i = 0; i < pGraphState->m_DashCount; i ++) {
            pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]);
            if (pDash[i] < 1) {
                pDash[i] = 1;
            }
        }
    }
    HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash);
    if (pDash) {
        FX_Free(pDash);
    }
    return hPen;
}
static HBRUSH _CreateBrush(FX_DWORD argb)
{
    int a;
    FX_COLORREF rgb;
    ArgbDecode(argb, a, rgb);
    return CreateSolidBrush(rgb);
}
static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix)
{
    BeginPath(hDC);
    int nPoints = pPathData->GetPointCount();
    FX_PATHPOINT* pPoints = pPathData->GetPoints();
    for(int i = 0; i < nPoints; i++) {
        FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
        if (pMatrix) {
            pMatrix->Transform(posx, posy);
        }
        int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
        int point_type = pPoints[i].m_Flag & FXPT_TYPE;
        if(point_type == PT_MOVETO) {
            MoveToEx(hDC, screen_x, screen_y, NULL);
        } else if(point_type == PT_LINETO) {
            if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
                screen_x ++;
            }
            LineTo(hDC, screen_x, screen_y);
        } else if(point_type == PT_BEZIERTO) {
            POINT lppt[3];
            lppt[0].x = screen_x;
            lppt[0].y = screen_y;
            posx = pPoints[i + 1].m_PointX;
            posy = pPoints[i + 1].m_PointY;
            if (pMatrix) {
                pMatrix->Transform(posx, posy);
            }
            lppt[1].x = FXSYS_round(posx);
            lppt[1].y = FXSYS_round(posy);
            posx = pPoints[i + 2].m_PointX;
            posy = pPoints[i + 2].m_PointY;
            if (pMatrix) {
                pMatrix->Transform(posx, posy);
            }
            lppt[2].x = FXSYS_round(posx);
            lppt[2].y = FXSYS_round(posy);
            PolyBezierTo(hDC, lppt, 3);
            i += 2;
        }
        if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
            CloseFigure(hDC);
        }
    }
    EndPath(hDC);
}
void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
{
    int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3);
    int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3);
    if (flag1 & flag2) {
        return;
    }
    if (flag1 || flag2) {
        agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height));
        FX_FLOAT x[2], y[2];
        int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
        if (np == 0) {
            return;
        }
        if (np == 1) {
            x2 = x[0];
            y2 = y[0];
        } else {
            x1 = x[0];
            y1 = y[0];
            x2 = x[np - 1];
            y2 = y[np - 1];
        }
    }
    MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
    LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
}
static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
{
    return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
}
FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
                                   const CFX_AffineMatrix* pMatrix,
                                   const CFX_GraphStateData* pGraphState,
                                   FX_DWORD fill_color,
                                   FX_DWORD stroke_color,
                                   int fill_mode,
                                   int alpha_flag,
                                   void* pIccTransform,
                                   int	blend_type
                                  )
{
    if (blend_type != FXDIB_BLEND_NORMAL) {
        return FALSE;
    }
    _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
    _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
    CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
    if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) {
        CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
        if (pMatrix) {
            bbox_f.Transform(pMatrix);
        }
        FX_RECT bbox = bbox_f.GetInnerRect();
        if (bbox.Width() <= 0) {
            return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color,
                                    alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
        } else if (bbox.Height() <= 0) {
            return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color,
                                    alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
        }
    }
    int fill_alpha = FXARGB_A(fill_color);
    int stroke_alpha = FXARGB_A(stroke_color);
    FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
    if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
        return FALSE;
    }
    if (pPlatform->m_GdiplusExt.IsAvailable()) {
        if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || (pGraphState && pGraphState->m_DashCount))) {
            if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
                    pGraphState && pGraphState->m_LineWidth == 1.f &&
                    (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
                    pPathData->IsRect()) ) {
                if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
                    return TRUE;
                }
            }
        }
    }
    int old_fill_mode = fill_mode;
    fill_mode &= 3;
    HPEN hPen = NULL;
    HBRUSH hBrush = NULL;
    if (pGraphState && stroke_alpha) {
        SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
        hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
        hPen = (HPEN)SelectObject(m_hDC, hPen);
    }
    if (fill_mode && fill_alpha) {
        SetPolyFillMode(m_hDC, fill_mode);
        hBrush = _CreateBrush(fill_color);
        hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
    }
    if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) {
        FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
        if (pMatrix) {
            pMatrix->Transform(x1, y1);
        }
        FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
        if (pMatrix) {
            pMatrix->Transform(x2, y2);
        }
        DrawLine(x1, y1, x2, y2);
    } else {
        _SetPathToDC(m_hDC, pPathData, pMatrix);
        if (pGraphState && stroke_alpha) {
            if (fill_mode && fill_alpha) {
                if (old_fill_mode & FX_FILL_TEXT_MODE) {
                    StrokeAndFillPath(m_hDC);
                } else {
                    FillPath(m_hDC);
                    _SetPathToDC(m_hDC, pPathData, pMatrix);
                    StrokePath(m_hDC);
                }
            } else {
                StrokePath(m_hDC);
            }
        } else if (fill_mode && fill_alpha) {
            FillPath(m_hDC);
        }
    }
    if (hPen) {
        hPen = (HPEN)SelectObject(m_hDC, hPen);
        DeleteObject(hPen);
    }
    if (hBrush) {
        hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
        DeleteObject(hBrush);
    }
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
{
    if (blend_type != FXDIB_BLEND_NORMAL) {
        return FALSE;
    }
    _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
    int alpha;
    FX_COLORREF rgb;
    ArgbDecode(fill_color, alpha, rgb);
    if (alpha == 0) {
        return TRUE;
    }
    if (alpha < 255) {
        return FALSE;
    }
    HBRUSH hBrush = CreateSolidBrush(rgb);
    ::FillRect(m_hDC, (RECT*)pRect, hBrush);
    DeleteObject(hBrush);
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
        const CFX_AffineMatrix* pMatrix,
        int fill_mode
                                          )
{
    if (pPathData->GetPointCount() == 5) {
        CFX_FloatRect rectf;
        if (pPathData->IsRect(pMatrix, &rectf)) {
            FX_RECT rect = rectf.GetOutterRect();
            IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
            return TRUE;
        }
    }
    _SetPathToDC(m_hDC, pPathData, pMatrix);
    SetPolyFillMode(m_hDC, fill_mode & 3);
    SelectClipPath(m_hDC, RGN_AND);
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
        const CFX_AffineMatrix* pMatrix,
        const CFX_GraphStateData* pGraphState
                                            )
{
    HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
    hPen = (HPEN)SelectObject(m_hDC, hPen);
    _SetPathToDC(m_hDC, pPathData, pMatrix);
    WidenPath(m_hDC);
    SetPolyFillMode(m_hDC, WINDING);
    FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
    hPen = (HPEN)SelectObject(m_hDC, hPen);
    DeleteObject(hPen);
    return ret;
}
FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
        int alpha_flag, void* pIccTransform, int	blend_type)
{
    if (blend_type != FXDIB_BLEND_NORMAL) {
        return FALSE;
    }
    _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
    int a;
    FX_COLORREF rgb;
    ArgbDecode(color, a, rgb);
    if (a == 0) {
        return TRUE;
    }
    HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
    hPen = (HPEN)SelectObject(m_hDC, hPen);
    MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
    LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
    hPen = (HPEN)SelectObject(m_hDC, hPen);
    DeleteObject(hPen);
    return TRUE;
}
FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(void* pRgn)
{
    DeleteObject((HGDIOBJ)pRgn);
    return TRUE;
}
CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_DISPLAY)
{
    CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
    if (pPlatform->m_GdiplusExt.IsAvailable()) {
        m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE;
    }
}
FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge)
{
    FX_BOOL ret = FALSE;
    int width = pBitmap->GetWidth();
    int height = pBitmap->GetHeight();
    HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height);
    HDC hDCMemory = CreateCompatibleDC(m_hDC);
    HBITMAP holdbmp  = (HBITMAP)SelectObject(hDCMemory, hbmp);
    BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY);
    SelectObject(hDCMemory, holdbmp);
    BITMAPINFO bmi;
    FXSYS_memset(&bmi, 0, sizeof bmi);
    bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
    bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
    bmi.bmiHeader.biHeight = -height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biWidth = width;
    if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
        pIccTransform = NULL;
    }
    if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) {
        ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height;
    } else {
        CFX_DIBitmap bitmap;
        if (bitmap.Create(width, height, FXDIB_Rgb)) {
            bmi.bmiHeader.biBitCount = 24;
            ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS);
            ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform);
        } else {
            ret = FALSE;
        }
    }
    if (pBitmap->HasAlpha() && ret) {
        pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
    }
    DeleteObject(hbmp);
    DeleteObject(hDCMemory);
    return ret;
}
FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
                                     int alpha_flag, void* pIccTransform)
{
    ASSERT(blend_type == FXDIB_BLEND_NORMAL);
    if (pSource->IsAlphaMask()) {
        int width = pSource->GetWidth(), height = pSource->GetHeight();
        int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
        FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255;
        if (!bGDI) {
            CFX_DIBitmap background;
            if (!background.Create(width, height, FXDIB_Rgb32) ||
                !GetDIBits(&background, left, top, NULL) ||
                !background.CompositeMask(0, 0, width, height, pSource, color,
                                          0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE,
                                          alpha_flag, pIccTransform)) {
                return FALSE;
            }
            FX_RECT src_rect(0, 0, width, height);
            return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
        }
        FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
        return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, width, height,
                             &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
    }
    int width = pSrcRect->Width(), height = pSrcRect->Height();
    if (pSource->HasAlpha()) {
        CFX_DIBitmap bitmap;
        if (!bitmap.Create(width, height, FXDIB_Rgb) ||
            !GetDIBits(&bitmap, left, top, NULL) ||
            !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
            return FALSE;
        }
        FX_RECT src_rect(0, 0, width, height);
        return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
    }
    CFX_DIBExtractor temp(pSource);
    CFX_DIBitmap* pBitmap = temp;
    if (pBitmap) {
        return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
    }
    return FALSE;
}
FX_BOOL CGdiDisplayDriver::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, void* pIccTransform, int blend_type)
{
    FX_RECT bitmap_clip = *pClipRect;
    if (dest_width < 0) {
        dest_left += dest_width;
    }
    if (dest_height < 0) {
        dest_top += dest_height;
    }
    bitmap_clip.Offset(-dest_left, -dest_top);
    CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
    if (pStretched == NULL) {
        return TRUE;
    }
    FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
    FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
    delete pStretched;
    return ret;
}
FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, 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)
{
    ASSERT(pSource != NULL && pClipRect != NULL);
    if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000) {
        return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
                                     pClipRect, flags, alpha_flag, pIccTransform, blend_type);
    }
    if (pSource->IsAlphaMask()) {
        FX_RECT image_rect;
        image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
        image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
        image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
        image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
        FX_RECT clip_rect = image_rect;
        clip_rect.Intersect(*pClipRect);
        clip_rect.Offset(-image_rect.left, -image_rect.top);
        int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
        CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
        if (pStretched == NULL) {
            return TRUE;
        }
        CFX_DIBitmap background;
        if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
            !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) ||
            !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
            delete pStretched;
            return FALSE;
        }
        FX_RECT src_rect(0, 0, clip_width, clip_height);
        FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
        delete pStretched;
        return ret;
    }
    if (pSource->HasAlpha()) {
        CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
        if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) {
            CFX_DIBExtractor temp(pSource);
            CFX_DIBitmap* pBitmap = temp;
            if (pBitmap == NULL) {
                return FALSE;
            }
            return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags);
        }
        return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
                                     pClipRect, flags, alpha_flag, pIccTransform, blend_type);
    }
    CFX_DIBExtractor temp(pSource);
    CFX_DIBitmap* pBitmap = temp;
    if (pBitmap) {
        return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
    }
    return FALSE;
}
#define GET_PS_FEATURESETTING        4121
#define FEATURESETTING_PSLEVEL       2
int GetPSLevel(HDC hDC)
{
    int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
    if (device_type != DT_RASPRINTER) {
        return 0;
    }
    FX_DWORD esc = GET_PS_FEATURESETTING;
    if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
        int param = FEATURESETTING_PSLEVEL;
        if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
            return param;
        }
    }
    esc = POSTSCRIPT_IDENTIFY;
    if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
        esc = POSTSCRIPT_DATA;
        if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
            return 2;
        }
        return 0;
    }
    esc = PSIDENT_GDICENTRIC;
    if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) {
        return 2;
    }
    esc = GET_PS_FEATURESETTING;
    if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
        int param = FEATURESETTING_PSLEVEL;
        if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
            return param;
        }
    }
    return 2;
}
int CFX_WindowsDevice::m_psLevel = 2;
CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel)
{
    m_bForcePSOutput = bForcePSOutput;
    m_psLevel = psLevel;
    if (bForcePSOutput) {
        IFX_RenderDeviceDriver* pDriver = new CPSPrinterDriver;
        ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput);
        SetDeviceDriver(pDriver);
        return;
    }
    SetDeviceDriver(CreateDriver(hDC, bCmykOutput));
}
HDC CFX_WindowsDevice::GetDC() const
{
    IFX_RenderDeviceDriver *pRDD = GetDeviceDriver();
    if (!pRDD) {
        return NULL;
    }
    return (HDC)pRDD->GetPlatformSurface();
}
IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, FX_BOOL bCmykOutput)
{
    int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
    int obj_type = ::GetObjectType(hDC);
    int device_class;
    if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC) {
        device_class = FXDC_PRINTER;
    } else {
        device_class = FXDC_DISPLAY;
    }
    if (device_class == FXDC_PRINTER) {
        return new CGdiPrinterDriver(hDC);
    }
    return new CGdiDisplayDriver(hDC);
}
CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format)
{
    BITMAPINFOHEADER bmih;
    FXSYS_memset(&bmih, 0, sizeof (BITMAPINFOHEADER));
    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biBitCount = format & 0xff;
    bmih.biHeight = -height;
    bmih.biPlanes = 1;
    bmih.biWidth = width;
    uint8_t* pBuffer;
    m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&pBuffer, NULL, 0);
    if (m_hBitmap == NULL) {
        return;
    }
    CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
    pBitmap->Create(width, height, format, pBuffer);
    SetBitmap(pBitmap);
    m_hDC = ::CreateCompatibleDC(NULL);
    m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
    IFX_RenderDeviceDriver* pDriver = new CGdiDisplayDriver(m_hDC);
    SetDeviceDriver(pDriver);
}
CFX_WinBitmapDevice::~CFX_WinBitmapDevice()
{
    if (m_hDC) {
        SelectObject(m_hDC, m_hOldBitmap);
        DeleteDC(m_hDC);
    }
    if (m_hBitmap) {
        DeleteObject(m_hBitmap);
    }
    delete GetBitmap();
}

#endif  // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
