diff --git a/bin/Release/EasyHK32.dll b/bin/Release/EasyHK32.dll index b14402a..85d1501 100644 Binary files a/bin/Release/EasyHK32.dll and b/bin/Release/EasyHK32.dll differ diff --git a/bin/Release/EasyHK64.dll b/bin/Release/EasyHK64.dll index 0349363..154c944 100644 Binary files a/bin/Release/EasyHK64.dll and b/bin/Release/EasyHK64.dll differ diff --git a/ini/win7/UserParams.ini b/ini/win7/UserParams.ini index ac217a4..0cd8545 100644 Binary files a/ini/win7/UserParams.ini and b/ini/win7/UserParams.ini differ diff --git a/ini/win8.1 or later/UserParams.ini b/ini/win8.1 or later/UserParams.ini index 1252c5b..7a723f6 100644 Binary files a/ini/win8.1 or later/UserParams.ini and b/ini/win8.1 or later/UserParams.ini differ diff --git a/readmeEN.txt b/readmeEN.txt index 50e3c74..a47f1de 100644 --- a/readmeEN.txt +++ b/readmeEN.txt @@ -16,6 +16,8 @@ How to use Good Luck! Version History +2016/10/11 1.17 Bug fix for High DPI. + Add ForceNoHinting for Windows Vista or later. 2016/10/08 1.16 Bug fix. 2016/10/07 1.15 Bug fix and speed up. 2016/10/05 1.14 Bug fix for High DPI. diff --git a/readmeJP.txt b/readmeJP.txt index 3b6281f..16fe98e 100644 Binary files a/readmeJP.txt and b/readmeJP.txt differ diff --git a/resource32.rc b/resource32.rc index 635dc6e..6f3a21d 100644 --- a/resource32.rc +++ b/resource32.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,16,0,0 - PRODUCTVERSION 1,16,0,0 + FILEVERSION 1,17,0,0 + PRODUCTVERSION 1,17,0,0 FILEFLAGSMASK 0x0L #ifdef _DEBUG FILEFLAGS 0x1L @@ -31,12 +31,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MacTypePatch for DirectWrite Hook" - VALUE "FileVersion", "1.16.0.0" + VALUE "FileVersion", "1.17.0.0" VALUE "InternalName", "EasyHK32.dll" VALUE "LegalCopyright", "Copyright (C) 2016 silight" VALUE "OriginalFilename", "EasyHK32.dll" VALUE "ProductName", "MacTypePatch for DirectWrite Hook" - VALUE "ProductVersion", "1.16.0.0" + VALUE "ProductVersion", "1.17.0.0" END END BLOCK "VarFileInfo" diff --git a/resource64.rc b/resource64.rc index 0ea4c51..106d68c 100644 --- a/resource64.rc +++ b/resource64.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,16,0,0 - PRODUCTVERSION 1,16,0,0 + FILEVERSION 1,17,0,0 + PRODUCTVERSION 1,17,0,0 FILEFLAGSMASK 0x0L #ifdef _DEBUG FILEFLAGS 0x1L @@ -31,12 +31,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MacTypePatch for DirectWrite Hook" - VALUE "FileVersion", "1.16.0.0" + VALUE "FileVersion", "1.17.0.0" VALUE "InternalName", "EasyHK64.dll" VALUE "LegalCopyright", "Copyright (C) 2016 silight" VALUE "OriginalFilename", "EasyHK64.dll" VALUE "ProductName", "MacTypePatch for DirectWrite Hook" - VALUE "ProductVersion", "1.16.0.0" + VALUE "ProductVersion", "1.17.0.0" END END BLOCK "VarFileInfo" diff --git a/src/direct2d.cpp b/src/direct2d.cpp index 58988ee..a5fb5f5 100644 --- a/src/direct2d.cpp +++ b/src/direct2d.cpp @@ -104,6 +104,43 @@ namespace Impl_ID2D1Device4 } } +namespace Impl_ID2D1DeviceContext +{ + static void WINAPI DrawGlyphRun( + ID2D1DeviceContext *This, + D2D1_POINT_2F baselineOrigin, + CONST DWRITE_GLYPH_RUN *glyphRun, + CONST DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, + ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode + ) { + if (GeneralParams.ForceNoHinting) { + D2D1_MATRIX_3X2_F prev; + This->GetTransform(&prev); + D2D1_MATRIX_3X2_F rotate = prev; + rotate.m12 += 1.0f / 0xFFFF; + rotate.m21 += 1.0f / 0xFFFF; + This->SetTransform(&rotate); + This->DrawGlyphRun( + baselineOrigin, + glyphRun, + glyphRunDescription, + foregroundBrush, + measuringMode + ); + This->SetTransform(&prev); + } else { + This->DrawGlyphRun( + baselineOrigin, + glyphRun, + glyphRunDescription, + foregroundBrush, + measuringMode + ); + } + } +} + namespace Impl_ID2D1Factory { static HRESULT WINAPI CreateWicBitmapRenderTarget( @@ -285,7 +322,109 @@ namespace Impl_ID2D1RenderTarget } return hr; } - + + static void WINAPI DrawText( + ID2D1RenderTarget* This, + CONST WCHAR *string, + UINT32 stringLength, + IDWriteTextFormat *textFormat, + CONST D2D1_RECT_F *layoutRect, + ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options, + DWRITE_MEASURING_MODE measuringMode + ) { + if (GeneralParams.ForceNoHinting) { + D2D1_MATRIX_3X2_F prev; + This->GetTransform(&prev); + D2D1_MATRIX_3X2_F rotate = prev; + rotate.m12 += 1.0f / 0xFFFF; + rotate.m21 += 1.0f / 0xFFFF; + This->SetTransform(&rotate); + This->DrawText( + string, + stringLength, + textFormat, + layoutRect, + defaultForegroundBrush, + options, + measuringMode + ); + This->SetTransform(&prev); + } else { + This->DrawText( + string, + stringLength, + textFormat, + layoutRect, + defaultForegroundBrush, + options, + measuringMode + ); + } + } + + static void WINAPI DrawTextLayout( + ID2D1RenderTarget* This, + D2D1_POINT_2F origin, + IDWriteTextLayout *textLayout, + ID2D1Brush *defaultForegroundBrush, + D2D1_DRAW_TEXT_OPTIONS options + ) { + if (GeneralParams.ForceNoHinting) { + D2D1_MATRIX_3X2_F prev; + This->GetTransform(&prev); + D2D1_MATRIX_3X2_F rotate = prev; + rotate.m12 += 1.0f / 0xFFFF; + rotate.m21 += 1.0f / 0xFFFF; + This->SetTransform(&rotate); + This->DrawTextLayout( + origin, + textLayout, + defaultForegroundBrush, + options + ); + This->SetTransform(&prev); + } else { + This->DrawTextLayout( + origin, + textLayout, + defaultForegroundBrush, + options + ); + } + } + + static void WINAPI DrawGlyphRun( + ID2D1RenderTarget* This, + D2D1_POINT_2F baselineOrigin, + CONST DWRITE_GLYPH_RUN *glyphRun, + ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode + ) { + if (GeneralParams.ForceNoHinting) { + D2D1_MATRIX_3X2_F prev; + This->GetTransform(&prev); + D2D1_MATRIX_3X2_F rotate = prev; + rotate.m12 += 1.0f / 0xFFFF; + rotate.m21 += 1.0f / 0xFFFF; + This->SetTransform(&rotate); + This->DrawGlyphRun( + baselineOrigin, + glyphRun, + foregroundBrush, + measuringMode + ); + This->SetTransform(&prev); + } else { + This->DrawGlyphRun( + baselineOrigin, + glyphRun, + foregroundBrush, + measuringMode + ); + } + } + static void WINAPI SetTextAntialiasMode( ID2D1RenderTarget* This, D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode @@ -364,10 +503,18 @@ static void hookID2D1Factory5(ID2D1Factory5* pD2D1Factory5) { static void hookID2D1RenderTarget(ID2D1RenderTarget* pD2D1RenderTarget) { void** v = getVtbl(pD2D1RenderTarget); hook(v[12], Impl_ID2D1RenderTarget::CreateCompatibleRenderTarget); + hook(v[27], Impl_ID2D1RenderTarget::DrawText); + hook(v[28], Impl_ID2D1RenderTarget::DrawTextLayout); + hook(v[29], Impl_ID2D1RenderTarget::DrawGlyphRun); hook(v[34], Impl_ID2D1RenderTarget::SetTextAntialiasMode); hook(v[36], Impl_ID2D1RenderTarget::SetTextRenderingParams); } +static void hookID2D1DeviceContext(ID2D1DeviceContext* pD2D1DeviceContext) { + void** v = getVtbl(pD2D1DeviceContext); + hook(v[82], Impl_ID2D1DeviceContext::DrawGlyphRun); +} + static void hookID2D1DeviceIfStill(ID2D1Device* pD2D1Device) { @@ -395,6 +542,7 @@ static void hookID2D1DeviceContextIfStill2(ID2D1DeviceContext* pD2D1DeviceContex auto lock = globalMutex.getLock(); if (insertVtbl(vtbl)) { hookID2D1RenderTarget(pD2D1DeviceContext); + hookID2D1DeviceContext(pD2D1DeviceContext); } } @@ -419,6 +567,7 @@ static void hookID2D1DeviceContextIfStill(ID2D1DeviceContext* pD2D1DeviceContext auto lock = globalMutex.getLock(); if (insertVtbl(vtbl)) { hookID2D1RenderTarget(pD2D1DeviceContext); + hookID2D1DeviceContext(pD2D1DeviceContext); hookIfImplemented(pD2D1DeviceContext, hookID2D1RenderTargetIfStill2); ID2D1Factory* pD2D1Factory; diff --git a/src/directwrite.cpp b/src/directwrite.cpp index 6dd4aaf..3fa2485 100644 --- a/src/directwrite.cpp +++ b/src/directwrite.cpp @@ -28,15 +28,34 @@ namespace Impl_IDWriteBitmapRenderTarget ) { HRESULT hr = E_FAIL; if (FAILED(hr)) { - hr = This->DrawGlyphRun( - baselineOriginX, - baselineOriginY, - measuringMode, - glyphRun, - DirectWriteParams.getDWriteRenderingParams(), - textColor, - blackBoxRect - ); + if (GeneralParams.ForceNoHinting) { + DWRITE_MATRIX prev; + This->GetCurrentTransform(&prev); + DWRITE_MATRIX rotate = prev; + rotate.m12 += 1.0f / 0xFFFF; + rotate.m21 += 1.0f / 0xFFFF; + This->SetCurrentTransform(&rotate); + hr = This->DrawGlyphRun( + baselineOriginX, + baselineOriginY, + measuringMode, + glyphRun, + DirectWriteParams.getDWriteRenderingParams(), + textColor, + blackBoxRect + ); + This->SetCurrentTransform(&prev); + } else { + hr = This->DrawGlyphRun( + baselineOriginX, + baselineOriginY, + measuringMode, + glyphRun, + DirectWriteParams.getDWriteRenderingParams(), + textColor, + blackBoxRect + ); + } } if (FAILED(hr)) { hr = This->DrawGlyphRun( @@ -66,7 +85,7 @@ namespace Impl_IDWriteFactory } return hr; } - + static HRESULT WINAPI GetGdiInterop( IDWriteFactory* This, IDWriteGdiInterop** gdiInterop @@ -98,7 +117,11 @@ namespace Impl_IDWriteFactory if (transform) { m = *transform; m.m11 *= pixelsPerDip; + m.m12 *= pixelsPerDip; + m.m21 *= pixelsPerDip; m.m22 *= pixelsPerDip; + m.dx *= pixelsPerDip; + m.dy *= pixelsPerDip; } else { m.m11 = pixelsPerDip; m.m22 = pixelsPerDip; @@ -117,12 +140,23 @@ namespace Impl_IDWriteFactory f->Release(); } } - if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) { + DWRITE_MATRIX m; + DWRITE_MATRIX const* pm = transform; + if (GeneralParams.ForceNoHinting) { + if (transform) { + m = *transform; + m.m12 += 1.0f / 0xFFFF; + m.m21 += 1.0f / 0xFFFF; + } else { + m = { 1, 1.0f / 0xFFFF, 1.0f / 0xFFFF, 1 }; + } + pm = &m; + } hr = This->CreateGlyphRunAnalysis( glyphRun, pixelsPerDip, - transform, + pm, DirectWriteParams.RenderingMode, measuringMode, baselineOriginX, @@ -183,9 +217,21 @@ namespace Impl_IDWriteFactory2 } } if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE_ALIASED) { + DWRITE_MATRIX m; + DWRITE_MATRIX const* pm = transform; + if (GeneralParams.ForceNoHinting) { + if (transform) { + m = *transform; + m.m12 += 1.0f / 0xFFFF; + m.m21 += 1.0f / 0xFFFF; + } else { + m = { 1, 1.0f / 0xFFFF, 1.0f / 0xFFFF, 1 }; + } + pm = &m; + } hr = This->CreateGlyphRunAnalysis( glyphRun, - transform, + pm, DirectWriteParams.RenderingMode, measuringMode, DirectWriteParams.GridFitMode, @@ -231,9 +277,21 @@ namespace Impl_IDWriteFactory3 ) { HRESULT hr = E_FAIL; if (FAILED(hr) && renderingMode != DWRITE_RENDERING_MODE1_ALIASED) { + DWRITE_MATRIX m; + DWRITE_MATRIX const* pm = transform; + if (GeneralParams.ForceNoHinting) { + if (transform) { + m = *transform; + m.m12 += 1.0f / 0xFFFF; + m.m21 += 1.0f / 0xFFFF; + } else { + m = { 1, 1.0f / 0xFFFF, 1.0f / 0xFFFF, 1 }; + } + pm = &m; + } hr = This->CreateGlyphRunAnalysis( glyphRun, - transform, + pm, DirectWriteParams.RenderingMode1, measuringMode, DirectWriteParams.GridFitMode, @@ -317,7 +375,6 @@ namespace Impl_IDWriteGlyphRunAnalysis namespace Impl_IDWriteFontCollection { - static HRESULT WINAPI FindFamilyName( IDWriteFontCollection* This, WCHAR const* familyName, diff --git a/src/userparams.cpp b/src/userparams.cpp index 693709d..9bd1f35 100644 --- a/src/userparams.cpp +++ b/src/userparams.cpp @@ -39,6 +39,11 @@ static void loadGeneralParams(LPCWSTR path) { L"HookTarget", (int)GeneralParams.HookTarget, path); + GeneralParams.ForceNoHinting = 0 != GetPrivateProfileIntW( + L"General", + L"ForceNoHinting", + (int)GeneralParams.ForceNoHinting, + path); wchar_t exePath[_MAX_PATH]; GetModuleFileNameW(NULL, exePath, _MAX_PATH); diff --git a/src/userparams.h b/src/userparams.h index 760607c..819d5e2 100644 --- a/src/userparams.h +++ b/src/userparams.h @@ -14,12 +14,13 @@ enum class HookTargetEnum { struct _GeneralParams { HookTargetEnum HookTarget = HookTargetEnum::None; bool isHookTarget = false; + bool ForceNoHinting = false; }; extern void initDWriteRenderingParams(); struct RenderingParams { - FLOAT Gamma = 1.5f; + FLOAT Gamma = 1.8f; FLOAT EnhancedContrast = 1.0f; FLOAT ClearTypeLevel = 1.0f; DWRITE_PIXEL_GEOMETRY PixelGeometry = DWRITE_PIXEL_GEOMETRY_RGB;