// 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 "core/include/fxge/fx_ge.h"

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

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

class CFX_Win32FallbackFontInfo final : public CFX_FolderFontInfo {
 public:
  void* MapFont(int weight,
                FX_BOOL bItalic,
                int charset,
                int pitch_family,
                const FX_CHAR* family,
                int& iExact) override;
};
class CFX_Win32FontInfo final : public IFX_SystemFontInfo {
 public:
  CFX_Win32FontInfo();
  ~CFX_Win32FontInfo() override;

  // IFX_SystemFontInfo
  void Release() override;
  FX_BOOL EnumFontList(CFX_FontMapper* pMapper) override;
  void* MapFont(int weight,
                FX_BOOL bItalic,
                int charset,
                int pitch_family,
                const FX_CHAR* face,
                int& iExact) override;
  void* GetFont(const FX_CHAR* face) override { return NULL; }
  FX_DWORD GetFontData(void* hFont,
                       FX_DWORD table,
                       uint8_t* buffer,
                       FX_DWORD size) override;
  FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name) override;
  FX_BOOL GetFontCharset(void* hFont, int& charset) override;
  void DeleteFont(void* hFont) override;

  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;
};

CFX_Win32FontInfo::CFX_Win32FontInfo() {
  m_hDC = CreateCompatibleDC(NULL);
}
CFX_Win32FontInfo::~CFX_Win32FontInfo() {
  m_pMapper = NULL;
}
void CFX_Win32FontInfo::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 CFX_Win32FontInfo::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 CFX_Win32FontInfo::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 CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA* plf,
                                         FX_DWORD FontType) {
  CFX_ByteString name(plf->lfFaceName);
  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) {
  CFX_Win32FontInfo* pFontInfo = (CFX_Win32FontInfo*)lParam;
  if (pFontInfo->m_pMapper->GetFontEnumerator()) {
    pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
  }
  pFontInfo->AddInstalledFont(plf, FontType);
  return 1;
}
FX_BOOL CFX_Win32FontInfo::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 CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) {
  if (!m_pMapper) {
    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();
}
void* CFX_Win32FallbackFontInfo::MapFont(int weight,
                                         FX_BOOL bItalic,
                                         int charset,
                                         int pitch_family,
                                         const FX_CHAR* cstr_face,
                                         int& iExact) {
  void* font = GetSubstFont(cstr_face);
  if (font) {
    iExact = 1;
    return font;
  }
  FX_BOOL bCJK = TRUE;
  switch (charset) {
    case FXFONT_SHIFTJIS_CHARSET:
    case FXFONT_GB2312_CHARSET:
    case FXFONT_CHINESEBIG5_CHARSET:
    case FXFONT_HANGEUL_CHARSET:
    default:
      bCJK = FALSE;
      break;
  }
  return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
}
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) {
    return FALSE;
  }
  name = found->m_pSubFontName;
  return TRUE;
}
void CFX_Win32FontInfo::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 CFX_Win32FontInfo::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* CFX_Win32FontInfo::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);
  ::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 CFX_Win32FontInfo::DeleteFont(void* hFont) {
  ::DeleteObject(hFont);
}
FX_DWORD CFX_Win32FontInfo::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 CFX_Win32FontInfo::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 CFX_Win32FontInfo::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(const char** pUnused) {
  HDC hdc = ::GetDC(NULL);
  if (hdc) {
    ::ReleaseDC(NULL, hdc);
    return new CFX_Win32FontInfo;
  }
  // If GDI is disabled then GetDC for the desktop will fail. Select the
  // fallback font information class if GDI is disabled.
  CFX_Win32FallbackFontInfo* pInfoFallback = new CFX_Win32FallbackFontInfo;
  // Construct the font path manually, SHGetKnownFolderPath won't work under
  // a restrictive sandbox.
  CHAR windows_path[MAX_PATH] = {};
  DWORD path_len = ::GetWindowsDirectoryA(windows_path, MAX_PATH);
  if (path_len > 0 && path_len < MAX_PATH) {
    CFX_ByteString fonts_path(windows_path);
    fonts_path += "\\Fonts";
    pInfoFallback->AddPath(fonts_path);
  }
  return pInfoFallback;
}
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(nullptr));
}
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) {
      return FALSE;
    }
    if ((pBitmap->IsCmykImage() || pIccTransform) &&
        !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
      return FALSE;
    }
    int width = pSrcRect->Width(), height = pSrcRect->Height();
    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();
    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 || 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 || 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_Matrix* 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);
  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_Matrix* 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_Matrix* 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_Matrix* 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 || 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_Matrix* 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_Matrix* 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) {
    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) {
    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 && pClipRect);
  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) {
      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 &&
        !pSource->IsCmykImage()) {
      CFX_DIBExtractor temp(pSource);
      CFX_DIBitmap* pBitmap = temp;
      if (!pBitmap) {
        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) {
    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_
