mactype/directwrite.cpp
MacType 54f5576792 add directwrite/direct2d tweak support.
better windows version detection.
2016-08-12 10:14:45 +08:00

1097 lines
28 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "directwrite.h"
#include "settings.h"
#define SET_VAL(x, y) *(DWORD_PTR*)&(x) = *(DWORD_PTR*)&(y)
#define HOOK(obj, name, index) { \
SET_VAL(ORIG_##name, (*reinterpret_cast<void***>(obj.p))[index]); \
hook_demand_##name(false); \
};
struct Params {
D2D1_TEXT_ANTIALIAS_MODE AntialiasMode;
IDWriteRenderingParams *RenderingParams;
FLOAT Gamma;
FLOAT EnhancedContrast;
FLOAT ClearTypeLevel;
DWRITE_PIXEL_GEOMETRY PixelGeometry;
DWRITE_RENDERING_MODE RenderingMode;
FLOAT GrayscaleEnhancedContrast;
DWRITE_GRID_FIT_MODE GridFitMode;
DWRITE_RENDERING_MODE1 RenderingMode1;
};
Params g_D2DParams, g_D2DParamsLarge;
void HookFactory(ID2D1Factory* pD2D1Factory) {
{//factory
CComQIPtr<ID2D1Factory> ptr = pD2D1Factory;
HOOK(ptr, CreateWicBitmapRenderTarget, 13);
HOOK(ptr, CreateHwndRenderTarget, 14);
HOOK(ptr, CreateDxgiSurfaceRenderTarget, 15);
HOOK(ptr, CreateDCRenderTarget, 16);
}
{//factory1
CComPtr<ID2D1Factory1> ptr;
HRESULT hr = pD2D1Factory->QueryInterface(&ptr);
if (SUCCEEDED(hr)){
HOOK(ptr, CreateDevice1, 17);
}
}
{//factory2
CComPtr<ID2D1Factory2> ptr;
HRESULT hr = pD2D1Factory->QueryInterface(&ptr);
if (SUCCEEDED(hr)){
HOOK(ptr, CreateDevice2, 27);
}
}
{//factory3
CComPtr<ID2D1Factory3> ptr;
HRESULT hr = pD2D1Factory->QueryInterface(&ptr);
if (SUCCEEDED(hr)){
HOOK(ptr, CreateDevice3, 28);
}
}
}
void HookRenderTarget(ID2D1RenderTarget* pD2D1RenderTarget) {
CComQIPtr<ID2D1RenderTarget> ptr = pD2D1RenderTarget;
HOOK(ptr, CreateCompatibleRenderTarget, 12);
HOOK(ptr, SetTextAntialiasMode, 34);
HOOK(ptr, SetTextRenderingParams, 36);
ID2D1Factory* pD2D1Factory;
pD2D1RenderTarget->GetFactory(&pD2D1Factory);
HookFactory(pD2D1Factory);
pD2D1RenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT);
pD2D1RenderTarget->SetTextRenderingParams(g_D2DParams.RenderingParams);
}
void HookDevice(ID2D1Device* d2dDevice){
CComQIPtr<ID2D1Device> ptr = d2dDevice;
HOOK(ptr, CreateDeviceContext, 4);
CComPtr<ID2D1Device1> ptr2;
HRESULT hr = (d2dDevice)->QueryInterface(&ptr2);
if SUCCEEDED(hr) {
HOOK(ptr2, CreateDeviceContext2, 11);
}
CComPtr<ID2D1Device2> ptr3;
hr = (d2dDevice)->QueryInterface(&ptr3);
if SUCCEEDED(hr) {
HOOK(ptr2, CreateDeviceContext3, 12);
}
}
//DWrite hooks
HRESULT WINAPI IMPL_CreateGlyphRunAnalysis(
IDWriteFactory* This,
DWRITE_GLYPH_RUN const* glyphRun,
FLOAT pixelsPerDip,
DWRITE_MATRIX const* transform,
DWRITE_RENDERING_MODE renderingMode,
DWRITE_MEASURING_MODE measuringMode,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
IDWriteGlyphRunAnalysis** glyphRunAnalysis)
{
HRESULT hr = E_FAIL;
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) {
IDWriteFactory3* f;
hr = This->QueryInterface(&f);
if (SUCCEEDED(hr)) {
DWRITE_MATRIX m;
DWRITE_MATRIX const* pm = transform;
if (pm) {
m = *transform;
m.m11 *= pixelsPerDip;
m.m22 *= pixelsPerDip;
pm = &m;
}
hr = ORIG_CreateGlyphRunAnalysis3(
f,
glyphRun,
pm,
(DWRITE_RENDERING_MODE1)renderingMode,
measuringMode,
DWRITE_GRID_FIT_MODE_DEFAULT,
DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
f->Release();
}
}
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) {
IDWriteFactory2* f;
hr = This->QueryInterface(&f);
if (SUCCEEDED(hr)) {
DWRITE_MATRIX m;
DWRITE_MATRIX const* pm = transform;
if (pm) {
m = *transform;
m.m11 *= pixelsPerDip;
m.m22 *= pixelsPerDip;
pm = &m;
}
hr = ORIG_CreateGlyphRunAnalysis2(
f,
glyphRun,
pm,
renderingMode,
measuringMode,
DWRITE_GRID_FIT_MODE_DEFAULT,
DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
f->Release();
}
}
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) {
hr = ORIG_CreateGlyphRunAnalysis(
This,
glyphRun,
pixelsPerDip,
transform,
g_D2DParams.RenderingMode,
measuringMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (FAILED(hr)) {
hr = ORIG_CreateGlyphRunAnalysis(
This,
glyphRun,
pixelsPerDip,
transform,
renderingMode,
measuringMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
CComQIPtr<IDWriteGlyphRunAnalysis> ptr = *glyphRunAnalysis;
HOOK(ptr, GetAlphaBlendParams, 5);
}
}
return hr;
}
HRESULT WINAPI IMPL_GetGdiInterop(
IDWriteFactory* This,
IDWriteGdiInterop** gdiInterop
)
{
static bool loaded = false;
HRESULT hr = ORIG_GetGdiInterop(This, gdiInterop);
if (!loaded) {
loaded = true;
CComQIPtr<IDWriteGdiInterop> gdip = *gdiInterop;
HOOK(gdip, CreateBitmapRenderTarget, 7);
}
return hr;
}
HRESULT WINAPI IMPL_CreateBitmapRenderTarget(
IDWriteGdiInterop* This,
HDC hdc,
UINT32 width,
UINT32 height,
IDWriteBitmapRenderTarget** renderTarget
)
{
HRESULT hr = ORIG_CreateBitmapRenderTarget(
This,
hdc,
width,
height,
renderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
CComQIPtr<IDWriteBitmapRenderTarget> ptr = *renderTarget;
HOOK(ptr, DrawGlyphRun, 3);
}
}
return hr;
}
HRESULT WINAPI IMPL_GetAlphaBlendParams(
IDWriteGlyphRunAnalysis* This,
IDWriteRenderingParams* renderingParams,
FLOAT* blendGamma,
FLOAT* blendEnhancedContrast,
FLOAT* blendClearTypeLevel
)
{
HRESULT hr = E_FAIL;
if (FAILED(hr)) {
hr = ORIG_GetAlphaBlendParams(
This,
g_D2DParams.RenderingParams,
blendGamma,
blendEnhancedContrast,
blendClearTypeLevel
);
}
if (FAILED(hr)) {
hr = ORIG_GetAlphaBlendParams(
This,
renderingParams,
blendGamma,
blendEnhancedContrast,
blendClearTypeLevel
);
}
return hr;
}
HRESULT WINAPI IMPL_CreateGlyphRunAnalysis2(
IDWriteFactory2* This,
DWRITE_GLYPH_RUN const* glyphRun,
DWRITE_MATRIX const* transform,
DWRITE_RENDERING_MODE renderingMode,
DWRITE_MEASURING_MODE measuringMode,
DWRITE_GRID_FIT_MODE gridFitMode,
DWRITE_TEXT_ANTIALIAS_MODE antialiasMode,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
IDWriteGlyphRunAnalysis** glyphRunAnalysis
)
{
HRESULT hr = E_FAIL;
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) {
IDWriteFactory3* f;
hr = This->QueryInterface(&f);
if (SUCCEEDED(hr)) {
hr = ORIG_CreateGlyphRunAnalysis3(
f,
glyphRun,
transform,
(DWRITE_RENDERING_MODE1)renderingMode,
measuringMode,
gridFitMode,
antialiasMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
f->Release();
}
}
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) {
hr = ORIG_CreateGlyphRunAnalysis2(
This,
glyphRun,
transform,
g_D2DParams.RenderingMode,
measuringMode,
g_D2DParams.GridFitMode,
antialiasMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (FAILED(hr)) {
hr = ORIG_CreateGlyphRunAnalysis2(
This,
glyphRun,
transform,
renderingMode,
measuringMode,
gridFitMode,
antialiasMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
CComQIPtr<IDWriteGlyphRunAnalysis> ptr = *glyphRunAnalysis;
HOOK(ptr, GetAlphaBlendParams, 5);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateGlyphRunAnalysis3(
IDWriteFactory3* This,
DWRITE_GLYPH_RUN const* glyphRun,
DWRITE_MATRIX const* transform,
DWRITE_RENDERING_MODE1 renderingMode,
DWRITE_MEASURING_MODE measuringMode,
DWRITE_GRID_FIT_MODE gridFitMode,
DWRITE_TEXT_ANTIALIAS_MODE antialiasMode,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
IDWriteGlyphRunAnalysis** glyphRunAnalysis
)
{
HRESULT hr = E_FAIL;
if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE1_ALIASED) {
hr = ORIG_CreateGlyphRunAnalysis3(
This,
glyphRun,
transform,
g_D2DParams.RenderingMode1,
measuringMode,
g_D2DParams.GridFitMode,
antialiasMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (FAILED(hr)) {
hr = ORIG_CreateGlyphRunAnalysis3(
This,
glyphRun,
transform,
renderingMode,
measuringMode,
gridFitMode,
antialiasMode,
baselineOriginX,
baselineOriginY,
glyphRunAnalysis
);
}
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
CComQIPtr<IDWriteGlyphRunAnalysis> ptr = *glyphRunAnalysis;
HOOK(ptr, GetAlphaBlendParams, 5);
}
}
return hr;
}
//d2d1 hooks
HRESULT WINAPI IMPL_D2D1CreateDevice(
IDXGIDevice* dxgiDevice,
CONST D2D1_CREATION_PROPERTIES* creationProperties,
ID2D1Device** d2dDevice) {
HRESULT hr = ORIG_D2D1CreateDevice(
dxgiDevice,
creationProperties,
d2dDevice
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookDevice(*d2dDevice);
}
}
return hr;
}
HRESULT WINAPI IMPL_D2D1CreateDeviceContext(
IDXGISurface* dxgiSurface,
CONST D2D1_CREATION_PROPERTIES* creationProperties,
ID2D1DeviceContext** d2dDeviceContext){
HRESULT hr = ORIG_D2D1CreateDeviceContext(
dxgiSurface,
creationProperties,
d2dDeviceContext
);
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*d2dDeviceContext);
}
return hr;
}
HRESULT WINAPI IMPL_D2D1CreateFactory(
D2D1_FACTORY_TYPE factoryType,
REFIID riid,
const D2D1_FACTORY_OPTIONS* pFactoryOptions,
void** ppIFactory){
HRESULT hr = ORIG_D2D1CreateFactory(factoryType, riid, pFactoryOptions, ppIFactory);
if (SUCCEEDED(hr)) {
auto pUnknown = reinterpret_cast<IUnknown*>(*ppIFactory);
ID2D1Factory* pD2D1Factory;
HRESULT hr2 = pUnknown->QueryInterface(&pD2D1Factory);
if (SUCCEEDED(hr2)) {
HookFactory(pD2D1Factory);
pD2D1Factory->Release();
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateWicBitmapRenderTarget(
ID2D1Factory* This,
IWICBitmap* target,
const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties,
ID2D1RenderTarget** renderTarget
) {
HRESULT hr = ORIG_CreateWicBitmapRenderTarget(
This,
target,
renderTargetProperties,
renderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*renderTarget);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateHwndRenderTarget(
ID2D1Factory* This,
const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties,
const D2D1_HWND_RENDER_TARGET_PROPERTIES* hwndRenderTargetProperties,
ID2D1HwndRenderTarget** hwndRenderTarget
) {
HRESULT hr = ORIG_CreateHwndRenderTarget(
This,
renderTargetProperties,
hwndRenderTargetProperties,
hwndRenderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*hwndRenderTarget);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDxgiSurfaceRenderTarget(
ID2D1Factory* This,
IDXGISurface* dxgiSurface,
const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties,
ID2D1RenderTarget** renderTarget
) {
HRESULT hr = ORIG_CreateDxgiSurfaceRenderTarget(
This,
dxgiSurface,
renderTargetProperties,
renderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*renderTarget);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDCRenderTarget(
ID2D1Factory* This,
const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties,
ID2D1DCRenderTarget** dcRenderTarget
) {
HRESULT hr = ORIG_CreateDCRenderTarget(
This,
renderTargetProperties,
dcRenderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*dcRenderTarget);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateCompatibleRenderTarget(
ID2D1RenderTarget* This,
CONST D2D1_SIZE_F* desiredSize,
CONST D2D1_SIZE_U* desiredPixelSize,
CONST D2D1_PIXEL_FORMAT* desiredFormat,
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options,
ID2D1BitmapRenderTarget** bitmapRenderTarget
) {
HRESULT hr = ORIG_CreateCompatibleRenderTarget(
This,
desiredSize,
desiredPixelSize,
desiredFormat,
options,
bitmapRenderTarget
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*bitmapRenderTarget);
}
}
return hr;
}
void WINAPI IMPL_SetTextAntialiasMode(
ID2D1RenderTarget* This,
D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode
) {
ORIG_SetTextAntialiasMode(This, D2D1_TEXT_ANTIALIAS_MODE_DEFAULT);
}
void WINAPI IMPL_SetTextRenderingParams(
ID2D1RenderTarget* This,
_In_opt_ IDWriteRenderingParams* textRenderingParams
) {
ORIG_SetTextRenderingParams(This, g_D2DParams.RenderingParams);
}
HRESULT WINAPI IMPL_CreateDeviceContext(
ID2D1Device* This,
D2D1_DEVICE_CONTEXT_OPTIONS options,
ID2D1DeviceContext** deviceContext
) {
HRESULT hr = ORIG_CreateDeviceContext(
This,
options,
deviceContext
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*deviceContext);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDeviceContext2(
ID2D1Device1* This,
D2D1_DEVICE_CONTEXT_OPTIONS options,
ID2D1DeviceContext1** deviceContext1
) {
HRESULT hr = ORIG_CreateDeviceContext2(
This,
options,
deviceContext1
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*deviceContext1);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDeviceContext3(
ID2D1Device2* This,
D2D1_DEVICE_CONTEXT_OPTIONS options,
ID2D1DeviceContext2** deviceContext2
) {
HRESULT hr = ORIG_CreateDeviceContext3(
This,
options,
deviceContext2
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookRenderTarget(*deviceContext2);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDevice1(
ID2D1Factory1* This,
IDXGIDevice* dxgiDevice,
ID2D1Device** d2dDevice
) {
HRESULT hr = ORIG_CreateDevice1(
This,
dxgiDevice,
d2dDevice
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookDevice(*d2dDevice);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDevice2(
ID2D1Factory2* This,
IDXGIDevice* dxgiDevice,
ID2D1Device1** d2dDevice1
){
HRESULT hr = ORIG_CreateDevice2(
This,
dxgiDevice,
d2dDevice1
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookDevice(*d2dDevice1);
}
}
return hr;
}
HRESULT WINAPI IMPL_CreateDevice3(
ID2D1Factory3* This,
IDXGIDevice* dxgiDevice,
ID2D1Device2** d2dDevice2
){
HRESULT hr = ORIG_CreateDevice3(
This,
dxgiDevice,
d2dDevice2
);
if (SUCCEEDED(hr)) {
static bool loaded = false;
if (!loaded) {
loaded = true;
HookDevice(*d2dDevice2);
}
}
return hr;
}
bool MakeD2DParams(IDWriteFactory* dw_factory)
{
CComPtr<IDWriteRenderingParams> dwrpm;
if (FAILED(dw_factory->CreateRenderingParams(&dwrpm)))
return false;
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
//
g_D2DParams.Gamma = pSettings->GammaValue()*pSettings->GammaValue()>1.3 ? pSettings->GammaValue()*pSettings->GammaValue() / 2 : 0.7f;
g_D2DParams.EnhancedContrast = 0.5f;
g_D2DParams.ClearTypeLevel = 1.0f;
switch (pSettings->GetFontSettings().GetAntiAliasMode())
{
case 2:
case 4:
g_D2DParams.PixelGeometry = DWRITE_PIXEL_GEOMETRY_RGB;
break;
case 3:
case 5:
g_D2DParams.PixelGeometry = DWRITE_PIXEL_GEOMETRY_BGR;
break;
default:
g_D2DParams.PixelGeometry = DWRITE_PIXEL_GEOMETRY_FLAT;
}
g_D2DParams.AntialiasMode = (D2D1_TEXT_ANTIALIAS_MODE)D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
g_D2DParams.RenderingMode = (DWRITE_RENDERING_MODE)DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
g_D2DParams.GrayscaleEnhancedContrast = 0.5f;
g_D2DParams.GridFitMode = DWRITE_GRID_FIT_MODE_DISABLED;
g_D2DParams.RenderingMode1 = DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC;
DWORD dwVersion = GetVersion();
if (IsWindows8OrGreater()) { //optimized for win8/win10
g_D2DParams.GrayscaleEnhancedContrast = 1.0f;
g_D2DParams.EnhancedContrast = 1.0f;
}
IDWriteFactory3* dw3 = NULL;
IDWriteFactory2* dw2 = NULL;
IDWriteFactory1* dw1 = NULL;
IDWriteRenderingParams3* r3 = NULL;
IDWriteRenderingParams2* r2 = NULL;
IDWriteRenderingParams1* r1 = NULL;
HRESULT hr = dw_factory->QueryInterface(&dw3);
if SUCCEEDED(hr) {
hr = dw3->CreateCustomRenderingParams(
g_D2DParams.Gamma,
g_D2DParams.EnhancedContrast,
g_D2DParams.GrayscaleEnhancedContrast,
g_D2DParams.ClearTypeLevel,
g_D2DParams.PixelGeometry,
g_D2DParams.RenderingMode1,
g_D2DParams.GridFitMode,
&r3);
dw3->Release();
if SUCCEEDED(hr) {
g_D2DParams.RenderingParams = r3;
return true;
}
}
hr = dw_factory->QueryInterface(&dw2);
if SUCCEEDED(hr) {
hr = dw2->CreateCustomRenderingParams(
g_D2DParams.Gamma,
g_D2DParams.EnhancedContrast,
g_D2DParams.GrayscaleEnhancedContrast,
g_D2DParams.ClearTypeLevel,
g_D2DParams.PixelGeometry,
g_D2DParams.RenderingMode,
g_D2DParams.GridFitMode,
&r2);
dw2->Release();
if SUCCEEDED(hr) {
g_D2DParams.RenderingParams = r2;
return true;
}
}
hr = dw_factory->QueryInterface(&dw1);
if SUCCEEDED(hr) {
hr = dw1->CreateCustomRenderingParams(
g_D2DParams.Gamma,
g_D2DParams.EnhancedContrast,
g_D2DParams.GrayscaleEnhancedContrast,
g_D2DParams.ClearTypeLevel,
g_D2DParams.PixelGeometry,
g_D2DParams.RenderingMode,
&r1);
dw1->Release();
if SUCCEEDED(hr) {
g_D2DParams.RenderingParams = r1;
return true;
}
}
if (FAILED(dw_factory->CreateCustomRenderingParams(
g_D2DParams.Gamma,
g_D2DParams.EnhancedContrast,
g_D2DParams.ClearTypeLevel,
g_D2DParams.PixelGeometry,
g_D2DParams.RenderingMode,
&g_D2DParams.RenderingParams)))
return false;
return true;
}
/*
bool CreateFontFace(IDWriteGdiInterop* gdi, IDWriteFont*** dfont, LOGFONT* lf)
{
__try
{
gdi->CreateFontFromLOGFONT(lf, *dfont);
return true;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
}*/
/*
void WINAPI IMPL_SetTextRenderingParams(ID2D1RenderTarget* self, __in_opt IDWriteRenderingParams *textRenderingParams = NULL)
{
return ORIG_SetTextRenderingParams(self, g_D2DParamsLarge.RenderingParams);
}
void WINAPI IMPL_SetTextAntialiasMode(ID2D1RenderTarget* self, D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode)
{
return ORIG_SetTextAntialiasMode(self, g_D2DParamsLarge.AntialiasMode);
}*/
BOOL bDWLoaded = false, bD2D1Loaded = false;
IDWriteFactory* g_pDWriteFactory = NULL;
IDWriteGdiInterop* g_pGdiInterop = NULL;
bool hookD2D1() {
//MessageBox(NULL, L"HookD2D1", NULL, MB_OK);
if (InterlockedExchange((LONG*)&bD2D1Loaded, true)) return false;
}
#define FAILEXIT { /*CoUninitialize();*/ return false;}
bool hookDirectWrite(IUnknown ** factory) //<2F>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>hook
{
//CoInitialize(NULL);
//MessageBox(NULL, L"HookDW", NULL, MB_OK);
if (InterlockedExchange((LONG*)&bDWLoaded, true)) return false;
//dwrite 1
CComPtr<IDWriteFactory> pDWriteFactory;
HRESULT hr1 = (*factory)->QueryInterface(&pDWriteFactory);
if (FAILED(hr1)) FAILEXIT;
void** COM_DW1 = (*reinterpret_cast<void***>(pDWriteFactory.p));
*(DWORD_PTR*)&ORIG_GetGdiInterop = *(DWORD_PTR*)&COM_DW1[17];
*(DWORD_PTR*)&ORIG_CreateGlyphRunAnalysis = *(DWORD_PTR*)&COM_DW1[23];
hook_demand_GetGdiInterop();
hook_demand_CreateGlyphRunAnalysis();
//dwrite2
CComPtr<IDWriteFactory2> pDWriteFactory2;
HRESULT hr2 = (*factory)->QueryInterface(&pDWriteFactory2);
if (FAILED(hr2)) FAILEXIT;
void** COM_DW2 = (*reinterpret_cast<void***>(pDWriteFactory2.p));
*(DWORD_PTR*)&ORIG_CreateGlyphRunAnalysis2 = *(DWORD_PTR*)&COM_DW2[30];
hook_demand_CreateGlyphRunAnalysis2();
//dwrite3
CComPtr<IDWriteFactory3> pDWriteFactory3;
HRESULT hr3 = (*factory)->QueryInterface(&pDWriteFactory3);
if (FAILED(hr3)) FAILEXIT;
void** COM_DW3 = (*reinterpret_cast<void***>(pDWriteFactory3.p));
*(DWORD_PTR*)&ORIG_CreateGlyphRunAnalysis3 = *(DWORD_PTR*)&COM_DW3[31];
hook_demand_CreateGlyphRunAnalysis3();
return true;
/*
if (FAILED(g_pDWriteFactory->GetGdiInterop(&g_pGdiInterop))) FAILEXIT; //<2F>жϲ<D0B6><CFB2><EFBFBD>ȷ
if (!MakeD2DParams(g_pDWriteFactory)) FAILEXIT; //׼<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>õIJ<C3B5><C4B2><EFBFBD>
const D2D1_PIXEL_FORMAT format =D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
const D2D1_RENDER_TARGET_PROPERTIES properties =
D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, format, 0.0f,0.0f,D2D1_RENDER_TARGET_USAGE_NONE);
CComPtr<ID2D1DCRenderTarget>target;
if (FAILED(d2d_factory->CreateDCRenderTarget(&properties, &target))) FAILEXIT;
void* pDraw = (*reinterpret_cast<void***>(target.p))[29];
//void* pRenderParam = (*reinterpret_cast<void***>(target.p))[36];
//void* pAAParam = (*reinterpret_cast<void***>(target.p))[34];
*(DWORD_PTR*)&ORIG_DrawGlyphRun= *(DWORD_PTR*)&pDraw; //ǿ<>Ƹ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
//*(DWORD_PTR*)&ORIG_SetTextRenderingParams= *(DWORD_PTR*)&pRenderParam;
//*(DWORD_PTR*)&ORIG_SetTextAntialiasMode= *(DWORD_PTR*)&pAAParam;
hook_demand_DrawGlyphRun(); //<2F><><EFBFBD><EFBFBD>D2D hook
//hook_demand_SetTextAntialiasMode();
//hook_demand_SetTextRenderingParams();
void* pTextFormat = (*reinterpret_cast<void***>(g_pDWriteFactory))[15];
IDWriteFont * dfont = NULL;
IDWriteFontCollection * fontcollection = NULL;
IDWriteFontFamily* ffamily = NULL;
if (FAILED(g_pDWriteFactory->GetSystemFontCollection(&fontcollection, false))) FAILEXIT;
if (FAILED(fontcollection->GetFontFamily(0, &ffamily))) FAILEXIT;
if (FAILED(ffamily->GetFont(0, &dfont))) FAILEXIT;
ffamily->Release();
fontcollection->Release();
void* pCreateFontFace = (*reinterpret_cast<void***>(dfont))[13];
*(DWORD_PTR*)&ORIG_CreateTextFormat= *(DWORD_PTR*)&pTextFormat; //ǿ<>Ƹ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
*(DWORD_PTR*)&ORIG_CreateFontFace= *(DWORD_PTR*)&pCreateFontFace;
hook_demand_CreateTextFormat();
hook_demand_CreateFontFace();
dfont->Release();
return true;*/
}
void HookD2DDll()
{
typedef HRESULT (WINAPI *PFN_DWriteCreateFactory)(
_In_ DWRITE_FACTORY_TYPE factoryType,
_In_ REFIID iid,
_COM_Outptr_ IUnknown **factory
);
#ifdef DEBUG
MessageBox(0, L"HookD2DDll", NULL, MB_OK);
#endif
HMODULE d2d1 = LoadLibrary(_T("d2d1.dll"));
HMODULE dw = LoadLibrary(_T("dwrite.dll"));
void* D2D1Factory = GetProcAddress(d2d1, "D2D1CreateFactory");
void* D2D1Device = GetProcAddress(d2d1, "D2D1CreateDevice");
void* D2D1Context = GetProcAddress(d2d1, "D2D1CreateDeviceContext");
void* DWFactory = GetProcAddress(dw, "DWriteCreateFactory");
*(DWORD_PTR*)&ORIG_D2D1CreateFactory = (DWORD_PTR)D2D1Factory;
*(DWORD_PTR*)&ORIG_D2D1CreateDevice = (DWORD_PTR)D2D1Device;
*(DWORD_PTR*)&ORIG_D2D1CreateDeviceContext = (DWORD_PTR)D2D1Context;
*(DWORD_PTR*)&ORIG_DWriteCreateFactory = (DWORD_PTR)DWFactory;
if (DWFactory) {
hook_demand_DWriteCreateFactory();
}
if (D2D1Factory){
hook_demand_D2D1CreateFactory();
}
if (D2D1Device) {
hook_demand_D2D1CreateDevice();
}
if (D2D1Context) {
hook_demand_D2D1CreateDeviceContext();
}
if (dw) {
CComPtr<IDWriteFactory> pDWriteFactory;
PFN_DWriteCreateFactory(DWFactory)(DWRITE_FACTORY_TYPE_ISOLATED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&pDWriteFactory));
MakeD2DParams(pDWriteFactory);
}
}
/*
void HookGdiplus()
{
InitGdiplusFuncs();
//*(DWORD_PTR*)&ORIG_D2D1CreateFactory = (DWORD_PTR)D2D1Factory;
*(DWORD_PTR*)&ORIG_GdipDrawString = (DWORD_PTR)pfnGdipDrawString;
hook_demand_GdipDrawString();
}
GpStatus WINAPI IMPL_GdipDrawString(
GpGraphics *graphics,
GDIPCONST WCHAR *string,
INT length,
GDIPCONST GpFont *font,
GDIPCONST RectF *layoutRect,
GDIPCONST GpStringFormat *stringFormat,
GDIPCONST GpBrush *brush
)
{
#define GDIPEXEC ORIG_GdipDrawString(graphics, string, length, font, layoutRect, stringFormat, brush)
#define GDIPCHECK(x) if ((x)!=Ok) return GDIPEXEC
if (string)
{
HDC dc = NULL;
LOGFONTW lf = {0};
GpBrushType bt;
ARGB FontColor=0 ,bkColor = 0;
//GDIPLUS to gdi32 data preparation
GDIPCHECK(pfnGdipGetLogFontW((GpFont*)font, graphics, &lf));
GDIPCHECK(pfnGdipGetBrushType((GpBrush*)brush, &bt));
if (bt!=BrushTypeSolidColor) return GDIPEXEC; //only solid brush is supported by GDI32
GDIPCHECK(pfnGdipGetSolidFillColor((GpSolidFill*)brush, &FontColor));
if (FontColor>>24!=0xFF) return GDIPEXEC; //only transparent and Opaque is supported.
GDIPCHECK(pfnGdipGetDC(graphics, &dc));
HFONT ft = CreateFontIndirectW(&lf);
HFONT oldfont = SelectFont(dc, ft);
SetTextColor(dc, FontColor & 0x00FFFFFF);
SetBkMode(dc, TRANSPARENT);
RECT gdiRect = {ROUND(layoutRect->X), ROUND(layoutRect->Y), ROUND(layoutRect->X+layoutRect->Width), ROUND(layoutRect->Y+layoutRect->Height)};
DrawText(dc, string, length, &gdiRect, DT_WORDBREAK);
//ExtTextOutW(dc, gdiRect.left, gdiRect.top, 0, &gdiRect, string, wcslen(string), NULL);
SelectObject(dc, oldfont);
DeleteObject(ft);
pfnGdipReleaseDC(graphics, dc);
return Ok;
}
else
return ORIG_GdipDrawString(graphics, string, length, font, layoutRect, stringFormat, brush);
#undef GDIPCHECK
#undef GDIPEXEC
}
*/
HRESULT WINAPI IMPL_DWriteCreateFactory(__in DWRITE_FACTORY_TYPE factoryType,
__in REFIID iid,
__out IUnknown **factory)
{
HRESULT ret = ORIG_DWriteCreateFactory(factoryType, iid, factory);
if (!bDWLoaded && SUCCEEDED(ret))
hookDirectWrite(factory);
return ret;
}
HRESULT WINAPI IMPL_CreateFontFace(IDWriteFont* self,
__out IDWriteFontFace** fontFace)
{
HRESULT ret = ORIG_CreateFontFace(self, fontFace);
if (ret == S_OK)
{
LOGFONT lf = { 0 };
if (FAILED(g_pGdiInterop->ConvertFontFaceToLOGFONT(*fontFace, &lf)))
return ret;
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
if (pSettings->CopyForceFont(lf, lf))
{
IDWriteFont* writefont = NULL;
if (FAILED(g_pGdiInterop->CreateFontFromLOGFONT(&lf, &writefont)))
return ret;
(*fontFace)->Release();
writefont->CreateFontFace(fontFace);
writefont->Release();
}
}
return ret;
}
HRESULT WINAPI IMPL_CreateTextFormat(IDWriteFactory* self,
__in_z WCHAR const* fontFamilyName,
__maybenull IDWriteFontCollection* fontCollection,
DWRITE_FONT_WEIGHT fontWeight,
DWRITE_FONT_STYLE fontStyle,
DWRITE_FONT_STRETCH fontStretch,
FLOAT fontSize,
__in_z WCHAR const* localeName,
__out IDWriteTextFormat** textFormat)
{
LOGFONT lf = { 0 };
StringCchCopy(lf.lfFaceName, LF_FACESIZE, fontFamilyName);
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
if (pSettings->CopyForceFont(lf, lf))
return ORIG_CreateTextFormat(self, lf.lfFaceName, fontCollection, fontWeight, fontStyle, fontStretch, fontSize, localeName, textFormat);
else
return ORIG_CreateTextFormat(self, fontFamilyName, fontCollection, fontWeight, fontStyle, fontStretch, fontSize, localeName, textFormat);
}
HRESULT WINAPI IMPL_DrawGlyphRun(
IDWriteBitmapRenderTarget* This,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_MEASURING_MODE measuringMode,
DWRITE_GLYPH_RUN const* glyphRun,
IDWriteRenderingParams* renderingParams,
COLORREF textColor,
RECT* blackBoxRect)
{
HRESULT hr = E_FAIL;
if (FAILED(hr)) {
hr = ORIG_DrawGlyphRun(
This,
baselineOriginX,
baselineOriginY,
measuringMode,
glyphRun,
g_D2DParams.RenderingParams,
textColor,
blackBoxRect
);
}
if (FAILED(hr)) {
hr = ORIG_DrawGlyphRun(
This,
baselineOriginX,
baselineOriginY,
measuringMode,
glyphRun,
renderingParams,
textColor,
blackBoxRect
);
}
return hr;
}