// 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/fxge/agg/fx_agg_driver.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/ge/fx_text_int.h"
#include "core/fxge/win32/dwrite_int.h"
#include "core/fxge/win32/win32_int.h"
#include "core/include/fxcodec/fx_codec.h"
#include "core/include/fxge/fx_freetype.h"
#include "core/include/fxge/fx_ge_win32.h"
#include "third_party/base/stl_util.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 = pdfium::CollectionSize<int>(m_pMapper->m_InstalledTTFonts);
  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;
}
static FX_BOOL IsGDIEnabled() {
  // If GDI is disabled then GetDC for the desktop will fail.
  HDC hdc = ::GetDC(NULL);
  if (hdc) {
    ::ReleaseDC(NULL, hdc);
    return TRUE;
  }
  return FALSE;
}
IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) {
  if (IsGDIEnabled()) {
    return new CFX_Win32FontInfo;
  }
  // 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;
  if (IsGDIEnabled()) {
    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);
    if (pSource->GetBPP() != 1 || alpha != 255) {
      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_
