summaryrefslogtreecommitdiff
path: root/core/src/fxge/win32
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxge/win32')
-rw-r--r--core/src/fxge/win32/dwrite_int.h118
-rw-r--r--core/src/fxge/win32/fx_win32_device.cpp2400
-rw-r--r--core/src/fxge/win32/fx_win32_dib.cpp620
-rw-r--r--core/src/fxge/win32/fx_win32_dwrite.cpp960
-rw-r--r--core/src/fxge/win32/fx_win32_gdipext.cpp2572
-rw-r--r--core/src/fxge/win32/fx_win32_print.cpp852
-rw-r--r--core/src/fxge/win32/win32_int.h476
7 files changed, 3999 insertions, 3999 deletions
diff --git a/core/src/fxge/win32/dwrite_int.h b/core/src/fxge/win32/dwrite_int.h
index 1f0770d0bf..2eecc7c76b 100644
--- a/core/src/fxge/win32/dwrite_int.h
+++ b/core/src/fxge/win32/dwrite_int.h
@@ -1,59 +1,59 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_DIRECT_WRITE_
-#define _FX_DIRECT_WRITE_
-#ifndef DECLSPEC_UUID
-#if (_MSC_VER >= 1100) && defined (__cplusplus)
-#define DECLSPEC_UUID(x) __declspec(uuid(x))
-#else
-#define DECLSPEC_UUID(x)
-#endif
-#endif
-#ifndef DECLSPEC_NOVTABLE
-#if (_MSC_VER >= 1100) && defined(__cplusplus)
-#define DECLSPEC_NOVTABLE __declspec(novtable)
-#else
-#define DECLSPEC_NOVTABLE
-#endif
-#endif
-#if(WINVER < 0x0500)
-#ifndef _MAC
-DECLARE_HANDLE(HMONITOR);
-#endif
-#endif
-class CDWriteExt
-{
-public:
- CDWriteExt();
- ~CDWriteExt();
-
- void Load();
- void Unload();
-
- FX_BOOL IsAvailable()
- {
- return m_pDWriteFactory != NULL;
- }
-
- void* DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style);
- FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget);
- void DwDeleteRenderingTarget(void* renderTarget);
- FX_BOOL DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
- void *font, FX_FLOAT font_size, FX_ARGB text_color,
- int glyph_count, unsigned short* glyph_indices,
- FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
- void* glyph_offsets,
- FX_FLOAT* glyph_advances);
- void DwDeleteFont(void* pFont);
-
-protected:
- void* m_hModule;
- void* m_pDWriteFactory;
- void* m_pDwFontContext;
- void* m_pDwTextRenderer;
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_DIRECT_WRITE_
+#define _FX_DIRECT_WRITE_
+#ifndef DECLSPEC_UUID
+#if (_MSC_VER >= 1100) && defined (__cplusplus)
+#define DECLSPEC_UUID(x) __declspec(uuid(x))
+#else
+#define DECLSPEC_UUID(x)
+#endif
+#endif
+#ifndef DECLSPEC_NOVTABLE
+#if (_MSC_VER >= 1100) && defined(__cplusplus)
+#define DECLSPEC_NOVTABLE __declspec(novtable)
+#else
+#define DECLSPEC_NOVTABLE
+#endif
+#endif
+#if(WINVER < 0x0500)
+#ifndef _MAC
+DECLARE_HANDLE(HMONITOR);
+#endif
+#endif
+class CDWriteExt
+{
+public:
+ CDWriteExt();
+ ~CDWriteExt();
+
+ void Load();
+ void Unload();
+
+ FX_BOOL IsAvailable()
+ {
+ return m_pDWriteFactory != NULL;
+ }
+
+ void* DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style);
+ FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget);
+ void DwDeleteRenderingTarget(void* renderTarget);
+ FX_BOOL DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
+ void *font, FX_FLOAT font_size, FX_ARGB text_color,
+ int glyph_count, unsigned short* glyph_indices,
+ FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
+ void* glyph_offsets,
+ FX_FLOAT* glyph_advances);
+ void DwDeleteFont(void* pFont);
+
+protected:
+ void* m_hModule;
+ void* m_pDWriteFactory;
+ void* m_pDwFontContext;
+ void* m_pDwTextRenderer;
+};
+#endif
diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp
index e3f5ae0609..592886249b 100644
--- a/core/src/fxge/win32/fx_win32_device.cpp
+++ b/core/src/fxge/win32/fx_win32_device.cpp
@@ -1,1200 +1,1200 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include "../../../include/fxge/fx_ge_win32.h"
-#include <crtdbg.h>
-#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
-#include "dwrite_int.h"
-#include "win32_int.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#include "../agg/include/fx_agg_driver.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "../../../include/fxcodec/fx_codec.h"
-class CWin32FontInfo : public IFX_SystemFontInfo
-{
-public:
- CWin32FontInfo();
- ~CWin32FontInfo();
- virtual void Release();
- virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
- virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
- virtual void* GetFont(FX_LPCSTR face)
- {
- return NULL;
- }
- virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
- virtual void DeleteFont(void* hFont);
- virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name);
- virtual FX_BOOL GetFontCharset(void* hFont, int& charset);
- FX_BOOL IsOpenTypeFromDiv(const LOGFONTA *plf);
- FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf);
- void AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType);
- void GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
- void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family);
- CFX_ByteString FindFont(const CFX_ByteString& name);
- HDC m_hDC;
- CFX_FontMapper* m_pMapper;
- CFX_ByteString m_LastFamily;
- CFX_ByteString m_KaiTi, m_FangSong;
-};
-CWin32FontInfo::CWin32FontInfo()
-{
- m_hDC = CreateCompatibleDC(NULL);
-}
-CWin32FontInfo::~CWin32FontInfo()
-{
- m_pMapper = NULL;
-}
-void CWin32FontInfo::Release()
-{
- DeleteDC(m_hDC);
- delete this;
-}
-#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4)
-FX_BOOL CWin32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf)
-{
- HFONT hFont = CreateFontIndirectA(plf);
- FX_BOOL ret = FALSE;
- FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
- if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
- FX_DWORD lVersion = 0;
- GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
- lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
- ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
- if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
- lVersion == 0x00010000 ||
- lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
- lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
- lVersion == 0x00020000) {
- ret = TRUE;
- }
- }
- DeleteFont(hFont);
- return ret;
-}
-FX_BOOL CWin32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf)
-{
- HFONT hFont = CreateFontIndirectA(plf);
- FX_BOOL ret = FALSE;
- FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
- if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
- FX_DWORD lVersion = 0;
- GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
- lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
- ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
- if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
- lVersion == 0x00010000 ||
- lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
- lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
- lVersion == 0x00020000) {
- ret = TRUE;
- } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
- (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
- ret = TRUE;
- }
- }
- DeleteFont(hFont);
- return ret;
-}
-void CWin32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
-{
- CFX_ByteString name(plf->lfFaceName, -1);
- if (name[0] == '@') {
- return;
- }
- if (name == m_LastFamily) {
- m_pMapper->AddInstalledFont(name, plf->lfCharSet);
- return;
- }
- if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
- return;
- }
- if (!(FontType & TRUETYPE_FONTTYPE)) {
- if (!IsSupportFontFormDiv(plf)) {
- return;
- }
- }
- m_pMapper->AddInstalledFont(name, plf->lfCharSet);
- m_LastFamily = name;
-}
-static int CALLBACK FontEnumProc(
- const LOGFONTA *plf,
- const TEXTMETRICA *lpntme,
- FX_DWORD FontType,
- LPARAM lParam
-)
-{
- CWin32FontInfo* pFontInfo = (CWin32FontInfo*)lParam;
- if (pFontInfo->m_pMapper->GetFontEnumerator()) {
- pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
- }
- pFontInfo->AddInstalledFont(plf, FontType);
- return 1;
-}
-FX_BOOL CWin32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
-{
- m_pMapper = pMapper;
- LOGFONTA lf;
- FXSYS_memset32(&lf, 0, sizeof(LOGFONTA));
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfFaceName[0] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (FX_UINTPTR)this, 0);
- if (pMapper->GetFontEnumerator()) {
- pMapper->GetFontEnumerator()->Finish();
- }
- return TRUE;
-}
-static const struct {
- FX_LPCSTR m_pFaceName;
- FX_LPCSTR m_pVariantName;
-}
-VariantNames[] = {
- {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
-};
-static const struct {
- FX_LPCSTR m_pName;
- FX_LPCSTR m_pWinName;
- FX_BOOL m_bBold;
- FX_BOOL m_bItalic;
-}
-Base14Substs[] = {
- {"Courier", "Courier New", FALSE, FALSE},
- {"Courier-Bold", "Courier New", TRUE, FALSE},
- {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
- {"Courier-Oblique", "Courier New", FALSE, TRUE},
- {"Helvetica", "Arial", FALSE, FALSE},
- {"Helvetica-Bold", "Arial", TRUE, FALSE},
- {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
- {"Helvetica-Oblique", "Arial", FALSE, TRUE},
- {"Times-Roman", "Times New Roman", FALSE, FALSE},
- {"Times-Bold", "Times New Roman", TRUE, FALSE},
- {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
- {"Times-Italic", "Times New Roman", FALSE, TRUE},
-};
-CFX_ByteString CWin32FontInfo::FindFont(const CFX_ByteString& name)
-{
- if (m_pMapper == NULL) {
- return name;
- }
- int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
- for (int i = 0; i < nFonts; i ++) {
- CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
- if (thisname[0] == ' ') {
- if (thisname.Mid(1, name.GetLength()) == name) {
- return m_pMapper->m_InstalledTTFonts[i + 1];
- }
- } else if (thisname.Left(name.GetLength()) == name) {
- return m_pMapper->m_InstalledTTFonts[i];
- }
- }
- return CFX_ByteString();
-}
-struct _FontNameMap {
- FX_LPCSTR m_pSubFontName;
- FX_LPCSTR m_pSrcFontName;
-};
-const _FontNameMap g_JpFontNameMap[] = {
- {"MS Mincho", "Heiseimin-W3"},
- {"MS Gothic", "Jun101-Light"},
-};
-const _FontNameMap g_GbFontNameMap[1];
-extern "C" {
- static int compareString(const void* key, const void* element)
- {
- return FXSYS_stricmp((FX_LPCSTR)key, ((_FontNameMap*)element)->m_pSrcFontName);
- }
-}
-FX_BOOL _GetSubFontName(CFX_ByteString& name, int lang)
-{
- int size = sizeof g_JpFontNameMap;
- void* pFontnameMap = (void*)g_JpFontNameMap;
- if (lang == 1) {
- size = sizeof g_GbFontNameMap;
- pFontnameMap = (void*)g_GbFontNameMap;
- } else if (lang == 2) {
- size = 0;
- }
- _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch((FX_LPCSTR)name, pFontnameMap,
- size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString);
- if (found == NULL) {
- return FALSE;
- }
- name = found->m_pSubFontName;
- return TRUE;
-}
-void CWin32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family)
-{
- if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
- if (m_KaiTi.IsEmpty()) {
- m_KaiTi = FindFont("KaiTi");
- if (m_KaiTi.IsEmpty()) {
- m_KaiTi = "SimSun";
- }
- }
- face = m_KaiTi;
- } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
- if (m_FangSong.IsEmpty()) {
- m_FangSong = FindFont("FangSong");
- if (m_FangSong.IsEmpty()) {
- m_FangSong = "SimSun";
- }
- }
- face = m_FangSong;
- } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
- face = "SimSun";
- } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
- face = "SimHei";
- } else if (!(picth_family & FF_ROMAN) && weight > 550) {
- face = "SimHei";
- } else {
- face = "SimSun";
- }
-}
-void CWin32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
-{
- if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- face = "MS PGothic";
- } else if (face.Find("UI Gothic") >= 0) {
- face = "MS UI Gothic";
- } else {
- if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
- face = "MS PGothic";
- } else {
- face = "MS Gothic";
- }
- }
- return;
- } else 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, 0)) {
- return;
- }
- if (!(picth_family & FF_ROMAN) && weight > 400) {
- face = "MS PGothic";
- } else {
- face = "MS PMincho";
- }
-}
-void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
-{
- 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;
- bExact = TRUE;
- break;
- }
- if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
- charset = DEFAULT_CHARSET;
- }
- int subst_pitch_family = pitch_family;
- switch (charset) {
- case SHIFTJIS_CHARSET:
- subst_pitch_family = FF_ROMAN;
- break;
- case CHINESEBIG5_CHARSET:
- case HANGUL_CHARSET:
- case GB2312_CHARSET:
- subst_pitch_family = 0;
- break;
- }
- HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
- 0, 0, subst_pitch_family, face);
- char facebuf[100];
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
- int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
- ::SelectObject(m_hDC, hOldFont);
- if (face.EqualNoCase(facebuf)) {
- return hFont;
- }
- int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
- for (int i = 0; i < iCount; ++i) {
- if (face == VariantNames[i].m_pFaceName) {
- CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
- CFX_WideString wsName = CFX_WideString::FromUTF16LE((const unsigned short*)VariantNames[i].m_pVariantName);
- if (wsFace == wsName) {
- return hFont;
- }
- }
- }
- ::DeleteObject(hFont);
- if (charset == DEFAULT_CHARSET) {
- return NULL;
- }
- switch (charset) {
- case SHIFTJIS_CHARSET:
- GetJapanesePreference(face, weight, pitch_family);
- break;
- case GB2312_CHARSET:
- GetGBPreference(face, weight, pitch_family);
- break;
- case HANGUL_CHARSET:
- face = "Gulim";
- break;
- case CHINESEBIG5_CHARSET:
- if (face.Find("MSung") >= 0) {
- face = "MingLiU";
- } else {
- face = "PMingLiU";
- }
- break;
- }
- hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
- 0, 0, subst_pitch_family, face);
- return hFont;
-}
-void CWin32FontInfo::DeleteFont(void* hFont)
-{
- ::DeleteObject(hFont);
-}
-FX_DWORD CWin32FontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
-{
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- table = FXDWORD_FROM_MSBFIRST(table);
- size = ::GetFontData(m_hDC, table, 0, buffer, size);
- ::SelectObject(m_hDC, hOldFont);
- if (size == GDI_ERROR) {
- return 0;
- }
- return size;
-}
-FX_BOOL CWin32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
-{
- char facebuf[100];
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
- ::SelectObject(m_hDC, hOldFont);
- if (ret == 0) {
- return FALSE;
- }
- name = facebuf;
- return TRUE;
-}
-FX_BOOL CWin32FontInfo::GetFontCharset(void* hFont, int& charset)
-{
- TEXTMETRIC tm;
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- ::GetTextMetrics(m_hDC, &tm);
- ::SelectObject(m_hDC, hOldFont);
- charset = tm.tmCharSet;
- return TRUE;
-}
-#ifndef _FPDFAPI_MINI_
-IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
-{
- return FX_NEW CWin32FontInfo;
-}
-#endif
-void CFX_GEModule::InitPlatform()
-{
- CWin32Platform* pPlatformData = FX_NEW CWin32Platform;
- if (!pPlatformData) {
- return;
- }
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
- pPlatformData->m_GdiplusExt.Load();
- m_pPlatformData = pPlatformData;
- m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
-}
-void CFX_GEModule::DestroyPlatform()
-{
- if (m_pPlatformData) {
- 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;
-}
-FX_LPVOID CGdiDeviceDriver::GetClipRgn()
-{
- HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
- if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
- DeleteObject(hClipRgn);
- hClipRgn = NULL;
- }
- return (FX_LPVOID)hClipRgn;
-}
-FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform)
-{
- if (m_DeviceClass == FXDC_PRINTER) {
- CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
- if (pBitmap == NULL) {
- return FALSE;
- }
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
- return FALSE;
- }
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- int pitch = pBitmap->GetPitch();
- LPBYTE pBuffer = pBitmap->GetBuffer();
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- ((BITMAPINFOHEADER*)(FX_LPCSTR)info)->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*)(FX_LPCSTR)info, DIB_RGB_COLORS, SRCCOPY);
- delete pBitmap;
- } else {
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) {
- return FALSE;
- }
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- int pitch = pBitmap->GetPitch();
- LPBYTE pBuffer = pBitmap->GetBuffer();
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom,
- 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (pBitmap != pBitmap1) {
- delete pBitmap;
- }
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
-{
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if (pBitmap == NULL) {
- return FALSE;
- }
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
- return FALSE;
- }
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- if (abs(dest_width) * abs(dest_height) < 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 && (pBitmap->GetWidth() * pBitmap->GetHeight() > 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*)(FX_LPCSTR)toStrechBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
- if (del) {
- delete pToStrechBitmap;
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
- int alpha_flag, void* pIccTransform)
-{
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if (pBitmap == NULL) {
- 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_memset32(&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;
- ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
- 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, SRCAND);
- return TRUE;
-}
-BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
-{
- return ::GetClipBox(m_hDC, (RECT*)pRect);
-}
-FX_BOOL CGdiDeviceDriver::SetClipRgn(FX_LPVOID hRgn)
-{
- ::SelectClipRgn(m_hDC, (HRGN)hRgn);
- return TRUE;
-}
-static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb)
-{
- FX_FLOAT width;
- FX_FLOAT scale = 1.f;
- if (pMatrix)
- scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
- FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
- if (pGraphState) {
- width = scale * pGraphState->m_LineWidth;
- } else {
- width = 1.0f;
- }
- FX_DWORD PenStyle = PS_GEOMETRIC;
- if (width < 1) {
- width = 1;
- }
- if(pGraphState->m_DashCount) {
- PenStyle |= PS_USERSTYLE;
- } else {
- PenStyle |= PS_SOLID;
- }
- switch(pGraphState->m_LineCap) {
- case 0:
- PenStyle |= PS_ENDCAP_FLAT;
- break;
- case 1:
- PenStyle |= PS_ENDCAP_ROUND;
- break;
- case 2:
- PenStyle |= PS_ENDCAP_SQUARE;
- break;
- }
- switch(pGraphState->m_LineJoin) {
- case 0:
- PenStyle |= PS_JOIN_MITER;
- break;
- case 1:
- PenStyle |= PS_JOIN_ROUND;
- break;
- case 2:
- PenStyle |= PS_JOIN_BEVEL;
- break;
- }
- int a;
- FX_COLORREF rgb;
- ArgbDecode(argb, a, rgb);
- LOGBRUSH lb;
- lb.lbColor = rgb;
- lb.lbStyle = BS_SOLID;
- lb.lbHatch = 0;
- FX_DWORD* pDash = NULL;
- if (pGraphState->m_DashCount) {
- pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
- if (!pDash) {
- return NULL;
- }
- for (int i = 0; i < pGraphState->m_DashCount; i ++) {
- pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]);
- if (pDash[i] < 1) {
- pDash[i] = 1;
- }
- }
- }
- HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash);
- if (pDash) {
- FX_Free(pDash);
- }
- return hPen;
-}
-static HBRUSH _CreateBrush(FX_DWORD argb)
-{
- int a;
- FX_COLORREF rgb;
- ArgbDecode(argb, a, rgb);
- return CreateSolidBrush(rgb);
-}
-static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix)
-{
- BeginPath(hDC);
- int nPoints = pPathData->GetPointCount();
- FX_PATHPOINT* pPoints = pPathData->GetPoints();
- for(int i = 0; i < nPoints; i++) {
- FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
- int point_type = pPoints[i].m_Flag & FXPT_TYPE;
- if(point_type == PT_MOVETO) {
- MoveToEx(hDC, screen_x, screen_y, NULL);
- } else if(point_type == PT_LINETO) {
- if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
- screen_x ++;
- }
- LineTo(hDC, screen_x, screen_y);
- } else if(point_type == PT_BEZIERTO) {
- POINT lppt[3];
- lppt[0].x = screen_x;
- lppt[0].y = screen_y;
- posx = pPoints[i + 1].m_PointX;
- posy = pPoints[i + 1].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- lppt[1].x = FXSYS_round(posx);
- lppt[1].y = FXSYS_round(posy);
- posx = pPoints[i + 2].m_PointX;
- posy = pPoints[i + 2].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- lppt[2].x = FXSYS_round(posx);
- lppt[2].y = FXSYS_round(posy);
- PolyBezierTo(hDC, lppt, 3);
- i += 2;
- }
- if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
- CloseFigure(hDC);
- }
- }
- EndPath(hDC);
-}
-void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
-{
- int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3);
- int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3);
- if (flag1 & flag2) {
- return;
- }
- if (flag1 || flag2) {
- agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height));
- FX_FLOAT x[2], y[2];
- int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
- if (np == 0) {
- return;
- }
- if (np == 1) {
- x2 = x[0];
- y2 = y[0];
- } else {
- x1 = x[0];
- y1 = y[0];
- x2 = x[np - 1];
- y2 = y[np - 1];
- }
- }
- MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
- LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
-}
-static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
-{
- return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
-}
-FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- )
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) {
- CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
- if (pMatrix) {
- bbox_f.Transform(pMatrix);
- }
- FX_RECT bbox = bbox_f.GetInnerRect();
- if (bbox.Width() <= 0) {
- return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color,
- alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- } else if (bbox.Height() <= 0) {
- return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color,
- alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- }
- }
- int fill_alpha = FXARGB_A(fill_color);
- int stroke_alpha = FXARGB_A(stroke_color);
- FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
- if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
- return FALSE;
- }
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || pGraphState && pGraphState->m_DashCount)) {
- if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
- pGraphState && pGraphState->m_LineWidth == 1.f &&
- (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
- pPathData->IsRect()) ) {
- if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
- return TRUE;
- }
- }
- }
- }
- int old_fill_mode = fill_mode;
- fill_mode &= 3;
- HPEN hPen = NULL;
- HBRUSH hBrush = NULL;
- if (pGraphState && stroke_alpha) {
- SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
- hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- }
- if (fill_mode && fill_alpha) {
- SetPolyFillMode(m_hDC, fill_mode);
- hBrush = _CreateBrush(fill_color);
- hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
- }
- if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) {
- FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
- if (pMatrix) {
- pMatrix->Transform(x1, y1);
- }
- FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
- if (pMatrix) {
- pMatrix->Transform(x2, y2);
- }
- DrawLine(x1, y1, x2, y2);
- } else {
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- if (pGraphState && stroke_alpha) {
- if (fill_mode && fill_alpha) {
- if (old_fill_mode & FX_FILL_TEXT_MODE) {
- StrokeAndFillPath(m_hDC);
- } else {
- FillPath(m_hDC);
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- StrokePath(m_hDC);
- }
- } else {
- StrokePath(m_hDC);
- }
- } else if (fill_mode && fill_alpha) {
- FillPath(m_hDC);
- }
- }
- if (hPen) {
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- }
- if (hBrush) {
- hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
- DeleteObject(hBrush);
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- int alpha;
- FX_COLORREF rgb;
- ArgbDecode(fill_color, alpha, rgb);
- if (alpha == 0) {
- return TRUE;
- }
- if (alpha < 255) {
- return FALSE;
- }
- HBRUSH hBrush = CreateSolidBrush(rgb);
- ::FillRect(m_hDC, (RECT*)pRect, hBrush);
- DeleteObject(hBrush);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- int fill_mode
- )
-{
- if (pPathData->GetPointCount() == 5) {
- CFX_FloatRect rectf;
- if (pPathData->IsRect(pMatrix, &rectf)) {
- FX_RECT rect = rectf.GetOutterRect();
- IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
- return TRUE;
- }
- }
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- SetPolyFillMode(m_hDC, fill_mode & 3);
- SelectClipPath(m_hDC, RGN_AND);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- const CFX_GraphStateData* pGraphState
- )
-{
- HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- WidenPath(m_hDC);
- SetPolyFillMode(m_hDC, WINDING);
- FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- return ret;
-}
-FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
- int a;
- FX_COLORREF rgb;
- ArgbDecode(color, a, rgb);
- if (a == 0) {
- return TRUE;
- }
- HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
- LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(FX_LPVOID 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_memset32(&bmi, 0, sizeof bmi);
- bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
- bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
- bmi.bmiHeader.biHeight = -height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biWidth = width;
- if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- pIccTransform = NULL;
- }
- if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) {
- ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height;
- } else {
- CFX_DIBitmap bitmap;
- if (bitmap.Create(width, height, FXDIB_Rgb)) {
- bmi.bmiHeader.biBitCount = 24;
- ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS);
- ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform);
- } else {
- ret = FALSE;
- }
- }
-#ifndef _FPDFAPI_MINI_
- if (pBitmap->HasAlpha() && ret) {
- pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
- }
-#endif
- 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);
- } else {
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- if (pSource->HasAlpha()) {
- CFX_DIBitmap bitmap;
- if (!bitmap.Create(width, height, FXDIB_Rgb) ||
- !GetDIBits(&bitmap, left, top, NULL) ||
- !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, width, height);
- return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap) {
- return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
- }
- }
- return FALSE;
-}
-FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- FX_RECT bitmap_clip = *pClipRect;
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- bitmap_clip.Offset(-dest_left, -dest_top);
- CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
- if (pStretched == NULL) {
- return TRUE;
- }
- FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
- FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
- delete pStretched;
- return ret;
-}
-FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- ASSERT(pSource != NULL && pClipRect != NULL);
- if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000)
- return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
- pClipRect, flags, alpha_flag, pIccTransform, blend_type);
- if (pSource->IsAlphaMask()) {
- FX_RECT image_rect;
- image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
- image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
- image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
- image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
- FX_RECT clip_rect = image_rect;
- clip_rect.Intersect(*pClipRect);
- clip_rect.Offset(-image_rect.left, -image_rect.top);
- int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
- CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
- if (pStretched == NULL) {
- return TRUE;
- }
- CFX_DIBitmap background;
- if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
- !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) ||
- !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
- delete pStretched;
- return FALSE;
- }
- FX_RECT src_rect(0, 0, clip_width, clip_height);
- FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
- delete pStretched;
- return ret;
- } else {
- if (pSource->HasAlpha()) {
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) {
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags);
- }
- return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
- pClipRect, flags, alpha_flag, pIccTransform, blend_type);
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap) {
- return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
- }
- }
- return FALSE;
-}
-#define GET_PS_FEATURESETTING 4121
-#define FEATURESETTING_PSLEVEL 2
-int GetPSLevel(HDC hDC)
-{
- int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
- if (device_type != DT_RASPRINTER) {
- return 0;
- }
- FX_DWORD esc = GET_PS_FEATURESETTING;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- int param = FEATURESETTING_PSLEVEL;
- if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
- return param;
- }
- }
- esc = POSTSCRIPT_IDENTIFY;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
- esc = POSTSCRIPT_DATA;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- return 2;
- }
- return 0;
- }
- esc = PSIDENT_GDICENTRIC;
- if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) {
- return 2;
- }
- esc = GET_PS_FEATURESETTING;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- int param = FEATURESETTING_PSLEVEL;
- if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
- return param;
- }
- }
- return 2;
-}
-int CFX_WindowsDevice::m_psLevel = 2;
-CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel)
-{
- m_bForcePSOutput = bForcePSOutput;
- m_psLevel = psLevel;
- if (bForcePSOutput) {
- IFX_RenderDeviceDriver* pDriver = FX_NEW CPSPrinterDriver;
- if (!pDriver) {
- return;
- }
- ((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;
- }
- return FX_NEW CGdiDisplayDriver(hDC);
-}
-CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format)
-{
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof (BITMAPINFOHEADER));
- bmih.biSize = sizeof(BITMAPINFOHEADER);
- bmih.biBitCount = format & 0xff;
- bmih.biHeight = -height;
- bmih.biPlanes = 1;
- bmih.biWidth = width;
- FX_LPBYTE pBuffer;
- m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (FX_LPVOID*)&pBuffer, NULL, 0);
- if (m_hBitmap == NULL) {
- return;
- }
- CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
- if (!pBitmap) {
- return;
- }
- pBitmap->Create(width, height, format, pBuffer);
- SetBitmap(pBitmap);
- m_hDC = ::CreateCompatibleDC(NULL);
- m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
- IFX_RenderDeviceDriver* pDriver = FX_NEW CGdiDisplayDriver(m_hDC);
- if (!pDriver) {
- return;
- }
- 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
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include "../../../include/fxge/fx_ge_win32.h"
+#include <crtdbg.h>
+#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
+#include "dwrite_int.h"
+#include "win32_int.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#include "../agg/include/fx_agg_driver.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "../../../include/fxcodec/fx_codec.h"
+class CWin32FontInfo : public IFX_SystemFontInfo
+{
+public:
+ CWin32FontInfo();
+ ~CWin32FontInfo();
+ virtual void Release();
+ virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
+ virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
+ virtual void* GetFont(FX_LPCSTR face)
+ {
+ return NULL;
+ }
+ virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
+ virtual void DeleteFont(void* hFont);
+ virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name);
+ virtual FX_BOOL GetFontCharset(void* hFont, int& charset);
+ FX_BOOL IsOpenTypeFromDiv(const LOGFONTA *plf);
+ FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf);
+ void AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType);
+ void GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
+ void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family);
+ CFX_ByteString FindFont(const CFX_ByteString& name);
+ HDC m_hDC;
+ CFX_FontMapper* m_pMapper;
+ CFX_ByteString m_LastFamily;
+ CFX_ByteString m_KaiTi, m_FangSong;
+};
+CWin32FontInfo::CWin32FontInfo()
+{
+ m_hDC = CreateCompatibleDC(NULL);
+}
+CWin32FontInfo::~CWin32FontInfo()
+{
+ m_pMapper = NULL;
+}
+void CWin32FontInfo::Release()
+{
+ DeleteDC(m_hDC);
+ delete this;
+}
+#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4)
+FX_BOOL CWin32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf)
+{
+ HFONT hFont = CreateFontIndirectA(plf);
+ FX_BOOL ret = FALSE;
+ FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
+ if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
+ FX_DWORD lVersion = 0;
+ GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
+ lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
+ ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
+ if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
+ lVersion == 0x00010000 ||
+ lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
+ lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
+ lVersion == 0x00020000) {
+ ret = TRUE;
+ }
+ }
+ DeleteFont(hFont);
+ return ret;
+}
+FX_BOOL CWin32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf)
+{
+ HFONT hFont = CreateFontIndirectA(plf);
+ FX_BOOL ret = FALSE;
+ FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
+ if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
+ FX_DWORD lVersion = 0;
+ GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
+ lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
+ ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
+ if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
+ lVersion == 0x00010000 ||
+ lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
+ lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
+ lVersion == 0x00020000) {
+ ret = TRUE;
+ } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
+ (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
+ ret = TRUE;
+ }
+ }
+ DeleteFont(hFont);
+ return ret;
+}
+void CWin32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
+{
+ CFX_ByteString name(plf->lfFaceName, -1);
+ if (name[0] == '@') {
+ return;
+ }
+ if (name == m_LastFamily) {
+ m_pMapper->AddInstalledFont(name, plf->lfCharSet);
+ return;
+ }
+ if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
+ return;
+ }
+ if (!(FontType & TRUETYPE_FONTTYPE)) {
+ if (!IsSupportFontFormDiv(plf)) {
+ return;
+ }
+ }
+ m_pMapper->AddInstalledFont(name, plf->lfCharSet);
+ m_LastFamily = name;
+}
+static int CALLBACK FontEnumProc(
+ const LOGFONTA *plf,
+ const TEXTMETRICA *lpntme,
+ FX_DWORD FontType,
+ LPARAM lParam
+)
+{
+ CWin32FontInfo* pFontInfo = (CWin32FontInfo*)lParam;
+ if (pFontInfo->m_pMapper->GetFontEnumerator()) {
+ pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
+ }
+ pFontInfo->AddInstalledFont(plf, FontType);
+ return 1;
+}
+FX_BOOL CWin32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
+{
+ m_pMapper = pMapper;
+ LOGFONTA lf;
+ FXSYS_memset32(&lf, 0, sizeof(LOGFONTA));
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfFaceName[0] = 0;
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (FX_UINTPTR)this, 0);
+ if (pMapper->GetFontEnumerator()) {
+ pMapper->GetFontEnumerator()->Finish();
+ }
+ return TRUE;
+}
+static const struct {
+ FX_LPCSTR m_pFaceName;
+ FX_LPCSTR m_pVariantName;
+}
+VariantNames[] = {
+ {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
+};
+static const struct {
+ FX_LPCSTR m_pName;
+ FX_LPCSTR m_pWinName;
+ FX_BOOL m_bBold;
+ FX_BOOL m_bItalic;
+}
+Base14Substs[] = {
+ {"Courier", "Courier New", FALSE, FALSE},
+ {"Courier-Bold", "Courier New", TRUE, FALSE},
+ {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
+ {"Courier-Oblique", "Courier New", FALSE, TRUE},
+ {"Helvetica", "Arial", FALSE, FALSE},
+ {"Helvetica-Bold", "Arial", TRUE, FALSE},
+ {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
+ {"Helvetica-Oblique", "Arial", FALSE, TRUE},
+ {"Times-Roman", "Times New Roman", FALSE, FALSE},
+ {"Times-Bold", "Times New Roman", TRUE, FALSE},
+ {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
+ {"Times-Italic", "Times New Roman", FALSE, TRUE},
+};
+CFX_ByteString CWin32FontInfo::FindFont(const CFX_ByteString& name)
+{
+ if (m_pMapper == NULL) {
+ return name;
+ }
+ int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
+ for (int i = 0; i < nFonts; i ++) {
+ CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
+ if (thisname[0] == ' ') {
+ if (thisname.Mid(1, name.GetLength()) == name) {
+ return m_pMapper->m_InstalledTTFonts[i + 1];
+ }
+ } else if (thisname.Left(name.GetLength()) == name) {
+ return m_pMapper->m_InstalledTTFonts[i];
+ }
+ }
+ return CFX_ByteString();
+}
+struct _FontNameMap {
+ FX_LPCSTR m_pSubFontName;
+ FX_LPCSTR m_pSrcFontName;
+};
+const _FontNameMap g_JpFontNameMap[] = {
+ {"MS Mincho", "Heiseimin-W3"},
+ {"MS Gothic", "Jun101-Light"},
+};
+const _FontNameMap g_GbFontNameMap[1];
+extern "C" {
+ static int compareString(const void* key, const void* element)
+ {
+ return FXSYS_stricmp((FX_LPCSTR)key, ((_FontNameMap*)element)->m_pSrcFontName);
+ }
+}
+FX_BOOL _GetSubFontName(CFX_ByteString& name, int lang)
+{
+ int size = sizeof g_JpFontNameMap;
+ void* pFontnameMap = (void*)g_JpFontNameMap;
+ if (lang == 1) {
+ size = sizeof g_GbFontNameMap;
+ pFontnameMap = (void*)g_GbFontNameMap;
+ } else if (lang == 2) {
+ size = 0;
+ }
+ _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch((FX_LPCSTR)name, pFontnameMap,
+ size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString);
+ if (found == NULL) {
+ return FALSE;
+ }
+ name = found->m_pSubFontName;
+ return TRUE;
+}
+void CWin32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family)
+{
+ if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
+ if (m_KaiTi.IsEmpty()) {
+ m_KaiTi = FindFont("KaiTi");
+ if (m_KaiTi.IsEmpty()) {
+ m_KaiTi = "SimSun";
+ }
+ }
+ face = m_KaiTi;
+ } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
+ if (m_FangSong.IsEmpty()) {
+ m_FangSong = FindFont("FangSong");
+ if (m_FangSong.IsEmpty()) {
+ m_FangSong = "SimSun";
+ }
+ }
+ face = m_FangSong;
+ } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
+ face = "SimSun";
+ } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
+ face = "SimHei";
+ } else if (!(picth_family & FF_ROMAN) && weight > 550) {
+ face = "SimHei";
+ } else {
+ face = "SimSun";
+ }
+}
+void CWin32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
+{
+ if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ face = "MS PGothic";
+ } else if (face.Find("UI Gothic") >= 0) {
+ face = "MS UI Gothic";
+ } else {
+ if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
+ face = "MS PGothic";
+ } else {
+ face = "MS Gothic";
+ }
+ }
+ return;
+ } else 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, 0)) {
+ return;
+ }
+ if (!(picth_family & FF_ROMAN) && weight > 400) {
+ face = "MS PGothic";
+ } else {
+ face = "MS PMincho";
+ }
+}
+void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
+{
+ 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;
+ bExact = TRUE;
+ break;
+ }
+ if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
+ charset = DEFAULT_CHARSET;
+ }
+ int subst_pitch_family = pitch_family;
+ switch (charset) {
+ case SHIFTJIS_CHARSET:
+ subst_pitch_family = FF_ROMAN;
+ break;
+ case CHINESEBIG5_CHARSET:
+ case HANGUL_CHARSET:
+ case GB2312_CHARSET:
+ subst_pitch_family = 0;
+ break;
+ }
+ HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
+ 0, 0, subst_pitch_family, face);
+ char facebuf[100];
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
+ int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
+ ::SelectObject(m_hDC, hOldFont);
+ if (face.EqualNoCase(facebuf)) {
+ return hFont;
+ }
+ int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
+ for (int i = 0; i < iCount; ++i) {
+ if (face == VariantNames[i].m_pFaceName) {
+ CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
+ CFX_WideString wsName = CFX_WideString::FromUTF16LE((const unsigned short*)VariantNames[i].m_pVariantName);
+ if (wsFace == wsName) {
+ return hFont;
+ }
+ }
+ }
+ ::DeleteObject(hFont);
+ if (charset == DEFAULT_CHARSET) {
+ return NULL;
+ }
+ switch (charset) {
+ case SHIFTJIS_CHARSET:
+ GetJapanesePreference(face, weight, pitch_family);
+ break;
+ case GB2312_CHARSET:
+ GetGBPreference(face, weight, pitch_family);
+ break;
+ case HANGUL_CHARSET:
+ face = "Gulim";
+ break;
+ case CHINESEBIG5_CHARSET:
+ if (face.Find("MSung") >= 0) {
+ face = "MingLiU";
+ } else {
+ face = "PMingLiU";
+ }
+ break;
+ }
+ hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
+ 0, 0, subst_pitch_family, face);
+ return hFont;
+}
+void CWin32FontInfo::DeleteFont(void* hFont)
+{
+ ::DeleteObject(hFont);
+}
+FX_DWORD CWin32FontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
+{
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ table = FXDWORD_FROM_MSBFIRST(table);
+ size = ::GetFontData(m_hDC, table, 0, buffer, size);
+ ::SelectObject(m_hDC, hOldFont);
+ if (size == GDI_ERROR) {
+ return 0;
+ }
+ return size;
+}
+FX_BOOL CWin32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
+{
+ char facebuf[100];
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
+ ::SelectObject(m_hDC, hOldFont);
+ if (ret == 0) {
+ return FALSE;
+ }
+ name = facebuf;
+ return TRUE;
+}
+FX_BOOL CWin32FontInfo::GetFontCharset(void* hFont, int& charset)
+{
+ TEXTMETRIC tm;
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ ::GetTextMetrics(m_hDC, &tm);
+ ::SelectObject(m_hDC, hOldFont);
+ charset = tm.tmCharSet;
+ return TRUE;
+}
+#ifndef _FPDFAPI_MINI_
+IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
+{
+ return FX_NEW CWin32FontInfo;
+}
+#endif
+void CFX_GEModule::InitPlatform()
+{
+ CWin32Platform* pPlatformData = FX_NEW CWin32Platform;
+ if (!pPlatformData) {
+ return;
+ }
+ OSVERSIONINFO ver;
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ GetVersionEx(&ver);
+ pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
+ pPlatformData->m_GdiplusExt.Load();
+ m_pPlatformData = pPlatformData;
+ m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
+}
+void CFX_GEModule::DestroyPlatform()
+{
+ if (m_pPlatformData) {
+ 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;
+}
+FX_LPVOID CGdiDeviceDriver::GetClipRgn()
+{
+ HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
+ if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
+ DeleteObject(hClipRgn);
+ hClipRgn = NULL;
+ }
+ return (FX_LPVOID)hClipRgn;
+}
+FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform)
+{
+ if (m_DeviceClass == FXDC_PRINTER) {
+ CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
+ return FALSE;
+ }
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ int pitch = pBitmap->GetPitch();
+ LPBYTE pBuffer = pBitmap->GetBuffer();
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ ((BITMAPINFOHEADER*)(FX_LPCSTR)info)->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*)(FX_LPCSTR)info, DIB_RGB_COLORS, SRCCOPY);
+ delete pBitmap;
+ } else {
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) {
+ return FALSE;
+ }
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ int pitch = pBitmap->GetPitch();
+ LPBYTE pBuffer = pBitmap->GetBuffer();
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom,
+ 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (pBitmap != pBitmap1) {
+ delete pBitmap;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
+{
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
+ return FALSE;
+ }
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ if (abs(dest_width) * abs(dest_height) < 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 && (pBitmap->GetWidth() * pBitmap->GetHeight() > 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*)(FX_LPCSTR)toStrechBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
+ if (del) {
+ delete pToStrechBitmap;
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform)
+{
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if (pBitmap == NULL) {
+ 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_memset32(&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;
+ ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
+ 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, SRCAND);
+ return TRUE;
+}
+BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
+{
+ return ::GetClipBox(m_hDC, (RECT*)pRect);
+}
+FX_BOOL CGdiDeviceDriver::SetClipRgn(FX_LPVOID hRgn)
+{
+ ::SelectClipRgn(m_hDC, (HRGN)hRgn);
+ return TRUE;
+}
+static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb)
+{
+ FX_FLOAT width;
+ FX_FLOAT scale = 1.f;
+ if (pMatrix)
+ scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
+ FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
+ if (pGraphState) {
+ width = scale * pGraphState->m_LineWidth;
+ } else {
+ width = 1.0f;
+ }
+ FX_DWORD PenStyle = PS_GEOMETRIC;
+ if (width < 1) {
+ width = 1;
+ }
+ if(pGraphState->m_DashCount) {
+ PenStyle |= PS_USERSTYLE;
+ } else {
+ PenStyle |= PS_SOLID;
+ }
+ switch(pGraphState->m_LineCap) {
+ case 0:
+ PenStyle |= PS_ENDCAP_FLAT;
+ break;
+ case 1:
+ PenStyle |= PS_ENDCAP_ROUND;
+ break;
+ case 2:
+ PenStyle |= PS_ENDCAP_SQUARE;
+ break;
+ }
+ switch(pGraphState->m_LineJoin) {
+ case 0:
+ PenStyle |= PS_JOIN_MITER;
+ break;
+ case 1:
+ PenStyle |= PS_JOIN_ROUND;
+ break;
+ case 2:
+ PenStyle |= PS_JOIN_BEVEL;
+ break;
+ }
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(argb, a, rgb);
+ LOGBRUSH lb;
+ lb.lbColor = rgb;
+ lb.lbStyle = BS_SOLID;
+ lb.lbHatch = 0;
+ FX_DWORD* pDash = NULL;
+ if (pGraphState->m_DashCount) {
+ pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
+ if (!pDash) {
+ return NULL;
+ }
+ for (int i = 0; i < pGraphState->m_DashCount; i ++) {
+ pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]);
+ if (pDash[i] < 1) {
+ pDash[i] = 1;
+ }
+ }
+ }
+ HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash);
+ if (pDash) {
+ FX_Free(pDash);
+ }
+ return hPen;
+}
+static HBRUSH _CreateBrush(FX_DWORD argb)
+{
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(argb, a, rgb);
+ return CreateSolidBrush(rgb);
+}
+static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix)
+{
+ BeginPath(hDC);
+ int nPoints = pPathData->GetPointCount();
+ FX_PATHPOINT* pPoints = pPathData->GetPoints();
+ for(int i = 0; i < nPoints; i++) {
+ FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
+ int point_type = pPoints[i].m_Flag & FXPT_TYPE;
+ if(point_type == PT_MOVETO) {
+ MoveToEx(hDC, screen_x, screen_y, NULL);
+ } else if(point_type == PT_LINETO) {
+ if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
+ screen_x ++;
+ }
+ LineTo(hDC, screen_x, screen_y);
+ } else if(point_type == PT_BEZIERTO) {
+ POINT lppt[3];
+ lppt[0].x = screen_x;
+ lppt[0].y = screen_y;
+ posx = pPoints[i + 1].m_PointX;
+ posy = pPoints[i + 1].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ lppt[1].x = FXSYS_round(posx);
+ lppt[1].y = FXSYS_round(posy);
+ posx = pPoints[i + 2].m_PointX;
+ posy = pPoints[i + 2].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ lppt[2].x = FXSYS_round(posx);
+ lppt[2].y = FXSYS_round(posy);
+ PolyBezierTo(hDC, lppt, 3);
+ i += 2;
+ }
+ if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
+ CloseFigure(hDC);
+ }
+ }
+ EndPath(hDC);
+}
+void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
+{
+ int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3);
+ int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3);
+ if (flag1 & flag2) {
+ return;
+ }
+ if (flag1 || flag2) {
+ agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height));
+ FX_FLOAT x[2], y[2];
+ int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
+ if (np == 0) {
+ return;
+ }
+ if (np == 1) {
+ x2 = x[0];
+ y2 = y[0];
+ } else {
+ x1 = x[0];
+ y1 = y[0];
+ x2 = x[np - 1];
+ y2 = y[np - 1];
+ }
+ }
+ MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
+ LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
+}
+static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
+{
+ return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
+}
+FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ )
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) {
+ CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
+ if (pMatrix) {
+ bbox_f.Transform(pMatrix);
+ }
+ FX_RECT bbox = bbox_f.GetInnerRect();
+ if (bbox.Width() <= 0) {
+ return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color,
+ alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ } else if (bbox.Height() <= 0) {
+ return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color,
+ alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ }
+ }
+ int fill_alpha = FXARGB_A(fill_color);
+ int stroke_alpha = FXARGB_A(stroke_color);
+ FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
+ if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
+ return FALSE;
+ }
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || pGraphState && pGraphState->m_DashCount)) {
+ if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
+ pGraphState && pGraphState->m_LineWidth == 1.f &&
+ (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
+ pPathData->IsRect()) ) {
+ if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ int old_fill_mode = fill_mode;
+ fill_mode &= 3;
+ HPEN hPen = NULL;
+ HBRUSH hBrush = NULL;
+ if (pGraphState && stroke_alpha) {
+ SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
+ hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ }
+ if (fill_mode && fill_alpha) {
+ SetPolyFillMode(m_hDC, fill_mode);
+ hBrush = _CreateBrush(fill_color);
+ hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
+ }
+ if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) {
+ FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
+ if (pMatrix) {
+ pMatrix->Transform(x1, y1);
+ }
+ FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
+ if (pMatrix) {
+ pMatrix->Transform(x2, y2);
+ }
+ DrawLine(x1, y1, x2, y2);
+ } else {
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ if (pGraphState && stroke_alpha) {
+ if (fill_mode && fill_alpha) {
+ if (old_fill_mode & FX_FILL_TEXT_MODE) {
+ StrokeAndFillPath(m_hDC);
+ } else {
+ FillPath(m_hDC);
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ StrokePath(m_hDC);
+ }
+ } else {
+ StrokePath(m_hDC);
+ }
+ } else if (fill_mode && fill_alpha) {
+ FillPath(m_hDC);
+ }
+ }
+ if (hPen) {
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ }
+ if (hBrush) {
+ hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
+ DeleteObject(hBrush);
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ int alpha;
+ FX_COLORREF rgb;
+ ArgbDecode(fill_color, alpha, rgb);
+ if (alpha == 0) {
+ return TRUE;
+ }
+ if (alpha < 255) {
+ return FALSE;
+ }
+ HBRUSH hBrush = CreateSolidBrush(rgb);
+ ::FillRect(m_hDC, (RECT*)pRect, hBrush);
+ DeleteObject(hBrush);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ int fill_mode
+ )
+{
+ if (pPathData->GetPointCount() == 5) {
+ CFX_FloatRect rectf;
+ if (pPathData->IsRect(pMatrix, &rectf)) {
+ FX_RECT rect = rectf.GetOutterRect();
+ IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
+ return TRUE;
+ }
+ }
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ SetPolyFillMode(m_hDC, fill_mode & 3);
+ SelectClipPath(m_hDC, RGN_AND);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ const CFX_GraphStateData* pGraphState
+ )
+{
+ HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ WidenPath(m_hDC);
+ SetPolyFillMode(m_hDC, WINDING);
+ FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ return ret;
+}
+FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(color, a, rgb);
+ if (a == 0) {
+ return TRUE;
+ }
+ HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
+ LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(FX_LPVOID 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_memset32(&bmi, 0, sizeof bmi);
+ bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
+ bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biWidth = width;
+ if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ pIccTransform = NULL;
+ }
+ if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) {
+ ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height;
+ } else {
+ CFX_DIBitmap bitmap;
+ if (bitmap.Create(width, height, FXDIB_Rgb)) {
+ bmi.bmiHeader.biBitCount = 24;
+ ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS);
+ ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform);
+ } else {
+ ret = FALSE;
+ }
+ }
+#ifndef _FPDFAPI_MINI_
+ if (pBitmap->HasAlpha() && ret) {
+ pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
+ }
+#endif
+ 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);
+ } else {
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ if (pSource->HasAlpha()) {
+ CFX_DIBitmap bitmap;
+ if (!bitmap.Create(width, height, FXDIB_Rgb) ||
+ !GetDIBits(&bitmap, left, top, NULL) ||
+ !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, width, height);
+ return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap) {
+ return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ FX_RECT bitmap_clip = *pClipRect;
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ bitmap_clip.Offset(-dest_left, -dest_top);
+ CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
+ if (pStretched == NULL) {
+ return TRUE;
+ }
+ FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
+ FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
+ delete pStretched;
+ return ret;
+}
+FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ ASSERT(pSource != NULL && pClipRect != NULL);
+ if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000)
+ return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
+ pClipRect, flags, alpha_flag, pIccTransform, blend_type);
+ if (pSource->IsAlphaMask()) {
+ FX_RECT image_rect;
+ image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
+ image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
+ image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
+ image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
+ FX_RECT clip_rect = image_rect;
+ clip_rect.Intersect(*pClipRect);
+ clip_rect.Offset(-image_rect.left, -image_rect.top);
+ int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
+ CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
+ if (pStretched == NULL) {
+ return TRUE;
+ }
+ CFX_DIBitmap background;
+ if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
+ !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) ||
+ !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
+ delete pStretched;
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, clip_width, clip_height);
+ FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
+ delete pStretched;
+ return ret;
+ } else {
+ if (pSource->HasAlpha()) {
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) {
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags);
+ }
+ return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
+ pClipRect, flags, alpha_flag, pIccTransform, blend_type);
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap) {
+ return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
+ }
+ }
+ return FALSE;
+}
+#define GET_PS_FEATURESETTING 4121
+#define FEATURESETTING_PSLEVEL 2
+int GetPSLevel(HDC hDC)
+{
+ int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
+ if (device_type != DT_RASPRINTER) {
+ return 0;
+ }
+ FX_DWORD esc = GET_PS_FEATURESETTING;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ int param = FEATURESETTING_PSLEVEL;
+ if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
+ return param;
+ }
+ }
+ esc = POSTSCRIPT_IDENTIFY;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
+ esc = POSTSCRIPT_DATA;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ return 2;
+ }
+ return 0;
+ }
+ esc = PSIDENT_GDICENTRIC;
+ if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) {
+ return 2;
+ }
+ esc = GET_PS_FEATURESETTING;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ int param = FEATURESETTING_PSLEVEL;
+ if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
+ return param;
+ }
+ }
+ return 2;
+}
+int CFX_WindowsDevice::m_psLevel = 2;
+CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel)
+{
+ m_bForcePSOutput = bForcePSOutput;
+ m_psLevel = psLevel;
+ if (bForcePSOutput) {
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CPSPrinterDriver;
+ if (!pDriver) {
+ return;
+ }
+ ((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;
+ }
+ return FX_NEW CGdiDisplayDriver(hDC);
+}
+CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format)
+{
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof (BITMAPINFOHEADER));
+ bmih.biSize = sizeof(BITMAPINFOHEADER);
+ bmih.biBitCount = format & 0xff;
+ bmih.biHeight = -height;
+ bmih.biPlanes = 1;
+ bmih.biWidth = width;
+ FX_LPBYTE pBuffer;
+ m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (FX_LPVOID*)&pBuffer, NULL, 0);
+ if (m_hBitmap == NULL) {
+ return;
+ }
+ CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
+ if (!pBitmap) {
+ return;
+ }
+ pBitmap->Create(width, height, format, pBuffer);
+ SetBitmap(pBitmap);
+ m_hDC = ::CreateCompatibleDC(NULL);
+ m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CGdiDisplayDriver(m_hDC);
+ if (!pDriver) {
+ return;
+ }
+ 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
diff --git a/core/src/fxge/win32/fx_win32_dib.cpp b/core/src/fxge/win32/fx_win32_dib.cpp
index a9cf78eac3..0093d5e41b 100644
--- a/core/src/fxge/win32/fx_win32_dib.cpp
+++ b/core/src/fxge/win32/fx_win32_dib.cpp
@@ -1,310 +1,310 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
-{
- CFX_ByteString result;
- int len = sizeof (BITMAPINFOHEADER);
- if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
- len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
- }
- BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
- FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
- pbmih->biSize = sizeof(BITMAPINFOHEADER);
- pbmih->biBitCount = pBitmap->GetBPP();
- pbmih->biCompression = BI_RGB;
- pbmih->biHeight = -(int)pBitmap->GetHeight();
- pbmih->biPlanes = 1;
- pbmih->biWidth = pBitmap->GetWidth();
- if (pBitmap->GetBPP() == 8) {
- FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
- if (pBitmap->GetPalette() == NULL) {
- for (int i = 0; i < 256; i ++) {
- pPalette[i] = i * 0x010101;
- }
- } else {
- for (int i = 0; i < 256; i ++) {
- pPalette[i] = pBitmap->GetPalette()[i];
- }
- }
- }
- if (pBitmap->GetBPP() == 1) {
- FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
- if (pBitmap->GetPalette() == NULL) {
- pPalette[0] = 0;
- pPalette[1] = 0xffffff;
- } else {
- pPalette[0] = pBitmap->GetPalette()[0];
- pPalette[1] = pBitmap->GetPalette()[1];
- }
- }
- result.ReleaseBuffer(len);
- return result;
-}
-CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
-{
- int width = pbmi->bmiHeader.biWidth;
- int height = pbmi->bmiHeader.biHeight;
- BOOL bBottomUp = TRUE;
- if (height < 0) {
- height = -height;
- bBottomUp = FALSE;
- }
- int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
- CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
- if (!pBitmap) {
- return NULL;
- }
- FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
- FX_BOOL ret = pBitmap->Create(width, height, format);
- if (!ret) {
- delete pBitmap;
- return NULL;
- }
- FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
- if (bBottomUp) {
- FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
- if (!temp_buf) {
- if (pBitmap) {
- delete pBitmap;
- }
- return NULL;
- }
- int top = 0, bottom = height - 1;
- while (top < bottom) {
- FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
- FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch);
- FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
- top ++;
- bottom --;
- }
- FX_Free(temp_buf);
- temp_buf = NULL;
- }
- if (pbmi->bmiHeader.biBitCount == 1) {
- for (int i = 0; i < 2; i ++) {
- pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
- }
- } else if (pbmi->bmiHeader.biBitCount == 8) {
- for (int i = 0; i < 256; i ++) {
- pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
- }
- }
- return pBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
-{
- return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
-}
-HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
-{
- CFX_ByteString info = GetBitmapInfo(pBitmap);
- HBITMAP hBitmap = NULL;
- hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT,
- pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- return hBitmap;
-}
-void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
-{
- BITMAP bmp;
- GetObject(hBitmap, sizeof bmp, &bmp);
- w = bmp.bmWidth;
- h = bmp.bmHeight;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
-{
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- WINDIB_Open_Args_ args;
- args.flags = WINDIB_OPEN_PATHNAME;
- args.path_name = filename;
- return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
- }
- HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
- if (hBitmap == NULL) {
- return NULL;
- }
- HDC hDC = CreateCompatibleDC(NULL);
- int width, height;
- GetBitmapSize(hBitmap, width, height);
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- DeleteDC(hDC);
- return NULL;
- }
- if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
- delete pDIBitmap;
- DeleteDC(hDC);
- return NULL;
- }
- CFX_ByteString info = GetBitmapInfo(pDIBitmap);
- int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (!ret) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- DeleteDC(hDC);
- return pDIBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
- } else if (args.flags == WINDIB_OPEN_MEMORY) {
- return NULL;
- }
- HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
- if (hBitmap == NULL) {
- return NULL;
- }
- HDC hDC = CreateCompatibleDC(NULL);
- int width, height;
- GetBitmapSize(hBitmap, width, height);
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- DeleteDC(hDC);
- return NULL;
- }
- if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
- delete pDIBitmap;
- DeleteDC(hDC);
- return NULL;
- }
- CFX_ByteString info = GetBitmapInfo(pDIBitmap);
- int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (!ret) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- DeleteDC(hDC);
- return pDIBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
-{
- FX_BOOL bCreatedDC = hDC == NULL;
- if (hDC == NULL) {
- hDC = CreateCompatibleDC(NULL);
- }
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof bmih);
- bmih.biSize = sizeof bmih;
- GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
- int width = bmih.biWidth;
- int height = abs(bmih.biHeight);
- bmih.biHeight = -height;
- bmih.biCompression = BI_RGB;
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- return NULL;
- }
- int ret = 0;
- if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
- int size = sizeof (BITMAPINFOHEADER) + 8;
- if (bmih.biBitCount == 8) {
- size += sizeof (FX_DWORD) * 254;
- }
- BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
- if (!pbmih) {
- delete pDIBitmap;
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
- pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmih->bmiHeader.biBitCount = bmih.biBitCount;
- pbmih->bmiHeader.biCompression = BI_RGB;
- pbmih->bmiHeader.biHeight = -height;
- pbmih->bmiHeader.biPlanes = 1;
- pbmih->bmiHeader.biWidth = bmih.biWidth;
- if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
- delete pDIBitmap;
- FX_Free(pbmih);
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
- FX_Free(pbmih);
- pbmih = NULL;
- pDIBitmap->CopyPalette(pPalette, palsize);
- } else {
- if (bmih.biBitCount <= 24) {
- bmih.biBitCount = 24;
- } else {
- bmih.biBitCount = 32;
- }
- if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
- delete pDIBitmap;
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
- if (ret != 0 && bmih.biBitCount == 32) {
- int pitch = pDIBitmap->GetPitch();
- for (int row = 0; row < height; row ++) {
- FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch);
- for (int col = 0; col < width; col++) {
- dest_scan[3] = 255;
- dest_scan += 4;
- }
- }
- }
- }
- if (ret == 0) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return pDIBitmap;
-}
-CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
-{
- Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1);
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof bmih);
- bmih.biSize = sizeof bmih;
- bmih.biBitCount = 24;
- bmih.biHeight = -height;
- bmih.biPlanes = 1;
- bmih.biWidth = width;
- m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
- m_hMemDC = CreateCompatibleDC(hDC);
- m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
-}
-CFX_WindowsDIB::~CFX_WindowsDIB()
-{
- SelectObject(m_hMemDC, m_hOldBitmap);
- DeleteDC(m_hMemDC);
- DeleteObject(m_hBitmap);
-}
-void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
-{
- ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
-}
-void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
-{
- ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
+{
+ CFX_ByteString result;
+ int len = sizeof (BITMAPINFOHEADER);
+ if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
+ len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
+ }
+ BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
+ FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
+ pbmih->biSize = sizeof(BITMAPINFOHEADER);
+ pbmih->biBitCount = pBitmap->GetBPP();
+ pbmih->biCompression = BI_RGB;
+ pbmih->biHeight = -(int)pBitmap->GetHeight();
+ pbmih->biPlanes = 1;
+ pbmih->biWidth = pBitmap->GetWidth();
+ if (pBitmap->GetBPP() == 8) {
+ FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
+ if (pBitmap->GetPalette() == NULL) {
+ for (int i = 0; i < 256; i ++) {
+ pPalette[i] = i * 0x010101;
+ }
+ } else {
+ for (int i = 0; i < 256; i ++) {
+ pPalette[i] = pBitmap->GetPalette()[i];
+ }
+ }
+ }
+ if (pBitmap->GetBPP() == 1) {
+ FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
+ if (pBitmap->GetPalette() == NULL) {
+ pPalette[0] = 0;
+ pPalette[1] = 0xffffff;
+ } else {
+ pPalette[0] = pBitmap->GetPalette()[0];
+ pPalette[1] = pBitmap->GetPalette()[1];
+ }
+ }
+ result.ReleaseBuffer(len);
+ return result;
+}
+CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
+{
+ int width = pbmi->bmiHeader.biWidth;
+ int height = pbmi->bmiHeader.biHeight;
+ BOOL bBottomUp = TRUE;
+ if (height < 0) {
+ height = -height;
+ bBottomUp = FALSE;
+ }
+ int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
+ CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
+ if (!pBitmap) {
+ return NULL;
+ }
+ FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
+ FX_BOOL ret = pBitmap->Create(width, height, format);
+ if (!ret) {
+ delete pBitmap;
+ return NULL;
+ }
+ FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
+ if (bBottomUp) {
+ FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
+ if (!temp_buf) {
+ if (pBitmap) {
+ delete pBitmap;
+ }
+ return NULL;
+ }
+ int top = 0, bottom = height - 1;
+ while (top < bottom) {
+ FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
+ FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch);
+ FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
+ top ++;
+ bottom --;
+ }
+ FX_Free(temp_buf);
+ temp_buf = NULL;
+ }
+ if (pbmi->bmiHeader.biBitCount == 1) {
+ for (int i = 0; i < 2; i ++) {
+ pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
+ }
+ } else if (pbmi->bmiHeader.biBitCount == 8) {
+ for (int i = 0; i < 256; i ++) {
+ pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
+ }
+ }
+ return pBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
+{
+ return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
+}
+HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
+{
+ CFX_ByteString info = GetBitmapInfo(pBitmap);
+ HBITMAP hBitmap = NULL;
+ hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT,
+ pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ return hBitmap;
+}
+void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
+{
+ BITMAP bmp;
+ GetObject(hBitmap, sizeof bmp, &bmp);
+ w = bmp.bmWidth;
+ h = bmp.bmHeight;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
+{
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ WINDIB_Open_Args_ args;
+ args.flags = WINDIB_OPEN_PATHNAME;
+ args.path_name = filename;
+ return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
+ }
+ HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (hBitmap == NULL) {
+ return NULL;
+ }
+ HDC hDC = CreateCompatibleDC(NULL);
+ int width, height;
+ GetBitmapSize(hBitmap, width, height);
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ DeleteDC(hDC);
+ return NULL;
+ }
+ if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
+ delete pDIBitmap;
+ DeleteDC(hDC);
+ return NULL;
+ }
+ CFX_ByteString info = GetBitmapInfo(pDIBitmap);
+ int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (!ret) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ DeleteDC(hDC);
+ return pDIBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
+ } else if (args.flags == WINDIB_OPEN_MEMORY) {
+ return NULL;
+ }
+ HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (hBitmap == NULL) {
+ return NULL;
+ }
+ HDC hDC = CreateCompatibleDC(NULL);
+ int width, height;
+ GetBitmapSize(hBitmap, width, height);
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ DeleteDC(hDC);
+ return NULL;
+ }
+ if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
+ delete pDIBitmap;
+ DeleteDC(hDC);
+ return NULL;
+ }
+ CFX_ByteString info = GetBitmapInfo(pDIBitmap);
+ int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (!ret) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ DeleteDC(hDC);
+ return pDIBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
+{
+ FX_BOOL bCreatedDC = hDC == NULL;
+ if (hDC == NULL) {
+ hDC = CreateCompatibleDC(NULL);
+ }
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof bmih);
+ bmih.biSize = sizeof bmih;
+ GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
+ int width = bmih.biWidth;
+ int height = abs(bmih.biHeight);
+ bmih.biHeight = -height;
+ bmih.biCompression = BI_RGB;
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ return NULL;
+ }
+ int ret = 0;
+ if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
+ int size = sizeof (BITMAPINFOHEADER) + 8;
+ if (bmih.biBitCount == 8) {
+ size += sizeof (FX_DWORD) * 254;
+ }
+ BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
+ if (!pbmih) {
+ delete pDIBitmap;
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
+ pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmih->bmiHeader.biBitCount = bmih.biBitCount;
+ pbmih->bmiHeader.biCompression = BI_RGB;
+ pbmih->bmiHeader.biHeight = -height;
+ pbmih->bmiHeader.biPlanes = 1;
+ pbmih->bmiHeader.biWidth = bmih.biWidth;
+ if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
+ delete pDIBitmap;
+ FX_Free(pbmih);
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
+ FX_Free(pbmih);
+ pbmih = NULL;
+ pDIBitmap->CopyPalette(pPalette, palsize);
+ } else {
+ if (bmih.biBitCount <= 24) {
+ bmih.biBitCount = 24;
+ } else {
+ bmih.biBitCount = 32;
+ }
+ if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
+ delete pDIBitmap;
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
+ if (ret != 0 && bmih.biBitCount == 32) {
+ int pitch = pDIBitmap->GetPitch();
+ for (int row = 0; row < height; row ++) {
+ FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch);
+ for (int col = 0; col < width; col++) {
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ }
+ }
+ }
+ }
+ if (ret == 0) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return pDIBitmap;
+}
+CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
+{
+ Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1);
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof bmih);
+ bmih.biSize = sizeof bmih;
+ bmih.biBitCount = 24;
+ bmih.biHeight = -height;
+ bmih.biPlanes = 1;
+ bmih.biWidth = width;
+ m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
+ m_hMemDC = CreateCompatibleDC(hDC);
+ m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
+}
+CFX_WindowsDIB::~CFX_WindowsDIB()
+{
+ SelectObject(m_hMemDC, m_hOldBitmap);
+ DeleteDC(m_hMemDC);
+ DeleteObject(m_hBitmap);
+}
+void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
+{
+ ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
+}
+void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
+{
+ ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_dwrite.cpp b/core/src/fxge/win32/fx_win32_dwrite.cpp
index d4c962036e..2c275a88c8 100644
--- a/core/src/fxge/win32/fx_win32_dwrite.cpp
+++ b/core/src/fxge/win32/fx_win32_dwrite.cpp
@@ -1,480 +1,480 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "dwrite_int.h"
-#include "../Microsoft SDK/include/DWrite.h"
-typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **);
-template <typename InterfaceType>
-inline void SafeRelease(InterfaceType** currentObject)
-{
- if (*currentObject != NULL) {
- (*currentObject)->Release();
- *currentObject = NULL;
- }
-}
-template <typename InterfaceType>
-inline InterfaceType* SafeAcquire(InterfaceType* newObject)
-{
- if (newObject != NULL) {
- newObject->AddRef();
- }
- return newObject;
-}
-class CDwFontFileStream : public IDWriteFontFileStream, public CFX_Object
-{
-public:
- explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize);
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
- virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext);
- virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
- virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
- virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
- bool IsInitialized()
- {
- return resourcePtr_ != NULL;
- }
-private:
- ULONG refCount_;
- void const* resourcePtr_;
- DWORD resourceSize_;
-};
-class CDwFontFileLoader : public IDWriteFontFileLoader, public CFX_Object
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
- virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream);
-
- static IDWriteFontFileLoader* GetLoader()
- {
- if (instance_ == NULL) {
- instance_ = FX_NEW CDwFontFileLoader();
- return instance_;
- }
- return instance_;
- }
- static bool IsLoaderInitialized()
- {
- return instance_ != NULL;
- }
-private:
- CDwFontFileLoader();
- ULONG refCount_;
- static IDWriteFontFileLoader* instance_;
-};
-class CDwFontContext : public CFX_Object
-{
-public:
- CDwFontContext(IDWriteFactory* dwriteFactory);
- ~CDwFontContext();
- HRESULT Initialize();
-private:
- CDwFontContext(CDwFontContext const&);
- void operator=(CDwFontContext const&);
- HRESULT hr_;
- IDWriteFactory* dwriteFactory_;
-};
-class CDwGdiTextRenderer : public CFX_Object
-{
-public:
- CDwGdiTextRenderer(
- CFX_DIBitmap* pBitmap,
- IDWriteBitmapRenderTarget* bitmapRenderTarget,
- IDWriteRenderingParams* renderingParams
- );
- CDwGdiTextRenderer::~CDwGdiTextRenderer();
- HRESULT STDMETHODCALLTYPE DrawGlyphRun(
- const FX_RECT& text_bbox,
- __in_opt CFX_ClipRgn* pClipRgn,
- __in_opt DWRITE_MATRIX const* pMatrix,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- const COLORREF& textColor
- );
-private:
- CFX_DIBitmap* pBitmap_;
- IDWriteBitmapRenderTarget* pRenderTarget_;
- IDWriteRenderingParams* pRenderingParams_;
-};
-CDWriteExt::CDWriteExt()
-{
- m_hModule = NULL;
- m_pDWriteFactory = NULL;
- m_pDwFontContext = NULL;
- m_pDwTextRenderer = NULL;
-}
-void CDWriteExt::Load()
-{
-}
-void CDWriteExt::Unload()
-{
- if (m_pDwFontContext) {
- delete (CDwFontContext*)m_pDwFontContext;
- m_pDwFontContext = NULL;
- }
- SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
-}
-CDWriteExt::~CDWriteExt()
-{
- Unload();
-}
-LPVOID CDWriteExt::DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style)
-{
- IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
- IDWriteFontFile* pDwFontFile = NULL;
- IDWriteFontFace* pDwFontFace = NULL;
- BOOL isSupportedFontType = FALSE;
- DWRITE_FONT_FILE_TYPE fontFileType;
- DWRITE_FONT_FACE_TYPE fontFaceType;
- UINT32 numberOfFaces;
- DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3);
- HRESULT hr = S_OK;
- hr = pDwFactory->CreateCustomFontFileReference(
- (void const*)pData,
- (UINT32)size,
- CDwFontFileLoader::GetLoader(),
- &pDwFontFile
- );
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pDwFontFile->Analyze(
- &isSupportedFontType,
- &fontFileType,
- &fontFaceType,
- &numberOfFaces
- );
- if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) {
- goto failed;
- }
- hr = pDwFactory->CreateFontFace(
- fontFaceType,
- 1,
- &pDwFontFile,
- 0,
- fontStyle,
- &pDwFontFace
- );
- if (FAILED(hr)) {
- goto failed;
- }
- SafeRelease(&pDwFontFile);
- return pDwFontFace;
-failed:
- SafeRelease(&pDwFontFile);
- return NULL;
-}
-FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget)
-{
- if (pBitmap->GetFormat() > FXDIB_Argb) {
- return FALSE;
- }
- IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
- IDWriteGdiInterop* pGdiInterop = NULL;
- IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL;
- IDWriteRenderingParams* pRenderingParams = NULL;
- HRESULT hr = S_OK;
- hr = pDwFactory->GetGdiInterop(&pGdiInterop);
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(),
- &pBitmapRenderTarget);
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pDwFactory->CreateCustomRenderingParams(
- 1.0f,
- 0.0f,
- 1.0f,
- DWRITE_PIXEL_GEOMETRY_RGB,
- DWRITE_RENDERING_MODE_DEFAULT,
- &pRenderingParams
- );
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f);
- if (FAILED(hr)) {
- goto failed;
- }
- *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams);
- if (*(CDwGdiTextRenderer**)renderTarget == NULL) {
- goto failed;
- }
- SafeRelease(&pGdiInterop);
- SafeRelease(&pBitmapRenderTarget);
- SafeRelease(&pRenderingParams);
- return TRUE;
-failed:
- SafeRelease(&pGdiInterop);
- SafeRelease(&pBitmapRenderTarget);
- SafeRelease(&pRenderingParams);
- return FALSE;
-}
-FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
- void *font, FX_FLOAT font_size, FX_ARGB text_color,
- int glyph_count, unsigned short* glyph_indices,
- FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
- void* glyph_offsets,
- FX_FLOAT* glyph_advances)
-{
- if (renderTarget == NULL) {
- return TRUE;
- }
- CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget;
- DWRITE_MATRIX transform;
- DWRITE_GLYPH_RUN glyphRun;
- HRESULT hr = S_OK;
- if (pMatrix) {
- transform.m11 = pMatrix->a;
- transform.m12 = pMatrix->b;
- transform.m21 = pMatrix->c;
- transform.m22 = pMatrix->d;
- transform.dx = pMatrix->e;
- transform.dy = pMatrix->f;
- }
- glyphRun.fontFace = (IDWriteFontFace*)font;
- glyphRun.fontEmSize = font_size;
- glyphRun.glyphCount = glyph_count;
- glyphRun.glyphIndices = glyph_indices;
- glyphRun.glyphAdvances = glyph_advances;
- glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets;
- glyphRun.isSideways = FALSE;
- glyphRun.bidiLevel = 0;
- hr = pTextRenderer->DrawGlyphRun(
- stringRect,
- pClipRgn,
- pMatrix ? &transform : NULL,
- baselineOriginX, baselineOriginY,
- DWRITE_MEASURING_MODE_NATURAL,
- &glyphRun,
- RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))
- );
- return SUCCEEDED(hr) ? TRUE : FALSE;
-}
-void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget)
-{
- if (renderTarget) {
- delete (CDwGdiTextRenderer*)renderTarget;
- }
-}
-void CDWriteExt::DwDeleteFont(void* pFont)
-{
- if (pFont) {
- SafeRelease((IDWriteFontFace**)&pFont);
- }
-}
-CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize)
-{
- refCount_ = 0;
- resourcePtr_ = fontFileReferenceKey;
- resourceSize_ = fontFileReferenceKeySize;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject)
-{
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
- *ppvObject = this;
- AddRef();
- return S_OK;
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-}
-ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef()
-{
- return InterlockedIncrement((long*)(&refCount_));
-}
-ULONG STDMETHODCALLTYPE CDwFontFileStream::Release()
-{
- ULONG newCount = InterlockedDecrement((long*)(&refCount_));
- if (newCount == 0) {
- delete this;
- }
- return newCount;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment(
- void const** fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void** fragmentContext
-)
-{
- if (fileOffset <= resourceSize_ &&
- fragmentSize <= resourceSize_ - fileOffset) {
- *fragmentStart = static_cast<FX_BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset);
- *fragmentContext = NULL;
- return S_OK;
- } else {
- *fragmentStart = NULL;
- *fragmentContext = NULL;
- return E_FAIL;
- }
-}
-void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext)
-{
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize)
-{
- *fileSize = resourceSize_;
- return S_OK;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime)
-{
- *lastWriteTime = 0;
- return E_NOTIMPL;
-}
-IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL;
-CDwFontFileLoader::CDwFontFileLoader() :
- refCount_(0)
-{
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject)
-{
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
- *ppvObject = this;
- AddRef();
- return S_OK;
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-}
-ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef()
-{
- return InterlockedIncrement((long*)(&refCount_));
-}
-ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release()
-{
- ULONG newCount = InterlockedDecrement((long*)(&refCount_));
- if (newCount == 0) {
- instance_ = NULL;
- delete this;
- }
- return newCount;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
- void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- OUT IDWriteFontFileStream** fontFileStream
-)
-{
- *fontFileStream = NULL;
- CDwFontFileStream* stream = FX_NEW CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize);
- if (stream == NULL) {
- return E_OUTOFMEMORY;
- }
- if (!stream->IsInitialized()) {
- delete stream;
- return E_FAIL;
- }
- *fontFileStream = SafeAcquire(stream);
- return S_OK;
-}
-CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) :
- hr_(S_FALSE),
- dwriteFactory_(SafeAcquire(dwriteFactory))
-{
-}
-CDwFontContext::~CDwFontContext()
-{
- if(dwriteFactory_ && hr_ == S_OK) {
- dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader());
- }
- SafeRelease(&dwriteFactory_);
-}
-HRESULT CDwFontContext::Initialize()
-{
- if (hr_ == S_FALSE) {
- return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader());
- }
- return hr_;
-}
-CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams):
- pBitmap_(pBitmap),
- pRenderTarget_(SafeAcquire(bitmapRenderTarget)),
- pRenderingParams_(SafeAcquire(renderingParams))
-{
-}
-CDwGdiTextRenderer::~CDwGdiTextRenderer()
-{
- SafeRelease(&pRenderTarget_);
- SafeRelease(&pRenderingParams_);
-}
-STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
- const FX_RECT& text_bbox,
- __in_opt CFX_ClipRgn* pClipRgn,
- __in_opt DWRITE_MATRIX const* pMatrix,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- const COLORREF& textColor
-)
-{
- HRESULT hr = S_OK;
- if (pMatrix) {
- hr = pRenderTarget_->SetCurrentTransform(pMatrix);
- if (FAILED(hr)) {
- return hr;
- }
- }
- HDC hDC = pRenderTarget_->GetMemoryDC();
- HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
- BITMAP bitmap;
- GetObject(hBitmap, sizeof bitmap, &bitmap);
- CFX_DIBitmap dib;
- dib.Create(
- bitmap.bmWidth,
- bitmap.bmHeight,
- bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
- (FX_LPBYTE)bitmap.bmBits
- );
- dib.CompositeBitmap(
- text_bbox.left,
- text_bbox.top,
- text_bbox.Width(),
- text_bbox.Height(),
- pBitmap_,
- text_bbox.left,
- text_bbox.top,
- FXDIB_BLEND_NORMAL,
- NULL
- );
- hr = pRenderTarget_->DrawGlyphRun(
- baselineOriginX,
- baselineOriginY,
- measuringMode,
- glyphRun,
- pRenderingParams_,
- textColor
- );
- if (FAILED(hr)) {
- return hr;
- }
- pBitmap_->CompositeBitmap(
- text_bbox.left,
- text_bbox.top,
- text_bbox.Width(),
- text_bbox.Height(),
- &dib,
- text_bbox.left,
- text_bbox.top,
- FXDIB_BLEND_NORMAL,
- pClipRgn
- );
- return hr;
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "dwrite_int.h"
+#include "../Microsoft SDK/include/DWrite.h"
+typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **);
+template <typename InterfaceType>
+inline void SafeRelease(InterfaceType** currentObject)
+{
+ if (*currentObject != NULL) {
+ (*currentObject)->Release();
+ *currentObject = NULL;
+ }
+}
+template <typename InterfaceType>
+inline InterfaceType* SafeAcquire(InterfaceType* newObject)
+{
+ if (newObject != NULL) {
+ newObject->AddRef();
+ }
+ return newObject;
+}
+class CDwFontFileStream : public IDWriteFontFileStream, public CFX_Object
+{
+public:
+ explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize);
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+ virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext);
+ virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
+ virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
+ virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
+ bool IsInitialized()
+ {
+ return resourcePtr_ != NULL;
+ }
+private:
+ ULONG refCount_;
+ void const* resourcePtr_;
+ DWORD resourceSize_;
+};
+class CDwFontFileLoader : public IDWriteFontFileLoader, public CFX_Object
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+ virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream);
+
+ static IDWriteFontFileLoader* GetLoader()
+ {
+ if (instance_ == NULL) {
+ instance_ = FX_NEW CDwFontFileLoader();
+ return instance_;
+ }
+ return instance_;
+ }
+ static bool IsLoaderInitialized()
+ {
+ return instance_ != NULL;
+ }
+private:
+ CDwFontFileLoader();
+ ULONG refCount_;
+ static IDWriteFontFileLoader* instance_;
+};
+class CDwFontContext : public CFX_Object
+{
+public:
+ CDwFontContext(IDWriteFactory* dwriteFactory);
+ ~CDwFontContext();
+ HRESULT Initialize();
+private:
+ CDwFontContext(CDwFontContext const&);
+ void operator=(CDwFontContext const&);
+ HRESULT hr_;
+ IDWriteFactory* dwriteFactory_;
+};
+class CDwGdiTextRenderer : public CFX_Object
+{
+public:
+ CDwGdiTextRenderer(
+ CFX_DIBitmap* pBitmap,
+ IDWriteBitmapRenderTarget* bitmapRenderTarget,
+ IDWriteRenderingParams* renderingParams
+ );
+ CDwGdiTextRenderer::~CDwGdiTextRenderer();
+ HRESULT STDMETHODCALLTYPE DrawGlyphRun(
+ const FX_RECT& text_bbox,
+ __in_opt CFX_ClipRgn* pClipRgn,
+ __in_opt DWRITE_MATRIX const* pMatrix,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ const COLORREF& textColor
+ );
+private:
+ CFX_DIBitmap* pBitmap_;
+ IDWriteBitmapRenderTarget* pRenderTarget_;
+ IDWriteRenderingParams* pRenderingParams_;
+};
+CDWriteExt::CDWriteExt()
+{
+ m_hModule = NULL;
+ m_pDWriteFactory = NULL;
+ m_pDwFontContext = NULL;
+ m_pDwTextRenderer = NULL;
+}
+void CDWriteExt::Load()
+{
+}
+void CDWriteExt::Unload()
+{
+ if (m_pDwFontContext) {
+ delete (CDwFontContext*)m_pDwFontContext;
+ m_pDwFontContext = NULL;
+ }
+ SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
+}
+CDWriteExt::~CDWriteExt()
+{
+ Unload();
+}
+LPVOID CDWriteExt::DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style)
+{
+ IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
+ IDWriteFontFile* pDwFontFile = NULL;
+ IDWriteFontFace* pDwFontFace = NULL;
+ BOOL isSupportedFontType = FALSE;
+ DWRITE_FONT_FILE_TYPE fontFileType;
+ DWRITE_FONT_FACE_TYPE fontFaceType;
+ UINT32 numberOfFaces;
+ DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3);
+ HRESULT hr = S_OK;
+ hr = pDwFactory->CreateCustomFontFileReference(
+ (void const*)pData,
+ (UINT32)size,
+ CDwFontFileLoader::GetLoader(),
+ &pDwFontFile
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pDwFontFile->Analyze(
+ &isSupportedFontType,
+ &fontFileType,
+ &fontFaceType,
+ &numberOfFaces
+ );
+ if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) {
+ goto failed;
+ }
+ hr = pDwFactory->CreateFontFace(
+ fontFaceType,
+ 1,
+ &pDwFontFile,
+ 0,
+ fontStyle,
+ &pDwFontFace
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ SafeRelease(&pDwFontFile);
+ return pDwFontFace;
+failed:
+ SafeRelease(&pDwFontFile);
+ return NULL;
+}
+FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget)
+{
+ if (pBitmap->GetFormat() > FXDIB_Argb) {
+ return FALSE;
+ }
+ IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
+ IDWriteGdiInterop* pGdiInterop = NULL;
+ IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL;
+ IDWriteRenderingParams* pRenderingParams = NULL;
+ HRESULT hr = S_OK;
+ hr = pDwFactory->GetGdiInterop(&pGdiInterop);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(),
+ &pBitmapRenderTarget);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pDwFactory->CreateCustomRenderingParams(
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ DWRITE_PIXEL_GEOMETRY_RGB,
+ DWRITE_RENDERING_MODE_DEFAULT,
+ &pRenderingParams
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams);
+ if (*(CDwGdiTextRenderer**)renderTarget == NULL) {
+ goto failed;
+ }
+ SafeRelease(&pGdiInterop);
+ SafeRelease(&pBitmapRenderTarget);
+ SafeRelease(&pRenderingParams);
+ return TRUE;
+failed:
+ SafeRelease(&pGdiInterop);
+ SafeRelease(&pBitmapRenderTarget);
+ SafeRelease(&pRenderingParams);
+ return FALSE;
+}
+FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
+ void *font, FX_FLOAT font_size, FX_ARGB text_color,
+ int glyph_count, unsigned short* glyph_indices,
+ FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
+ void* glyph_offsets,
+ FX_FLOAT* glyph_advances)
+{
+ if (renderTarget == NULL) {
+ return TRUE;
+ }
+ CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget;
+ DWRITE_MATRIX transform;
+ DWRITE_GLYPH_RUN glyphRun;
+ HRESULT hr = S_OK;
+ if (pMatrix) {
+ transform.m11 = pMatrix->a;
+ transform.m12 = pMatrix->b;
+ transform.m21 = pMatrix->c;
+ transform.m22 = pMatrix->d;
+ transform.dx = pMatrix->e;
+ transform.dy = pMatrix->f;
+ }
+ glyphRun.fontFace = (IDWriteFontFace*)font;
+ glyphRun.fontEmSize = font_size;
+ glyphRun.glyphCount = glyph_count;
+ glyphRun.glyphIndices = glyph_indices;
+ glyphRun.glyphAdvances = glyph_advances;
+ glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets;
+ glyphRun.isSideways = FALSE;
+ glyphRun.bidiLevel = 0;
+ hr = pTextRenderer->DrawGlyphRun(
+ stringRect,
+ pClipRgn,
+ pMatrix ? &transform : NULL,
+ baselineOriginX, baselineOriginY,
+ DWRITE_MEASURING_MODE_NATURAL,
+ &glyphRun,
+ RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))
+ );
+ return SUCCEEDED(hr) ? TRUE : FALSE;
+}
+void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget)
+{
+ if (renderTarget) {
+ delete (CDwGdiTextRenderer*)renderTarget;
+ }
+}
+void CDWriteExt::DwDeleteFont(void* pFont)
+{
+ if (pFont) {
+ SafeRelease((IDWriteFontFace**)&pFont);
+ }
+}
+CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize)
+{
+ refCount_ = 0;
+ resourcePtr_ = fontFileReferenceKey;
+ resourceSize_ = fontFileReferenceKeySize;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject)
+{
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+}
+ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef()
+{
+ return InterlockedIncrement((long*)(&refCount_));
+}
+ULONG STDMETHODCALLTYPE CDwFontFileStream::Release()
+{
+ ULONG newCount = InterlockedDecrement((long*)(&refCount_));
+ if (newCount == 0) {
+ delete this;
+ }
+ return newCount;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment(
+ void const** fragmentStart,
+ UINT64 fileOffset,
+ UINT64 fragmentSize,
+ OUT void** fragmentContext
+)
+{
+ if (fileOffset <= resourceSize_ &&
+ fragmentSize <= resourceSize_ - fileOffset) {
+ *fragmentStart = static_cast<FX_BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset);
+ *fragmentContext = NULL;
+ return S_OK;
+ } else {
+ *fragmentStart = NULL;
+ *fragmentContext = NULL;
+ return E_FAIL;
+ }
+}
+void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext)
+{
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize)
+{
+ *fileSize = resourceSize_;
+ return S_OK;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime)
+{
+ *lastWriteTime = 0;
+ return E_NOTIMPL;
+}
+IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL;
+CDwFontFileLoader::CDwFontFileLoader() :
+ refCount_(0)
+{
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject)
+{
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+}
+ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef()
+{
+ return InterlockedIncrement((long*)(&refCount_));
+}
+ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release()
+{
+ ULONG newCount = InterlockedDecrement((long*)(&refCount_));
+ if (newCount == 0) {
+ instance_ = NULL;
+ delete this;
+ }
+ return newCount;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
+ void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ OUT IDWriteFontFileStream** fontFileStream
+)
+{
+ *fontFileStream = NULL;
+ CDwFontFileStream* stream = FX_NEW CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize);
+ if (stream == NULL) {
+ return E_OUTOFMEMORY;
+ }
+ if (!stream->IsInitialized()) {
+ delete stream;
+ return E_FAIL;
+ }
+ *fontFileStream = SafeAcquire(stream);
+ return S_OK;
+}
+CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) :
+ hr_(S_FALSE),
+ dwriteFactory_(SafeAcquire(dwriteFactory))
+{
+}
+CDwFontContext::~CDwFontContext()
+{
+ if(dwriteFactory_ && hr_ == S_OK) {
+ dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader());
+ }
+ SafeRelease(&dwriteFactory_);
+}
+HRESULT CDwFontContext::Initialize()
+{
+ if (hr_ == S_FALSE) {
+ return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader());
+ }
+ return hr_;
+}
+CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams):
+ pBitmap_(pBitmap),
+ pRenderTarget_(SafeAcquire(bitmapRenderTarget)),
+ pRenderingParams_(SafeAcquire(renderingParams))
+{
+}
+CDwGdiTextRenderer::~CDwGdiTextRenderer()
+{
+ SafeRelease(&pRenderTarget_);
+ SafeRelease(&pRenderingParams_);
+}
+STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
+ const FX_RECT& text_bbox,
+ __in_opt CFX_ClipRgn* pClipRgn,
+ __in_opt DWRITE_MATRIX const* pMatrix,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ const COLORREF& textColor
+)
+{
+ HRESULT hr = S_OK;
+ if (pMatrix) {
+ hr = pRenderTarget_->SetCurrentTransform(pMatrix);
+ if (FAILED(hr)) {
+ return hr;
+ }
+ }
+ HDC hDC = pRenderTarget_->GetMemoryDC();
+ HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
+ BITMAP bitmap;
+ GetObject(hBitmap, sizeof bitmap, &bitmap);
+ CFX_DIBitmap dib;
+ dib.Create(
+ bitmap.bmWidth,
+ bitmap.bmHeight,
+ bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
+ (FX_LPBYTE)bitmap.bmBits
+ );
+ dib.CompositeBitmap(
+ text_bbox.left,
+ text_bbox.top,
+ text_bbox.Width(),
+ text_bbox.Height(),
+ pBitmap_,
+ text_bbox.left,
+ text_bbox.top,
+ FXDIB_BLEND_NORMAL,
+ NULL
+ );
+ hr = pRenderTarget_->DrawGlyphRun(
+ baselineOriginX,
+ baselineOriginY,
+ measuringMode,
+ glyphRun,
+ pRenderingParams_,
+ textColor
+ );
+ if (FAILED(hr)) {
+ return hr;
+ }
+ pBitmap_->CompositeBitmap(
+ text_bbox.left,
+ text_bbox.top,
+ text_bbox.Width(),
+ text_bbox.Height(),
+ &dib,
+ text_bbox.left,
+ text_bbox.top,
+ FXDIB_BLEND_NORMAL,
+ pClipRgn
+ );
+ return hr;
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_gdipext.cpp b/core/src/fxge/win32/fx_win32_gdipext.cpp
index 7f9240629c..d3aeecc515 100644
--- a/core/src/fxge/win32/fx_win32_gdipext.cpp
+++ b/core/src/fxge/win32/fx_win32_gdipext.cpp
@@ -1,1286 +1,1286 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-#include "../Microsoft SDK/include/GdiPlus.h"
-using namespace Gdiplus;
-using namespace Gdiplus::DllExports;
-#define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding)
-static CombineMode GdiCombineMode2Gdip(int mode)
-{
- switch (mode) {
- case RGN_AND:
- return CombineModeIntersect;
- }
- return CombineModeIntersect;
-}
-enum {
- FuncId_GdipCreatePath2,
- FuncId_GdipSetPenDashStyle,
- FuncId_GdipSetPenDashArray,
- FuncId_GdipSetPenDashCap197819,
- FuncId_GdipSetPenLineJoin,
- FuncId_GdipSetPenWidth,
- FuncId_GdipCreateFromHDC,
- FuncId_GdipSetPageUnit,
- FuncId_GdipSetSmoothingMode,
- FuncId_GdipCreateSolidFill,
- FuncId_GdipFillPath,
- FuncId_GdipDeleteBrush,
- FuncId_GdipCreatePen1,
- FuncId_GdipSetPenMiterLimit,
- FuncId_GdipDrawPath,
- FuncId_GdipDeletePen,
- FuncId_GdipDeletePath,
- FuncId_GdipDeleteGraphics,
- FuncId_GdipCreateBitmapFromFileICM,
- FuncId_GdipCreateBitmapFromStreamICM,
- FuncId_GdipGetImageHeight,
- FuncId_GdipGetImageWidth,
- FuncId_GdipGetImagePixelFormat,
- FuncId_GdipBitmapLockBits,
- FuncId_GdipGetImagePaletteSize,
- FuncId_GdipGetImagePalette,
- FuncId_GdipBitmapUnlockBits,
- FuncId_GdipDisposeImage,
- FuncId_GdipFillRectangle,
- FuncId_GdipCreateBitmapFromScan0,
- FuncId_GdipSetImagePalette,
- FuncId_GdipSetInterpolationMode,
- FuncId_GdipDrawImagePointsI,
- FuncId_GdipCreateBitmapFromGdiDib,
- FuncId_GdiplusStartup,
- FuncId_GdipDrawLineI,
- FuncId_GdipResetClip,
- FuncId_GdipCreatePath,
- FuncId_GdipAddPathPath,
- FuncId_GdipSetPathFillMode,
- FuncId_GdipSetClipPath,
- FuncId_GdipGetClip,
- FuncId_GdipCreateRegion,
- FuncId_GdipGetClipBoundsI,
- FuncId_GdipSetClipRegion,
- FuncId_GdipWidenPath,
- FuncId_GdipAddPathLine,
- FuncId_GdipAddPathRectangle,
- FuncId_GdipDeleteRegion,
- FuncId_GdipGetDC,
- FuncId_GdipReleaseDC,
- FuncId_GdipSetPenLineCap197819,
- FuncId_GdipSetPenDashOffset,
- FuncId_GdipResetPath,
- FuncId_GdipCreateRegionPath,
- FuncId_GdipCreateFont,
- FuncId_GdipGetFontSize,
- FuncId_GdipCreateFontFamilyFromName,
- FuncId_GdipSetTextRenderingHint,
- FuncId_GdipDrawDriverString,
- FuncId_GdipCreateMatrix2,
- FuncId_GdipDeleteMatrix,
- FuncId_GdipSetWorldTransform,
- FuncId_GdipResetWorldTransform,
- FuncId_GdipDeleteFontFamily,
- FuncId_GdipDeleteFont,
- FuncId_GdipNewPrivateFontCollection,
- FuncId_GdipDeletePrivateFontCollection,
- FuncId_GdipPrivateAddMemoryFont,
- FuncId_GdipGetFontCollectionFamilyList,
- FuncId_GdipGetFontCollectionFamilyCount,
- FuncId_GdipSetTextContrast,
- FuncId_GdipSetPixelOffsetMode,
- FuncId_GdipGetImageGraphicsContext,
- FuncId_GdipDrawImageI,
- FuncId_GdipDrawImageRectI,
- FuncId_GdipDrawString,
- FuncId_GdipSetPenTransform,
-};
-static LPCSTR g_GdipFuncNames[] = {
- "GdipCreatePath2",
- "GdipSetPenDashStyle",
- "GdipSetPenDashArray",
- "GdipSetPenDashCap197819",
- "GdipSetPenLineJoin",
- "GdipSetPenWidth",
- "GdipCreateFromHDC",
- "GdipSetPageUnit",
- "GdipSetSmoothingMode",
- "GdipCreateSolidFill",
- "GdipFillPath",
- "GdipDeleteBrush",
- "GdipCreatePen1",
- "GdipSetPenMiterLimit",
- "GdipDrawPath",
- "GdipDeletePen",
- "GdipDeletePath",
- "GdipDeleteGraphics",
- "GdipCreateBitmapFromFileICM",
- "GdipCreateBitmapFromStreamICM",
- "GdipGetImageHeight",
- "GdipGetImageWidth",
- "GdipGetImagePixelFormat",
- "GdipBitmapLockBits",
- "GdipGetImagePaletteSize",
- "GdipGetImagePalette",
- "GdipBitmapUnlockBits",
- "GdipDisposeImage",
- "GdipFillRectangle",
- "GdipCreateBitmapFromScan0",
- "GdipSetImagePalette",
- "GdipSetInterpolationMode",
- "GdipDrawImagePointsI",
- "GdipCreateBitmapFromGdiDib",
- "GdiplusStartup",
- "GdipDrawLineI",
- "GdipResetClip",
- "GdipCreatePath",
- "GdipAddPathPath",
- "GdipSetPathFillMode",
- "GdipSetClipPath",
- "GdipGetClip",
- "GdipCreateRegion",
- "GdipGetClipBoundsI",
- "GdipSetClipRegion",
- "GdipWidenPath",
- "GdipAddPathLine",
- "GdipAddPathRectangle",
- "GdipDeleteRegion",
- "GdipGetDC",
- "GdipReleaseDC",
- "GdipSetPenLineCap197819",
- "GdipSetPenDashOffset",
- "GdipResetPath",
- "GdipCreateRegionPath",
- "GdipCreateFont",
- "GdipGetFontSize",
- "GdipCreateFontFamilyFromName",
- "GdipSetTextRenderingHint",
- "GdipDrawDriverString",
- "GdipCreateMatrix2",
- "GdipDeleteMatrix",
- "GdipSetWorldTransform",
- "GdipResetWorldTransform",
- "GdipDeleteFontFamily",
- "GdipDeleteFont",
- "GdipNewPrivateFontCollection",
- "GdipDeletePrivateFontCollection",
- "GdipPrivateAddMemoryFont",
- "GdipGetFontCollectionFamilyList",
- "GdipGetFontCollectionFamilyCount",
- "GdipSetTextContrast",
- "GdipSetPixelOffsetMode",
- "GdipGetImageGraphicsContext",
- "GdipDrawImageI",
- "GdipDrawImageRectI",
- "GdipDrawString",
- "GdipSetPenTransform",
-};
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode, GpPath **path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashStyle dashstyle);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONST REAL *dash, INT count);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDashCap dashCap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoin lineJoin);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics **graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, GpUnit unit);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphics, SmoothingMode smoothingMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidFill **brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBrush *brush, GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, GpUnit unit, GpPen **pen);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL miterLimit);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* stream, GpBitmap **bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT *width);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDIPCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, ColorPalette *palette, INT size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIPCONST ColorPalette *palette);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *graphics, InterpolationMode interpolationMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphics, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap);
-typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT FX_UINTPTR *token, const GdiplusStartupInput *input, OUT GdiplusStartupOutput *output);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpPath **path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFillMode fillmode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegion *region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hdc);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL offset);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpRegion **region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *graphics, TextRenderingHint mode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphics, GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontFamily);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontCollection** fontCollection);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCollection** fontCollection);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCollection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontCollection* fontCollection, INT* numFound);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics, UINT contrast);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *image, GpGraphics **graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpImage *image, INT x, INT y);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix);
-#define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname])
-typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts);
-typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle);
-void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face)
-{
- if (m_pGdiAddFontMemResourceEx) {
- return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face);
- }
- return NULL;
-}
-FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle)
-{
- if (m_pGdiRemoveFontMemResourseEx) {
- return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)((HANDLE)handle);
- }
- return FALSE;
-}
-static GpBrush* _GdipCreateBrush(DWORD argb)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpSolidFill* solidBrush = NULL;
- CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
- return solidBrush;
-}
-static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height,
- const CFX_DIBitmap* pSource, FX_RECT* pClipRect)
-{
- FX_BOOL bFlipX = dest_width < 0;
- if (bFlipX) {
- dest_width = -dest_width;
- }
- FX_BOOL bFlipY = dest_height < 0;
- if (bFlipY) {
- dest_height = -dest_height;
- }
- int result_width = pClipRect->Width();
- int result_height = pClipRect->Height();
- int result_pitch = (result_width + 3) / 4 * 4;
- CFX_DIBitmap* pStretched = FX_NEW CFX_DIBitmap;
- if (!pStretched) {
- return NULL;
- }
- if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) {
- delete pStretched;
- return NULL;
- }
- LPBYTE dest_buf = pStretched->GetBuffer();
- int src_width = pSource->GetWidth();
- int src_height = pSource->GetHeight();
- int src_count = src_width * src_height;
- int dest_count = dest_width * dest_height;
- int ratio = 255 * dest_count / src_count;
- int y_unit = src_height / dest_height;
- int x_unit = src_width / dest_width;
- int area_unit = y_unit * x_unit;
- LPBYTE src_buf = pSource->GetBuffer();
- int src_pitch = pSource->GetPitch();
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- LPBYTE dest_scan = dest_buf + dest_y * result_pitch;
- int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top);
- src_y_start = src_y_start * src_height / dest_height;
- LPBYTE src_scan = src_buf + src_y_start * src_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int sum = 0;
- int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) : (dest_x + pClipRect->left);
- src_x_start = src_x_start * src_width / dest_width;
- int src_x_end = src_x_start + x_unit;
- LPBYTE src_line = src_scan;
- for (int src_y = 0; src_y < y_unit; src_y ++) {
- for (int src_x = src_x_start; src_x < src_x_end; src_x ++) {
- if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) {
- sum += 255;
- }
- }
- src_line += src_pitch;
- }
- dest_scan[dest_x] = 255 - sum / area_unit;
- }
- }
- return pStretched;
-}
-static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect)
-{
- ASSERT(pBitmap->GetBPP() == 1);
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight();
- int src_pitch = pBitmap->GetPitch();
- FX_LPBYTE scan0 = pBitmap->GetBuffer();
- if (src_width == 1 && src_height == 1) {
- if ((scan0[0] & 0x80) == 0) {
- return;
- }
- GpSolidFill* solidBrush;
- CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
- if (dest_width < 0) {
- dest_width = -dest_width;
- dest_left -= dest_width;
- }
- if (dest_height < 0) {
- dest_height = -dest_height;
- dest_top -= dest_height;
- }
- CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (float)dest_top,
- (float)dest_width, (float)dest_height);
- CallFunc(GdipDeleteBrush)(solidBrush);
- return;
- }
- if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_height) {
- FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height);
- image_rect.Normalize();
- FX_RECT image_clip = image_rect;
- image_clip.Intersect(*pClipRect);
- if (image_clip.IsEmpty()) {
- return;
- }
- image_clip.Offset(-image_rect.left, -image_rect.top);
- CFX_DIBitmap* pStretched = NULL;
- if (src_width * src_height > 10000) {
- pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip);
- } else {
- pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip);
- }
- GpBitmap* bitmap;
- CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(),
- (image_clip.Width() + 3) / 4 * 4, PixelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap);
- int a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- UINT pal[258];
- pal[0] = 0;
- pal[1] = 256;
- for (int i = 0; i < 256; i ++) {
- pal[i + 2] = ArgbEncode(i * a / 255, r, g, b);
- }
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
- CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip.left,
- image_rect.top + image_clip.top);
- CallFunc(GdipDisposeImage)(bitmap);
- delete pStretched;
- return;
- }
- GpBitmap* bitmap;
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelFormat1bppIndexed, scan0, &bitmap);
- UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb };
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette);
- Point destinationPoints[] = {
- Point(dest_left, dest_top),
- Point(dest_left + dest_width, dest_top),
- Point(dest_left, dest_top + dest_height)
- };
- CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
- CallFunc(GdipDisposeImage)(bitmap);
-}
-static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect,
- int dest_left, int dest_top, int dest_width, int dest_height)
-{
- int src_width = pSrcRect->Width(), src_height = pSrcRect->Height();
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) {
- FX_RECT new_rect(0, 0, src_width, src_height);
- CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect);
- if (!pCloned) {
- return;
- }
- OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, dest_height);
- delete pCloned;
- return;
- }
- int src_pitch = pBitmap->GetPitch();
- FX_LPBYTE scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap->GetBPP() * pSrcRect->left / 8;
- GpBitmap* bitmap = NULL;
- switch (pBitmap->GetFormat()) {
- case FXDIB_Argb:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat32bppARGB, scan0, &bitmap);
- break;
- case FXDIB_Rgb32:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat32bppRGB, scan0, &bitmap);
- break;
- case FXDIB_Rgb:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat24bppRGB, scan0, &bitmap);
- break;
- case FXDIB_8bppRgb: {
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat8bppIndexed, scan0, &bitmap);
- UINT pal[258];
- pal[0] = 0;
- pal[1] = 256;
- for (int i = 0; i < 256; i ++) {
- pal[i + 2] = pBitmap->GetPaletteEntry(i);
- }
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
- break;
- }
- case FXDIB_1bppRgb: {
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat1bppIndexed, scan0, &bitmap);
- break;
- }
- }
- if (dest_height < 0) {
- dest_height --;
- }
- if (dest_width < 0) {
- dest_width --;
- }
- Point destinationPoints[] = {
- Point(dest_left, dest_top),
- Point(dest_left + dest_width, dest_top),
- Point(dest_left, dest_top + dest_height)
- };
- CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
- CallFunc(GdipDisposeImage)(bitmap);
-}
-CGdiplusExt::CGdiplusExt()
-{
- m_hModule = NULL;
- m_GdiModule = NULL;
- for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
- m_Functions[i] = NULL;
- }
- m_pGdiAddFontMemResourceEx = NULL;
- m_pGdiRemoveFontMemResourseEx = NULL;
-}
-void CGdiplusExt::Load()
-{
- CFX_ByteString strPlusPath = "";
- FX_CHAR buf[MAX_PATH];
- GetSystemDirectoryA(buf, MAX_PATH);
- strPlusPath += buf;
- strPlusPath += "\\";
- strPlusPath += "GDIPLUS.DLL";
- m_hModule = LoadLibraryA(strPlusPath);
- if (m_hModule == NULL) {
- return;
- }
- for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
- m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
- if (m_Functions[i] == NULL) {
- m_hModule = NULL;
- return;
- }
- }
- FX_UINTPTR gdiplusToken;
- GdiplusStartupInput gdiplusStartupInput;
- ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL);
- m_GdiModule = LoadLibraryA("GDI32.DLL");
- if (m_GdiModule == NULL) {
- return;
- }
- m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResourceEx");
- m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx");
-}
-CGdiplusExt::~CGdiplusExt()
-{
-}
-LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size)
-{
- GpFontCollection* pCollection = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipNewPrivateFontCollection)(&pCollection);
- GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size);
- if (status == Ok) {
- return pCollection;
- }
- CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
- return NULL;
-}
-void CGdiplusExt::DeleteMemFont(LPVOID pCollection)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
-}
-FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- PixelFormat format;
- switch (pBitmap->GetFormat()) {
- case FXDIB_Rgb:
- format = PixelFormat24bppRGB;
- break;
- case FXDIB_Rgb32:
- format = PixelFormat32bppRGB;
- break;
- case FXDIB_Argb:
- format = PixelFormat32bppARGB;
- break;
- default:
- return FALSE;
- }
- GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), pBitmap->GetHeight(),
- pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitmap**)bitmap);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, (GpGraphics**)graphics);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *)name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, Unit(flag), (GpFont**)pFont);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size)
-{
- REAL get_size;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_size);
- if (status == Ok) {
- *size = (FX_FLOAT)get_size;
- } else {
- *size = 0;
- }
-}
-void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint)mode);
-}
-void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit);
-}
-FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length,
- void *font, void* brush, void *positions, int flags, const void *matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDIPCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush*)brush,
- (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMatrix *)matrix);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush);
-}
-void CGdiplusExt::GdipDeleteBrush(void* pBrush)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush);
-}
-void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- int numFamilies = 0;
- GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollection*)pFontCollection, &numFamilies);
- if (status != Ok) {
- return NULL;
- }
- GpFontFamily* family_list[1];
- status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontCollection, 1, family_list, &numFamilies);
- if (status != Ok) {
- return NULL;
- }
- GpFont* pFont = NULL;
- status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, UnitPixel, &pFont);
- if (status != Ok) {
- return NULL;
- }
- return pFont;
-}
-void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix);
-}
-void CGdiplusExt::GdipDeleteMatrix(void* matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix);
-}
-void CGdiplusExt::GdipDeleteFontFamily(void* pFamily)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily);
-}
-void CGdiplusExt::GdipDeleteFont(void* pFont)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteFont)((GpFont*)pFont);
-}
-void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix);
-}
-void CGdiplusExt::GdipDisposeImage(void* bitmap)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
-}
-void CGdiplusExt::GdipDeleteGraphics(void* graphics)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
-}
-FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags)
-{
- ASSERT(pBitmap->GetBPP() == 1);
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpGraphics* pGraphics = NULL;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- if (flags & FXDIB_NOSMOOTH) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
- } else {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
- }
- OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_width, dest_height, argb, pClipRect);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int flags)
-{
- GpGraphics* pGraphics;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- if (flags & FXDIB_NOSMOOTH) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
- } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
- } else {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear);
- }
- FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
- OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
- if (!bTextMode) {
- FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2);
- if (width < unit) {
- width = unit;
- }
- }
- GpPen* pPen = NULL;
- CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
- LineCap lineCap;
- DashCap dashCap = DashCapFlat;
- FX_BOOL bDashExtend = FALSE;
- switch(pGraphState->m_LineCap) {
- case CFX_GraphStateData::LineCapButt:
- lineCap = LineCapFlat;
- break;
- case CFX_GraphStateData::LineCapRound:
- lineCap = LineCapRound;
- dashCap = DashCapRound;
- bDashExtend = TRUE;
- break;
- case CFX_GraphStateData::LineCapSquare:
- lineCap = LineCapSquare;
- bDashExtend = TRUE;
- break;
- }
- CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
- LineJoin lineJoin;
- switch(pGraphState->m_LineJoin) {
- case CFX_GraphStateData::LineJoinMiter:
- lineJoin = LineJoinMiterClipped;
- break;
- case CFX_GraphStateData::LineJoinRound:
- lineJoin = LineJoinRound;
- break;
- case CFX_GraphStateData::LineJoinBevel:
- lineJoin = LineJoinBevel;
- break;
- }
- CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
- if(pGraphState->m_DashCount) {
- FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2);
- if (!pDashArray) {
- return NULL;
- }
- int nCount = 0;
- FX_FLOAT on_leftover = 0, off_leftover = 0;
- for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
- FX_FLOAT on_phase = pGraphState->m_DashArray[i];
- FX_FLOAT off_phase;
- if (i == pGraphState->m_DashCount - 1) {
- off_phase = on_phase;
- } else {
- off_phase = pGraphState->m_DashArray[i + 1];
- }
- on_phase /= width;
- off_phase /= width;
- if (on_phase + off_phase <= 0.00002f) {
- on_phase = 1.0f / 10;
- off_phase = 1.0f / 10;
- }
- if (bDashExtend) {
- if (off_phase < 1) {
- off_phase = 0;
- } else {
- off_phase -= 1;
- }
- on_phase += 1;
- }
- if (on_phase == 0 || off_phase == 0) {
- if (nCount == 0) {
- on_leftover += on_phase;
- off_leftover += off_phase;
- } else {
- pDashArray[nCount - 2] += on_phase;
- pDashArray[nCount - 1] += off_phase;
- }
- } else {
- pDashArray[nCount++] = on_phase + on_leftover;
- on_leftover = 0;
- pDashArray[nCount++] = off_phase + off_leftover;
- off_leftover = 0;
- }
- }
- CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
- FX_FLOAT phase = pGraphState->m_DashPhase;
- if (bDashExtend)
- if (phase < 0.5f) {
- phase = 0;
- } else {
- phase -= 0.5f;
- }
- CallFunc(GdipSetPenDashOffset)(pPen, phase);
- FX_Free(pDashArray);
- pDashArray = NULL;
- }
- CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
- return pPen;
-}
-static BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2)
-{
- int pairs[] = {1, 2, 0, 2, 0, 1};
- for (int i = 0; i < 3; i ++) {
- int pair1 = pairs[i * 2];
- int pair2 = pairs[i * 2 + 1];
- FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
- FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
- if (pMatrix) {
- pMatrix->Transform(x1, y1);
- pMatrix->Transform(x2, y2);
- }
- FX_FLOAT dx = x1 - x2;
- FX_FLOAT dy = y1 - y2;
- FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
- if (distance_square < (1.0f * 2 + 1.0f / 4)) {
- v1 = i;
- v2 = pair1;
- return TRUE;
- }
- }
- return FALSE;
-}
-BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_argb,
- FX_DWORD stroke_argb,
- int fill_mode
- )
-{
- int nPoints = pPathData->GetPointCount();
- if (nPoints == 0) {
- return TRUE;
- }
- FX_PATHPOINT* pPoints = pPathData->GetPoints();
- GpGraphics* pGraphics = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
- GpMatrix* pMatrix = NULL;
- if (pObject2Device) {
- CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObject2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix);
- CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
- }
- PointF *points = FX_Alloc(PointF, nPoints);
- if (!points) {
- return FALSE;
- }
- BYTE * types = FX_Alloc(BYTE, nPoints);
- if (!types) {
- FX_Free(points);
- return FALSE;
- }
- int nSubPathes = 0;
- FX_BOOL bSubClose = FALSE;
- int pos_subclose = 0;
- FX_BOOL bSmooth = FALSE;
- int startpoint = 0;
- for(int i = 0; i < nPoints; i++) {
- points[i].X = pPoints[i].m_PointX;
- points[i].Y = pPoints[i].m_PointY;
- FX_FLOAT x, y;
- if (pObject2Device) {
- pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
- } else {
- x = pPoints[i].m_PointX;
- y = pPoints[i].m_PointY;
- }
- if (x > 50000 * 1.0f) {
- points[i].X = 50000 * 1.0f;
- }
- if (x < -50000 * 1.0f) {
- points[i].X = -50000 * 1.0f;
- }
- if (y > 50000 * 1.0f) {
- points[i].Y = 50000 * 1.0f;
- }
- if (y < -50000 * 1.0f) {
- points[i].Y = -50000 * 1.0f;
- }
- int point_type = pPoints[i].m_Flag & FXPT_TYPE;
- if(point_type == FXPT_MOVETO) {
- types[i] = PathPointTypeStart;
- nSubPathes ++;
- bSubClose = FALSE;
- startpoint = i;
- } else if (point_type == FXPT_LINETO) {
- types[i] = PathPointTypeLine;
- if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
- points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
- points[i].X += 0.01f;
- continue;
- }
- if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != points[i - 1].Y) {
- bSmooth = TRUE;
- }
- } else if (point_type == FXPT_BEZIERTO) {
- types[i] = PathPointTypeBezier;
- bSmooth = TRUE;
- }
- if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
- if (bSubClose) {
- types[pos_subclose] &= ~PathPointTypeCloseSubpath;
- } else {
- bSubClose = TRUE;
- }
- pos_subclose = i;
- types[i] |= PathPointTypeCloseSubpath;
- if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y != points[startpoint].Y) {
- bSmooth = TRUE;
- }
- }
- }
- if (fill_mode & FXFILL_NOPATHSMOOTH) {
- bSmooth = FALSE;
- CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
- } else if (!(fill_mode & FXFILL_FULLCOVER)) {
- if (!bSmooth && (fill_mode & 3)) {
- bSmooth = TRUE;
- }
- if (bSmooth || pGraphState && pGraphState->m_LineWidth > 2) {
- CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
- }
- }
- int new_fill_mode = fill_mode & 3;
- if (nPoints == 4 && pGraphState == NULL) {
- int v1, v2;
- if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
- GpPen* pPen = NULL;
- CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
- CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
- FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y));
- CallFunc(GdipDeletePen)(pPen);
- return TRUE;
- }
- }
- GpPath* pGpPath = NULL;
- CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_mode), &pGpPath);
- if (!pGpPath) {
- if (pMatrix) {
- CallFunc(GdipDeleteMatrix)(pMatrix);
- }
- FX_Free(points);
- FX_Free(types);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return FALSE;
- }
- if (new_fill_mode) {
- GpBrush* pBrush = _GdipCreateBrush(fill_argb);
- CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
- CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
- CallFunc(GdipDeleteBrush)(pBrush);
- }
- if (pGraphState && stroke_argb) {
- GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, fill_mode & FX_STROKE_TEXT_MODE);
- if (nSubPathes == 1) {
- CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
- } else {
- int iStart = 0;
- for (int i = 0; i < nPoints; i ++) {
- if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
- GpPath* pSubPath;
- CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath);
- iStart = i + 1;
- CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
- CallFunc(GdipDeletePath)(pSubPath);
- }
- }
- }
- CallFunc(GdipDeletePen)(pPen);
- }
- if (pMatrix) {
- CallFunc(GdipDeleteMatrix)(pMatrix);
- }
- FX_Free(points);
- FX_Free(types);
- CallFunc(GdipDeletePath)(pGpPath);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-class GpStream : public IStream, public CFX_Object
-{
- LONG m_RefCount;
- int m_ReadPos;
- CFX_ByteTextBuf m_InterStream;
-public:
- GpStream()
- {
- m_RefCount = 1;
- m_ReadPos = 0;
- }
- virtual HRESULT STDMETHODCALLTYPE
- QueryInterface(REFIID iid, void ** ppvObject)
- {
- if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) ||
- iid == __uuidof(ISequentialStream)) {
- *ppvObject = static_cast<IStream*>(this);
- AddRef();
- return S_OK;
- } else {
- return E_NOINTERFACE;
- }
- }
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- return (ULONG)InterlockedIncrement(&m_RefCount);
- }
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- ULONG res = (ULONG) InterlockedDecrement(&m_RefCount);
- if (res == 0) {
- delete this;
- }
- return res;
- }
-public:
- virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRead)
- {
- size_t bytes_left;
- size_t bytes_out;
- if (pcbRead != NULL) {
- *pcbRead = 0;
- }
- if (m_ReadPos == m_InterStream.GetLength()) {
- return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA);
- }
- bytes_left = m_InterStream.GetLength() - m_ReadPos;
- bytes_out = FX_MIN(cb, bytes_left);
- FXSYS_memcpy32(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out);
- m_ReadPos += (FX_INT32)bytes_out;
- if (pcbRead != NULL) {
- *pcbRead = (ULONG)bytes_out;
- }
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten)
- {
- if (cb <= 0) {
- if (pcbWritten != NULL) {
- *pcbWritten = 0;
- }
- return S_OK;
- }
- m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb);
- if (pcbWritten != NULL) {
- *pcbWritten = cb;
- }
- return S_OK;
- }
-public:
- virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Revert(void)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer)
- {
- long start = 0;
- long new_read_position;
- switch(dwOrigin) {
- case STREAM_SEEK_SET:
- start = 0;
- break;
- case STREAM_SEEK_CUR:
- start = m_ReadPos;
- break;
- case STREAM_SEEK_END:
- start = m_InterStream.GetLength();
- break;
- default:
- return STG_E_INVALIDFUNCTION;
- break;
- }
- new_read_position = start + (long)liDistanceToMove.QuadPart;
- if (new_read_position < 0 || new_read_position > m_InterStream.GetLength()) {
- return STG_E_SEEKERROR;
- }
- m_ReadPos = new_read_position;
- if (lpNewFilePointer != NULL) {
- lpNewFilePointer->QuadPart = m_ReadPos;
- }
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag)
- {
- if (pStatstg == NULL) {
- return STG_E_INVALIDFUNCTION;
- }
- ZeroMemory(pStatstg, sizeof(STATSTG));
- pStatstg->cbSize.QuadPart = m_InterStream.GetLength();
- return S_OK;
- }
-};
-typedef struct {
- BITMAPINFO* pbmi;
- int Stride;
- LPBYTE pScan0;
- GpBitmap* pBitmap;
- BitmapData* pBitmapData;
- GpStream* pStream;
-} PREVIEW3_DIBITMAP;
-static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- GpBitmap* pBitmap;
- GpStream* pStream = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- Status status = Ok;
- if (args.flags == WINDIB_OPEN_PATHNAME) {
- status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap);
- } else {
- if (args.memory_size == 0 || !args.memory_base) {
- return NULL;
- }
- pStream = FX_NEW GpStream;
- if (!pStream) {
- return NULL;
- }
- pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL);
- status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap);
- }
- if (status != Ok) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- UINT height, width;
- CallFunc(GdipGetImageHeight)(pBitmap, &height);
- CallFunc(GdipGetImageWidth)(pBitmap, &width);
- PixelFormat pixel_format;
- CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format);
- int info_size = sizeof(BITMAPINFOHEADER);
- int bpp = 24;
- int dest_pixel_format = PixelFormat24bppRGB;
- if (pixel_format == PixelFormat1bppIndexed) {
- info_size += 8;
- bpp = 1;
- dest_pixel_format = PixelFormat1bppIndexed;
- } else if (pixel_format == PixelFormat8bppIndexed) {
- info_size += 1024;
- bpp = 8;
- dest_pixel_format = PixelFormat8bppIndexed;
- } else if (pixel_format == PixelFormat32bppARGB) {
- bpp = 32;
- dest_pixel_format = PixelFormat32bppARGB;
- }
- LPBYTE buf = FX_Alloc(BYTE, info_size);
- if (!buf) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf;
- FXSYS_memset32(buf, 0, info_size);
- pbmih->biBitCount = bpp;
- pbmih->biCompression = BI_RGB;
- pbmih->biHeight = -(int)height;
- pbmih->biPlanes = 1;
- pbmih->biWidth = width;
- Rect rect(0, 0, width, height);
- BitmapData* pBitmapData = FX_Alloc(BitmapData, 1);
- if (!pBitmapData) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead,
- dest_pixel_format, pBitmapData);
- if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bppIndexed) {
- DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER));
- struct {
- UINT flags;
- UINT Count;
- DWORD Entries[256];
- } pal;
- int size = 0;
- CallFunc(GdipGetImagePaletteSize)(pBitmap, &size);
- CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size);
- int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256;
- for (int i = 0; i < entries; i ++) {
- ppal[i] = pal.Entries[i] & 0x00ffffff;
- }
- }
- PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1);
- if (!pInfo) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- pInfo->pbmi = (BITMAPINFO*)buf;
- pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0;
- pInfo->Stride = pBitmapData->Stride;
- pInfo->pBitmap = pBitmap;
- pInfo->pBitmapData = pBitmapData;
- pInfo->pStream = pStream;
- return pInfo;
-}
-static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData);
- CallFunc(GdipDisposeImage)(pInfo->pBitmap);
- FX_Free(pInfo->pBitmapData);
- FX_Free((LPBYTE)pInfo->pbmi);
- if (pInfo->pStream) {
- pInfo->pStream->Release();
- }
- FX_Free(pInfo);
-}
-CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha);
-CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args);
- if (pInfo == NULL) {
- return NULL;
- }
- int height = abs(pInfo->pbmi->bmiHeader.biHeight);
- int width = pInfo->pbmi->bmiHeader.biWidth;
- int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
- LPBYTE pData = FX_Alloc(BYTE, dest_pitch * height);
- if (pData == NULL) {
- FreeDIBitmap(pInfo);
- return NULL;
- }
- if (dest_pitch == pInfo->Stride) {
- FXSYS_memcpy32(pData, pInfo->pScan0, dest_pitch * height);
- } else for (int i = 0; i < height; i ++) {
- FXSYS_memcpy32(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch);
- }
- CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32);
- FX_Free(pData);
- FreeDIBitmap(pInfo);
- return pDIBitmap;
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+#include "../Microsoft SDK/include/GdiPlus.h"
+using namespace Gdiplus;
+using namespace Gdiplus::DllExports;
+#define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding)
+static CombineMode GdiCombineMode2Gdip(int mode)
+{
+ switch (mode) {
+ case RGN_AND:
+ return CombineModeIntersect;
+ }
+ return CombineModeIntersect;
+}
+enum {
+ FuncId_GdipCreatePath2,
+ FuncId_GdipSetPenDashStyle,
+ FuncId_GdipSetPenDashArray,
+ FuncId_GdipSetPenDashCap197819,
+ FuncId_GdipSetPenLineJoin,
+ FuncId_GdipSetPenWidth,
+ FuncId_GdipCreateFromHDC,
+ FuncId_GdipSetPageUnit,
+ FuncId_GdipSetSmoothingMode,
+ FuncId_GdipCreateSolidFill,
+ FuncId_GdipFillPath,
+ FuncId_GdipDeleteBrush,
+ FuncId_GdipCreatePen1,
+ FuncId_GdipSetPenMiterLimit,
+ FuncId_GdipDrawPath,
+ FuncId_GdipDeletePen,
+ FuncId_GdipDeletePath,
+ FuncId_GdipDeleteGraphics,
+ FuncId_GdipCreateBitmapFromFileICM,
+ FuncId_GdipCreateBitmapFromStreamICM,
+ FuncId_GdipGetImageHeight,
+ FuncId_GdipGetImageWidth,
+ FuncId_GdipGetImagePixelFormat,
+ FuncId_GdipBitmapLockBits,
+ FuncId_GdipGetImagePaletteSize,
+ FuncId_GdipGetImagePalette,
+ FuncId_GdipBitmapUnlockBits,
+ FuncId_GdipDisposeImage,
+ FuncId_GdipFillRectangle,
+ FuncId_GdipCreateBitmapFromScan0,
+ FuncId_GdipSetImagePalette,
+ FuncId_GdipSetInterpolationMode,
+ FuncId_GdipDrawImagePointsI,
+ FuncId_GdipCreateBitmapFromGdiDib,
+ FuncId_GdiplusStartup,
+ FuncId_GdipDrawLineI,
+ FuncId_GdipResetClip,
+ FuncId_GdipCreatePath,
+ FuncId_GdipAddPathPath,
+ FuncId_GdipSetPathFillMode,
+ FuncId_GdipSetClipPath,
+ FuncId_GdipGetClip,
+ FuncId_GdipCreateRegion,
+ FuncId_GdipGetClipBoundsI,
+ FuncId_GdipSetClipRegion,
+ FuncId_GdipWidenPath,
+ FuncId_GdipAddPathLine,
+ FuncId_GdipAddPathRectangle,
+ FuncId_GdipDeleteRegion,
+ FuncId_GdipGetDC,
+ FuncId_GdipReleaseDC,
+ FuncId_GdipSetPenLineCap197819,
+ FuncId_GdipSetPenDashOffset,
+ FuncId_GdipResetPath,
+ FuncId_GdipCreateRegionPath,
+ FuncId_GdipCreateFont,
+ FuncId_GdipGetFontSize,
+ FuncId_GdipCreateFontFamilyFromName,
+ FuncId_GdipSetTextRenderingHint,
+ FuncId_GdipDrawDriverString,
+ FuncId_GdipCreateMatrix2,
+ FuncId_GdipDeleteMatrix,
+ FuncId_GdipSetWorldTransform,
+ FuncId_GdipResetWorldTransform,
+ FuncId_GdipDeleteFontFamily,
+ FuncId_GdipDeleteFont,
+ FuncId_GdipNewPrivateFontCollection,
+ FuncId_GdipDeletePrivateFontCollection,
+ FuncId_GdipPrivateAddMemoryFont,
+ FuncId_GdipGetFontCollectionFamilyList,
+ FuncId_GdipGetFontCollectionFamilyCount,
+ FuncId_GdipSetTextContrast,
+ FuncId_GdipSetPixelOffsetMode,
+ FuncId_GdipGetImageGraphicsContext,
+ FuncId_GdipDrawImageI,
+ FuncId_GdipDrawImageRectI,
+ FuncId_GdipDrawString,
+ FuncId_GdipSetPenTransform,
+};
+static LPCSTR g_GdipFuncNames[] = {
+ "GdipCreatePath2",
+ "GdipSetPenDashStyle",
+ "GdipSetPenDashArray",
+ "GdipSetPenDashCap197819",
+ "GdipSetPenLineJoin",
+ "GdipSetPenWidth",
+ "GdipCreateFromHDC",
+ "GdipSetPageUnit",
+ "GdipSetSmoothingMode",
+ "GdipCreateSolidFill",
+ "GdipFillPath",
+ "GdipDeleteBrush",
+ "GdipCreatePen1",
+ "GdipSetPenMiterLimit",
+ "GdipDrawPath",
+ "GdipDeletePen",
+ "GdipDeletePath",
+ "GdipDeleteGraphics",
+ "GdipCreateBitmapFromFileICM",
+ "GdipCreateBitmapFromStreamICM",
+ "GdipGetImageHeight",
+ "GdipGetImageWidth",
+ "GdipGetImagePixelFormat",
+ "GdipBitmapLockBits",
+ "GdipGetImagePaletteSize",
+ "GdipGetImagePalette",
+ "GdipBitmapUnlockBits",
+ "GdipDisposeImage",
+ "GdipFillRectangle",
+ "GdipCreateBitmapFromScan0",
+ "GdipSetImagePalette",
+ "GdipSetInterpolationMode",
+ "GdipDrawImagePointsI",
+ "GdipCreateBitmapFromGdiDib",
+ "GdiplusStartup",
+ "GdipDrawLineI",
+ "GdipResetClip",
+ "GdipCreatePath",
+ "GdipAddPathPath",
+ "GdipSetPathFillMode",
+ "GdipSetClipPath",
+ "GdipGetClip",
+ "GdipCreateRegion",
+ "GdipGetClipBoundsI",
+ "GdipSetClipRegion",
+ "GdipWidenPath",
+ "GdipAddPathLine",
+ "GdipAddPathRectangle",
+ "GdipDeleteRegion",
+ "GdipGetDC",
+ "GdipReleaseDC",
+ "GdipSetPenLineCap197819",
+ "GdipSetPenDashOffset",
+ "GdipResetPath",
+ "GdipCreateRegionPath",
+ "GdipCreateFont",
+ "GdipGetFontSize",
+ "GdipCreateFontFamilyFromName",
+ "GdipSetTextRenderingHint",
+ "GdipDrawDriverString",
+ "GdipCreateMatrix2",
+ "GdipDeleteMatrix",
+ "GdipSetWorldTransform",
+ "GdipResetWorldTransform",
+ "GdipDeleteFontFamily",
+ "GdipDeleteFont",
+ "GdipNewPrivateFontCollection",
+ "GdipDeletePrivateFontCollection",
+ "GdipPrivateAddMemoryFont",
+ "GdipGetFontCollectionFamilyList",
+ "GdipGetFontCollectionFamilyCount",
+ "GdipSetTextContrast",
+ "GdipSetPixelOffsetMode",
+ "GdipGetImageGraphicsContext",
+ "GdipDrawImageI",
+ "GdipDrawImageRectI",
+ "GdipDrawString",
+ "GdipSetPenTransform",
+};
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode, GpPath **path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashStyle dashstyle);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONST REAL *dash, INT count);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDashCap dashCap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoin lineJoin);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics **graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, GpUnit unit);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphics, SmoothingMode smoothingMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidFill **brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBrush *brush, GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, GpUnit unit, GpPen **pen);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL miterLimit);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* stream, GpBitmap **bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT *width);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDIPCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, ColorPalette *palette, INT size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIPCONST ColorPalette *palette);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *graphics, InterpolationMode interpolationMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphics, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap);
+typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT FX_UINTPTR *token, const GdiplusStartupInput *input, OUT GdiplusStartupOutput *output);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpPath **path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFillMode fillmode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegion *region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hdc);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL offset);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpRegion **region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *graphics, TextRenderingHint mode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphics, GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontFamily);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontCollection** fontCollection);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCollection** fontCollection);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCollection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontCollection* fontCollection, INT* numFound);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics, UINT contrast);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *image, GpGraphics **graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpImage *image, INT x, INT y);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix);
+#define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname])
+typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts);
+typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle);
+void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face)
+{
+ if (m_pGdiAddFontMemResourceEx) {
+ return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face);
+ }
+ return NULL;
+}
+FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle)
+{
+ if (m_pGdiRemoveFontMemResourseEx) {
+ return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)((HANDLE)handle);
+ }
+ return FALSE;
+}
+static GpBrush* _GdipCreateBrush(DWORD argb)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpSolidFill* solidBrush = NULL;
+ CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
+ return solidBrush;
+}
+static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height,
+ const CFX_DIBitmap* pSource, FX_RECT* pClipRect)
+{
+ FX_BOOL bFlipX = dest_width < 0;
+ if (bFlipX) {
+ dest_width = -dest_width;
+ }
+ FX_BOOL bFlipY = dest_height < 0;
+ if (bFlipY) {
+ dest_height = -dest_height;
+ }
+ int result_width = pClipRect->Width();
+ int result_height = pClipRect->Height();
+ int result_pitch = (result_width + 3) / 4 * 4;
+ CFX_DIBitmap* pStretched = FX_NEW CFX_DIBitmap;
+ if (!pStretched) {
+ return NULL;
+ }
+ if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) {
+ delete pStretched;
+ return NULL;
+ }
+ LPBYTE dest_buf = pStretched->GetBuffer();
+ int src_width = pSource->GetWidth();
+ int src_height = pSource->GetHeight();
+ int src_count = src_width * src_height;
+ int dest_count = dest_width * dest_height;
+ int ratio = 255 * dest_count / src_count;
+ int y_unit = src_height / dest_height;
+ int x_unit = src_width / dest_width;
+ int area_unit = y_unit * x_unit;
+ LPBYTE src_buf = pSource->GetBuffer();
+ int src_pitch = pSource->GetPitch();
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ LPBYTE dest_scan = dest_buf + dest_y * result_pitch;
+ int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top);
+ src_y_start = src_y_start * src_height / dest_height;
+ LPBYTE src_scan = src_buf + src_y_start * src_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int sum = 0;
+ int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) : (dest_x + pClipRect->left);
+ src_x_start = src_x_start * src_width / dest_width;
+ int src_x_end = src_x_start + x_unit;
+ LPBYTE src_line = src_scan;
+ for (int src_y = 0; src_y < y_unit; src_y ++) {
+ for (int src_x = src_x_start; src_x < src_x_end; src_x ++) {
+ if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) {
+ sum += 255;
+ }
+ }
+ src_line += src_pitch;
+ }
+ dest_scan[dest_x] = 255 - sum / area_unit;
+ }
+ }
+ return pStretched;
+}
+static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect)
+{
+ ASSERT(pBitmap->GetBPP() == 1);
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight();
+ int src_pitch = pBitmap->GetPitch();
+ FX_LPBYTE scan0 = pBitmap->GetBuffer();
+ if (src_width == 1 && src_height == 1) {
+ if ((scan0[0] & 0x80) == 0) {
+ return;
+ }
+ GpSolidFill* solidBrush;
+ CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
+ if (dest_width < 0) {
+ dest_width = -dest_width;
+ dest_left -= dest_width;
+ }
+ if (dest_height < 0) {
+ dest_height = -dest_height;
+ dest_top -= dest_height;
+ }
+ CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (float)dest_top,
+ (float)dest_width, (float)dest_height);
+ CallFunc(GdipDeleteBrush)(solidBrush);
+ return;
+ }
+ if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_height) {
+ FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height);
+ image_rect.Normalize();
+ FX_RECT image_clip = image_rect;
+ image_clip.Intersect(*pClipRect);
+ if (image_clip.IsEmpty()) {
+ return;
+ }
+ image_clip.Offset(-image_rect.left, -image_rect.top);
+ CFX_DIBitmap* pStretched = NULL;
+ if (src_width * src_height > 10000) {
+ pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip);
+ } else {
+ pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip);
+ }
+ GpBitmap* bitmap;
+ CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(),
+ (image_clip.Width() + 3) / 4 * 4, PixelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap);
+ int a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ UINT pal[258];
+ pal[0] = 0;
+ pal[1] = 256;
+ for (int i = 0; i < 256; i ++) {
+ pal[i + 2] = ArgbEncode(i * a / 255, r, g, b);
+ }
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
+ CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip.left,
+ image_rect.top + image_clip.top);
+ CallFunc(GdipDisposeImage)(bitmap);
+ delete pStretched;
+ return;
+ }
+ GpBitmap* bitmap;
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelFormat1bppIndexed, scan0, &bitmap);
+ UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb };
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette);
+ Point destinationPoints[] = {
+ Point(dest_left, dest_top),
+ Point(dest_left + dest_width, dest_top),
+ Point(dest_left, dest_top + dest_height)
+ };
+ CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
+ CallFunc(GdipDisposeImage)(bitmap);
+}
+static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect,
+ int dest_left, int dest_top, int dest_width, int dest_height)
+{
+ int src_width = pSrcRect->Width(), src_height = pSrcRect->Height();
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) {
+ FX_RECT new_rect(0, 0, src_width, src_height);
+ CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect);
+ if (!pCloned) {
+ return;
+ }
+ OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, dest_height);
+ delete pCloned;
+ return;
+ }
+ int src_pitch = pBitmap->GetPitch();
+ FX_LPBYTE scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap->GetBPP() * pSrcRect->left / 8;
+ GpBitmap* bitmap = NULL;
+ switch (pBitmap->GetFormat()) {
+ case FXDIB_Argb:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat32bppARGB, scan0, &bitmap);
+ break;
+ case FXDIB_Rgb32:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat32bppRGB, scan0, &bitmap);
+ break;
+ case FXDIB_Rgb:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat24bppRGB, scan0, &bitmap);
+ break;
+ case FXDIB_8bppRgb: {
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat8bppIndexed, scan0, &bitmap);
+ UINT pal[258];
+ pal[0] = 0;
+ pal[1] = 256;
+ for (int i = 0; i < 256; i ++) {
+ pal[i + 2] = pBitmap->GetPaletteEntry(i);
+ }
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
+ break;
+ }
+ case FXDIB_1bppRgb: {
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat1bppIndexed, scan0, &bitmap);
+ break;
+ }
+ }
+ if (dest_height < 0) {
+ dest_height --;
+ }
+ if (dest_width < 0) {
+ dest_width --;
+ }
+ Point destinationPoints[] = {
+ Point(dest_left, dest_top),
+ Point(dest_left + dest_width, dest_top),
+ Point(dest_left, dest_top + dest_height)
+ };
+ CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
+ CallFunc(GdipDisposeImage)(bitmap);
+}
+CGdiplusExt::CGdiplusExt()
+{
+ m_hModule = NULL;
+ m_GdiModule = NULL;
+ for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
+ m_Functions[i] = NULL;
+ }
+ m_pGdiAddFontMemResourceEx = NULL;
+ m_pGdiRemoveFontMemResourseEx = NULL;
+}
+void CGdiplusExt::Load()
+{
+ CFX_ByteString strPlusPath = "";
+ FX_CHAR buf[MAX_PATH];
+ GetSystemDirectoryA(buf, MAX_PATH);
+ strPlusPath += buf;
+ strPlusPath += "\\";
+ strPlusPath += "GDIPLUS.DLL";
+ m_hModule = LoadLibraryA(strPlusPath);
+ if (m_hModule == NULL) {
+ return;
+ }
+ for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
+ m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
+ if (m_Functions[i] == NULL) {
+ m_hModule = NULL;
+ return;
+ }
+ }
+ FX_UINTPTR gdiplusToken;
+ GdiplusStartupInput gdiplusStartupInput;
+ ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL);
+ m_GdiModule = LoadLibraryA("GDI32.DLL");
+ if (m_GdiModule == NULL) {
+ return;
+ }
+ m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResourceEx");
+ m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx");
+}
+CGdiplusExt::~CGdiplusExt()
+{
+}
+LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size)
+{
+ GpFontCollection* pCollection = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipNewPrivateFontCollection)(&pCollection);
+ GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size);
+ if (status == Ok) {
+ return pCollection;
+ }
+ CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
+ return NULL;
+}
+void CGdiplusExt::DeleteMemFont(LPVOID pCollection)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
+}
+FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ PixelFormat format;
+ switch (pBitmap->GetFormat()) {
+ case FXDIB_Rgb:
+ format = PixelFormat24bppRGB;
+ break;
+ case FXDIB_Rgb32:
+ format = PixelFormat32bppRGB;
+ break;
+ case FXDIB_Argb:
+ format = PixelFormat32bppARGB;
+ break;
+ default:
+ return FALSE;
+ }
+ GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), pBitmap->GetHeight(),
+ pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitmap**)bitmap);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, (GpGraphics**)graphics);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *)name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, Unit(flag), (GpFont**)pFont);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size)
+{
+ REAL get_size;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_size);
+ if (status == Ok) {
+ *size = (FX_FLOAT)get_size;
+ } else {
+ *size = 0;
+ }
+}
+void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint)mode);
+}
+void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit);
+}
+FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length,
+ void *font, void* brush, void *positions, int flags, const void *matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDIPCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush*)brush,
+ (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMatrix *)matrix);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush);
+}
+void CGdiplusExt::GdipDeleteBrush(void* pBrush)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush);
+}
+void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ int numFamilies = 0;
+ GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollection*)pFontCollection, &numFamilies);
+ if (status != Ok) {
+ return NULL;
+ }
+ GpFontFamily* family_list[1];
+ status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontCollection, 1, family_list, &numFamilies);
+ if (status != Ok) {
+ return NULL;
+ }
+ GpFont* pFont = NULL;
+ status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, UnitPixel, &pFont);
+ if (status != Ok) {
+ return NULL;
+ }
+ return pFont;
+}
+void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix);
+}
+void CGdiplusExt::GdipDeleteMatrix(void* matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix);
+}
+void CGdiplusExt::GdipDeleteFontFamily(void* pFamily)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily);
+}
+void CGdiplusExt::GdipDeleteFont(void* pFont)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteFont)((GpFont*)pFont);
+}
+void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix);
+}
+void CGdiplusExt::GdipDisposeImage(void* bitmap)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
+}
+void CGdiplusExt::GdipDeleteGraphics(void* graphics)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
+}
+FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags)
+{
+ ASSERT(pBitmap->GetBPP() == 1);
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpGraphics* pGraphics = NULL;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ if (flags & FXDIB_NOSMOOTH) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
+ } else {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
+ }
+ OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_width, dest_height, argb, pClipRect);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int flags)
+{
+ GpGraphics* pGraphics;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ if (flags & FXDIB_NOSMOOTH) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
+ } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
+ } else {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear);
+ }
+ FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+ OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
+ if (!bTextMode) {
+ FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2);
+ if (width < unit) {
+ width = unit;
+ }
+ }
+ GpPen* pPen = NULL;
+ CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
+ LineCap lineCap;
+ DashCap dashCap = DashCapFlat;
+ FX_BOOL bDashExtend = FALSE;
+ switch(pGraphState->m_LineCap) {
+ case CFX_GraphStateData::LineCapButt:
+ lineCap = LineCapFlat;
+ break;
+ case CFX_GraphStateData::LineCapRound:
+ lineCap = LineCapRound;
+ dashCap = DashCapRound;
+ bDashExtend = TRUE;
+ break;
+ case CFX_GraphStateData::LineCapSquare:
+ lineCap = LineCapSquare;
+ bDashExtend = TRUE;
+ break;
+ }
+ CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
+ LineJoin lineJoin;
+ switch(pGraphState->m_LineJoin) {
+ case CFX_GraphStateData::LineJoinMiter:
+ lineJoin = LineJoinMiterClipped;
+ break;
+ case CFX_GraphStateData::LineJoinRound:
+ lineJoin = LineJoinRound;
+ break;
+ case CFX_GraphStateData::LineJoinBevel:
+ lineJoin = LineJoinBevel;
+ break;
+ }
+ CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
+ if(pGraphState->m_DashCount) {
+ FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2);
+ if (!pDashArray) {
+ return NULL;
+ }
+ int nCount = 0;
+ FX_FLOAT on_leftover = 0, off_leftover = 0;
+ for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
+ FX_FLOAT on_phase = pGraphState->m_DashArray[i];
+ FX_FLOAT off_phase;
+ if (i == pGraphState->m_DashCount - 1) {
+ off_phase = on_phase;
+ } else {
+ off_phase = pGraphState->m_DashArray[i + 1];
+ }
+ on_phase /= width;
+ off_phase /= width;
+ if (on_phase + off_phase <= 0.00002f) {
+ on_phase = 1.0f / 10;
+ off_phase = 1.0f / 10;
+ }
+ if (bDashExtend) {
+ if (off_phase < 1) {
+ off_phase = 0;
+ } else {
+ off_phase -= 1;
+ }
+ on_phase += 1;
+ }
+ if (on_phase == 0 || off_phase == 0) {
+ if (nCount == 0) {
+ on_leftover += on_phase;
+ off_leftover += off_phase;
+ } else {
+ pDashArray[nCount - 2] += on_phase;
+ pDashArray[nCount - 1] += off_phase;
+ }
+ } else {
+ pDashArray[nCount++] = on_phase + on_leftover;
+ on_leftover = 0;
+ pDashArray[nCount++] = off_phase + off_leftover;
+ off_leftover = 0;
+ }
+ }
+ CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
+ FX_FLOAT phase = pGraphState->m_DashPhase;
+ if (bDashExtend)
+ if (phase < 0.5f) {
+ phase = 0;
+ } else {
+ phase -= 0.5f;
+ }
+ CallFunc(GdipSetPenDashOffset)(pPen, phase);
+ FX_Free(pDashArray);
+ pDashArray = NULL;
+ }
+ CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
+ return pPen;
+}
+static BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2)
+{
+ int pairs[] = {1, 2, 0, 2, 0, 1};
+ for (int i = 0; i < 3; i ++) {
+ int pair1 = pairs[i * 2];
+ int pair2 = pairs[i * 2 + 1];
+ FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
+ FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
+ if (pMatrix) {
+ pMatrix->Transform(x1, y1);
+ pMatrix->Transform(x2, y2);
+ }
+ FX_FLOAT dx = x1 - x2;
+ FX_FLOAT dy = y1 - y2;
+ FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
+ if (distance_square < (1.0f * 2 + 1.0f / 4)) {
+ v1 = i;
+ v2 = pair1;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_argb,
+ FX_DWORD stroke_argb,
+ int fill_mode
+ )
+{
+ int nPoints = pPathData->GetPointCount();
+ if (nPoints == 0) {
+ return TRUE;
+ }
+ FX_PATHPOINT* pPoints = pPathData->GetPoints();
+ GpGraphics* pGraphics = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
+ GpMatrix* pMatrix = NULL;
+ if (pObject2Device) {
+ CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObject2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix);
+ CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
+ }
+ PointF *points = FX_Alloc(PointF, nPoints);
+ if (!points) {
+ return FALSE;
+ }
+ BYTE * types = FX_Alloc(BYTE, nPoints);
+ if (!types) {
+ FX_Free(points);
+ return FALSE;
+ }
+ int nSubPathes = 0;
+ FX_BOOL bSubClose = FALSE;
+ int pos_subclose = 0;
+ FX_BOOL bSmooth = FALSE;
+ int startpoint = 0;
+ for(int i = 0; i < nPoints; i++) {
+ points[i].X = pPoints[i].m_PointX;
+ points[i].Y = pPoints[i].m_PointY;
+ FX_FLOAT x, y;
+ if (pObject2Device) {
+ pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
+ } else {
+ x = pPoints[i].m_PointX;
+ y = pPoints[i].m_PointY;
+ }
+ if (x > 50000 * 1.0f) {
+ points[i].X = 50000 * 1.0f;
+ }
+ if (x < -50000 * 1.0f) {
+ points[i].X = -50000 * 1.0f;
+ }
+ if (y > 50000 * 1.0f) {
+ points[i].Y = 50000 * 1.0f;
+ }
+ if (y < -50000 * 1.0f) {
+ points[i].Y = -50000 * 1.0f;
+ }
+ int point_type = pPoints[i].m_Flag & FXPT_TYPE;
+ if(point_type == FXPT_MOVETO) {
+ types[i] = PathPointTypeStart;
+ nSubPathes ++;
+ bSubClose = FALSE;
+ startpoint = i;
+ } else if (point_type == FXPT_LINETO) {
+ types[i] = PathPointTypeLine;
+ if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
+ points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
+ points[i].X += 0.01f;
+ continue;
+ }
+ if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != points[i - 1].Y) {
+ bSmooth = TRUE;
+ }
+ } else if (point_type == FXPT_BEZIERTO) {
+ types[i] = PathPointTypeBezier;
+ bSmooth = TRUE;
+ }
+ if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
+ if (bSubClose) {
+ types[pos_subclose] &= ~PathPointTypeCloseSubpath;
+ } else {
+ bSubClose = TRUE;
+ }
+ pos_subclose = i;
+ types[i] |= PathPointTypeCloseSubpath;
+ if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y != points[startpoint].Y) {
+ bSmooth = TRUE;
+ }
+ }
+ }
+ if (fill_mode & FXFILL_NOPATHSMOOTH) {
+ bSmooth = FALSE;
+ CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
+ } else if (!(fill_mode & FXFILL_FULLCOVER)) {
+ if (!bSmooth && (fill_mode & 3)) {
+ bSmooth = TRUE;
+ }
+ if (bSmooth || pGraphState && pGraphState->m_LineWidth > 2) {
+ CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
+ }
+ }
+ int new_fill_mode = fill_mode & 3;
+ if (nPoints == 4 && pGraphState == NULL) {
+ int v1, v2;
+ if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
+ GpPen* pPen = NULL;
+ CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
+ CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
+ FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y));
+ CallFunc(GdipDeletePen)(pPen);
+ return TRUE;
+ }
+ }
+ GpPath* pGpPath = NULL;
+ CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_mode), &pGpPath);
+ if (!pGpPath) {
+ if (pMatrix) {
+ CallFunc(GdipDeleteMatrix)(pMatrix);
+ }
+ FX_Free(points);
+ FX_Free(types);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return FALSE;
+ }
+ if (new_fill_mode) {
+ GpBrush* pBrush = _GdipCreateBrush(fill_argb);
+ CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
+ CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
+ CallFunc(GdipDeleteBrush)(pBrush);
+ }
+ if (pGraphState && stroke_argb) {
+ GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, fill_mode & FX_STROKE_TEXT_MODE);
+ if (nSubPathes == 1) {
+ CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
+ } else {
+ int iStart = 0;
+ for (int i = 0; i < nPoints; i ++) {
+ if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
+ GpPath* pSubPath;
+ CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath);
+ iStart = i + 1;
+ CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
+ CallFunc(GdipDeletePath)(pSubPath);
+ }
+ }
+ }
+ CallFunc(GdipDeletePen)(pPen);
+ }
+ if (pMatrix) {
+ CallFunc(GdipDeleteMatrix)(pMatrix);
+ }
+ FX_Free(points);
+ FX_Free(types);
+ CallFunc(GdipDeletePath)(pGpPath);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+class GpStream : public IStream, public CFX_Object
+{
+ LONG m_RefCount;
+ int m_ReadPos;
+ CFX_ByteTextBuf m_InterStream;
+public:
+ GpStream()
+ {
+ m_RefCount = 1;
+ m_ReadPos = 0;
+ }
+ virtual HRESULT STDMETHODCALLTYPE
+ QueryInterface(REFIID iid, void ** ppvObject)
+ {
+ if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) ||
+ iid == __uuidof(ISequentialStream)) {
+ *ppvObject = static_cast<IStream*>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return E_NOINTERFACE;
+ }
+ }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ {
+ return (ULONG)InterlockedIncrement(&m_RefCount);
+ }
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ ULONG res = (ULONG) InterlockedDecrement(&m_RefCount);
+ if (res == 0) {
+ delete this;
+ }
+ return res;
+ }
+public:
+ virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRead)
+ {
+ size_t bytes_left;
+ size_t bytes_out;
+ if (pcbRead != NULL) {
+ *pcbRead = 0;
+ }
+ if (m_ReadPos == m_InterStream.GetLength()) {
+ return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA);
+ }
+ bytes_left = m_InterStream.GetLength() - m_ReadPos;
+ bytes_out = FX_MIN(cb, bytes_left);
+ FXSYS_memcpy32(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out);
+ m_ReadPos += (FX_INT32)bytes_out;
+ if (pcbRead != NULL) {
+ *pcbRead = (ULONG)bytes_out;
+ }
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten)
+ {
+ if (cb <= 0) {
+ if (pcbWritten != NULL) {
+ *pcbWritten = 0;
+ }
+ return S_OK;
+ }
+ m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb);
+ if (pcbWritten != NULL) {
+ *pcbWritten = cb;
+ }
+ return S_OK;
+ }
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Revert(void)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer)
+ {
+ long start = 0;
+ long new_read_position;
+ switch(dwOrigin) {
+ case STREAM_SEEK_SET:
+ start = 0;
+ break;
+ case STREAM_SEEK_CUR:
+ start = m_ReadPos;
+ break;
+ case STREAM_SEEK_END:
+ start = m_InterStream.GetLength();
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
+ break;
+ }
+ new_read_position = start + (long)liDistanceToMove.QuadPart;
+ if (new_read_position < 0 || new_read_position > m_InterStream.GetLength()) {
+ return STG_E_SEEKERROR;
+ }
+ m_ReadPos = new_read_position;
+ if (lpNewFilePointer != NULL) {
+ lpNewFilePointer->QuadPart = m_ReadPos;
+ }
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag)
+ {
+ if (pStatstg == NULL) {
+ return STG_E_INVALIDFUNCTION;
+ }
+ ZeroMemory(pStatstg, sizeof(STATSTG));
+ pStatstg->cbSize.QuadPart = m_InterStream.GetLength();
+ return S_OK;
+ }
+};
+typedef struct {
+ BITMAPINFO* pbmi;
+ int Stride;
+ LPBYTE pScan0;
+ GpBitmap* pBitmap;
+ BitmapData* pBitmapData;
+ GpStream* pStream;
+} PREVIEW3_DIBITMAP;
+static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ GpBitmap* pBitmap;
+ GpStream* pStream = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ Status status = Ok;
+ if (args.flags == WINDIB_OPEN_PATHNAME) {
+ status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap);
+ } else {
+ if (args.memory_size == 0 || !args.memory_base) {
+ return NULL;
+ }
+ pStream = FX_NEW GpStream;
+ if (!pStream) {
+ return NULL;
+ }
+ pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL);
+ status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap);
+ }
+ if (status != Ok) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ UINT height, width;
+ CallFunc(GdipGetImageHeight)(pBitmap, &height);
+ CallFunc(GdipGetImageWidth)(pBitmap, &width);
+ PixelFormat pixel_format;
+ CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format);
+ int info_size = sizeof(BITMAPINFOHEADER);
+ int bpp = 24;
+ int dest_pixel_format = PixelFormat24bppRGB;
+ if (pixel_format == PixelFormat1bppIndexed) {
+ info_size += 8;
+ bpp = 1;
+ dest_pixel_format = PixelFormat1bppIndexed;
+ } else if (pixel_format == PixelFormat8bppIndexed) {
+ info_size += 1024;
+ bpp = 8;
+ dest_pixel_format = PixelFormat8bppIndexed;
+ } else if (pixel_format == PixelFormat32bppARGB) {
+ bpp = 32;
+ dest_pixel_format = PixelFormat32bppARGB;
+ }
+ LPBYTE buf = FX_Alloc(BYTE, info_size);
+ if (!buf) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf;
+ FXSYS_memset32(buf, 0, info_size);
+ pbmih->biBitCount = bpp;
+ pbmih->biCompression = BI_RGB;
+ pbmih->biHeight = -(int)height;
+ pbmih->biPlanes = 1;
+ pbmih->biWidth = width;
+ Rect rect(0, 0, width, height);
+ BitmapData* pBitmapData = FX_Alloc(BitmapData, 1);
+ if (!pBitmapData) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead,
+ dest_pixel_format, pBitmapData);
+ if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bppIndexed) {
+ DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER));
+ struct {
+ UINT flags;
+ UINT Count;
+ DWORD Entries[256];
+ } pal;
+ int size = 0;
+ CallFunc(GdipGetImagePaletteSize)(pBitmap, &size);
+ CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size);
+ int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256;
+ for (int i = 0; i < entries; i ++) {
+ ppal[i] = pal.Entries[i] & 0x00ffffff;
+ }
+ }
+ PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1);
+ if (!pInfo) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ pInfo->pbmi = (BITMAPINFO*)buf;
+ pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0;
+ pInfo->Stride = pBitmapData->Stride;
+ pInfo->pBitmap = pBitmap;
+ pInfo->pBitmapData = pBitmapData;
+ pInfo->pStream = pStream;
+ return pInfo;
+}
+static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData);
+ CallFunc(GdipDisposeImage)(pInfo->pBitmap);
+ FX_Free(pInfo->pBitmapData);
+ FX_Free((LPBYTE)pInfo->pbmi);
+ if (pInfo->pStream) {
+ pInfo->pStream->Release();
+ }
+ FX_Free(pInfo);
+}
+CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha);
+CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args);
+ if (pInfo == NULL) {
+ return NULL;
+ }
+ int height = abs(pInfo->pbmi->bmiHeader.biHeight);
+ int width = pInfo->pbmi->bmiHeader.biWidth;
+ int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
+ LPBYTE pData = FX_Alloc(BYTE, dest_pitch * height);
+ if (pData == NULL) {
+ FreeDIBitmap(pInfo);
+ return NULL;
+ }
+ if (dest_pitch == pInfo->Stride) {
+ FXSYS_memcpy32(pData, pInfo->pScan0, dest_pitch * height);
+ } else for (int i = 0; i < height; i ++) {
+ FXSYS_memcpy32(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch);
+ }
+ CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32);
+ FX_Free(pData);
+ FreeDIBitmap(pInfo);
+ return pDIBitmap;
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_print.cpp b/core/src/fxge/win32/fx_win32_print.cpp
index c08c8e7bb6..9e7a0aae95 100644
--- a/core/src/fxge/win32/fx_win32_print.cpp
+++ b/core/src/fxge/win32/fx_win32_print.cpp
@@ -1,426 +1,426 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#define SIZETHRESHOLD 1000
-#define OUTPUTPSLEN 4096
-CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINTER)
-{
- m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
- m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
- m_bSupportROP = TRUE;
-}
-int CGdiPrinterDriver::GetDeviceCaps(int caps_id)
-{
- if (caps_id == FXDC_HORZ_SIZE) {
- return m_HorzSize;
- }
- if (caps_id == FXDC_VERT_SIZE) {
- return m_VertSize;
- }
- return CGdiDeviceDriver::GetDeviceCaps(caps_id);
-}
-FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform)
-{
- if (pSource->IsAlphaMask()) {
- FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
- return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(),
- &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- }
- ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL);
- ASSERT(blend_type == FXDIB_BLEND_NORMAL);
- if (pSource->HasAlpha()) {
- return FALSE;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
-}
-FX_BOOL CGdiPrinterDriver::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)
-{
- if (pSource->IsAlphaMask()) {
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
- if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) {
- return FALSE;
- }
- if (dest_width < 0 || dest_height < 0) {
- CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
- if (pFlipped == NULL) {
- return FALSE;
- }
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform);
- delete pFlipped;
- return ret;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest_height, color, flags, alpha_flag, pIccTransform);
- } else {
- ASSERT(pSource != NULL);
- if (pSource->HasAlpha()) {
- return FALSE;
- }
- if (dest_width < 0 || dest_height < 0) {
- CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
- if (pFlipped == NULL) {
- return FALSE;
- }
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), flags, pIccTransform);
- delete pFlipped;
- return ret;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
- }
-}
-static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix)
-{
- ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk);
- CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
- FX_RECT full_rect = unit_rect.GetOutterRect();
- int full_left = full_rect.left;
- int full_top = full_rect.top;
- CFX_DIBExtractor src_bitmap(pSrc);
- CFX_DIBitmap* pSrcBitmap = src_bitmap;
- if (pSrcBitmap == NULL) {
- return NULL;
- }
- int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight();
- FX_LPBYTE src_buf = pSrcBitmap->GetBuffer();
- FX_DWORD src_pitch = pSrcBitmap->GetPitch();
- FX_FLOAT dest_area = pDestMatrix->GetUnitArea();
- FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area);
- FX_FLOAT size_scale = FXSYS_sqrt(area_scale);
- CFX_AffineMatrix adjusted_matrix(*pDestMatrix);
- adjusted_matrix.Scale(size_scale, size_scale);
- CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect();
- FX_RECT result_rect = result_rect_f.GetOutterRect();
- CFX_AffineMatrix src2result;
- src2result.e = adjusted_matrix.c + adjusted_matrix.e;
- src2result.f = adjusted_matrix.d + adjusted_matrix.f;
- src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth();
- src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth();
- src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight();
- src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight();
- src2result.TranslateI(-result_rect.left, -result_rect.top);
- CFX_AffineMatrix result2src;
- result2src.SetReverse(src2result);
- CPDF_FixedMatrix result2src_fix(result2src, 8);
- int result_width = result_rect.Width();
- int result_height = result_rect.Height();
- CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap;
- if (!pTempBitmap) {
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return NULL;
- }
- if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) {
- delete pTempBitmap;
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return NULL;
- }
- pTempBitmap->CopyPalette(pSrc->GetPalette());
- FX_LPBYTE dest_buf = pTempBitmap->GetBuffer();
- int dest_pitch = pTempBitmap->GetPitch();
- FXSYS_memset8(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height);
- if (pSrcBitmap->IsAlphaMask()) {
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int src_x, src_y;
- result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
- if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
- continue;
- }
- if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) {
- continue;
- }
- dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8);
- }
- }
- } else {
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int src_x, src_y;
- result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
- if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
- continue;
- }
- if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) {
- continue;
- }
- dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8));
- }
- }
- }
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return pTempBitmap;
-}
-FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) {
- return FALSE;
- }
- CFX_FloatRect unit_rect = pMatrix->GetUnitRect();
- FX_RECT full_rect = unit_rect.GetOutterRect();
- if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) {
- FX_BOOL bFlipX = pMatrix->a < 0;
- FX_BOOL bFlipY = pMatrix->d > 0;
- return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rect.left, bFlipY ? full_rect.bottom : full_rect.top,
- bFlipX ? -full_rect.Width() : full_rect.Width(), bFlipY ? -full_rect.Height() : full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- }
- if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) {
- CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0);
- if (pTransformed == NULL) {
- return FALSE;
- }
- FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- delete pTransformed;
- return ret;
- }
- if (pSource->GetBPP() == 1) {
- CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix);
- if (pIccTransform == NULL) {
- return FALSE;
- }
- SaveState();
- CFX_PathData path;
- path.AppendRect(0, 0, 1.0f, 1.0f);
- SetClip_PathFill(&path, pMatrix, WINDING);
- FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- RestoreState();
- delete pTransformed;
- handle = NULL;
- return ret;
- }
- return FALSE;
-}
-CPSOutput::CPSOutput(HDC hDC)
-{
- m_hDC = hDC;
- m_pBuf = NULL;
-}
-CPSOutput::~CPSOutput()
-{
- if (m_pBuf) {
- FX_Free(m_pBuf);
- }
-}
-void CPSOutput::Init()
-{
- m_pBuf = FX_Alloc(FX_CHAR, 1026);
-}
-void CPSOutput::OutputPS(FX_LPCSTR string, int len)
-{
- if (len < 0) {
- len = (int)FXSYS_strlen(string);
- }
- int sent_len = 0;
- while (len > 0) {
- int send_len = len > 1024 ? 1024 : len;
- *(FX_WORD*)m_pBuf = send_len;
- FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len);
- int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL);
- sent_len += send_len;
- len -= send_len;
- }
-}
-CPSPrinterDriver::CPSPrinterDriver()
-{
- m_pPSOutput = NULL;
- m_bCmykOutput = FALSE;
-}
-CPSPrinterDriver::~CPSPrinterDriver()
-{
- EndRendering();
- if (m_pPSOutput) {
- delete m_pPSOutput;
- }
-}
-FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput)
-{
- m_hDC = hDC;
- m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
- m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
- m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
- m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
- m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
- m_pPSOutput = FX_NEW CPSOutput(hDC);
- if (!m_pPSOutput) {
- return FALSE;
- }
- ((CPSOutput*)m_pPSOutput)->Init();
- m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput);
- m_bCmykOutput = bCmykOutput;
- HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1);
- int ret = ::GetClipRgn(hDC, hRgn);
- if (ret == 1) {
- ret = ::GetRegionData(hRgn, 0, NULL);
- if (ret) {
- RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret);
- if (!pData) {
- return FALSE;
- }
- ret = ::GetRegionData(hRgn, ret, pData);
- if (ret) {
- CFX_PathData path;
- path.AllocPointCount(pData->rdh.nCount * 5);
- for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) {
- RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i);
- path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
- }
- m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING);
- }
- FX_Free(pData);
- }
- }
- ::DeleteObject(hRgn);
- return TRUE;
-}
-int CPSPrinterDriver::GetDeviceCaps(int caps_id)
-{
- switch (caps_id) {
- case FXDC_DEVICE_CLASS:
- return FXDC_PRINTER;
- 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_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK;
- case FXDC_HORZ_SIZE:
- return m_HorzSize;
- case FXDC_VERT_SIZE:
- return m_VertSize;
- }
- return 0;
-}
-FX_BOOL CPSPrinterDriver::StartRendering()
-{
- return m_PSRenderer.StartRendering();
-}
-void CPSPrinterDriver::EndRendering()
-{
- m_PSRenderer.EndRendering();
-}
-void CPSPrinterDriver::SaveState()
-{
- m_PSRenderer.SaveState();
-}
-void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved)
-{
- m_PSRenderer.RestoreState(bKeepSaved);
-}
-FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device,
- int fill_mode)
-{
- m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode);
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState)
-{
- m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState);
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState, FX_ARGB fill_color, FX_ARGB stroke_color,
- int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode & 3, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect)
-{
- *pRect = m_PSRenderer.GetClipBox();
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_width, dest_height, flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- if (bitmap_alpha < 255) {
- return FALSE;
- }
- handle = NULL;
- return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag, void* pIccTransform)
-{
- return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, font_size, color, alpha_flag, pIccTransform);
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#define SIZETHRESHOLD 1000
+#define OUTPUTPSLEN 4096
+CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINTER)
+{
+ m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
+ m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
+ m_bSupportROP = TRUE;
+}
+int CGdiPrinterDriver::GetDeviceCaps(int caps_id)
+{
+ if (caps_id == FXDC_HORZ_SIZE) {
+ return m_HorzSize;
+ }
+ if (caps_id == FXDC_VERT_SIZE) {
+ return m_VertSize;
+ }
+ return CGdiDeviceDriver::GetDeviceCaps(caps_id);
+}
+FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform)
+{
+ if (pSource->IsAlphaMask()) {
+ FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
+ return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(),
+ &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ }
+ ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL);
+ ASSERT(blend_type == FXDIB_BLEND_NORMAL);
+ if (pSource->HasAlpha()) {
+ return FALSE;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
+}
+FX_BOOL CGdiPrinterDriver::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)
+{
+ if (pSource->IsAlphaMask()) {
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
+ if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) {
+ return FALSE;
+ }
+ if (dest_width < 0 || dest_height < 0) {
+ CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
+ if (pFlipped == NULL) {
+ return FALSE;
+ }
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform);
+ delete pFlipped;
+ return ret;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest_height, color, flags, alpha_flag, pIccTransform);
+ } else {
+ ASSERT(pSource != NULL);
+ if (pSource->HasAlpha()) {
+ return FALSE;
+ }
+ if (dest_width < 0 || dest_height < 0) {
+ CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
+ if (pFlipped == NULL) {
+ return FALSE;
+ }
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), flags, pIccTransform);
+ delete pFlipped;
+ return ret;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
+ }
+}
+static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix)
+{
+ ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk);
+ CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
+ FX_RECT full_rect = unit_rect.GetOutterRect();
+ int full_left = full_rect.left;
+ int full_top = full_rect.top;
+ CFX_DIBExtractor src_bitmap(pSrc);
+ CFX_DIBitmap* pSrcBitmap = src_bitmap;
+ if (pSrcBitmap == NULL) {
+ return NULL;
+ }
+ int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight();
+ FX_LPBYTE src_buf = pSrcBitmap->GetBuffer();
+ FX_DWORD src_pitch = pSrcBitmap->GetPitch();
+ FX_FLOAT dest_area = pDestMatrix->GetUnitArea();
+ FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area);
+ FX_FLOAT size_scale = FXSYS_sqrt(area_scale);
+ CFX_AffineMatrix adjusted_matrix(*pDestMatrix);
+ adjusted_matrix.Scale(size_scale, size_scale);
+ CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect();
+ FX_RECT result_rect = result_rect_f.GetOutterRect();
+ CFX_AffineMatrix src2result;
+ src2result.e = adjusted_matrix.c + adjusted_matrix.e;
+ src2result.f = adjusted_matrix.d + adjusted_matrix.f;
+ src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth();
+ src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth();
+ src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight();
+ src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight();
+ src2result.TranslateI(-result_rect.left, -result_rect.top);
+ CFX_AffineMatrix result2src;
+ result2src.SetReverse(src2result);
+ CPDF_FixedMatrix result2src_fix(result2src, 8);
+ int result_width = result_rect.Width();
+ int result_height = result_rect.Height();
+ CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap;
+ if (!pTempBitmap) {
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return NULL;
+ }
+ if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) {
+ delete pTempBitmap;
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return NULL;
+ }
+ pTempBitmap->CopyPalette(pSrc->GetPalette());
+ FX_LPBYTE dest_buf = pTempBitmap->GetBuffer();
+ int dest_pitch = pTempBitmap->GetPitch();
+ FXSYS_memset8(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height);
+ if (pSrcBitmap->IsAlphaMask()) {
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int src_x, src_y;
+ result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
+ if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
+ continue;
+ }
+ if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) {
+ continue;
+ }
+ dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8);
+ }
+ }
+ } else {
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int src_x, src_y;
+ result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
+ if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
+ continue;
+ }
+ if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) {
+ continue;
+ }
+ dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8));
+ }
+ }
+ }
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return pTempBitmap;
+}
+FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) {
+ return FALSE;
+ }
+ CFX_FloatRect unit_rect = pMatrix->GetUnitRect();
+ FX_RECT full_rect = unit_rect.GetOutterRect();
+ if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) {
+ FX_BOOL bFlipX = pMatrix->a < 0;
+ FX_BOOL bFlipY = pMatrix->d > 0;
+ return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rect.left, bFlipY ? full_rect.bottom : full_rect.top,
+ bFlipX ? -full_rect.Width() : full_rect.Width(), bFlipY ? -full_rect.Height() : full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ }
+ if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) {
+ CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0);
+ if (pTransformed == NULL) {
+ return FALSE;
+ }
+ FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ delete pTransformed;
+ return ret;
+ }
+ if (pSource->GetBPP() == 1) {
+ CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix);
+ if (pIccTransform == NULL) {
+ return FALSE;
+ }
+ SaveState();
+ CFX_PathData path;
+ path.AppendRect(0, 0, 1.0f, 1.0f);
+ SetClip_PathFill(&path, pMatrix, WINDING);
+ FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ RestoreState();
+ delete pTransformed;
+ handle = NULL;
+ return ret;
+ }
+ return FALSE;
+}
+CPSOutput::CPSOutput(HDC hDC)
+{
+ m_hDC = hDC;
+ m_pBuf = NULL;
+}
+CPSOutput::~CPSOutput()
+{
+ if (m_pBuf) {
+ FX_Free(m_pBuf);
+ }
+}
+void CPSOutput::Init()
+{
+ m_pBuf = FX_Alloc(FX_CHAR, 1026);
+}
+void CPSOutput::OutputPS(FX_LPCSTR string, int len)
+{
+ if (len < 0) {
+ len = (int)FXSYS_strlen(string);
+ }
+ int sent_len = 0;
+ while (len > 0) {
+ int send_len = len > 1024 ? 1024 : len;
+ *(FX_WORD*)m_pBuf = send_len;
+ FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len);
+ int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL);
+ sent_len += send_len;
+ len -= send_len;
+ }
+}
+CPSPrinterDriver::CPSPrinterDriver()
+{
+ m_pPSOutput = NULL;
+ m_bCmykOutput = FALSE;
+}
+CPSPrinterDriver::~CPSPrinterDriver()
+{
+ EndRendering();
+ if (m_pPSOutput) {
+ delete m_pPSOutput;
+ }
+}
+FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput)
+{
+ m_hDC = hDC;
+ m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
+ m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
+ m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
+ m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
+ m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
+ m_pPSOutput = FX_NEW CPSOutput(hDC);
+ if (!m_pPSOutput) {
+ return FALSE;
+ }
+ ((CPSOutput*)m_pPSOutput)->Init();
+ m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput);
+ m_bCmykOutput = bCmykOutput;
+ HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1);
+ int ret = ::GetClipRgn(hDC, hRgn);
+ if (ret == 1) {
+ ret = ::GetRegionData(hRgn, 0, NULL);
+ if (ret) {
+ RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret);
+ if (!pData) {
+ return FALSE;
+ }
+ ret = ::GetRegionData(hRgn, ret, pData);
+ if (ret) {
+ CFX_PathData path;
+ path.AllocPointCount(pData->rdh.nCount * 5);
+ for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) {
+ RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i);
+ path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
+ }
+ m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING);
+ }
+ FX_Free(pData);
+ }
+ }
+ ::DeleteObject(hRgn);
+ return TRUE;
+}
+int CPSPrinterDriver::GetDeviceCaps(int caps_id)
+{
+ switch (caps_id) {
+ case FXDC_DEVICE_CLASS:
+ return FXDC_PRINTER;
+ 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_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK;
+ case FXDC_HORZ_SIZE:
+ return m_HorzSize;
+ case FXDC_VERT_SIZE:
+ return m_VertSize;
+ }
+ return 0;
+}
+FX_BOOL CPSPrinterDriver::StartRendering()
+{
+ return m_PSRenderer.StartRendering();
+}
+void CPSPrinterDriver::EndRendering()
+{
+ m_PSRenderer.EndRendering();
+}
+void CPSPrinterDriver::SaveState()
+{
+ m_PSRenderer.SaveState();
+}
+void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved)
+{
+ m_PSRenderer.RestoreState(bKeepSaved);
+}
+FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device,
+ int fill_mode)
+{
+ m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode);
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState)
+{
+ m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState);
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState, FX_ARGB fill_color, FX_ARGB stroke_color,
+ int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode & 3, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect)
+{
+ *pRect = m_PSRenderer.GetClipBox();
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_width, dest_height, flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ if (bitmap_alpha < 255) {
+ return FALSE;
+ }
+ handle = NULL;
+ return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag, void* pIccTransform)
+{
+ return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, font_size, color, alpha_flag, pIccTransform);
+}
+#endif
diff --git a/core/src/fxge/win32/win32_int.h b/core/src/fxge/win32/win32_int.h
index 3f940eda1e..83595cbf8d 100644
--- a/core/src/fxge/win32/win32_int.h
+++ b/core/src/fxge/win32/win32_int.h
@@ -1,238 +1,238 @@
-// 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
-
-struct WINDIB_Open_Args_;
-class CGdiplusExt
-{
-public:
- CGdiplusExt();
- ~CGdiplusExt();
- void Load();
- FX_BOOL IsAvailable()
- {
- return m_hModule != NULL;
- }
- FX_BOOL StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags);
- FX_BOOL StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int flags);
- FX_BOOL DrawPath(HDC hDC, const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_argb,
- FX_DWORD stroke_argb,
- int fill_mode
- );
-
- void* LoadMemFont(FX_BYTE* pData, FX_DWORD size);
- void DeleteMemFont(void* pFontCollection);
- FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics);
- void GdipDeleteGraphics(void* graphics);
- void GdipSetTextRenderingHint(void* graphics, int mode);
- void GdipSetPageUnit(void* graphics, FX_DWORD unit);
- void GdipSetWorldTransform(void* graphics, void* pMatrix);
- FX_BOOL GdipDrawDriverString(void *graphics, unsigned short *text, int length, void *font, void* brush, void *positions, int flags, const void *matrix);
- void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush);
- void GdipDeleteBrush(void* pBrush);
- void GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix);
- void GdipDeleteMatrix(void* matrix);
- FX_BOOL GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily);
- void GdipDeleteFontFamily(void* pFamily);
- FX_BOOL GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont);
- void* GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle);
- void GdipDeleteFont(void* pFont);
- FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap);
- void GdipDisposeImage(void* bitmap);
- void GdipGetFontSize(void *pFont, FX_FLOAT *size);
- void* GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face);
- FX_BOOL GdiRemoveFontMemResourceEx(void* handle);
- void* m_Functions[100];
- void* m_pGdiAddFontMemResourceEx;
- void* m_pGdiRemoveFontMemResourseEx;
- CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);
-protected:
- HMODULE m_hModule;
- HMODULE m_GdiModule;
-};
-#include "dwrite_int.h"
-class CWin32Platform : public CFX_Object
-{
-public:
- FX_BOOL m_bHalfTone;
- CGdiplusExt m_GdiplusExt;
- CDWriteExt m_DWriteExt;
-};
-class CGdiDeviceDriver : public IFX_RenderDeviceDriver
-{
-protected:
- virtual int GetDeviceCaps(int caps_id);
- virtual void SaveState()
- {
- SaveDC(m_hDC);
- }
- virtual void RestoreState(FX_BOOL bKeepSaved = FALSE)
- {
- RestoreDC(m_hDC, -1);
- if (bKeepSaved) {
- SaveDC(m_hDC);
- }
- }
- virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- );
- virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- );
- virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- );
- virtual FX_BOOL FillRect(const FX_RECT* pRect,
- FX_DWORD fill_color,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_LPVOID GetClipRgn() ;
- virtual FX_BOOL SetClipRgn(FX_LPVOID pRgn) ;
- virtual FX_BOOL GetClipBox(FX_RECT* pRect);
- virtual FX_BOOL DeleteDeviceRgn(FX_LPVOID pRgn);
- virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
- virtual void* GetPlatformSurface()
- {
- return (void*)m_hDC;
- }
- FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, int left, int top,
- void* pIccTransform);
- FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD flags,
- void* pIccTransform);
- FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
- int alpha_flag, void* pIccTransform);
- HDC m_hDC;
- int m_Width, m_Height, m_nBitsPerPixel;
- int m_DeviceClass, m_RenderCaps;
- CGdiDeviceDriver(HDC hDC, int device_class);
- ~CGdiDeviceDriver() {}
-};
-class CGdiDisplayDriver : public CGdiDeviceDriver
-{
-public:
- CGdiDisplayDriver(HDC hDC);
-protected:
- virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
- {
- return FALSE;
- }
- FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
- int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
-};
-class CGdiPrinterDriver : public CGdiDeviceDriver
-{
-public:
- CGdiPrinterDriver(HDC hDC);
-protected:
- virtual int GetDeviceCaps(int caps_id);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type);
- int m_HorzSize, m_VertSize;
- FX_BOOL m_bSupportROP;
-};
-class CPSOutput : public IFX_PSOutput, public CFX_Object
-{
-public:
- CPSOutput(HDC hDC);
- virtual ~CPSOutput();
- virtual void Release()
- {
- delete this;
- }
- void Init();
- virtual void OutputPS(FX_LPCSTR string, int len);
- HDC m_hDC;
- FX_LPSTR m_pBuf;
-};
-class CPSPrinterDriver : public IFX_RenderDeviceDriver
-{
-public:
- CPSPrinterDriver();
- FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput);
- ~CPSPrinterDriver();
-protected:
- virtual FX_BOOL IsPSPrintDriver()
- {
- return TRUE;
- }
- virtual int GetDeviceCaps(int caps_id);
- virtual FX_BOOL StartRendering();
- virtual void EndRendering();
- virtual void SaveState();
- virtual void RestoreState(FX_BOOL bKeepSaved = FALSE);
- virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- );
- virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- );
- virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- );
- virtual FX_BOOL GetClipBox(FX_RECT* pRect);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag, void* pIccTransform);
- virtual void* GetPlatformSurface()
- {
- return (void*)m_hDC;
- }
- HDC m_hDC;
- FX_BOOL m_bCmykOutput;
- int m_Width, m_Height, m_nBitsPerPixel;
- int m_HorzSize, m_VertSize;
- CPSOutput* m_pPSOutput;
- CFX_PSRenderer m_PSRenderer;
-};
-void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform);
+// 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
+
+struct WINDIB_Open_Args_;
+class CGdiplusExt
+{
+public:
+ CGdiplusExt();
+ ~CGdiplusExt();
+ void Load();
+ FX_BOOL IsAvailable()
+ {
+ return m_hModule != NULL;
+ }
+ FX_BOOL StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags);
+ FX_BOOL StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int flags);
+ FX_BOOL DrawPath(HDC hDC, const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_argb,
+ FX_DWORD stroke_argb,
+ int fill_mode
+ );
+
+ void* LoadMemFont(FX_BYTE* pData, FX_DWORD size);
+ void DeleteMemFont(void* pFontCollection);
+ FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics);
+ void GdipDeleteGraphics(void* graphics);
+ void GdipSetTextRenderingHint(void* graphics, int mode);
+ void GdipSetPageUnit(void* graphics, FX_DWORD unit);
+ void GdipSetWorldTransform(void* graphics, void* pMatrix);
+ FX_BOOL GdipDrawDriverString(void *graphics, unsigned short *text, int length, void *font, void* brush, void *positions, int flags, const void *matrix);
+ void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush);
+ void GdipDeleteBrush(void* pBrush);
+ void GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix);
+ void GdipDeleteMatrix(void* matrix);
+ FX_BOOL GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily);
+ void GdipDeleteFontFamily(void* pFamily);
+ FX_BOOL GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont);
+ void* GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle);
+ void GdipDeleteFont(void* pFont);
+ FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap);
+ void GdipDisposeImage(void* bitmap);
+ void GdipGetFontSize(void *pFont, FX_FLOAT *size);
+ void* GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face);
+ FX_BOOL GdiRemoveFontMemResourceEx(void* handle);
+ void* m_Functions[100];
+ void* m_pGdiAddFontMemResourceEx;
+ void* m_pGdiRemoveFontMemResourseEx;
+ CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);
+protected:
+ HMODULE m_hModule;
+ HMODULE m_GdiModule;
+};
+#include "dwrite_int.h"
+class CWin32Platform : public CFX_Object
+{
+public:
+ FX_BOOL m_bHalfTone;
+ CGdiplusExt m_GdiplusExt;
+ CDWriteExt m_DWriteExt;
+};
+class CGdiDeviceDriver : public IFX_RenderDeviceDriver
+{
+protected:
+ virtual int GetDeviceCaps(int caps_id);
+ virtual void SaveState()
+ {
+ SaveDC(m_hDC);
+ }
+ virtual void RestoreState(FX_BOOL bKeepSaved = FALSE)
+ {
+ RestoreDC(m_hDC, -1);
+ if (bKeepSaved) {
+ SaveDC(m_hDC);
+ }
+ }
+ virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ );
+ virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ );
+ virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ );
+ virtual FX_BOOL FillRect(const FX_RECT* pRect,
+ FX_DWORD fill_color,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_LPVOID GetClipRgn() ;
+ virtual FX_BOOL SetClipRgn(FX_LPVOID pRgn) ;
+ virtual FX_BOOL GetClipBox(FX_RECT* pRect);
+ virtual FX_BOOL DeleteDeviceRgn(FX_LPVOID pRgn);
+ virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
+ virtual void* GetPlatformSurface()
+ {
+ return (void*)m_hDC;
+ }
+ FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, int left, int top,
+ void* pIccTransform);
+ FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD flags,
+ void* pIccTransform);
+ FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform);
+ HDC m_hDC;
+ int m_Width, m_Height, m_nBitsPerPixel;
+ int m_DeviceClass, m_RenderCaps;
+ CGdiDeviceDriver(HDC hDC, int device_class);
+ ~CGdiDeviceDriver() {}
+};
+class CGdiDisplayDriver : public CGdiDeviceDriver
+{
+public:
+ CGdiDisplayDriver(HDC hDC);
+protected:
+ virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+ {
+ return FALSE;
+ }
+ FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
+ int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
+};
+class CGdiPrinterDriver : public CGdiDeviceDriver
+{
+public:
+ CGdiPrinterDriver(HDC hDC);
+protected:
+ virtual int GetDeviceCaps(int caps_id);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ int m_HorzSize, m_VertSize;
+ FX_BOOL m_bSupportROP;
+};
+class CPSOutput : public IFX_PSOutput, public CFX_Object
+{
+public:
+ CPSOutput(HDC hDC);
+ virtual ~CPSOutput();
+ virtual void Release()
+ {
+ delete this;
+ }
+ void Init();
+ virtual void OutputPS(FX_LPCSTR string, int len);
+ HDC m_hDC;
+ FX_LPSTR m_pBuf;
+};
+class CPSPrinterDriver : public IFX_RenderDeviceDriver
+{
+public:
+ CPSPrinterDriver();
+ FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput);
+ ~CPSPrinterDriver();
+protected:
+ virtual FX_BOOL IsPSPrintDriver()
+ {
+ return TRUE;
+ }
+ virtual int GetDeviceCaps(int caps_id);
+ virtual FX_BOOL StartRendering();
+ virtual void EndRendering();
+ virtual void SaveState();
+ virtual void RestoreState(FX_BOOL bKeepSaved = FALSE);
+ virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ );
+ virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ );
+ virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ );
+ virtual FX_BOOL GetClipBox(FX_RECT* pRect);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag, void* pIccTransform);
+ virtual void* GetPlatformSurface()
+ {
+ return (void*)m_hDC;
+ }
+ HDC m_hDC;
+ FX_BOOL m_bCmykOutput;
+ int m_Width, m_Height, m_nBitsPerPixel;
+ int m_HorzSize, m_VertSize;
+ CPSOutput* m_pPSOutput;
+ CFX_PSRenderer m_PSRenderer;
+};
+void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform);