├── dwmhook ├── FW1 │ ├── .gitkeep │ ├── FW1Precompiled.cpp │ ├── FW1CompileSettings.h │ ├── FW1Precompiled.h │ ├── CFW1ColorRGBA.cpp │ ├── CFW1TextGeometry.cpp │ ├── FW1FontWrapper.cpp │ ├── CFW1ColorRGBA.h │ ├── CFW1TextRenderer.cpp │ ├── CFW1TextGeometry.h │ ├── CFW1ColorRGBAInterface.cpp │ ├── CFW1GlyphVertexDrawerInterface.cpp │ ├── CFW1GlyphVertexDrawer.h │ ├── CFW1DWriteRenderTarget.h │ ├── CFW1StateSaver.h │ ├── CFW1Factory.cpp │ ├── CFW1Object.h │ ├── CFW1GlyphAtlas.h │ ├── CFW1GlyphRenderStates.h │ ├── CFW1GlyphAtlas.cpp │ ├── CFW1GlyphProvider.h │ ├── CFW1TextGeometryInterface.cpp │ ├── CFW1DWriteRenderTargetInterface.cpp │ ├── CFW1Factory.h │ ├── CFW1GlyphSheet.h │ ├── CFW1GlyphRenderStatesInterface.cpp │ ├── CFW1GlyphProviderInterface.cpp │ ├── CFW1FontWrapper.h │ ├── CFW1GlyphAtlasInterface.cpp │ ├── CFW1FontWrapper.cpp │ ├── CFW1TextRenderer.h │ ├── CFW1DWriteRenderTarget.cpp │ ├── CFW1StateSaver.cpp │ ├── CFW1TextRendererInterface.cpp │ ├── CFW1GlyphSheet.cpp │ ├── CFW1GlyphProvider.cpp │ ├── CFW1GlyphSheetInterface.cpp │ ├── CFW1GlyphVertexDrawer.cpp │ └── CFW1FontWrapperInterface.cpp ├── minhook.lib ├── minhook-debug.lib ├── dwmhook.vcxproj.user ├── includes.hpp ├── imgui │ ├── imgui_impl_dx11.h │ ├── imgui_impl_win32.h │ └── imconfig.h ├── save_state.hpp ├── render.hpp ├── save_state.cpp ├── dwmhook.vcxproj ├── MinHook.h ├── dwmhook.vcxproj.filters └── render.cpp ├── img ├── inj.jpg ├── type.jpg └── overlay.jpg ├── .gitignore ├── readme.md └── dwmhook.sln /dwmhook/FW1/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /img/inj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seiftnesse/DWM_Hook/HEAD/img/inj.jpg -------------------------------------------------------------------------------- /img/type.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seiftnesse/DWM_Hook/HEAD/img/type.jpg -------------------------------------------------------------------------------- /img/overlay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seiftnesse/DWM_Hook/HEAD/img/overlay.jpg -------------------------------------------------------------------------------- /dwmhook/minhook.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seiftnesse/DWM_Hook/HEAD/dwmhook/minhook.lib -------------------------------------------------------------------------------- /dwmhook/FW1/FW1Precompiled.cpp: -------------------------------------------------------------------------------- 1 | // FW1Precompiled.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | -------------------------------------------------------------------------------- /dwmhook/minhook-debug.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seiftnesse/DWM_Hook/HEAD/dwmhook/minhook-debug.lib -------------------------------------------------------------------------------- /dwmhook/dwmhook.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /dwmhook/FW1/FW1CompileSettings.h: -------------------------------------------------------------------------------- 1 | // FW1CompileSettings.h 2 | 3 | #ifndef IncludeGuard__FW1_FW1CompileSettings_h 4 | #define IncludeGuard__FW1_FW1CompileSettings_h 5 | 6 | 7 | // Define if building a DLL for the font-wrapper 8 | #define FW1_COMPILETODLL 9 | 10 | // Define to use LoadLibrary instead of linking to DLLs 11 | #define FW1_DELAYLOAD_DWRITE_DLL 12 | #define FW1_DELAYLOAD_D3DCOMPILER_XX_DLL 13 | 14 | 15 | #endif// IncludeGuard__FW1_FW1CompileSettings_h 16 | -------------------------------------------------------------------------------- /dwmhook/FW1/FW1Precompiled.h: -------------------------------------------------------------------------------- 1 | // FW1Precompiled.h 2 | 3 | #ifndef IncludeGuard__FW1_FW1Precompiled_h 4 | #define IncludeGuard__FW1_FW1Precompiled_h 5 | 6 | 7 | #define NOMINMAX 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "FW1CompileSettings.h" 21 | #include "FW1FontWrapper.h" 22 | 23 | 24 | #endif// IncludeGuard__FW1_FW1Precompiled_h 25 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1ColorRGBA.cpp: -------------------------------------------------------------------------------- 1 | // CFW1ColorRGBA.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1ColorRGBA.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Construct 12 | CFW1ColorRGBA::CFW1ColorRGBA() : 13 | m_color32(0xffffffff) 14 | { 15 | } 16 | 17 | 18 | // Destruct 19 | CFW1ColorRGBA::~CFW1ColorRGBA() { 20 | } 21 | 22 | 23 | // Init 24 | HRESULT CFW1ColorRGBA::initColor(IFW1Factory *pFW1Factory, UINT32 initialColor32) { 25 | HRESULT hResult = initBaseObject(pFW1Factory); 26 | if(FAILED(hResult)) 27 | return hResult; 28 | 29 | m_color32 = initialColor32; 30 | 31 | return S_OK; 32 | } 33 | 34 | 35 | }// namespace FW1FontWrapper 36 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextGeometry.cpp: -------------------------------------------------------------------------------- 1 | // CFW1TextGeometry.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1TextGeometry.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Construct 12 | CFW1TextGeometry::CFW1TextGeometry() : 13 | m_maxSheetIndex(0), 14 | m_sorted(false) 15 | { 16 | } 17 | 18 | 19 | // Destruct 20 | CFW1TextGeometry::~CFW1TextGeometry() { 21 | } 22 | 23 | 24 | // Init glyph provider 25 | HRESULT CFW1TextGeometry::initTextGeometry(IFW1Factory *pFW1Factory) { 26 | HRESULT hResult = initBaseObject(pFW1Factory); 27 | if(FAILED(hResult)) 28 | return hResult; 29 | 30 | return hResult; 31 | } 32 | 33 | 34 | }// namespace FW1FontWrapper 35 | -------------------------------------------------------------------------------- /dwmhook/FW1/FW1FontWrapper.cpp: -------------------------------------------------------------------------------- 1 | // FW1FontWrapper.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1Factory.h" 6 | 7 | #ifndef FW1_DELAYLOAD_DWRITE_DLL 8 | #pragma comment (lib, "DWrite.lib") 9 | #endif 10 | 11 | #ifndef FW1_DELAYLOAD_D3DCOMPILER_XX_DLL 12 | #pragma comment (lib, "DWrite.lib") 13 | #endif 14 | 15 | #ifdef FW1_COMPILETODLL 16 | #ifndef _M_X64 17 | #pragma comment (linker, "/EXPORT:FW1CreateFactory=_FW1CreateFactory@8,@1") 18 | #endif 19 | #endif 20 | 21 | 22 | // Create FW1 factory 23 | extern "C" HRESULT STDMETHODCALLTYPE FW1CreateFactory(UINT32 Version, IFW1Factory **ppFactory) { 24 | if(Version != FW1_VERSION) 25 | return E_FAIL; 26 | 27 | if(ppFactory == NULL) 28 | return E_INVALIDARG; 29 | 30 | FW1FontWrapper::CFW1Factory *pFactory = new FW1FontWrapper::CFW1Factory; 31 | HRESULT hResult = pFactory->initFactory(); 32 | if(FAILED(hResult)) { 33 | pFactory->Release(); 34 | } 35 | else { 36 | *ppFactory = pFactory; 37 | 38 | hResult = S_OK; 39 | } 40 | 41 | return hResult; 42 | } 43 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # DWM Overlay ...-1909 build Windows 10 2 | ## Improved from: [First](https://github.com/Rythorndoran/dwm-overlay) | [Second](https://github.com/armasm/dwmhook) 3 | 4 | **Pattern:** 5 | ```c++ 6 | auto dwRender = FindPattern("d2d1.dll", PBYTE("\x48\x8D\x05\x00\x00\x00\x00\x33\xED\x48\x8D\x71\x08"), "xxx????xxxxxx"); 7 | ``` 8 | 9 | **Change overlay font:** 10 | ```c++ 11 | pFontFactory->CreateFontWrapper(pD3DXDevice, L"Arial", &pFontWrapper); 12 | ``` 13 | ## You can use [Extreme Injector ](https://github.com/master131/ExtremeInjector/releases/tag/v3.7.3) 14 | 15 | ![injector](https://github.com/rlybasic/DWM_Hook/blob/main/img/inj.jpg) 16 | 17 | ![type](https://github.com/rlybasic/DWM_Hook/blob/main/img/type.jpg) 18 | 19 | ## Demonstration 20 | 21 | ![type](https://github.com/rlybasic/DWM_Hook/blob/main/img/overlay.jpg) 22 | 23 | ## To update pattern: 24 | 25 | ```c++ 26 | lea rax, ??_7DrawingContext@@6BIMILRefCount@@@ ; const DrawingContext::`vftable'{for `IMILRefCount'} 27 | xor ebp, ebp 28 | lea rsi, [rcx+8] 29 | mov [rcx], rax 30 | ``` 31 | -------------------------------------------------------------------------------- /dwmhook/includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace DirectX; 24 | 25 | #pragma comment( lib, "dxgi" ) 26 | #pragma comment( lib, "d2d1" ) 27 | #pragma comment( lib, "d3d11" ) 28 | #pragma comment( lib, "dcomp" ) 29 | #pragma comment( lib, "dwrite" ) 30 | #ifdef _DEBUG 31 | #pragma comment( lib, "minhook-debug.lib" ) 32 | #else 33 | #pragma comment( lib, "minhook.lib" ) 34 | #endif 35 | #pragma comment( lib, "d3dcompiler.lib" ) 36 | 37 | #define SAFE_RELEASE( p ) if( p ) { p->Release(); p = nullptr; } 38 | #define LOG_FILE_PATH "C:\\DWM_GAY.log" 39 | 40 | #include "MinHook.h" 41 | #include "save_state.hpp" -------------------------------------------------------------------------------- /dwmhook.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30104.148 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dwmhook", "dwmhook\dwmhook.vcxproj", "{BF574599-3CE2-4360-B229-D747272D45CF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BF574599-3CE2-4360-B229-D747272D45CF}.Debug|x64.ActiveCfg = Debug|x64 15 | {BF574599-3CE2-4360-B229-D747272D45CF}.Debug|x64.Build.0 = Debug|x64 16 | {BF574599-3CE2-4360-B229-D747272D45CF}.Release|x64.ActiveCfg = Release|x64 17 | {BF574599-3CE2-4360-B229-D747272D45CF}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {51E0A73F-C664-4A65-85CA-663F187C0F94} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1ColorRGBA.h: -------------------------------------------------------------------------------- 1 | // CFW1ColorRGBA.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1ColorRGBA 4 | #define IncludeGuard__FW1_CFW1ColorRGBA 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // A color 13 | class CFW1ColorRGBA : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1Color32 19 | virtual void STDMETHODCALLTYPE SetColor(UINT32 Color); 20 | virtual void STDMETHODCALLTYPE SetColor(FLOAT Red, FLOAT Green, FLOAT Blue, FLOAT Alpha); 21 | virtual void STDMETHODCALLTYPE SetColor(const FLOAT *pColor); 22 | virtual void STDMETHODCALLTYPE SetColor(const BYTE *pColor); 23 | 24 | virtual UINT32 STDMETHODCALLTYPE GetColor32(); 25 | 26 | // Public functions 27 | public: 28 | CFW1ColorRGBA(); 29 | 30 | HRESULT initColor(IFW1Factory *pFW1Factory, UINT32 initialColor32); 31 | 32 | // Internal functions 33 | private: 34 | virtual ~CFW1ColorRGBA(); 35 | 36 | // Internal data 37 | private: 38 | UINT32 m_color32; 39 | }; 40 | 41 | 42 | }// namespace FW1FontWrapper 43 | 44 | 45 | #endif// IncludeGuard__FW1_CFW1ColorRGBA 46 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextRenderer.cpp: -------------------------------------------------------------------------------- 1 | // CFW1TextRenderer.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1TextRenderer.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1TextRenderer::CFW1TextRenderer() : 15 | m_pGlyphProvider(NULL), 16 | 17 | m_currentFlags(0), 18 | m_currentColor(0xff000000), 19 | 20 | m_cachedGlyphMap(0), 21 | m_pCachedGlyphMapFontFace(NULL), 22 | m_cachedGlyphMapFontSize(0), 23 | 24 | m_pDWriteTextRendererProxy(0) 25 | { 26 | } 27 | 28 | 29 | // Destruct 30 | CFW1TextRenderer::~CFW1TextRenderer() { 31 | SAFE_RELEASE(m_pGlyphProvider); 32 | 33 | delete m_pDWriteTextRendererProxy; 34 | } 35 | 36 | 37 | // Init 38 | HRESULT CFW1TextRenderer::initTextRenderer( 39 | IFW1Factory *pFW1Factory, 40 | IFW1GlyphProvider *pGlyphProvider 41 | ) { 42 | HRESULT hResult = initBaseObject(pFW1Factory); 43 | if(FAILED(hResult)) 44 | return hResult; 45 | 46 | if(pGlyphProvider == NULL) 47 | return E_INVALIDARG; 48 | 49 | pGlyphProvider->AddRef(); 50 | m_pGlyphProvider = pGlyphProvider; 51 | 52 | m_pDWriteTextRendererProxy = new CDWriteTextRendererProxy(this); 53 | 54 | return S_OK; 55 | } 56 | 57 | 58 | }// namespace FW1FontWrapper 59 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextGeometry.h: -------------------------------------------------------------------------------- 1 | // CFW1TextGeometry.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1TextGeometry 4 | #define IncludeGuard__FW1_CFW1TextGeometry 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Vector of vertices with sorting per glyph sheet 13 | class CFW1TextGeometry : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1TextGeometry 19 | virtual void STDMETHODCALLTYPE Clear(); 20 | virtual void STDMETHODCALLTYPE AddGlyphVertex(const FW1_GLYPHVERTEX *pVertex); 21 | 22 | virtual FW1_VERTEXDATA STDMETHODCALLTYPE GetGlyphVerticesTemp(); 23 | 24 | // Public functions 25 | public: 26 | CFW1TextGeometry(); 27 | 28 | HRESULT initTextGeometry(IFW1Factory *pFW1Factory); 29 | 30 | // Internal functions 31 | private: 32 | virtual ~CFW1TextGeometry(); 33 | 34 | // Internal data 35 | private: 36 | std::vector m_vertices; 37 | std::vector m_sortedVertices; 38 | 39 | UINT m_maxSheetIndex; 40 | std::vector m_vertexCounts; 41 | std::vector m_vertexStartIndices; 42 | bool m_sorted; 43 | }; 44 | 45 | 46 | }// namespace FW1FontWrapper 47 | 48 | 49 | #endif// IncludeGuard__FW1_CFW1TextGeometry 50 | -------------------------------------------------------------------------------- /dwmhook/imgui/imgui_impl_dx11.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX11 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | #pragma once 14 | #include "imgui.h" // IMGUI_IMPL_API 15 | 16 | struct ID3D11Device; 17 | struct ID3D11DeviceContext; 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 22 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 23 | 24 | // Use if you want to reset your rendering device without losing Dear ImGui state. 25 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 26 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 27 | -------------------------------------------------------------------------------- /dwmhook/save_state.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class D3D11StateSaver 4 | { 5 | private: 6 | bool m_savedState; 7 | D3D_FEATURE_LEVEL m_featureLevel; 8 | ID3D11DeviceContext* m_pContext; 9 | D3D11_PRIMITIVE_TOPOLOGY m_primitiveTopology; 10 | ID3D11InputLayout* m_pInputLayout; 11 | ID3D11BlendState* m_pBlendState; 12 | float m_blendFactor[ 4 ]; 13 | UINT m_sampleMask; 14 | ID3D11DepthStencilState* m_pDepthStencilState; 15 | UINT m_stencilRef; 16 | ID3D11RasterizerState* m_pRasterizerState; 17 | ID3D11ShaderResourceView* m_pPSSRV; 18 | ID3D11SamplerState* m_pSamplerState; 19 | ID3D11VertexShader* m_pVS; 20 | ID3D11ClassInstance* m_pVSClassInstances[ 256 ]; 21 | UINT m_numVSClassInstances; 22 | ID3D11Buffer* m_pVSConstantBuffer; 23 | ID3D11GeometryShader* m_pGS; 24 | ID3D11ClassInstance* m_pGSClassInstances[ 256 ]; 25 | UINT m_numGSClassInstances; 26 | ID3D11Buffer* m_pGSConstantBuffer; 27 | ID3D11ShaderResourceView* m_pGSSRV; 28 | ID3D11PixelShader* m_pPS; 29 | ID3D11ClassInstance* m_pPSClassInstances[ 256 ]; 30 | UINT m_numPSClassInstances; 31 | ID3D11HullShader* m_pHS; 32 | ID3D11ClassInstance* m_pHSClassInstances[ 256 ]; 33 | UINT m_numHSClassInstances; 34 | ID3D11DomainShader* m_pDS; 35 | ID3D11ClassInstance* m_pDSClassInstances[ 256 ]; 36 | UINT m_numDSClassInstances; 37 | ID3D11Buffer* m_pVB; 38 | UINT m_vertexStride; 39 | UINT m_vertexOffset; 40 | ID3D11Buffer* m_pIndexBuffer; 41 | DXGI_FORMAT m_indexFormat; 42 | UINT m_indexOffset; 43 | 44 | D3D11StateSaver( const D3D11StateSaver& ); 45 | D3D11StateSaver& operator=( const D3D11StateSaver& ); 46 | 47 | public: 48 | D3D11StateSaver(); 49 | ~D3D11StateSaver(); 50 | 51 | HRESULT saveCurrentState( ID3D11DeviceContext* pContext ); 52 | HRESULT restoreSavedState(); 53 | void releaseSavedState(); 54 | }; -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1ColorRGBAInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1ColorRGBAInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1ColorRGBA.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1ColorRGBA::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1ColorRGBA))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Set the color 27 | void STDMETHODCALLTYPE CFW1ColorRGBA::SetColor(UINT32 Color) { 28 | m_color32 = Color; 29 | } 30 | 31 | 32 | // Set the color 33 | void STDMETHODCALLTYPE CFW1ColorRGBA::SetColor(FLOAT Red, FLOAT Green, FLOAT Blue, FLOAT Alpha) { 34 | UINT32 color32; 35 | BYTE *colorBytes = reinterpret_cast(&color32); 36 | colorBytes[0] = static_cast(Red * 255.0f + 0.5f); 37 | colorBytes[1] = static_cast(Green * 255.0f + 0.5f); 38 | colorBytes[2] = static_cast(Blue * 255.0f + 0.5f); 39 | colorBytes[3] = static_cast(Alpha * 255.0f + 0.5f); 40 | 41 | m_color32 = color32; 42 | } 43 | 44 | 45 | // Set the color 46 | void STDMETHODCALLTYPE CFW1ColorRGBA::SetColor(const FLOAT *pColor) { 47 | SetColor(pColor[0], pColor[1], pColor[2], pColor[3]); 48 | } 49 | 50 | 51 | // Set the color 52 | void STDMETHODCALLTYPE CFW1ColorRGBA::SetColor(const BYTE *pColor) { 53 | UINT32 color32; 54 | BYTE *colorBytes = reinterpret_cast(&color32); 55 | for(int i=0; i < 4; ++i) 56 | colorBytes[i] = pColor[i]; 57 | 58 | m_color32 = color32; 59 | } 60 | 61 | 62 | // Get the color 63 | UINT32 STDMETHODCALLTYPE CFW1ColorRGBA::GetColor32() { 64 | return m_color32; 65 | } 66 | 67 | 68 | }// namespace FW1FontWrapper 69 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphVertexDrawerInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphVertexDrawerInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphVertexDrawer.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1GlyphVertexDrawer::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1GlyphVertexDrawer))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Get the D3D11 device used by this vetex drawer 27 | HRESULT STDMETHODCALLTYPE CFW1GlyphVertexDrawer::GetDevice(ID3D11Device **ppDevice) { 28 | if(ppDevice == NULL) 29 | return E_INVALIDARG; 30 | 31 | m_pDevice->AddRef(); 32 | *ppDevice = m_pDevice; 33 | 34 | return S_OK; 35 | } 36 | 37 | 38 | // Draw vertices 39 | UINT STDMETHODCALLTYPE CFW1GlyphVertexDrawer::DrawVertices( 40 | ID3D11DeviceContext *pContext, 41 | IFW1GlyphAtlas *pGlyphAtlas, 42 | const FW1_VERTEXDATA *pVertexData, 43 | UINT Flags, 44 | UINT PreboundSheet 45 | ) { 46 | UINT stride; 47 | UINT offset = 0; 48 | 49 | if((Flags & FW1_NOGEOMETRYSHADER) == 0) 50 | stride = sizeof(FW1_GLYPHVERTEX); 51 | else { 52 | stride = sizeof(QuadVertex); 53 | if((Flags & FW1_BUFFERSPREPARED) == 0) 54 | pContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0); 55 | } 56 | if((Flags & FW1_BUFFERSPREPARED) == 0) 57 | pContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset); 58 | 59 | if((Flags & FW1_NOGEOMETRYSHADER) == 0) 60 | return drawVertices(pContext, pGlyphAtlas, pVertexData, PreboundSheet); 61 | else 62 | return drawGlyphsAsQuads(pContext, pGlyphAtlas, pVertexData, PreboundSheet); 63 | } 64 | 65 | 66 | }// namespace FW1FontWrapper 67 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphVertexDrawer.h: -------------------------------------------------------------------------------- 1 | // CFW1GlyphVertexDrawer.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1GlyphVertexDrawer 4 | #define IncludeGuard__FW1_CFW1GlyphVertexDrawer 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Draws glyph-vertices from system memory using a dynamic vertex buffer 13 | class CFW1GlyphVertexDrawer : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1GlyphVertexDrawer 19 | virtual HRESULT STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice); 20 | 21 | virtual UINT STDMETHODCALLTYPE DrawVertices( 22 | ID3D11DeviceContext *pContext, 23 | IFW1GlyphAtlas *pGlyphAtlas, 24 | const FW1_VERTEXDATA *pVertexData, 25 | UINT Flags, 26 | UINT PreboundSheet 27 | ); 28 | 29 | // Public functions 30 | public: 31 | CFW1GlyphVertexDrawer(); 32 | 33 | HRESULT initVertexDrawer(IFW1Factory *pFW1Factory, ID3D11Device *pDevice, UINT vertexBufferSize); 34 | 35 | // Internal types 36 | private: 37 | struct QuadVertex { 38 | FLOAT positionX; 39 | FLOAT positionY; 40 | FLOAT texCoordX; 41 | FLOAT texCoordY; 42 | UINT32 color; 43 | }; 44 | 45 | // Internal functions 46 | private: 47 | virtual ~CFW1GlyphVertexDrawer(); 48 | 49 | HRESULT createBuffers(); 50 | 51 | UINT drawVertices( 52 | ID3D11DeviceContext *pContext, 53 | IFW1GlyphAtlas *pGlyphAtlas, 54 | const FW1_VERTEXDATA *vertexData, 55 | UINT preboundSheet 56 | ); 57 | UINT drawGlyphsAsQuads( 58 | ID3D11DeviceContext *pContext, 59 | IFW1GlyphAtlas *pGlyphAtlas, 60 | const FW1_VERTEXDATA *vertexData, 61 | UINT preboundSheet 62 | ); 63 | 64 | // Internal data 65 | private: 66 | std::wstring m_lastError; 67 | 68 | ID3D11Device *m_pDevice; 69 | 70 | ID3D11Buffer *m_pVertexBuffer; 71 | ID3D11Buffer *m_pIndexBuffer; 72 | UINT m_vertexBufferSize; 73 | UINT m_maxIndexCount; 74 | }; 75 | 76 | 77 | }// namespace FW1FontWrapper 78 | 79 | 80 | #endif// IncludeGuard__FW1_CFW1GlyphVertexDrawer 81 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1DWriteRenderTarget.h: -------------------------------------------------------------------------------- 1 | // CFW1DWriteRenderTarget.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1DWriteRenderTarget 4 | #define IncludeGuard__FW1_CFW1DWriteRenderTarget 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Render target that provides pixels of one glyph-image at a time 13 | class CFW1DWriteRenderTarget : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1DWriteRenderTarget 19 | virtual HRESULT STDMETHODCALLTYPE DrawGlyphTemp( 20 | IDWriteFontFace *pFontFace, 21 | UINT16 GlyphIndex, 22 | FLOAT FontSize, 23 | DWRITE_RENDERING_MODE RenderingMode, 24 | DWRITE_MEASURING_MODE MeasuringMode, 25 | FW1_GLYPHIMAGEDATA *pOutData 26 | ); 27 | 28 | // Public functions 29 | public: 30 | CFW1DWriteRenderTarget(); 31 | 32 | HRESULT initRenderTarget( 33 | IFW1Factory *pFW1Factory, 34 | IDWriteFactory *pDWriteFactory, 35 | UINT renderTargetWidth, 36 | UINT renderTargetHeight 37 | ); 38 | 39 | // Internal types 40 | private: 41 | struct DWGlyphData { 42 | FLOAT offsetX; 43 | FLOAT offsetY; 44 | LONG maxWidth; 45 | LONG maxHeight; 46 | }; 47 | 48 | typedef std::map RenderingParamsMap; 49 | 50 | // Internal functions 51 | private: 52 | virtual ~CFW1DWriteRenderTarget(); 53 | 54 | HRESULT createRenderTarget(IDWriteFactory *pDWriteFactory); 55 | 56 | void initGlyphData( 57 | const DWRITE_FONT_METRICS *fontMetrics, 58 | const DWRITE_GLYPH_METRICS *glyphMetrics, 59 | FLOAT fontSize, 60 | DWGlyphData *outGlyphData 61 | ); 62 | 63 | // Internal data 64 | private: 65 | std::wstring m_lastError; 66 | 67 | IDWriteBitmapRenderTarget *m_pRenderTarget; 68 | HDC m_hDC; 69 | HBRUSH m_hBlackBrush; 70 | LPVOID m_bmBits; 71 | UINT m_bmWidthBytes; 72 | UINT m_bmBytesPixel; 73 | UINT m_renderTargetWidth; 74 | UINT m_renderTargetHeight; 75 | RenderingParamsMap m_renderingParams; 76 | }; 77 | 78 | 79 | }// namespace FW1FontWrapper 80 | 81 | 82 | #endif// IncludeGuard__FW1_CFW1DWriteRenderTarget 83 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1StateSaver.h: -------------------------------------------------------------------------------- 1 | // CFW1StateSaver.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1StateSaver 4 | #define IncludeGuard__FW1_CFW1StateSaver 5 | 6 | 7 | namespace FW1FontWrapper { 8 | 9 | 10 | // Saves all the states that can be changed when drawing a string 11 | class CFW1StateSaver { 12 | // Public functions 13 | public: 14 | CFW1StateSaver(); 15 | ~CFW1StateSaver(); 16 | 17 | HRESULT saveCurrentState(ID3D11DeviceContext *pContext); 18 | HRESULT restoreSavedState(); 19 | void releaseSavedState(); 20 | 21 | // Internal data 22 | private: 23 | bool m_savedState; 24 | D3D_FEATURE_LEVEL m_featureLevel; 25 | ID3D11DeviceContext *m_pContext; 26 | D3D11_PRIMITIVE_TOPOLOGY m_primitiveTopology; 27 | ID3D11InputLayout *m_pInputLayout; 28 | ID3D11BlendState *m_pBlendState; 29 | FLOAT m_blendFactor[4]; 30 | UINT m_sampleMask; 31 | ID3D11DepthStencilState *m_pDepthStencilState; 32 | UINT m_stencilRef; 33 | ID3D11RasterizerState *m_pRasterizerState; 34 | ID3D11ShaderResourceView *m_pPSSRV; 35 | ID3D11SamplerState *m_pSamplerState; 36 | ID3D11VertexShader *m_pVS; 37 | ID3D11ClassInstance *m_pVSClassInstances[256]; 38 | UINT m_numVSClassInstances; 39 | ID3D11Buffer *m_pVSConstantBuffer; 40 | ID3D11GeometryShader *m_pGS; 41 | ID3D11ClassInstance *m_pGSClassInstances[256]; 42 | UINT m_numGSClassInstances; 43 | ID3D11Buffer *m_pGSConstantBuffer; 44 | ID3D11ShaderResourceView *m_pGSSRV; 45 | ID3D11PixelShader *m_pPS; 46 | ID3D11ClassInstance *m_pPSClassInstances[256]; 47 | UINT m_numPSClassInstances; 48 | ID3D11HullShader *m_pHS; 49 | ID3D11ClassInstance *m_pHSClassInstances[256]; 50 | UINT m_numHSClassInstances; 51 | ID3D11DomainShader *m_pDS; 52 | ID3D11ClassInstance *m_pDSClassInstances[256]; 53 | UINT m_numDSClassInstances; 54 | ID3D11Buffer *m_pVB; 55 | UINT m_vertexStride; 56 | UINT m_vertexOffset; 57 | ID3D11Buffer *m_pIndexBuffer; 58 | DXGI_FORMAT m_indexFormat; 59 | UINT m_indexOffset; 60 | 61 | private: 62 | CFW1StateSaver(const CFW1StateSaver&); 63 | CFW1StateSaver& operator=(const CFW1StateSaver&); 64 | }; 65 | 66 | 67 | }// namespace FW1FontWrapper 68 | 69 | 70 | #endif// IncludeGuard__FW1_CFW1StateSaver 71 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1Factory.cpp: -------------------------------------------------------------------------------- 1 | // CFW1Factory.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1Factory.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Construct 12 | CFW1Factory::CFW1Factory() : 13 | m_cRefCount(1) 14 | { 15 | InitializeCriticalSection(&m_errorStringCriticalSection); 16 | } 17 | 18 | 19 | // Destruct 20 | CFW1Factory::~CFW1Factory() { 21 | DeleteCriticalSection(&m_errorStringCriticalSection); 22 | } 23 | 24 | 25 | // Init 26 | HRESULT CFW1Factory::initFactory() { 27 | return S_OK; 28 | } 29 | 30 | 31 | // Create a DWrite factory 32 | HRESULT CFW1Factory::createDWriteFactory(IDWriteFactory **ppDWriteFactory) { 33 | HRESULT hResult = E_FAIL; 34 | 35 | typedef HRESULT (WINAPI * PFN_DWRITECREATEFACTORY)(__in DWRITE_FACTORY_TYPE factoryType, __in REFIID iid, __out IUnknown **factory); 36 | PFN_DWRITECREATEFACTORY pfnDWriteCreateFactory = NULL; 37 | 38 | #ifdef FW1_DELAYLOAD_DWRITE_DLL 39 | HMODULE hDWriteLib = LoadLibrary(TEXT("DWrite.dll")); 40 | if(hDWriteLib == NULL) { 41 | DWORD dwErr = GetLastError(); 42 | dwErr; 43 | setErrorString(L"Failed to load DWrite.dll"); 44 | } 45 | else { 46 | pfnDWriteCreateFactory = 47 | reinterpret_cast(GetProcAddress(hDWriteLib, "DWriteCreateFactory")); 48 | if(pfnDWriteCreateFactory == NULL) { 49 | DWORD dwErr = GetLastError(); 50 | dwErr; 51 | setErrorString(L"Failed to load DWriteCreateFactory"); 52 | } 53 | } 54 | #else 55 | pfnDWriteCreateFactory = DWriteCreateFactory; 56 | #endif 57 | 58 | if(pfnDWriteCreateFactory != NULL) { 59 | IDWriteFactory *pDWriteFactory; 60 | 61 | hResult = pfnDWriteCreateFactory( 62 | DWRITE_FACTORY_TYPE_SHARED, 63 | __uuidof(IDWriteFactory), 64 | reinterpret_cast(&pDWriteFactory) 65 | ); 66 | if(FAILED(hResult)) { 67 | setErrorString(L"DWriteCreateFactory failed"); 68 | } 69 | else { 70 | *ppDWriteFactory = pDWriteFactory; 71 | 72 | hResult = S_OK; 73 | } 74 | } 75 | 76 | return hResult; 77 | } 78 | 79 | 80 | // Set error string 81 | void CFW1Factory::setErrorString(const wchar_t *str) { 82 | EnterCriticalSection(&m_errorStringCriticalSection); 83 | m_lastError = str; 84 | LeaveCriticalSection(&m_errorStringCriticalSection); 85 | } 86 | 87 | 88 | }// namespace FW1FontWrapper 89 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1Object.h: -------------------------------------------------------------------------------- 1 | // CFW1Object.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1Object 4 | #define IncludeGuard__FW1_CFW1Object 5 | 6 | 7 | namespace FW1FontWrapper { 8 | 9 | 10 | // Helper baseclass to avoid writing IUnknown and IFW1Object implementations once per class 11 | template 12 | class CFW1Object : public IBase { 13 | public: 14 | // IUnknown 15 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) = 0 { 16 | if(ppvObject == NULL) 17 | return E_INVALIDARG; 18 | 19 | if(IsEqualIID(riid, __uuidof(IUnknown))) { 20 | *ppvObject = static_cast(this); 21 | AddRef(); 22 | return S_OK; 23 | } 24 | else if(IsEqualIID(riid, __uuidof(IFW1Object))) { 25 | *ppvObject = static_cast(this); 26 | AddRef(); 27 | return S_OK; 28 | } 29 | 30 | *ppvObject = NULL; 31 | return E_NOINTERFACE; 32 | } 33 | 34 | virtual ULONG STDMETHODCALLTYPE AddRef() { 35 | return static_cast(InterlockedIncrement(reinterpret_cast(&m_cRefCount))); 36 | } 37 | 38 | virtual ULONG STDMETHODCALLTYPE Release() { 39 | ULONG newCount = static_cast(InterlockedDecrement(reinterpret_cast(&m_cRefCount))); 40 | 41 | if(newCount == 0) 42 | delete this; 43 | 44 | return newCount; 45 | } 46 | 47 | // IFW1Object 48 | virtual HRESULT STDMETHODCALLTYPE GetFactory(IFW1Factory **ppFW1Factory) { 49 | if(ppFW1Factory == NULL) 50 | return E_INVALIDARG; 51 | 52 | m_pFW1Factory->AddRef(); 53 | *ppFW1Factory = m_pFW1Factory; 54 | 55 | return S_OK; 56 | } 57 | 58 | // Internal functions 59 | protected: 60 | CFW1Object() : 61 | m_cRefCount(1), 62 | 63 | m_pFW1Factory(NULL) 64 | { 65 | } 66 | 67 | virtual ~CFW1Object() { 68 | if(m_pFW1Factory != NULL) 69 | m_pFW1Factory->Release(); 70 | } 71 | 72 | HRESULT initBaseObject(IFW1Factory *pFW1Factory) { 73 | if(pFW1Factory == NULL) 74 | return E_INVALIDARG; 75 | 76 | pFW1Factory->AddRef(); 77 | m_pFW1Factory = pFW1Factory; 78 | 79 | return S_OK; 80 | } 81 | 82 | // Internal data 83 | protected: 84 | IFW1Factory *m_pFW1Factory; 85 | 86 | private: 87 | ULONG m_cRefCount; 88 | 89 | private: 90 | CFW1Object(const CFW1Object&); 91 | CFW1Object& operator=(const CFW1Object&); 92 | }; 93 | 94 | 95 | }// namespace FW1FontWrapper 96 | 97 | 98 | #endif// IncludeGuard__FW1_CFW1Object 99 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphAtlas.h: -------------------------------------------------------------------------------- 1 | // CFW1GlyphAtlas.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1GlyphAtlas 4 | #define IncludeGuard__FW1_CFW1GlyphAtlas 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | class CFW1GlyphAtlas : public CFW1Object { 13 | // Interface 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1GlyphAtlas 19 | virtual HRESULT STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice); 20 | 21 | virtual UINT STDMETHODCALLTYPE GetTotalGlyphCount(); 22 | virtual UINT STDMETHODCALLTYPE GetSheetCount(); 23 | 24 | virtual HRESULT STDMETHODCALLTYPE GetSheet(UINT SheetIndex, IFW1GlyphSheet **ppGlyphSheet); 25 | 26 | virtual const FW1_GLYPHCOORDS* STDMETHODCALLTYPE GetGlyphCoords(UINT SheetIndex); 27 | virtual HRESULT STDMETHODCALLTYPE BindSheet(ID3D11DeviceContext *pContext, UINT SheetIndex, UINT Flags); 28 | 29 | virtual UINT STDMETHODCALLTYPE InsertGlyph( 30 | const FW1_GLYPHMETRICS *pGlyphMetrics, 31 | const void *pGlyphData, 32 | UINT RowPitch, 33 | UINT PixelStride 34 | ); 35 | virtual UINT STDMETHODCALLTYPE InsertSheet(IFW1GlyphSheet *pGlyphSheet); 36 | virtual void STDMETHODCALLTYPE Flush(ID3D11DeviceContext *pContext); 37 | 38 | // Public functions 39 | public: 40 | CFW1GlyphAtlas(); 41 | 42 | HRESULT initGlyphAtlas( 43 | IFW1Factory *pFW1Factory, 44 | ID3D11Device *pDevice, 45 | UINT sheetWidth, 46 | UINT sheetHeight, 47 | bool coordBuffer, 48 | bool allowOversizedTexture, 49 | UINT maxGlyphCountPerSheet, 50 | UINT mipLevelCount, 51 | UINT maxSheetCount 52 | ); 53 | 54 | // Internal functions 55 | private: 56 | virtual ~CFW1GlyphAtlas(); 57 | 58 | HRESULT createGlyphSheet(IFW1GlyphSheet **ppGlyphSheet); 59 | 60 | // Internal data 61 | private: 62 | ID3D11Device *m_pDevice; 63 | UINT m_sheetWidth; 64 | UINT m_sheetHeight; 65 | bool m_hardwareCoordBuffer; 66 | bool m_allowOversizedGlyph; 67 | UINT m_maxGlyphCount; 68 | UINT m_mipLevelCount; 69 | 70 | IFW1GlyphSheet **m_glyphSheets; 71 | UINT m_sheetCount; 72 | UINT m_maxSheetCount; 73 | UINT m_currentSheetIndex; 74 | UINT m_flushedSheetIndex; 75 | 76 | CRITICAL_SECTION m_glyphSheetsCriticalSection; 77 | }; 78 | 79 | 80 | }// namespace FW1FontWrapper 81 | 82 | 83 | #endif// IncludeGuard__FW1_CFW1GlyphAtlas 84 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphRenderStates.h: -------------------------------------------------------------------------------- 1 | // CFW1GlyphRenderStates.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1GlyphRenderStates 4 | #define IncludeGuard__FW1_CFW1GlyphRenderStates 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Shader etc. needed to draw glyphs 13 | class CFW1GlyphRenderStates : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1GlyphRenderStates 19 | virtual HRESULT STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice); 20 | 21 | virtual void STDMETHODCALLTYPE SetStates(ID3D11DeviceContext *pContext, UINT Flags); 22 | virtual void STDMETHODCALLTYPE UpdateShaderConstants( 23 | ID3D11DeviceContext *pContext, 24 | const FW1_RECTF *pClipRect, 25 | const FLOAT *pTransformMatrix 26 | ); 27 | virtual BOOL STDMETHODCALLTYPE HasGeometryShader(); 28 | 29 | // Public functions 30 | public: 31 | CFW1GlyphRenderStates(); 32 | 33 | HRESULT initRenderResources( 34 | IFW1Factory *pFW1Factory, 35 | ID3D11Device *pDevice, 36 | bool wantGeometryShader, 37 | bool anisotropicFiltering 38 | ); 39 | 40 | // Internal types 41 | private: 42 | struct ShaderConstants { 43 | FLOAT TransformMatrix[16]; 44 | FLOAT ClipRect[4]; 45 | }; 46 | 47 | // Internal functions 48 | private: 49 | virtual ~CFW1GlyphRenderStates(); 50 | 51 | HRESULT createQuadShaders(); 52 | HRESULT createGlyphShaders(); 53 | HRESULT createPixelShaders(); 54 | HRESULT createConstantBuffer(); 55 | HRESULT createRenderStates(bool anisotropicFiltering); 56 | 57 | // Internal data 58 | private: 59 | std::wstring m_lastError; 60 | 61 | pD3DCompile m_pfnD3DCompile; 62 | 63 | ID3D11Device *m_pDevice; 64 | D3D_FEATURE_LEVEL m_featureLevel; 65 | 66 | ID3D11VertexShader *m_pVertexShaderQuad; 67 | ID3D11VertexShader *m_pVertexShaderClipQuad; 68 | ID3D11InputLayout *m_pQuadInputLayout; 69 | 70 | ID3D11VertexShader *m_pVertexShaderPoint; 71 | ID3D11InputLayout *m_pPointInputLayout; 72 | ID3D11GeometryShader *m_pGeometryShaderPoint; 73 | ID3D11GeometryShader *m_pGeometryShaderClipPoint; 74 | bool m_hasGeometryShader; 75 | 76 | ID3D11PixelShader *m_pPixelShader; 77 | ID3D11PixelShader *m_pPixelShaderClip; 78 | 79 | ID3D11Buffer *m_pConstantBuffer; 80 | 81 | ID3D11BlendState *m_pBlendState; 82 | ID3D11SamplerState *m_pSamplerState; 83 | ID3D11RasterizerState *m_pRasterizerState; 84 | ID3D11DepthStencilState *m_pDepthStencilState; 85 | }; 86 | 87 | 88 | }// namespace FW1FontWrapper 89 | 90 | 91 | #endif// IncludeGuard__FW1_CFW1GlyphRenderStates 92 | -------------------------------------------------------------------------------- /dwmhook/imgui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 11 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 12 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 13 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 14 | 15 | #pragma once 16 | #include "imgui.h" // IMGUI_IMPL_API 17 | 18 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 19 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 20 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 21 | 22 | // Win32 message handler your application need to call. 23 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 24 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 25 | #if 0 26 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 27 | #endif 28 | 29 | // DPI-related helpers (optional) 30 | // - Use to enable DPI awareness without having to create an application manifest. 31 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 32 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 33 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 34 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 35 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 36 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 37 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 38 | 39 | // Transparency related helpers (optional) [experimental] 40 | // - Use to enable alpha compositing transparency with the desktop. 41 | // - Use together with e.g. clearing your framebuffer with zero-alpha. 42 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd 43 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphAtlas.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphAtlas.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphAtlas.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1GlyphAtlas::CFW1GlyphAtlas() : 15 | m_pDevice(NULL), 16 | m_sheetWidth(0), 17 | m_sheetHeight(0), 18 | m_hardwareCoordBuffer(false), 19 | m_allowOversizedGlyph(false), 20 | m_maxGlyphCount(0), 21 | m_mipLevelCount(0), 22 | 23 | m_glyphSheets(0), 24 | m_sheetCount(0), 25 | m_maxSheetCount(0), 26 | m_currentSheetIndex(0), 27 | m_flushedSheetIndex(0) 28 | { 29 | InitializeCriticalSection(&m_glyphSheetsCriticalSection); 30 | } 31 | 32 | 33 | // Destruct 34 | CFW1GlyphAtlas::~CFW1GlyphAtlas() { 35 | SAFE_RELEASE(m_pDevice); 36 | 37 | for(UINT i=0; i < m_sheetCount; ++i) 38 | m_glyphSheets[i]->Release(); 39 | delete[] m_glyphSheets; 40 | 41 | DeleteCriticalSection(&m_glyphSheetsCriticalSection); 42 | } 43 | 44 | 45 | // Init 46 | HRESULT CFW1GlyphAtlas::initGlyphAtlas( 47 | IFW1Factory *pFW1Factory, 48 | ID3D11Device *pDevice, 49 | UINT sheetWidth, 50 | UINT sheetHeight, 51 | bool coordBuffer, 52 | bool allowOversizedGlyph, 53 | UINT maxGlyphCount, 54 | UINT mipLevelCount, 55 | UINT maxSheetCount 56 | ) { 57 | HRESULT hResult = initBaseObject(pFW1Factory); 58 | if(FAILED(hResult)) 59 | return hResult; 60 | 61 | if(pDevice == NULL) 62 | return E_INVALIDARG; 63 | 64 | pDevice->AddRef(); 65 | m_pDevice = pDevice; 66 | 67 | m_sheetWidth = sheetWidth; 68 | m_sheetHeight = sheetHeight; 69 | m_hardwareCoordBuffer = coordBuffer; 70 | m_allowOversizedGlyph = allowOversizedGlyph; 71 | m_mipLevelCount = mipLevelCount; 72 | m_maxGlyphCount = maxGlyphCount; 73 | 74 | m_maxSheetCount = 4096; 75 | if(maxSheetCount > 0 && maxSheetCount < 655536) 76 | m_maxSheetCount = maxSheetCount; 77 | m_glyphSheets = new IFW1GlyphSheet* [m_maxSheetCount]; 78 | 79 | // Default glyph 80 | BYTE glyph0Pixels[256]; 81 | FillMemory(glyph0Pixels, 256, 0xff); 82 | 83 | FW1_GLYPHMETRICS glyph0Metrics; 84 | glyph0Metrics.OffsetX = 0.0f; 85 | glyph0Metrics.OffsetY = 0.0f; 86 | glyph0Metrics.Width = 16; 87 | glyph0Metrics.Height = 16; 88 | 89 | UINT glyph0 = InsertGlyph(&glyph0Metrics, glyph0Pixels, 16, 1); 90 | if(glyph0 == 0xffffffff) 91 | return E_FAIL; 92 | else 93 | return S_OK; 94 | } 95 | 96 | 97 | // Create new glyph sheet 98 | HRESULT CFW1GlyphAtlas::createGlyphSheet(IFW1GlyphSheet **ppGlyphSheet) { 99 | IFW1GlyphSheet *pGlyphSheet; 100 | HRESULT hResult = m_pFW1Factory->CreateGlyphSheet( 101 | m_pDevice, 102 | m_sheetWidth, 103 | m_sheetHeight, 104 | m_hardwareCoordBuffer, 105 | m_allowOversizedGlyph, 106 | m_maxGlyphCount, 107 | m_mipLevelCount, 108 | &pGlyphSheet 109 | ); 110 | if(FAILED(hResult)) { 111 | } 112 | else { 113 | *ppGlyphSheet = pGlyphSheet; 114 | 115 | hResult = S_OK; 116 | } 117 | 118 | return hResult; 119 | } 120 | 121 | 122 | }// namespace FW1FontWrapper 123 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphProvider.h: -------------------------------------------------------------------------------- 1 | // CFW1GlyphProvider.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1GlyphProvider 4 | #define IncludeGuard__FW1_CFW1GlyphProvider 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Fonts and glyphs-maps collection to match glyphs to images in a glyph-atlas 13 | class CFW1GlyphProvider : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1GlyphProvider 19 | virtual HRESULT STDMETHODCALLTYPE GetGlyphAtlas(IFW1GlyphAtlas **ppGlyphAtlas); 20 | virtual HRESULT STDMETHODCALLTYPE GetDWriteFactory(IDWriteFactory **ppDWriteFactory); 21 | virtual HRESULT STDMETHODCALLTYPE GetDWriteFontCollection(IDWriteFontCollection **ppFontCollection); 22 | 23 | virtual const void* STDMETHODCALLTYPE GetGlyphMapFromFont( 24 | IDWriteFontFace *pFontFace, 25 | FLOAT FontSize, 26 | UINT FontFlags 27 | ); 28 | virtual UINT STDMETHODCALLTYPE GetAtlasIdFromGlyphIndex( 29 | const void* pGlyphMap, 30 | UINT16 GlyphIndex, 31 | IDWriteFontFace *pFontFace, 32 | UINT FontFlags 33 | ); 34 | 35 | // Public functions 36 | public: 37 | CFW1GlyphProvider(); 38 | 39 | HRESULT initGlyphProvider( 40 | IFW1Factory *pFW1Factory, 41 | IFW1GlyphAtlas *pGlyphAtlas, 42 | IDWriteFactory *pDWriteFactory, 43 | IDWriteFontCollection *pFontCollection, 44 | UINT maxGlyphWidth, 45 | UINT maxGlyphHeight 46 | ); 47 | 48 | // Internal types 49 | private: 50 | struct GlyphMap { 51 | FLOAT fontSize; 52 | UINT fontFlags; 53 | 54 | UINT *glyphs; 55 | UINT glyphCount; 56 | }; 57 | 58 | struct FontInfo { 59 | IDWriteFontFace *pFontFace; 60 | std::wstring uniqueName; 61 | }; 62 | 63 | typedef std::pair > FontId; 64 | typedef std::map FontMap; 65 | 66 | FontId makeFontId(UINT fontIndex, UINT fontFlags, FLOAT fontSize) { 67 | UINT relevantFlags = (fontFlags & (FW1_ALIASED)); 68 | return std::make_pair(fontIndex, std::make_pair(relevantFlags, fontSize)); 69 | } 70 | 71 | // Internal functions 72 | private: 73 | virtual ~CFW1GlyphProvider(); 74 | 75 | UINT getFontIndexFromFontFace(IDWriteFontFace *pFontFace); 76 | std::wstring getUniqueNameFromFontFace(IDWriteFontFace *pFontFace); 77 | 78 | UINT insertNewGlyph(GlyphMap *glyphMap, UINT16 glyphIndex, IDWriteFontFace *pFontFace); 79 | 80 | // Internal data 81 | private: 82 | IFW1GlyphAtlas *m_pGlyphAtlas; 83 | 84 | IDWriteFactory *m_pDWriteFactory; 85 | UINT m_maxGlyphWidth; 86 | UINT m_maxGlyphHeight; 87 | std::stack m_glyphRenderTargets; 88 | 89 | IDWriteFontCollection *m_pFontCollection; 90 | std::vector m_fonts; 91 | 92 | FontMap m_fontMap; 93 | 94 | CRITICAL_SECTION m_renderTargetsCriticalSection; 95 | CRITICAL_SECTION m_glyphMapsCriticalSection; 96 | CRITICAL_SECTION m_fontsCriticalSection; 97 | CRITICAL_SECTION m_insertGlyphCriticalSection; 98 | }; 99 | 100 | 101 | }// namespace FW1FontWrapper 102 | 103 | 104 | #endif// IncludeGuard__FW1_CFW1GlyphProvider 105 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextGeometryInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1TextGeometryInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1TextGeometry.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1TextGeometry::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1TextGeometry))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Clear geometry 27 | void STDMETHODCALLTYPE CFW1TextGeometry::Clear() { 28 | m_vertices.clear(); 29 | m_maxSheetIndex = 0; 30 | 31 | m_sorted = false; 32 | } 33 | 34 | 35 | // Add a vertex 36 | void STDMETHODCALLTYPE CFW1TextGeometry::AddGlyphVertex(const FW1_GLYPHVERTEX *pVertex) { 37 | m_vertices.push_back(*pVertex); 38 | 39 | UINT sheetIndex = pVertex->GlyphIndex >> 16; 40 | m_maxSheetIndex = std::max(m_maxSheetIndex, sheetIndex); 41 | 42 | m_sorted = false; 43 | } 44 | 45 | 46 | // Get current glyph vertices 47 | FW1_VERTEXDATA STDMETHODCALLTYPE CFW1TextGeometry::GetGlyphVerticesTemp() { 48 | FW1_VERTEXDATA vertexData; 49 | 50 | if(!m_vertices.empty()) { 51 | UINT32 sheetCount = m_maxSheetIndex + 1; 52 | 53 | // Sort and prepare vertices 54 | if(!m_sorted) { 55 | m_sortedVertices.resize(m_vertices.size()); 56 | m_vertexCounts.resize(sheetCount); 57 | m_vertexStartIndices.resize(sheetCount); 58 | 59 | std::fill(m_vertexCounts.begin(), m_vertexCounts.end(), 0); 60 | 61 | UINT * const vertexCounts = &m_vertexCounts[0]; 62 | const FW1_GLYPHVERTEX * const vertices = &m_vertices[0]; 63 | const UINT32 vertexCount = static_cast(m_vertices.size()); 64 | 65 | for(UINT32 i=0; i < vertexCount; ++i) { 66 | UINT32 sheetIndex = vertices[i].GlyphIndex >> 16; 67 | 68 | ++vertexCounts[sheetIndex]; 69 | } 70 | 71 | UINT * const vertexStartIndices = &m_vertexStartIndices[0]; 72 | 73 | UINT currentStartIndex = 0; 74 | for(UINT32 i=0; i < sheetCount; ++i) { 75 | vertexStartIndices[i] = currentStartIndex; 76 | 77 | currentStartIndex += vertexCounts[i]; 78 | } 79 | 80 | FW1_GLYPHVERTEX * const sortedVertices = &m_sortedVertices[0]; 81 | 82 | for(UINT32 i=0; i < vertexCount; ++i) { 83 | const FW1_GLYPHVERTEX &vertex = vertices[i]; 84 | UINT32 sheetIndex = vertex.GlyphIndex >> 16; 85 | 86 | UINT &vertexIndex = vertexStartIndices[sheetIndex]; 87 | 88 | sortedVertices[vertexIndex] = vertex; 89 | sortedVertices[vertexIndex].GlyphIndex &= 0xffff; 90 | 91 | ++vertexIndex; 92 | } 93 | 94 | m_sorted = true; 95 | } 96 | 97 | vertexData.SheetCount = sheetCount; 98 | vertexData.pVertexCounts = &m_vertexCounts[0]; 99 | vertexData.TotalVertexCount = static_cast(m_vertices.size()); 100 | vertexData.pVertices = &m_sortedVertices[0]; 101 | } 102 | else { 103 | vertexData.SheetCount = 0; 104 | vertexData.pVertexCounts = 0; 105 | vertexData.TotalVertexCount = 0; 106 | vertexData.pVertices = 0; 107 | } 108 | 109 | return vertexData; 110 | } 111 | 112 | 113 | }// namespace FW1FontWrapper 114 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1DWriteRenderTargetInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1DWriteRenderTargetInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1DWriteRenderTarget.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1DWriteRenderTarget::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1DWriteRenderTarget))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Draw glyph to temporary storage 27 | HRESULT STDMETHODCALLTYPE CFW1DWriteRenderTarget::DrawGlyphTemp( 28 | IDWriteFontFace *pFontFace, 29 | UINT16 GlyphIndex, 30 | FLOAT FontSize, 31 | DWRITE_RENDERING_MODE RenderingMode, 32 | DWRITE_MEASURING_MODE MeasuringMode, 33 | FW1_GLYPHIMAGEDATA *pOutData 34 | ) { 35 | // Font metrics 36 | DWRITE_FONT_METRICS fontMetrics; 37 | pFontFace->GetMetrics(&fontMetrics); 38 | 39 | // Glyph metrics 40 | DWRITE_GLYPH_METRICS glyphMetrics; 41 | HRESULT hResult = pFontFace->GetDesignGlyphMetrics(&GlyphIndex, 1, &glyphMetrics, FALSE); 42 | if(FAILED(hResult)) 43 | return hResult; 44 | 45 | // Calculate pixel measurements 46 | DWGlyphData dwGlyphData; 47 | initGlyphData(&fontMetrics, &glyphMetrics, FontSize, &dwGlyphData); 48 | 49 | // Set up drawing 50 | FLOAT glyphAdvance = 0.0f; 51 | DWRITE_GLYPH_OFFSET glyphOffset = {0.0f, 0.0f}; 52 | 53 | DWRITE_GLYPH_RUN glyphRun; 54 | ZeroMemory(&glyphRun, sizeof(glyphRun)); 55 | glyphRun.fontFace = pFontFace; 56 | glyphRun.fontEmSize = FontSize; 57 | glyphRun.glyphCount = 1; 58 | glyphRun.glyphIndices = &GlyphIndex; 59 | glyphRun.glyphAdvances = &glyphAdvance; 60 | glyphRun.glyphOffsets = &glyphOffset; 61 | 62 | // Clear background 63 | RECT rect; 64 | SetRect(&rect, 0, 0, 2+dwGlyphData.maxWidth+5, 2+dwGlyphData.maxHeight+5); 65 | int iRet = FillRect(m_hDC, &rect, m_hBlackBrush); 66 | if(iRet == 0) { 67 | } 68 | 69 | // Rendering mode 70 | IDWriteRenderingParams *pRenderingParams; 71 | 72 | RenderingParamsMap::iterator it = m_renderingParams.find(RenderingMode); 73 | if(it != m_renderingParams.end()) 74 | pRenderingParams = it->second; 75 | else 76 | pRenderingParams = m_renderingParams.begin()->second; 77 | 78 | // Draw 79 | hResult = m_pRenderTarget->DrawGlyphRun( 80 | 2.0f - dwGlyphData.offsetX, 81 | 2.0f - dwGlyphData.offsetY, 82 | MeasuringMode, 83 | &glyphRun, 84 | pRenderingParams, 85 | RGB(255, 255, 255), 86 | &rect 87 | ); 88 | if(FAILED(hResult)) 89 | return hResult; 90 | 91 | // Clip to valid render target to avoid buffer overruns in case the glyph was too large 92 | rect.left = std::max(rect.left, 0L); 93 | rect.top = std::max(rect.top, 0L); 94 | rect.right = std::min(static_cast(m_renderTargetWidth), rect.right); 95 | rect.bottom = std::min(static_cast(m_renderTargetHeight), rect.bottom); 96 | 97 | // Return glyph data 98 | pOutData->Metrics.OffsetX = dwGlyphData.offsetX + static_cast(rect.left) - 2.0f; 99 | pOutData->Metrics.OffsetY = dwGlyphData.offsetY + static_cast(rect.top) - 2.0f; 100 | pOutData->Metrics.Width = static_cast(rect.right - rect.left); 101 | pOutData->Metrics.Height = static_cast(rect.bottom - rect.top); 102 | pOutData->pGlyphPixels = 103 | static_cast(m_bmBits) 104 | + rect.top * m_bmWidthBytes 105 | + rect.left * m_bmBytesPixel; 106 | pOutData->RowPitch = m_bmWidthBytes; 107 | pOutData->PixelStride = m_bmBytesPixel; 108 | 109 | return S_OK; 110 | } 111 | 112 | 113 | }// namespace FW1FontWrapper 114 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1Factory.h: -------------------------------------------------------------------------------- 1 | // CFW1Factory.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1Factory 4 | #define IncludeGuard__FW1_CFW1Factory 5 | 6 | 7 | namespace FW1FontWrapper { 8 | 9 | 10 | // Factory that creates FW1 objects 11 | class CFW1Factory : public IFW1Factory { 12 | public: 13 | // IUnknown 14 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 15 | virtual ULONG STDMETHODCALLTYPE AddRef(); 16 | virtual ULONG STDMETHODCALLTYPE Release(); 17 | 18 | // IFW1Factory 19 | virtual HRESULT STDMETHODCALLTYPE CreateFontWrapper( 20 | ID3D11Device *pDevice, 21 | LPCWSTR pszFontFamily, 22 | IFW1FontWrapper **ppFontWrapper 23 | ); 24 | virtual HRESULT STDMETHODCALLTYPE CreateFontWrapper( 25 | ID3D11Device *pDevice, 26 | IDWriteFactory *pDWriteFactory, 27 | const FW1_FONTWRAPPERCREATEPARAMS *pCreateParams, 28 | IFW1FontWrapper **ppFontWrapper 29 | ); 30 | virtual HRESULT STDMETHODCALLTYPE CreateFontWrapper( 31 | ID3D11Device *pDevice, 32 | IFW1GlyphAtlas *pGlyphAtlas, 33 | IFW1GlyphProvider *pGlyphProvider, 34 | IFW1GlyphVertexDrawer *pGlyphVertexDrawer, 35 | IFW1GlyphRenderStates *pGlyphRenderStates, 36 | IDWriteFactory *pDWriteFactory, 37 | const FW1_DWRITEFONTPARAMS *pDefaultFontParams, 38 | IFW1FontWrapper **ppFontWrapper 39 | ); 40 | virtual HRESULT STDMETHODCALLTYPE CreateGlyphVertexDrawer( 41 | ID3D11Device *pDevice, 42 | UINT VertexBufferSize, 43 | IFW1GlyphVertexDrawer **ppGlyphVertexDrawer 44 | ); 45 | virtual HRESULT STDMETHODCALLTYPE CreateGlyphRenderStates( 46 | ID3D11Device *pDevice, 47 | BOOL DisableGeometryShader, 48 | BOOL AnisotropicFiltering, 49 | IFW1GlyphRenderStates **ppGlyphRenderStates 50 | ); 51 | virtual HRESULT STDMETHODCALLTYPE CreateTextRenderer( 52 | IFW1GlyphProvider *pGlyphProvider, 53 | IFW1TextRenderer **ppTextRenderer 54 | ); 55 | virtual HRESULT STDMETHODCALLTYPE CreateTextGeometry( 56 | IFW1TextGeometry **ppTextGeometry 57 | ); 58 | virtual HRESULT STDMETHODCALLTYPE CreateGlyphProvider( 59 | IFW1GlyphAtlas *pGlyphAtlas, 60 | IDWriteFactory *pDWriteFactory, 61 | IDWriteFontCollection *pFontCollection, 62 | UINT MaxGlyphWidth, 63 | UINT MaxGlyphHeight, 64 | IFW1GlyphProvider **ppGlyphProvider 65 | ); 66 | virtual HRESULT STDMETHODCALLTYPE CreateDWriteRenderTarget( 67 | IDWriteFactory *pDWriteFactory, 68 | UINT RenderTargetWidth, 69 | UINT RenderTargetHeight, 70 | IFW1DWriteRenderTarget **ppRenderTarget 71 | ); 72 | virtual HRESULT STDMETHODCALLTYPE CreateGlyphAtlas( 73 | ID3D11Device *pDevice, 74 | UINT GlyphSheetWidth, 75 | UINT GlyphSheetHeight, 76 | BOOL HardwareCoordBuffer, 77 | BOOL AllowOversizedGlyph, 78 | UINT MaxGlyphCountPerSheet, 79 | UINT MipLevels, 80 | UINT MaxGlyphSheetCount, 81 | IFW1GlyphAtlas **ppGlyphAtlas 82 | ); 83 | virtual HRESULT STDMETHODCALLTYPE CreateGlyphSheet( 84 | ID3D11Device *pDevice, 85 | UINT GlyphSheetWidth, 86 | UINT GlyphSheetHeight, 87 | BOOL HardwareCoordBuffer, 88 | BOOL AllowOversizedGlyph, 89 | UINT MaxGlyphCount, 90 | UINT MipLevels, 91 | IFW1GlyphSheet **ppGlyphSheet 92 | ); 93 | virtual HRESULT STDMETHODCALLTYPE CreateColor( 94 | UINT32 Color, 95 | IFW1ColorRGBA **ppColor 96 | ); 97 | 98 | // Public functions 99 | public: 100 | CFW1Factory(); 101 | 102 | HRESULT initFactory(); 103 | 104 | // Internal functions 105 | private: 106 | virtual ~CFW1Factory(); 107 | 108 | HRESULT createDWriteFactory(IDWriteFactory **ppDWriteFactory); 109 | 110 | void setErrorString(const wchar_t *str); 111 | 112 | // Internal data 113 | private: 114 | ULONG m_cRefCount; 115 | 116 | std::wstring m_lastError; 117 | CRITICAL_SECTION m_errorStringCriticalSection; 118 | 119 | private: 120 | CFW1Factory(const CFW1Factory&); 121 | CFW1Factory& operator=(const CFW1Factory&); 122 | }; 123 | 124 | 125 | }// namespace FW1FontWrapper 126 | 127 | 128 | #endif// IncludeGuard__FW1_CFW1Factory 129 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphSheet.h: -------------------------------------------------------------------------------- 1 | // CFW1GlyphSheet.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1GlyphSheet 4 | #define IncludeGuard__FW1_CFW1GlyphSheet 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // A texture containing multiple glyphimages 13 | class CFW1GlyphSheet : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1GlyphSheet 19 | virtual HRESULT STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice); 20 | virtual void STDMETHODCALLTYPE GetDesc(FW1_GLYPHSHEETDESC *pDesc); 21 | 22 | virtual HRESULT STDMETHODCALLTYPE GetSheetTexture(ID3D11ShaderResourceView **ppSheetTextureSRV); 23 | virtual HRESULT STDMETHODCALLTYPE GetCoordBuffer(ID3D11ShaderResourceView **ppCoordBufferSRV); 24 | 25 | virtual const FW1_GLYPHCOORDS* STDMETHODCALLTYPE GetGlyphCoords(); 26 | virtual HRESULT STDMETHODCALLTYPE BindSheet(ID3D11DeviceContext *pContext, UINT Flags); 27 | 28 | virtual UINT STDMETHODCALLTYPE InsertGlyph( 29 | const FW1_GLYPHMETRICS *pGlyphMetrics, 30 | const void *pGlyphData, 31 | UINT RowPitch, 32 | UINT PixelStride 33 | ); 34 | virtual void STDMETHODCALLTYPE CloseSheet(); 35 | virtual void STDMETHODCALLTYPE Flush(ID3D11DeviceContext *pContext); 36 | 37 | // Public functions 38 | public: 39 | CFW1GlyphSheet(); 40 | 41 | HRESULT initGlyphSheet( 42 | IFW1Factory *pFW1Factory, 43 | ID3D11Device *pDevice, 44 | UINT sheetWidth, 45 | UINT sheetHeight, 46 | bool coordBuffer, 47 | bool allowOversizedGlyph, 48 | UINT maxGlyphCount, 49 | UINT mipLevelCount 50 | ); 51 | 52 | // Internal types 53 | private: 54 | struct RectUI { 55 | UINT left; 56 | UINT top; 57 | UINT right; 58 | UINT bottom; 59 | }; 60 | 61 | class HeightRange { 62 | public: 63 | HeightRange(UINT totalWidth); 64 | ~HeightRange(); 65 | 66 | UINT findMin(UINT width, UINT *outMin); 67 | void update(UINT startX, UINT width, UINT newHeight); 68 | 69 | private: 70 | HeightRange(); 71 | HeightRange(const HeightRange&); 72 | HeightRange& operator=(const HeightRange&); 73 | 74 | UINT findMax(UINT startX, UINT width); 75 | 76 | UINT *m_heights; 77 | UINT m_totalWidth; 78 | }; 79 | 80 | class CriticalSectionLock { 81 | public: 82 | CriticalSectionLock(LPCRITICAL_SECTION pCriticalSection) : m_pCriticalSection(pCriticalSection) { 83 | EnterCriticalSection(m_pCriticalSection); 84 | } 85 | ~CriticalSectionLock() { 86 | LeaveCriticalSection(m_pCriticalSection); 87 | } 88 | 89 | private: 90 | CriticalSectionLock(); 91 | CriticalSectionLock(const CriticalSectionLock&); 92 | CriticalSectionLock& operator=(const CriticalSectionLock&); 93 | 94 | LPCRITICAL_SECTION m_pCriticalSection; 95 | }; 96 | 97 | // Internal functions 98 | private: 99 | virtual ~CFW1GlyphSheet(); 100 | 101 | HRESULT createDeviceResources(); 102 | 103 | // Internal data 104 | private: 105 | std::wstring m_lastError; 106 | 107 | UINT m_sheetWidth; 108 | UINT m_sheetHeight; 109 | bool m_hardwareCoordBuffer; 110 | bool m_allowOversizedGlyph; 111 | UINT m_mipLevelCount; 112 | UINT m_alignWidth; 113 | 114 | UINT8 *m_textureData; 115 | FW1_GLYPHCOORDS *m_glyphCoords; 116 | UINT m_maxGlyphCount; 117 | UINT m_glyphCount; 118 | 119 | ID3D11Device *m_pDevice; 120 | 121 | ID3D11Texture2D *m_pTexture; 122 | ID3D11ShaderResourceView *m_pTextureSRV; 123 | ID3D11Buffer *m_pCoordBuffer; 124 | ID3D11ShaderResourceView *m_pCoordBufferSRV; 125 | 126 | bool m_closed; 127 | bool m_static; 128 | 129 | HeightRange *m_heightRange; 130 | 131 | UINT m_updatedGlyphCount; 132 | RectUI m_dirtyRect; 133 | CRITICAL_SECTION m_sheetCriticalSection; 134 | CRITICAL_SECTION m_flushCriticalSection; 135 | }; 136 | 137 | 138 | }// namespace FW1FontWrapper 139 | 140 | 141 | #endif// IncludeGuard__FW1_CFW1GlyphSheet 142 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphRenderStatesInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphRenderStatesInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphRenderStates.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1GlyphRenderStates::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1GlyphRenderStates))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Get the D3D11 device used by the render states 27 | HRESULT STDMETHODCALLTYPE CFW1GlyphRenderStates::GetDevice(ID3D11Device **ppDevice) { 28 | if(ppDevice == NULL) 29 | return E_INVALIDARG; 30 | 31 | m_pDevice->AddRef(); 32 | *ppDevice = m_pDevice; 33 | 34 | return S_OK; 35 | } 36 | 37 | 38 | // Set render states for glyph drawing 39 | void STDMETHODCALLTYPE CFW1GlyphRenderStates::SetStates(ID3D11DeviceContext *pContext, UINT Flags) { 40 | if(m_hasGeometryShader && ((Flags & FW1_NOGEOMETRYSHADER) == 0)) { 41 | // Point vertices with geometry shader 42 | pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); 43 | pContext->IASetInputLayout(m_pPointInputLayout); 44 | pContext->VSSetShader(m_pVertexShaderPoint, NULL, 0); 45 | if((Flags & FW1_CLIPRECT) != 0) 46 | pContext->GSSetShader(m_pGeometryShaderClipPoint, NULL, 0); 47 | else 48 | pContext->GSSetShader(m_pGeometryShaderPoint, NULL, 0); 49 | pContext->PSSetShader(m_pPixelShader, NULL, 0); 50 | pContext->GSSetConstantBuffers(0, 1, &m_pConstantBuffer); 51 | } 52 | else { 53 | // Quads constructed on the CPU 54 | pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 55 | pContext->IASetInputLayout(m_pQuadInputLayout); 56 | if((Flags & FW1_CLIPRECT) != 0) { 57 | pContext->VSSetShader(m_pVertexShaderClipQuad, NULL, 0); 58 | pContext->PSSetShader(m_pPixelShaderClip, NULL, 0); 59 | } 60 | else { 61 | pContext->VSSetShader(m_pVertexShaderQuad, NULL, 0); 62 | pContext->PSSetShader(m_pPixelShader, NULL, 0); 63 | } 64 | pContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer); 65 | 66 | if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0) 67 | pContext->GSSetShader(NULL, NULL, 0); 68 | } 69 | 70 | if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) { 71 | pContext->DSSetShader(NULL, NULL, 0); 72 | pContext->HSSetShader(NULL, NULL, 0); 73 | } 74 | 75 | pContext->OMSetBlendState(m_pBlendState, NULL, 0xffffffff); 76 | pContext->OMSetDepthStencilState(m_pDepthStencilState, 0); 77 | 78 | pContext->RSSetState(m_pRasterizerState); 79 | 80 | pContext->PSSetSamplers(0, 1, &m_pSamplerState); 81 | } 82 | 83 | 84 | // Update constant buffer 85 | void STDMETHODCALLTYPE CFW1GlyphRenderStates::UpdateShaderConstants( 86 | ID3D11DeviceContext *pContext, 87 | const FW1_RECTF *pClipRect, 88 | const FLOAT *pTransformMatrix 89 | ) { 90 | // Shader constants 91 | ShaderConstants constants; 92 | ZeroMemory(&constants, sizeof(constants)); 93 | 94 | // Transform matrix 95 | if(pTransformMatrix != NULL) 96 | CopyMemory(constants.TransformMatrix, pTransformMatrix, 16*sizeof(FLOAT)); 97 | else { 98 | // Get viewport size for orthographic transform 99 | FLOAT w = 512.0f; 100 | FLOAT h = 512.0f; 101 | 102 | D3D11_VIEWPORT vp; 103 | UINT nvp = 1; 104 | pContext->RSGetViewports(&nvp, &vp); 105 | if(nvp > 0) { 106 | if(vp.Width >= 1.0f && vp.Height >= 1.0f) { 107 | w = vp.Width; 108 | h = vp.Height; 109 | } 110 | } 111 | 112 | constants.TransformMatrix[0] = 2.0f / w; 113 | constants.TransformMatrix[12] = -1.0f; 114 | constants.TransformMatrix[5] = -2.0f / h; 115 | constants.TransformMatrix[13] = 1.0f; 116 | constants.TransformMatrix[10] = 1.0f; 117 | constants.TransformMatrix[15] = 1.0f; 118 | } 119 | 120 | // Clip rect 121 | if(pClipRect != NULL) { 122 | constants.ClipRect[0] = -pClipRect->Left; 123 | constants.ClipRect[1] = -pClipRect->Top; 124 | constants.ClipRect[2] = pClipRect->Right; 125 | constants.ClipRect[3] = pClipRect->Bottom; 126 | } 127 | else { 128 | constants.ClipRect[0] = FLT_MAX; 129 | constants.ClipRect[1] = FLT_MAX; 130 | constants.ClipRect[2] = FLT_MAX; 131 | constants.ClipRect[3] = FLT_MAX; 132 | } 133 | 134 | // Update constant buffer 135 | D3D11_MAPPED_SUBRESOURCE msr; 136 | HRESULT hResult = pContext->Map(m_pConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr); 137 | if(SUCCEEDED(hResult)) { 138 | CopyMemory(msr.pData, &constants, sizeof(constants)); 139 | 140 | pContext->Unmap(m_pConstantBuffer, 0); 141 | } 142 | } 143 | 144 | 145 | // Check for geometry shader 146 | BOOL STDMETHODCALLTYPE CFW1GlyphRenderStates::HasGeometryShader() { 147 | return (m_hasGeometryShader ? TRUE : FALSE); 148 | } 149 | 150 | 151 | }// namespace FW1FontWrapper 152 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphProviderInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphProviderInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphProvider.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1GlyphProvider::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1GlyphProvider))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Get glyph atlas 27 | HRESULT STDMETHODCALLTYPE CFW1GlyphProvider::GetGlyphAtlas(IFW1GlyphAtlas **ppGlyphAtlas) { 28 | if(ppGlyphAtlas == NULL) 29 | return E_INVALIDARG; 30 | 31 | m_pGlyphAtlas->AddRef(); 32 | *ppGlyphAtlas = m_pGlyphAtlas; 33 | 34 | return S_OK; 35 | } 36 | 37 | 38 | // Get DWrite factory 39 | HRESULT STDMETHODCALLTYPE CFW1GlyphProvider::GetDWriteFactory(IDWriteFactory **ppDWriteFactory) { 40 | if(ppDWriteFactory == NULL) 41 | return E_INVALIDARG; 42 | 43 | m_pDWriteFactory->AddRef(); 44 | *ppDWriteFactory = m_pDWriteFactory; 45 | 46 | return S_OK; 47 | } 48 | 49 | 50 | // Get DWrite font collection 51 | HRESULT STDMETHODCALLTYPE CFW1GlyphProvider::GetDWriteFontCollection(IDWriteFontCollection **ppFontCollection) { 52 | if(ppFontCollection == NULL) 53 | return E_INVALIDARG; 54 | 55 | m_pFontCollection->AddRef(); 56 | *ppFontCollection = m_pFontCollection; 57 | 58 | return S_OK; 59 | } 60 | 61 | 62 | // Get glyph map 63 | const void* STDMETHODCALLTYPE CFW1GlyphProvider::GetGlyphMapFromFont( 64 | IDWriteFontFace *pFontFace, 65 | FLOAT FontSize, 66 | UINT FontFlags 67 | ) { 68 | // Get font id 69 | UINT fontIndex = getFontIndexFromFontFace(pFontFace); 70 | FontId fontId = makeFontId(fontIndex, FontFlags, FontSize); 71 | 72 | const void *glyphMap = 0; 73 | 74 | // Get the glyph-map 75 | EnterCriticalSection(&m_glyphMapsCriticalSection); 76 | FontMap::iterator it = m_fontMap.find(fontId); 77 | if(it != m_fontMap.end()) 78 | glyphMap = (*it).second; 79 | LeaveCriticalSection(&m_glyphMapsCriticalSection); 80 | 81 | if(glyphMap == 0 && (FontFlags & FW1_NONEWGLYPHS) == 0) { 82 | // Create a new glyph-map 83 | GlyphMap *newGlyphMap = new GlyphMap; 84 | newGlyphMap->fontSize = FontSize; 85 | newGlyphMap->fontFlags = FontFlags; 86 | newGlyphMap->glyphCount = pFontFace->GetGlyphCount(); 87 | newGlyphMap->glyphs = new UINT[newGlyphMap->glyphCount]; 88 | for(UINT i=0; i < newGlyphMap->glyphCount; ++i) 89 | newGlyphMap->glyphs[i] = 0xffffffff; 90 | 91 | bool needless = false; 92 | 93 | // Inert the new glyph-map and map the font-id to its index 94 | EnterCriticalSection(&m_glyphMapsCriticalSection); 95 | 96 | it = m_fontMap.find(fontId); 97 | if(it != m_fontMap.end()) { 98 | glyphMap = (*it).second; 99 | needless = true; 100 | } 101 | else { 102 | m_fontMap.insert(std::make_pair(fontId, newGlyphMap)); 103 | glyphMap = newGlyphMap; 104 | } 105 | 106 | LeaveCriticalSection(&m_glyphMapsCriticalSection); 107 | 108 | if(needless) {// Simultaneous creation on two threads 109 | delete[] newGlyphMap->glyphs; 110 | delete newGlyphMap; 111 | } 112 | else { 113 | UINT glyphAtlasId = insertNewGlyph(newGlyphMap, 0, pFontFace); 114 | glyphAtlasId; 115 | } 116 | } 117 | 118 | return glyphMap; 119 | } 120 | 121 | 122 | // Get atlas id of a glyph 123 | UINT STDMETHODCALLTYPE CFW1GlyphProvider::GetAtlasIdFromGlyphIndex( 124 | const void *pGlyphMap, 125 | UINT16 GlyphIndex, 126 | IDWriteFontFace *pFontFace, 127 | UINT FontFlags 128 | ) { 129 | GlyphMap *glyphMap = static_cast(const_cast(pGlyphMap)); 130 | 131 | if(glyphMap == 0) 132 | return 0; 133 | 134 | if(GlyphIndex >= glyphMap->glyphCount) 135 | return 0; 136 | 137 | // Get the atlas id for this glyph 138 | UINT glyphAtlasId = glyphMap->glyphs[GlyphIndex]; 139 | if(glyphAtlasId == 0xffffffff && (FontFlags & FW1_NONEWGLYPHS) == 0) 140 | glyphAtlasId = insertNewGlyph(glyphMap, GlyphIndex, pFontFace); 141 | 142 | // Fall back to the font default-glyph or the atlas default-glyph on failure 143 | if(glyphAtlasId == 0xffffffff) { 144 | glyphAtlasId = glyphMap->glyphs[0]; 145 | 146 | if((FontFlags & FW1_NONEWGLYPHS) == 0) { 147 | if(glyphAtlasId == 0xffffffff) { 148 | if(GlyphIndex == 0) 149 | glyphAtlasId = 0; 150 | else 151 | glyphAtlasId = GetAtlasIdFromGlyphIndex(pGlyphMap, 0, pFontFace, FontFlags); 152 | } 153 | 154 | EnterCriticalSection(&m_insertGlyphCriticalSection); 155 | if(glyphMap->glyphs[GlyphIndex] == 0xffffffff) 156 | glyphMap->glyphs[GlyphIndex] = glyphAtlasId; 157 | LeaveCriticalSection(&m_insertGlyphCriticalSection); 158 | } 159 | 160 | if(glyphAtlasId == 0xffffffff) 161 | glyphAtlasId = 0; 162 | } 163 | 164 | return glyphAtlasId; 165 | } 166 | 167 | 168 | }// namespace FW1FontWrapper 169 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1FontWrapper.h: -------------------------------------------------------------------------------- 1 | // CFW1FontWrapper.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1FontWrapper 4 | #define IncludeGuard__FW1_CFW1FontWrapper 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Font-wrapper simplifying drawing strings and text-layouts 13 | class CFW1FontWrapper : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1FontWrapper 19 | virtual HRESULT STDMETHODCALLTYPE GetFactory(IFW1Factory **ppFactory); 20 | 21 | virtual HRESULT STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice); 22 | virtual HRESULT STDMETHODCALLTYPE GetDWriteFactory(IDWriteFactory **ppDWriteFactory); 23 | virtual HRESULT STDMETHODCALLTYPE GetGlyphAtlas(IFW1GlyphAtlas **ppGlyphAtlas); 24 | virtual HRESULT STDMETHODCALLTYPE GetGlyphProvider(IFW1GlyphProvider **ppGlyphProvider); 25 | virtual HRESULT STDMETHODCALLTYPE GetRenderStates(IFW1GlyphRenderStates **ppRenderStates); 26 | virtual HRESULT STDMETHODCALLTYPE GetVertexDrawer(IFW1GlyphVertexDrawer **ppVertexDrawer); 27 | 28 | virtual void STDMETHODCALLTYPE DrawTextLayout( 29 | ID3D11DeviceContext *pContext, 30 | IDWriteTextLayout *pTextLayout, 31 | FLOAT OriginX, 32 | FLOAT OriginY, 33 | UINT32 Color, 34 | UINT Flags 35 | ); 36 | virtual void STDMETHODCALLTYPE DrawTextLayout( 37 | ID3D11DeviceContext *pContext, 38 | IDWriteTextLayout *pTextLayout, 39 | FLOAT OriginX, 40 | FLOAT OriginY, 41 | UINT32 Color, 42 | const FW1_RECTF *pClipRect, 43 | const FLOAT *pTransformMatrix, 44 | UINT Flags 45 | ); 46 | 47 | virtual void STDMETHODCALLTYPE DrawString( 48 | ID3D11DeviceContext *pContext, 49 | const WCHAR *pszString, 50 | FLOAT FontSize, 51 | FLOAT X, 52 | FLOAT Y, 53 | UINT32 Color, 54 | UINT Flags 55 | ); 56 | virtual void STDMETHODCALLTYPE DrawString( 57 | ID3D11DeviceContext *pContext, 58 | const WCHAR *pszString, 59 | const WCHAR *pszFontFamily, 60 | FLOAT FontSize, 61 | FLOAT X, 62 | FLOAT Y, 63 | UINT32 Color, 64 | UINT Flags 65 | ); 66 | virtual void STDMETHODCALLTYPE DrawString( 67 | ID3D11DeviceContext *pContext, 68 | const WCHAR *pszString, 69 | const WCHAR *pszFontFamily, 70 | FLOAT FontSize, 71 | const FW1_RECTF *pLayoutRect, 72 | UINT32 Color, 73 | const FW1_RECTF *pClipRect, 74 | const FLOAT *pTransformMatrix, 75 | UINT Flags 76 | ); 77 | 78 | virtual FW1_RECTF STDMETHODCALLTYPE MeasureString( 79 | const WCHAR *pszString, 80 | const WCHAR *pszFontFamily, 81 | FLOAT FontSize, 82 | const FW1_RECTF *pLayoutRect, 83 | UINT Flags 84 | ); 85 | 86 | virtual void STDMETHODCALLTYPE AnalyzeString( 87 | ID3D11DeviceContext *pContext, 88 | const WCHAR *pszString, 89 | const WCHAR *pszFontFamily, 90 | FLOAT FontSize, 91 | const FW1_RECTF *pLayoutRect, 92 | UINT32 Color, 93 | UINT Flags, 94 | IFW1TextGeometry *pTextGeometry 95 | ); 96 | 97 | virtual void STDMETHODCALLTYPE AnalyzeTextLayout( 98 | ID3D11DeviceContext *pContext, 99 | IDWriteTextLayout *pTextLayout, 100 | FLOAT OriginX, 101 | FLOAT OriginY, 102 | UINT32 Color, 103 | UINT Flags, 104 | IFW1TextGeometry *pTextGeometry 105 | ); 106 | 107 | virtual void STDMETHODCALLTYPE DrawGeometry( 108 | ID3D11DeviceContext *pContext, 109 | IFW1TextGeometry *pGeometry, 110 | const FW1_RECTF *pClipRect, 111 | const FLOAT *pTransformMatrix, 112 | UINT Flags 113 | ); 114 | 115 | virtual void STDMETHODCALLTYPE Flush(ID3D11DeviceContext *pContext); 116 | 117 | // Public functions 118 | public: 119 | CFW1FontWrapper(); 120 | 121 | HRESULT initFontWrapper( 122 | IFW1Factory *pFW1Factory, 123 | ID3D11Device *pDevice, 124 | IFW1GlyphAtlas *pGlyphAtlas, 125 | IFW1GlyphProvider *pGlyphProvider, 126 | IFW1GlyphVertexDrawer *pGlyphVertexDrawer, 127 | IFW1GlyphRenderStates *pGlyphRenderStates, 128 | IDWriteFactory *pDWriteFactory, 129 | const FW1_DWRITEFONTPARAMS *pDefaultFontParams 130 | ); 131 | 132 | // Internal functions 133 | private: 134 | virtual ~CFW1FontWrapper(); 135 | 136 | IDWriteTextLayout* createTextLayout( 137 | const WCHAR *pszString, 138 | const WCHAR *pszFontFamily, 139 | FLOAT fontSize, 140 | const FW1_RECTF *pLayoutRect, 141 | UINT flags 142 | ); 143 | 144 | // Internal data 145 | private: 146 | std::wstring m_lastError; 147 | 148 | ID3D11Device *m_pDevice; 149 | D3D_FEATURE_LEVEL m_featureLevel; 150 | IDWriteFactory *m_pDWriteFactory; 151 | 152 | IFW1GlyphAtlas *m_pGlyphAtlas; 153 | IFW1GlyphProvider *m_pGlyphProvider; 154 | 155 | IFW1GlyphRenderStates *m_pGlyphRenderStates; 156 | IFW1GlyphVertexDrawer *m_pGlyphVertexDrawer; 157 | 158 | CRITICAL_SECTION m_textRenderersCriticalSection; 159 | std::stack m_textRenderers; 160 | CRITICAL_SECTION m_textGeometriesCriticalSection; 161 | std::stack m_textGeometries; 162 | 163 | bool m_defaultTextInited; 164 | IDWriteTextFormat *m_pDefaultTextFormat; 165 | }; 166 | 167 | 168 | }// namespace FW1FontWrapper 169 | 170 | 171 | #endif// IncludeGuard__FW1_CFW1FontWrapper 172 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphAtlasInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphAtlasInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphAtlas.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1GlyphAtlas::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1GlyphAtlas))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Get the D3D11 device used by this atlas 27 | HRESULT STDMETHODCALLTYPE CFW1GlyphAtlas::GetDevice(ID3D11Device **ppDevice) { 28 | if(ppDevice == NULL) 29 | return E_INVALIDARG; 30 | 31 | m_pDevice->AddRef(); 32 | *ppDevice = m_pDevice; 33 | 34 | return S_OK; 35 | } 36 | 37 | 38 | // Get total glyph count in atlas 39 | UINT STDMETHODCALLTYPE CFW1GlyphAtlas::GetTotalGlyphCount() { 40 | UINT total = 0; 41 | 42 | for(UINT i=0; i < m_sheetCount; ++i) { 43 | FW1_GLYPHSHEETDESC desc; 44 | m_glyphSheets[i]->GetDesc(&desc); 45 | 46 | total += desc.GlyphCount; 47 | } 48 | 49 | return total; 50 | } 51 | 52 | 53 | // Get sheet count 54 | UINT STDMETHODCALLTYPE CFW1GlyphAtlas::GetSheetCount() { 55 | return m_sheetCount; 56 | } 57 | 58 | 59 | // Get sheet 60 | HRESULT STDMETHODCALLTYPE CFW1GlyphAtlas::GetSheet(UINT SheetIndex, IFW1GlyphSheet **ppGlyphSheet) { 61 | if(ppGlyphSheet == NULL) 62 | return E_INVALIDARG; 63 | 64 | if(SheetIndex < m_sheetCount) { 65 | *ppGlyphSheet = m_glyphSheets[SheetIndex]; 66 | 67 | return S_OK; 68 | } 69 | 70 | *ppGlyphSheet = NULL; 71 | 72 | return E_INVALIDARG; 73 | } 74 | 75 | // Get texture coordinates 76 | const FW1_GLYPHCOORDS* STDMETHODCALLTYPE CFW1GlyphAtlas::GetGlyphCoords(UINT SheetIndex) { 77 | if(SheetIndex < m_sheetCount) 78 | return m_glyphSheets[SheetIndex]->GetGlyphCoords(); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | // Set sheet shader resources 85 | HRESULT STDMETHODCALLTYPE CFW1GlyphAtlas::BindSheet(ID3D11DeviceContext *pContext, UINT SheetIndex, UINT Flags) { 86 | if(SheetIndex < m_sheetCount) 87 | return m_glyphSheets[SheetIndex]->BindSheet(pContext, Flags); 88 | 89 | return E_INVALIDARG; 90 | } 91 | 92 | 93 | // Insert texture into atlas 94 | UINT STDMETHODCALLTYPE CFW1GlyphAtlas::InsertGlyph( 95 | const FW1_GLYPHMETRICS *pGlyphMetrics, 96 | const void *pGlyphData, 97 | UINT RowPitch, 98 | UINT PixelStride 99 | ) { 100 | UINT glyphIndex = 0xffffffff; 101 | UINT sheetIndex = 0; 102 | 103 | // Get open sheet range 104 | EnterCriticalSection(&m_glyphSheetsCriticalSection); 105 | UINT start = m_currentSheetIndex; 106 | UINT end = m_sheetCount; 107 | LeaveCriticalSection(&m_glyphSheetsCriticalSection); 108 | 109 | // Attempt to insert glyph 110 | for(UINT i=start; i < end; ++i) { 111 | IFW1GlyphSheet *pGlyphSheet = m_glyphSheets[i]; 112 | 113 | glyphIndex = pGlyphSheet->InsertGlyph(pGlyphMetrics, pGlyphData, RowPitch, PixelStride); 114 | if(glyphIndex != 0xffffffff) { 115 | sheetIndex = i; 116 | break; 117 | } 118 | } 119 | 120 | // Try to create a new glyph sheet on failure 121 | if(glyphIndex == 0xffffffff && m_sheetCount < m_maxSheetCount) { 122 | IFW1GlyphSheet *pGlyphSheet; 123 | if(SUCCEEDED(createGlyphSheet(&pGlyphSheet))) { 124 | glyphIndex = pGlyphSheet->InsertGlyph(pGlyphMetrics, pGlyphData, RowPitch, PixelStride); 125 | 126 | UINT newSheetIndex = InsertSheet(pGlyphSheet); 127 | if(newSheetIndex != 0xffffffff) 128 | sheetIndex = newSheetIndex; 129 | else 130 | glyphIndex = 0xffffffff; 131 | 132 | pGlyphSheet->Release(); 133 | } 134 | } 135 | 136 | if(glyphIndex == 0xffffffff) 137 | return 0xffffffff; 138 | 139 | return (sheetIndex << 16) | glyphIndex; 140 | } 141 | 142 | 143 | // Insert glyph sheets 144 | UINT STDMETHODCALLTYPE CFW1GlyphAtlas::InsertSheet(IFW1GlyphSheet *pGlyphSheet) { 145 | if(pGlyphSheet == NULL) 146 | return 0xffffffff; 147 | 148 | UINT sheetIndex = 0xffffffff; 149 | 150 | EnterCriticalSection(&m_glyphSheetsCriticalSection); 151 | if(m_sheetCount < m_maxSheetCount) { 152 | pGlyphSheet->AddRef(); 153 | 154 | sheetIndex = m_sheetCount; 155 | 156 | m_glyphSheets[sheetIndex] = pGlyphSheet; 157 | 158 | _WriteBarrier(); 159 | MemoryBarrier(); 160 | 161 | ++m_sheetCount; 162 | 163 | // Restrict the number of open sheets 164 | UINT numActiveSheets = 4; 165 | 166 | if(m_sheetCount > m_currentSheetIndex + numActiveSheets) { 167 | m_glyphSheets[m_currentSheetIndex]->CloseSheet(); 168 | 169 | ++m_currentSheetIndex; 170 | } 171 | } 172 | LeaveCriticalSection(&m_glyphSheetsCriticalSection); 173 | 174 | return sheetIndex; 175 | } 176 | 177 | 178 | // Flush all sheets with possible new glyphs 179 | void STDMETHODCALLTYPE CFW1GlyphAtlas::Flush(ID3D11DeviceContext *pContext) { 180 | UINT first = 0; 181 | UINT end = 0; 182 | 183 | EnterCriticalSection(&m_glyphSheetsCriticalSection); 184 | 185 | first = m_flushedSheetIndex; 186 | end = m_sheetCount; 187 | 188 | m_flushedSheetIndex = m_currentSheetIndex; 189 | 190 | LeaveCriticalSection(&m_glyphSheetsCriticalSection); 191 | 192 | for(UINT i=first; i < end; ++i) 193 | m_glyphSheets[i]->Flush(pContext); 194 | } 195 | 196 | 197 | }// namespace FW1FontWrapper 198 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1FontWrapper.cpp: -------------------------------------------------------------------------------- 1 | // CFW1FontWrapper.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1FontWrapper.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1FontWrapper::CFW1FontWrapper() : 15 | m_pDevice(NULL), 16 | m_featureLevel(D3D_FEATURE_LEVEL_9_1), 17 | m_pDWriteFactory(NULL), 18 | 19 | m_pGlyphAtlas(NULL), 20 | m_pGlyphProvider(NULL), 21 | 22 | m_pGlyphRenderStates(NULL), 23 | m_pGlyphVertexDrawer(NULL), 24 | 25 | m_defaultTextInited(false), 26 | m_pDefaultTextFormat(NULL) 27 | { 28 | InitializeCriticalSection(&m_textRenderersCriticalSection); 29 | InitializeCriticalSection(&m_textGeometriesCriticalSection); 30 | } 31 | 32 | 33 | // Destruct 34 | CFW1FontWrapper::~CFW1FontWrapper() { 35 | SAFE_RELEASE(m_pFW1Factory); 36 | 37 | SAFE_RELEASE(m_pDevice); 38 | SAFE_RELEASE(m_pDWriteFactory); 39 | 40 | SAFE_RELEASE(m_pGlyphAtlas); 41 | SAFE_RELEASE(m_pGlyphProvider); 42 | 43 | SAFE_RELEASE(m_pGlyphRenderStates); 44 | SAFE_RELEASE(m_pGlyphVertexDrawer); 45 | 46 | while(!m_textRenderers.empty()) { 47 | m_textRenderers.top()->Release(); 48 | m_textRenderers.pop(); 49 | } 50 | 51 | while(!m_textGeometries.empty()) { 52 | m_textGeometries.top()->Release(); 53 | m_textGeometries.pop(); 54 | } 55 | 56 | SAFE_RELEASE(m_pDefaultTextFormat); 57 | 58 | DeleteCriticalSection(&m_textRenderersCriticalSection); 59 | DeleteCriticalSection(&m_textGeometriesCriticalSection); 60 | } 61 | 62 | 63 | // Init 64 | HRESULT CFW1FontWrapper::initFontWrapper( 65 | IFW1Factory *pFW1Factory, 66 | ID3D11Device *pDevice, 67 | IFW1GlyphAtlas *pGlyphAtlas, 68 | IFW1GlyphProvider *pGlyphProvider, 69 | IFW1GlyphVertexDrawer *pGlyphVertexDrawer, 70 | IFW1GlyphRenderStates *pGlyphRenderStates, 71 | IDWriteFactory *pDWriteFactory, 72 | const FW1_DWRITEFONTPARAMS *pDefaultFontParams 73 | ) { 74 | HRESULT hResult = initBaseObject(pFW1Factory); 75 | if(FAILED(hResult)) 76 | return hResult; 77 | 78 | if( 79 | pDevice == NULL || 80 | pGlyphAtlas == NULL || 81 | pGlyphProvider == NULL || 82 | pGlyphVertexDrawer == NULL || 83 | pGlyphRenderStates == NULL || 84 | pDWriteFactory == NULL 85 | ) 86 | return E_INVALIDARG; 87 | 88 | pDevice->AddRef(); 89 | m_pDevice = pDevice; 90 | m_featureLevel = m_pDevice->GetFeatureLevel(); 91 | 92 | pDWriteFactory->AddRef(); 93 | m_pDWriteFactory = pDWriteFactory; 94 | 95 | pGlyphAtlas->AddRef(); 96 | m_pGlyphAtlas = pGlyphAtlas; 97 | pGlyphProvider->AddRef(); 98 | m_pGlyphProvider = pGlyphProvider; 99 | 100 | pGlyphRenderStates->AddRef(); 101 | m_pGlyphRenderStates = pGlyphRenderStates; 102 | pGlyphVertexDrawer->AddRef(); 103 | m_pGlyphVertexDrawer = pGlyphVertexDrawer; 104 | 105 | // Create default text format for strings, if provided 106 | if(pDefaultFontParams->pszFontFamily != NULL && pDefaultFontParams->pszFontFamily[0] != 0) { 107 | IDWriteTextFormat *pTextFormat; 108 | hResult = m_pDWriteFactory->CreateTextFormat( 109 | pDefaultFontParams->pszFontFamily, 110 | NULL, 111 | pDefaultFontParams->FontWeight, 112 | pDefaultFontParams->FontStyle, 113 | pDefaultFontParams->FontStretch, 114 | 32.0f, 115 | (pDefaultFontParams->pszLocale != NULL) ? pDefaultFontParams->pszLocale : L"", 116 | &pTextFormat 117 | ); 118 | if(FAILED(hResult)) { 119 | m_lastError = L"Failed to create DWrite text format"; 120 | } 121 | else { 122 | m_pDefaultTextFormat = pTextFormat; 123 | m_defaultTextInited = true; 124 | 125 | hResult = S_OK; 126 | } 127 | } 128 | 129 | return hResult; 130 | } 131 | 132 | 133 | // Create text layout from string 134 | IDWriteTextLayout* CFW1FontWrapper::createTextLayout( 135 | const WCHAR *pszString, 136 | const WCHAR *pszFontFamily, 137 | FLOAT fontSize, 138 | const FW1_RECTF *pLayoutRect, 139 | UINT flags 140 | ) { 141 | if(m_defaultTextInited) { 142 | UINT32 stringLength = 0; 143 | while(pszString[stringLength] != 0) 144 | ++stringLength; 145 | 146 | // Create DWrite text layout for the string 147 | IDWriteTextLayout *pTextLayout; 148 | HRESULT hResult = m_pDWriteFactory->CreateTextLayout( 149 | pszString, 150 | stringLength, 151 | m_pDefaultTextFormat, 152 | pLayoutRect->Right - pLayoutRect->Left, 153 | pLayoutRect->Bottom - pLayoutRect->Top, 154 | &pTextLayout 155 | ); 156 | if(SUCCEEDED(hResult)) { 157 | // Layout settings 158 | DWRITE_TEXT_RANGE allText = {0, stringLength}; 159 | pTextLayout->SetFontSize(fontSize, allText); 160 | 161 | if(pszFontFamily != NULL) 162 | pTextLayout->SetFontFamilyName(pszFontFamily, allText); 163 | 164 | if((flags & FW1_NOWORDWRAP) != 0) 165 | pTextLayout->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); 166 | 167 | if(flags & FW1_RIGHT) 168 | pTextLayout->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING); 169 | else if(flags & FW1_CENTER) 170 | pTextLayout->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); 171 | if(flags & FW1_BOTTOM) 172 | pTextLayout->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_FAR); 173 | else if(flags & FW1_VCENTER) 174 | pTextLayout->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); 175 | 176 | return pTextLayout; 177 | } 178 | } 179 | 180 | return NULL; 181 | } 182 | 183 | 184 | }// namespace FW1FontWrapper 185 | -------------------------------------------------------------------------------- /dwmhook/render.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | using namespace DirectX; 5 | 6 | extern ID3D11Device* pD3DXDevice; 7 | extern ID3D11DeviceContext* pD3DXDeviceCtx; 8 | 9 | #include "ck.h" 10 | #include "FW1/FW1FontWrapper.h" 11 | #include "save_state.hpp" 12 | 13 | #define SAFE_RELEASE( p ) if( p ) { p->Release(); p = nullptr; } 14 | 15 | static ULONGLONG t0 = 0; 16 | static float accum = 0; 17 | 18 | static TScopedHandle backbuffer_ptr; 19 | static TScopedHandle rtview_ptr; 20 | static TScopedHandle rasterizer_state; 21 | static TScopedHandle rasterizer_state_ov; 22 | 23 | static TScopedHandle vertex_shader_ptr; 24 | static TScopedHandle pixel_shader_ptr; 25 | static TScopedHandle input_layout_ptr; 26 | static TScopedHandle vertex_buffer_ptr; 27 | static TScopedHandle index_buffer_ptr; 28 | static TScopedHandle const_buffer_ptr; 29 | 30 | #define STRINGIFY(X) #X 31 | 32 | static const char* shader_code = STRINGIFY 33 | ( 34 | cbuffer ConstantBuffer : register( b0 ) 35 | { 36 | matrix World; 37 | matrix View; 38 | matrix Projection; 39 | } 40 | struct VS_OUTPUT 41 | { 42 | float4 Pos : SV_POSITION; 43 | float4 Color : COLOR0; 44 | }; 45 | VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR ) 46 | { 47 | VS_OUTPUT output = ( VS_OUTPUT )0; 48 | output.Pos = mul( Pos, World ); 49 | output.Pos = mul( output.Pos, View ); 50 | output.Pos = mul( output.Pos, Projection ); 51 | output.Color = Color; 52 | return output; 53 | } 54 | float4 PS( VS_OUTPUT input ) : SV_Target 55 | { 56 | return input.Color; 57 | } 58 | ); 59 | 60 | struct SimpleVertex 61 | { 62 | XMFLOAT3 Pos; 63 | XMFLOAT4 Color; 64 | }; 65 | 66 | struct ConstantBuffer 67 | { 68 | XMMATRIX mWorld; 69 | XMMATRIX mView; 70 | XMMATRIX mProjection; 71 | }; 72 | 73 | inline void fix_renderstate() 74 | { 75 | auto t1 = GetTickCount64(); 76 | float dt = ( t1 - t0 ) * 0.001f; 77 | accum += dt; 78 | t0 = t1; 79 | 80 | D3D11_TEXTURE2D_DESC bb; 81 | ZeroMemory( &bb, sizeof( bb ) ); 82 | backbuffer_ptr->GetDesc( &bb ); 83 | 84 | XMMATRIX world = XMMatrixRotationY( accum ); 85 | XMVECTOR eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f ); 86 | XMVECTOR at = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); 87 | XMVECTOR up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); 88 | XMMATRIX view = XMMatrixLookAtLH( eye, at, up ); 89 | XMMATRIX proj = XMMatrixPerspectiveFovLH( XM_PIDIV2, bb.Width / ( FLOAT )bb.Height, 0.01f, 100.0f ); 90 | 91 | //float color[4] = { 0, 0, 0, 0 }; 92 | //device_context_ptr->ClearRenderTargetView(*rtview_ptr, color); 93 | pD3DXDeviceCtx->OMSetRenderTargets( 1, &rtview_ptr, NULL ); 94 | 95 | D3D11_VIEWPORT viewport = { 0.0f, 0.0f, ( float )bb.Width, ( float )bb.Height, 0.0f, 1.0f }; 96 | pD3DXDeviceCtx->RSSetViewports( 1, &viewport ); 97 | pD3DXDeviceCtx->RSSetState( *rasterizer_state_ov ); 98 | 99 | pD3DXDeviceCtx->IASetInputLayout( *input_layout_ptr ); 100 | pD3DXDeviceCtx->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); 101 | 102 | UINT stride = sizeof( SimpleVertex ), offset = 0; 103 | pD3DXDeviceCtx->IASetVertexBuffers( 0, 1, &vertex_buffer_ptr, &stride, &offset ); 104 | pD3DXDeviceCtx->IASetIndexBuffer( *index_buffer_ptr, DXGI_FORMAT_R16_UINT, 0 ); 105 | 106 | ConstantBuffer cb; 107 | cb.mWorld = XMMatrixTranspose( world ); 108 | cb.mView = XMMatrixTranspose( view ); 109 | cb.mProjection = XMMatrixTranspose( proj ); 110 | pD3DXDeviceCtx->UpdateSubresource( *const_buffer_ptr, 0, NULL, &cb, 0, 0 ); 111 | 112 | pD3DXDeviceCtx->VSSetShader( *vertex_shader_ptr, NULL, 0 ); 113 | pD3DXDeviceCtx->VSSetConstantBuffers( 0, 1, &const_buffer_ptr ); 114 | pD3DXDeviceCtx->PSSetShader( *pixel_shader_ptr, NULL, 0 ); 115 | //pD3DXDeviceCtx->DrawIndexed( 36, 0, 0 ); 116 | 117 | pD3DXDeviceCtx->RSSetState( *rasterizer_state ); 118 | } 119 | 120 | struct COLOR_VERTEX 121 | { 122 | XMFLOAT3 Position; 123 | XMFLOAT4 Color; 124 | }; 125 | 126 | class CRender2D 127 | { 128 | ID3D11InputLayout* mInputLayout = nullptr; 129 | ID3D11Buffer* mVertexBuffer = nullptr; 130 | ID3D11VertexShader* mVS = nullptr; 131 | ID3D11PixelShader* mPS = nullptr; 132 | ID3D11BlendState* transparency = nullptr; 133 | D3D11StateSaver* stateSaver = new D3D11StateSaver(); 134 | IFW1FontWrapper* font; 135 | 136 | bool restoreState = false; 137 | public: 138 | CRender2D() = default; 139 | ~CRender2D() = default; 140 | 141 | bool Initialize( IFW1FontWrapper* pFontWrapper ); 142 | void BeginScene(); 143 | void EndScene(); 144 | void OnReset(); 145 | 146 | void FillRect( float x, float y, float w, float h, ULONG color ); 147 | void OutlineRect( float x1, float y1, float x2, float y2, ULONG color ); 148 | void DrawLine( const XMFLOAT2& point_1, const XMFLOAT2& point_2, ULONG color ); 149 | void DrawHealthBar( float x, float y, float w, float health, float max ); 150 | void DrawHealthBar( float x, float y, float w, float h, float health, float max ); 151 | 152 | void RenderText( const wchar_t* txt, float x, float y, ULONG color, bool center, bool shadow = true ); 153 | void RenderText( const char* txt, float x, float y, ULONG color, bool center, bool shadow = true ); 154 | }; 155 | 156 | extern CRender2D render; 157 | 158 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextRenderer.h: -------------------------------------------------------------------------------- 1 | // CFW1TextRenderer.h 2 | 3 | #ifndef IncludeGuard__FW1_CFW1TextRenderer 4 | #define IncludeGuard__FW1_CFW1TextRenderer 5 | 6 | #include "CFW1Object.h" 7 | 8 | 9 | namespace FW1FontWrapper { 10 | 11 | 12 | // Converts a DWrite text layout to vertices 13 | class CFW1TextRenderer : public CFW1Object { 14 | public: 15 | // IUnknown 16 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); 17 | 18 | // IFW1DWriteTextRenderer 19 | virtual HRESULT STDMETHODCALLTYPE GetGlyphProvider(IFW1GlyphProvider **ppGlyphProvider); 20 | 21 | virtual HRESULT STDMETHODCALLTYPE DrawTextLayout( 22 | IDWriteTextLayout *pTextLayout, 23 | FLOAT OriginX, 24 | FLOAT OriginY, 25 | UINT32 Color, 26 | UINT Flags, 27 | IFW1TextGeometry *pTextGeometry 28 | ); 29 | 30 | // Public functions 31 | public: 32 | CFW1TextRenderer(); 33 | 34 | HRESULT initTextRenderer( 35 | IFW1Factory *pFW1Factory, 36 | IFW1GlyphProvider *pGlyphProvider 37 | ); 38 | 39 | // Internal functions 40 | private: 41 | virtual ~CFW1TextRenderer(); 42 | 43 | // IDWritePixelSnapping interface (called via proxy) 44 | HRESULT IsPixelSnappingDisabled(void *clientDrawingContext, BOOL *isDisabled); 45 | HRESULT GetCurrentTransform(void *clientDrawingContext, DWRITE_MATRIX *transform); 46 | HRESULT GetPixelsPerDip(void *clientDrawingContext, FLOAT *pixelsPerDip); 47 | 48 | // IDWriteTextRenderer interface (called via proxy) 49 | HRESULT DrawGlyphRun( 50 | void *clientDrawingContext, 51 | FLOAT baselineOriginX, 52 | FLOAT baselineOriginY, 53 | DWRITE_MEASURING_MODE measuringMode, 54 | const DWRITE_GLYPH_RUN *glyphRun, 55 | const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, 56 | IUnknown *clientDrawingEffect 57 | ); 58 | HRESULT DrawUnderline( 59 | void *clientDrawingContext, 60 | FLOAT baselineOriginX, 61 | FLOAT baselineOriginY, 62 | const DWRITE_UNDERLINE *underline, 63 | IUnknown *clientDrawingEffect 64 | ); 65 | HRESULT DrawStrikethrough( 66 | void *clientDrawingContext, 67 | FLOAT baselineOriginX, 68 | FLOAT baselineOriginY, 69 | const DWRITE_STRIKETHROUGH *strikethrough, 70 | IUnknown *clientDrawingEffect 71 | ); 72 | HRESULT DrawInlineObject( 73 | void *clientDrawingContext, 74 | FLOAT originX, 75 | FLOAT originY, 76 | IDWriteInlineObject *inlineObject, 77 | BOOL isSideways, 78 | BOOL isRightToLeft, 79 | IUnknown *clientDrawingEffect 80 | ); 81 | 82 | // Internal data 83 | private: 84 | IFW1GlyphProvider *m_pGlyphProvider; 85 | 86 | UINT m_currentFlags; 87 | UINT32 m_currentColor; 88 | 89 | const void *m_cachedGlyphMap; 90 | IDWriteFontFace *m_pCachedGlyphMapFontFace; 91 | FLOAT m_cachedGlyphMapFontSize; 92 | 93 | 94 | // Proxy for IDWriteTextRenderer interface 95 | private: 96 | class CDWriteTextRendererProxy : public IDWriteTextRenderer { 97 | public: 98 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { 99 | return m_realObject->QueryInterface(riid, ppvObject); 100 | } 101 | virtual ULONG STDMETHODCALLTYPE AddRef() { 102 | return m_realObject->AddRef(); 103 | } 104 | virtual ULONG STDMETHODCALLTYPE Release() { 105 | return m_realObject->Release(); 106 | } 107 | 108 | virtual HRESULT STDMETHODCALLTYPE IsPixelSnappingDisabled(void *clientDrawingContext, BOOL *isDisabled) { 109 | return m_realObject->IsPixelSnappingDisabled(clientDrawingContext, isDisabled); 110 | } 111 | virtual HRESULT STDMETHODCALLTYPE GetCurrentTransform(void *clientDrawingContext, DWRITE_MATRIX *transform) { 112 | return m_realObject->GetCurrentTransform(clientDrawingContext, transform); 113 | } 114 | virtual HRESULT STDMETHODCALLTYPE GetPixelsPerDip(void *clientDrawingContext, FLOAT *pixelsPerDip) { 115 | return m_realObject->GetPixelsPerDip(clientDrawingContext, pixelsPerDip); 116 | } 117 | 118 | virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, const DWRITE_GLYPH_RUN *glyphRun, const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, IUnknown *clientDrawingEffect) { 119 | return m_realObject->DrawGlyphRun(clientDrawingContext, baselineOriginX, baselineOriginY, measuringMode, glyphRun, glyphRunDescription, clientDrawingEffect); 120 | } 121 | virtual HRESULT STDMETHODCALLTYPE DrawUnderline(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_UNDERLINE *underline, IUnknown *clientDrawingEffect) { 122 | return m_realObject->DrawUnderline(clientDrawingContext, baselineOriginX, baselineOriginY, underline, clientDrawingEffect); 123 | } 124 | virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *clientDrawingEffect) { 125 | return m_realObject->DrawStrikethrough(clientDrawingContext, baselineOriginX, baselineOriginY, strikethrough, clientDrawingEffect); 126 | } 127 | virtual HRESULT STDMETHODCALLTYPE DrawInlineObject(void *clientDrawingContext, FLOAT originX, FLOAT originY, IDWriteInlineObject *inlineObject, BOOL isSideways, BOOL isRightToLeft, IUnknown *clientDrawingEffect) { 128 | return m_realObject->DrawInlineObject(clientDrawingContext, originX, originY, inlineObject, isSideways, isRightToLeft, clientDrawingEffect); 129 | } 130 | 131 | public: 132 | CDWriteTextRendererProxy(CFW1TextRenderer *realObject) : m_realObject(realObject) {} 133 | 134 | private: 135 | CDWriteTextRendererProxy(const CDWriteTextRendererProxy&); 136 | CDWriteTextRendererProxy& operator=(const CDWriteTextRendererProxy&); 137 | 138 | private: 139 | CFW1TextRenderer *m_realObject; 140 | } *m_pDWriteTextRendererProxy; 141 | }; 142 | 143 | 144 | }// namespace FW1FontWrapper 145 | 146 | 147 | #endif// IncludeGuard__FW1_CFW1TextRenderer 148 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1DWriteRenderTarget.cpp: -------------------------------------------------------------------------------- 1 | // CFW1DWriteRenderTarget.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1DWriteRenderTarget.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1DWriteRenderTarget::CFW1DWriteRenderTarget() : 15 | m_pRenderTarget(NULL), 16 | m_hDC(NULL), 17 | m_hBlackBrush(NULL), 18 | m_bmWidthBytes(0), 19 | m_bmBytesPixel(0), 20 | m_renderTargetWidth(0), 21 | m_renderTargetHeight(0) 22 | { 23 | } 24 | 25 | 26 | // Destruct 27 | CFW1DWriteRenderTarget::~CFW1DWriteRenderTarget() { 28 | if(m_hBlackBrush != NULL) 29 | DeleteObject(m_hBlackBrush); 30 | 31 | SAFE_RELEASE(m_pRenderTarget); 32 | 33 | for(RenderingParamsMap::iterator it = m_renderingParams.begin(); it != m_renderingParams.end(); ++it) 34 | it->second->Release(); 35 | } 36 | 37 | 38 | // Init 39 | HRESULT CFW1DWriteRenderTarget::initRenderTarget( 40 | IFW1Factory *pFW1Factory, 41 | IDWriteFactory *pDWriteFactory, 42 | UINT renderTargetWidth, 43 | UINT renderTargetHeight 44 | ) { 45 | HRESULT hResult = initBaseObject(pFW1Factory); 46 | if(FAILED(hResult)) 47 | return hResult; 48 | 49 | if(pDWriteFactory == NULL) 50 | return E_INVALIDARG; 51 | 52 | m_renderTargetWidth = 384; 53 | if(renderTargetWidth > 0) 54 | m_renderTargetWidth = renderTargetWidth; 55 | 56 | m_renderTargetHeight = 384; 57 | if(renderTargetHeight > 0) 58 | m_renderTargetHeight = renderTargetHeight; 59 | 60 | // Create render target 61 | hResult = createRenderTarget(pDWriteFactory); 62 | 63 | if(SUCCEEDED(hResult)) 64 | hResult = S_OK; 65 | 66 | return hResult; 67 | } 68 | 69 | 70 | // Create render target 71 | HRESULT CFW1DWriteRenderTarget::createRenderTarget(IDWriteFactory *pDWriteFactory) { 72 | IDWriteGdiInterop *pGDIInterop; 73 | HRESULT hResult = pDWriteFactory->GetGdiInterop(&pGDIInterop); 74 | if(FAILED(hResult)) { 75 | m_lastError = L"Failed to get GDI interop"; 76 | } 77 | else { 78 | IDWriteBitmapRenderTarget *pRenderTarget; 79 | hResult = pGDIInterop->CreateBitmapRenderTarget( 80 | NULL, 81 | m_renderTargetWidth, 82 | m_renderTargetHeight, 83 | &pRenderTarget 84 | ); 85 | if(FAILED(hResult)) { 86 | m_lastError = L"Failed to create bitmap render target"; 87 | } 88 | else { 89 | hResult = pRenderTarget->SetPixelsPerDip(1.0f); 90 | hResult = S_OK; 91 | 92 | HDC hDC = pRenderTarget->GetMemoryDC(); 93 | if(hDC == NULL) { 94 | m_lastError = L"Failed to get render target DC"; 95 | hResult = E_FAIL; 96 | } 97 | else { 98 | HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); 99 | if(hBrush == NULL) { 100 | m_lastError = L"Failed to create brush"; 101 | hResult = E_FAIL; 102 | } 103 | else { 104 | HBITMAP hBitmap = static_cast(GetCurrentObject(hDC, OBJ_BITMAP)); 105 | if(hBitmap == NULL) { 106 | m_lastError = L"GetCurrentObject failed"; 107 | hResult = E_FAIL; 108 | } 109 | else { 110 | DIBSECTION dib; 111 | int iResult = GetObject(hBitmap, sizeof(dib), &dib); 112 | if(iResult < sizeof(dib)) { 113 | m_lastError = L"GetObject failed"; 114 | hResult = E_FAIL; 115 | } 116 | else { 117 | // Store render target resources and info 118 | m_pRenderTarget = pRenderTarget; 119 | 120 | m_hDC = hDC; 121 | m_hBlackBrush = hBrush; 122 | 123 | m_bmBits = dib.dsBm.bmBits; 124 | m_bmWidthBytes = static_cast(dib.dsBm.bmWidthBytes); 125 | m_bmBytesPixel = static_cast(dib.dsBm.bmBitsPixel) / 8; 126 | 127 | hResult = S_OK; 128 | } 129 | } 130 | 131 | if(FAILED(hResult)) 132 | DeleteObject(hBrush); 133 | } 134 | } 135 | 136 | if(FAILED(hResult)) 137 | pRenderTarget->Release(); 138 | } 139 | 140 | pGDIInterop->Release(); 141 | } 142 | 143 | // Create rendering params for all accepted rendering modes 144 | if(SUCCEEDED(hResult)) { 145 | const UINT renderingModeCount = 2; 146 | DWRITE_RENDERING_MODE renderingModes[renderingModeCount] = { 147 | DWRITE_RENDERING_MODE_DEFAULT, 148 | DWRITE_RENDERING_MODE_ALIASED 149 | }; 150 | 151 | for(UINT i=0; i < renderingModeCount; ++i) { 152 | DWRITE_RENDERING_MODE renderingMode = renderingModes[i]; 153 | IDWriteRenderingParams *pRenderingParams; 154 | 155 | hResult = pDWriteFactory->CreateCustomRenderingParams( 156 | 1.0f, 157 | 0.0f, 158 | 0.0f, 159 | DWRITE_PIXEL_GEOMETRY_FLAT, 160 | renderingMode, 161 | &pRenderingParams 162 | ); 163 | if(SUCCEEDED(hResult)) 164 | m_renderingParams.insert(std::make_pair(renderingMode, pRenderingParams)); 165 | } 166 | 167 | if(m_renderingParams.empty()) { 168 | m_lastError = L"Failed to create rendering params"; 169 | hResult = E_FAIL; 170 | } 171 | else 172 | hResult = S_OK; 173 | } 174 | 175 | return hResult; 176 | } 177 | 178 | 179 | // Init glyph data 180 | void CFW1DWriteRenderTarget::initGlyphData( 181 | const DWRITE_FONT_METRICS *fontMetrics, 182 | const DWRITE_GLYPH_METRICS *glyphMetrics, 183 | FLOAT fontSize, 184 | DWGlyphData *outGlyphData 185 | ) { 186 | // Calculate pixel-space coordinates 187 | FLOAT fscale = fontSize / static_cast(fontMetrics->designUnitsPerEm); 188 | 189 | FLOAT l = static_cast(glyphMetrics->leftSideBearing) * fscale; 190 | FLOAT t = static_cast(glyphMetrics->topSideBearing) * fscale; 191 | 192 | FLOAT r = static_cast(glyphMetrics->rightSideBearing) * fscale; 193 | FLOAT b = static_cast(glyphMetrics->bottomSideBearing) * fscale; 194 | 195 | FLOAT v = static_cast(glyphMetrics->verticalOriginY) * fscale; 196 | 197 | FLOAT aw = static_cast(glyphMetrics->advanceWidth) * fscale; 198 | FLOAT ah = static_cast(glyphMetrics->advanceHeight) * fscale; 199 | 200 | // Set up glyph data 201 | outGlyphData->offsetX = floor(l); 202 | outGlyphData->offsetY = floor(t) - floor(v); 203 | outGlyphData->maxWidth = static_cast(aw - r - l + 2.0f); 204 | outGlyphData->maxHeight = static_cast(ah - b - t + 2.0f); 205 | } 206 | 207 | 208 | }// namespace FW1FontWrapper 209 | -------------------------------------------------------------------------------- /dwmhook/save_state.cpp: -------------------------------------------------------------------------------- 1 | #include "includes.hpp" 2 | 3 | D3D11StateSaver::D3D11StateSaver() : 4 | m_savedState( false ), 5 | m_featureLevel( D3D_FEATURE_LEVEL_11_0 ), 6 | m_pContext( NULL ), 7 | m_primitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED ), 8 | m_pInputLayout( NULL ), 9 | m_pBlendState( NULL ), 10 | m_sampleMask( 0xffffffff ), 11 | m_pDepthStencilState( NULL ), 12 | m_stencilRef( 0 ), 13 | m_pRasterizerState( NULL ), 14 | m_pPSSRV( NULL ), 15 | m_pSamplerState( NULL ), 16 | m_pVS( NULL ), 17 | m_numVSClassInstances( 0 ), 18 | m_pVSConstantBuffer( NULL ), 19 | m_pGS( NULL ), 20 | m_numGSClassInstances( 0 ), 21 | m_pGSConstantBuffer( NULL ), 22 | m_pGSSRV( NULL ), 23 | m_pPS( NULL ), 24 | m_numPSClassInstances( 0 ), 25 | m_pHS( NULL ), 26 | m_numHSClassInstances( 0 ), 27 | m_pDS( NULL ), 28 | m_numDSClassInstances( 0 ), 29 | m_pVB( NULL ), 30 | m_vertexStride( 0 ), 31 | m_vertexOffset( 0 ), 32 | m_pIndexBuffer( NULL ), 33 | m_indexFormat( DXGI_FORMAT_UNKNOWN ), 34 | m_indexOffset( 0 ) 35 | { 36 | for ( int i = 0; i < 4; ++i ) 37 | m_blendFactor[ i ] = 0.0f; 38 | for ( int i = 0; i < 256; ++i ) 39 | { 40 | m_pVSClassInstances[ i ] = NULL; 41 | m_pGSClassInstances[ i ] = NULL; 42 | m_pPSClassInstances[ i ] = NULL; 43 | m_pHSClassInstances[ i ] = NULL; 44 | m_pDSClassInstances[ i ] = NULL; 45 | } 46 | } 47 | 48 | D3D11StateSaver::~D3D11StateSaver() 49 | { 50 | releaseSavedState(); 51 | } 52 | 53 | HRESULT D3D11StateSaver::saveCurrentState( ID3D11DeviceContext* pContext ) 54 | { 55 | if ( m_savedState ) 56 | releaseSavedState(); 57 | if ( pContext == NULL ) 58 | return E_INVALIDARG; 59 | 60 | ID3D11Device* pDevice; 61 | pContext->GetDevice( &pDevice ); 62 | if ( pDevice != NULL ) { 63 | m_featureLevel = pDevice->GetFeatureLevel(); 64 | pDevice->Release(); 65 | } 66 | 67 | pContext->AddRef(); 68 | m_pContext = pContext; 69 | 70 | m_pContext->IAGetPrimitiveTopology( &m_primitiveTopology ); 71 | m_pContext->IAGetInputLayout( &m_pInputLayout ); 72 | 73 | m_pContext->OMGetBlendState( &m_pBlendState, m_blendFactor, &m_sampleMask ); 74 | m_pContext->OMGetDepthStencilState( &m_pDepthStencilState, &m_stencilRef ); 75 | 76 | m_pContext->RSGetState( &m_pRasterizerState ); 77 | 78 | m_numVSClassInstances = 256; 79 | m_pContext->VSGetShader( &m_pVS, m_pVSClassInstances, &m_numVSClassInstances ); 80 | m_pContext->VSGetConstantBuffers( 0, 1, &m_pVSConstantBuffer ); 81 | 82 | m_numPSClassInstances = 256; 83 | m_pContext->PSGetShader( &m_pPS, m_pPSClassInstances, &m_numPSClassInstances ); 84 | m_pContext->PSGetShaderResources( 0, 1, &m_pPSSRV ); 85 | pContext->PSGetSamplers( 0, 1, &m_pSamplerState ); 86 | 87 | if ( m_featureLevel >= D3D_FEATURE_LEVEL_10_0 ) 88 | { 89 | m_numGSClassInstances = 256; 90 | m_pContext->GSGetShader( &m_pGS, m_pGSClassInstances, &m_numGSClassInstances ); 91 | m_pContext->GSGetConstantBuffers( 0, 1, &m_pGSConstantBuffer ); 92 | 93 | m_pContext->GSGetShaderResources( 0, 1, &m_pGSSRV ); 94 | 95 | if ( m_featureLevel >= D3D_FEATURE_LEVEL_11_0 ) 96 | { 97 | m_numHSClassInstances = 256; 98 | m_pContext->HSGetShader( &m_pHS, m_pHSClassInstances, &m_numHSClassInstances ); 99 | 100 | m_numDSClassInstances = 256; 101 | m_pContext->DSGetShader( &m_pDS, m_pDSClassInstances, &m_numDSClassInstances ); 102 | } 103 | } 104 | 105 | m_pContext->IAGetVertexBuffers( 0, 1, &m_pVB, &m_vertexStride, &m_vertexOffset ); 106 | 107 | m_pContext->IAGetIndexBuffer( &m_pIndexBuffer, &m_indexFormat, &m_indexOffset ); 108 | 109 | m_savedState = true; 110 | 111 | return S_OK; 112 | } 113 | 114 | HRESULT D3D11StateSaver::restoreSavedState() 115 | { 116 | if ( !m_savedState ) 117 | return E_FAIL; 118 | 119 | m_pContext->IASetPrimitiveTopology( m_primitiveTopology ); 120 | m_pContext->IASetInputLayout( m_pInputLayout ); 121 | 122 | m_pContext->OMSetBlendState( m_pBlendState, m_blendFactor, m_sampleMask ); 123 | m_pContext->OMSetDepthStencilState( m_pDepthStencilState, m_stencilRef ); 124 | 125 | m_pContext->RSSetState( m_pRasterizerState ); 126 | 127 | m_pContext->VSSetShader( m_pVS, m_pVSClassInstances, m_numVSClassInstances ); 128 | m_pContext->VSSetConstantBuffers( 0, 1, &m_pVSConstantBuffer ); 129 | 130 | m_pContext->PSSetShader( m_pPS, m_pPSClassInstances, m_numPSClassInstances ); 131 | m_pContext->PSSetShaderResources( 0, 1, &m_pPSSRV ); 132 | m_pContext->PSSetSamplers( 0, 1, &m_pSamplerState ); 133 | 134 | if ( m_featureLevel >= D3D_FEATURE_LEVEL_10_0 ) 135 | { 136 | m_pContext->GSSetShader( m_pGS, m_pGSClassInstances, m_numGSClassInstances ); 137 | m_pContext->GSSetConstantBuffers( 0, 1, &m_pGSConstantBuffer ); 138 | 139 | m_pContext->GSSetShaderResources( 0, 1, &m_pGSSRV ); 140 | 141 | if ( m_featureLevel >= D3D_FEATURE_LEVEL_11_0 ) 142 | { 143 | m_pContext->HSSetShader( m_pHS, m_pHSClassInstances, m_numHSClassInstances ); 144 | 145 | m_pContext->DSSetShader( m_pDS, m_pDSClassInstances, m_numDSClassInstances ); 146 | } 147 | } 148 | 149 | m_pContext->IASetVertexBuffers( 0, 1, &m_pVB, &m_vertexStride, &m_vertexOffset ); 150 | 151 | m_pContext->IASetIndexBuffer( m_pIndexBuffer, m_indexFormat, m_indexOffset ); 152 | 153 | return S_OK; 154 | } 155 | 156 | void D3D11StateSaver::releaseSavedState() 157 | { 158 | m_primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; 159 | SAFE_RELEASE( m_pInputLayout ); 160 | SAFE_RELEASE( m_pBlendState ); 161 | for ( int i = 0; i < 4; ++i ) 162 | m_blendFactor[ i ] = 0.0f; 163 | m_sampleMask = 0xffffffff; 164 | SAFE_RELEASE( m_pDepthStencilState ); 165 | m_stencilRef = 0; 166 | SAFE_RELEASE( m_pRasterizerState ); 167 | SAFE_RELEASE( m_pPSSRV ); 168 | SAFE_RELEASE( m_pSamplerState ); 169 | SAFE_RELEASE( m_pVS ); 170 | for ( UINT i = 0; i < m_numVSClassInstances; ++i ) 171 | SAFE_RELEASE( m_pVSClassInstances[ i ] ); 172 | m_numVSClassInstances = 0; 173 | SAFE_RELEASE( m_pVSConstantBuffer ); 174 | SAFE_RELEASE( m_pGS ); 175 | for ( UINT i = 0; i < m_numGSClassInstances; ++i ) 176 | SAFE_RELEASE( m_pGSClassInstances[ i ] ); 177 | m_numGSClassInstances = 0; 178 | SAFE_RELEASE( m_pGSConstantBuffer ); 179 | SAFE_RELEASE( m_pGSSRV ); 180 | SAFE_RELEASE( m_pPS ); 181 | for ( UINT i = 0; i < m_numPSClassInstances; ++i ) 182 | SAFE_RELEASE( m_pPSClassInstances[ i ] ); 183 | m_numPSClassInstances = 0; 184 | SAFE_RELEASE( m_pHS ); 185 | for ( UINT i = 0; i < m_numHSClassInstances; ++i ) 186 | SAFE_RELEASE( m_pHSClassInstances[ i ] ); 187 | m_numHSClassInstances = 0; 188 | SAFE_RELEASE( m_pDS ); 189 | for ( UINT i = 0; i < m_numDSClassInstances; ++i ) 190 | SAFE_RELEASE( m_pDSClassInstances[ i ] ); 191 | m_numDSClassInstances = 0; 192 | SAFE_RELEASE( m_pVB ); 193 | m_vertexStride = 0; 194 | m_vertexOffset = 0; 195 | SAFE_RELEASE( m_pIndexBuffer ); 196 | m_indexFormat = DXGI_FORMAT_UNKNOWN; 197 | m_indexOffset = 0; 198 | 199 | SAFE_RELEASE( m_pContext ); 200 | m_featureLevel = D3D_FEATURE_LEVEL_11_0; 201 | 202 | m_savedState = false; 203 | } -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1StateSaver.cpp: -------------------------------------------------------------------------------- 1 | // CFW1StateSaver.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1StateSaver.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1StateSaver::CFW1StateSaver() : 15 | m_savedState(false), 16 | m_featureLevel(D3D_FEATURE_LEVEL_11_0), 17 | m_pContext(NULL), 18 | m_primitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED), 19 | m_pInputLayout(NULL), 20 | m_pBlendState(NULL), 21 | m_sampleMask(0xffffffff), 22 | m_pDepthStencilState(NULL), 23 | m_stencilRef(0), 24 | m_pRasterizerState(NULL), 25 | m_pPSSRV(NULL), 26 | m_pSamplerState(NULL), 27 | m_pVS(NULL), 28 | m_numVSClassInstances(0), 29 | m_pVSConstantBuffer(NULL), 30 | m_pGS(NULL), 31 | m_numGSClassInstances(0), 32 | m_pGSConstantBuffer(NULL), 33 | m_pGSSRV(NULL), 34 | m_pPS(NULL), 35 | m_numPSClassInstances(0), 36 | m_pHS(NULL), 37 | m_numHSClassInstances(0), 38 | m_pDS(NULL), 39 | m_numDSClassInstances(0), 40 | m_pVB(NULL), 41 | m_vertexStride(0), 42 | m_vertexOffset(0), 43 | m_pIndexBuffer(NULL), 44 | m_indexFormat(DXGI_FORMAT_UNKNOWN), 45 | m_indexOffset(0) 46 | { 47 | for(int i=0; i < 4; ++i) 48 | m_blendFactor[i] = 0.0f; 49 | for(int i=0; i < 256; ++i) { 50 | m_pVSClassInstances[i] = NULL; 51 | m_pGSClassInstances[i] = NULL; 52 | m_pPSClassInstances[i] = NULL; 53 | m_pHSClassInstances[i] = NULL; 54 | m_pDSClassInstances[i] = NULL; 55 | } 56 | } 57 | 58 | 59 | // Destruct 60 | CFW1StateSaver::~CFW1StateSaver() { 61 | releaseSavedState(); 62 | } 63 | 64 | 65 | // Save all states that are changed by the font-wrapper when drawing a string 66 | HRESULT CFW1StateSaver::saveCurrentState(ID3D11DeviceContext *pContext) { 67 | if(m_savedState) 68 | releaseSavedState(); 69 | if(pContext == NULL) 70 | return E_INVALIDARG; 71 | 72 | ID3D11Device *pDevice; 73 | pContext->GetDevice(&pDevice); 74 | if(pDevice != NULL) { 75 | m_featureLevel = pDevice->GetFeatureLevel(); 76 | pDevice->Release(); 77 | } 78 | 79 | pContext->AddRef(); 80 | m_pContext = pContext; 81 | 82 | m_pContext->IAGetPrimitiveTopology(&m_primitiveTopology); 83 | m_pContext->IAGetInputLayout(&m_pInputLayout); 84 | 85 | m_pContext->OMGetBlendState(&m_pBlendState, m_blendFactor, &m_sampleMask); 86 | m_pContext->OMGetDepthStencilState(&m_pDepthStencilState, &m_stencilRef); 87 | 88 | m_pContext->RSGetState(&m_pRasterizerState); 89 | 90 | m_numVSClassInstances = 256; 91 | m_pContext->VSGetShader(&m_pVS, m_pVSClassInstances, &m_numVSClassInstances); 92 | m_pContext->VSGetConstantBuffers(0, 1, &m_pVSConstantBuffer); 93 | 94 | m_numPSClassInstances = 256; 95 | m_pContext->PSGetShader(&m_pPS, m_pPSClassInstances, &m_numPSClassInstances); 96 | m_pContext->PSGetShaderResources(0, 1, &m_pPSSRV); 97 | pContext->PSGetSamplers(0, 1, &m_pSamplerState); 98 | 99 | if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0) { 100 | m_numGSClassInstances = 256; 101 | m_pContext->GSGetShader(&m_pGS, m_pGSClassInstances, &m_numGSClassInstances); 102 | m_pContext->GSGetConstantBuffers(0, 1, &m_pGSConstantBuffer); 103 | 104 | m_pContext->GSGetShaderResources(0, 1, &m_pGSSRV); 105 | 106 | if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) { 107 | m_numHSClassInstances = 256; 108 | m_pContext->HSGetShader(&m_pHS, m_pHSClassInstances, &m_numHSClassInstances); 109 | 110 | m_numDSClassInstances = 256; 111 | m_pContext->DSGetShader(&m_pDS, m_pDSClassInstances, &m_numDSClassInstances); 112 | } 113 | } 114 | 115 | m_pContext->IAGetVertexBuffers(0, 1, &m_pVB, &m_vertexStride, &m_vertexOffset); 116 | 117 | m_pContext->IAGetIndexBuffer(&m_pIndexBuffer, &m_indexFormat, &m_indexOffset); 118 | 119 | m_savedState = true; 120 | 121 | return S_OK; 122 | } 123 | 124 | 125 | // Restore state 126 | HRESULT CFW1StateSaver::restoreSavedState() { 127 | if(!m_savedState) 128 | return E_FAIL; 129 | 130 | m_pContext->IASetPrimitiveTopology(m_primitiveTopology); 131 | m_pContext->IASetInputLayout(m_pInputLayout); 132 | 133 | m_pContext->OMSetBlendState(m_pBlendState, m_blendFactor, m_sampleMask); 134 | m_pContext->OMSetDepthStencilState(m_pDepthStencilState, m_stencilRef); 135 | 136 | m_pContext->RSSetState(m_pRasterizerState); 137 | 138 | m_pContext->VSSetShader(m_pVS, m_pVSClassInstances, m_numVSClassInstances); 139 | m_pContext->VSSetConstantBuffers(0, 1, &m_pVSConstantBuffer); 140 | 141 | m_pContext->PSSetShader(m_pPS, m_pPSClassInstances, m_numPSClassInstances); 142 | m_pContext->PSSetShaderResources(0, 1, &m_pPSSRV); 143 | m_pContext->PSSetSamplers(0, 1, &m_pSamplerState); 144 | 145 | if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0) { 146 | m_pContext->GSSetShader(m_pGS, m_pGSClassInstances, m_numGSClassInstances); 147 | m_pContext->GSSetConstantBuffers(0, 1, &m_pGSConstantBuffer); 148 | 149 | m_pContext->GSSetShaderResources(0, 1, &m_pGSSRV); 150 | 151 | if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) { 152 | m_pContext->HSSetShader(m_pHS, m_pHSClassInstances, m_numHSClassInstances); 153 | 154 | m_pContext->DSSetShader(m_pDS, m_pDSClassInstances, m_numDSClassInstances); 155 | } 156 | } 157 | 158 | m_pContext->IASetVertexBuffers(0, 1, &m_pVB, &m_vertexStride, &m_vertexOffset); 159 | 160 | m_pContext->IASetIndexBuffer(m_pIndexBuffer, m_indexFormat, m_indexOffset); 161 | 162 | return S_OK; 163 | } 164 | 165 | 166 | // Release state 167 | void CFW1StateSaver::releaseSavedState() { 168 | m_primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; 169 | SAFE_RELEASE(m_pInputLayout); 170 | SAFE_RELEASE(m_pBlendState); 171 | for(int i=0; i < 4; ++i) 172 | m_blendFactor[i] = 0.0f; 173 | m_sampleMask = 0xffffffff; 174 | SAFE_RELEASE(m_pDepthStencilState); 175 | m_stencilRef = 0; 176 | SAFE_RELEASE(m_pRasterizerState); 177 | SAFE_RELEASE(m_pPSSRV); 178 | SAFE_RELEASE(m_pSamplerState); 179 | SAFE_RELEASE(m_pVS); 180 | for(UINT i=0; i < m_numVSClassInstances; ++i) 181 | SAFE_RELEASE(m_pVSClassInstances[i]); 182 | m_numVSClassInstances = 0; 183 | SAFE_RELEASE(m_pVSConstantBuffer); 184 | SAFE_RELEASE(m_pGS); 185 | for(UINT i=0; i < m_numGSClassInstances; ++i) 186 | SAFE_RELEASE(m_pGSClassInstances[i]); 187 | m_numGSClassInstances = 0; 188 | SAFE_RELEASE(m_pGSConstantBuffer); 189 | SAFE_RELEASE(m_pGSSRV); 190 | SAFE_RELEASE(m_pPS); 191 | for(UINT i=0; i < m_numPSClassInstances; ++i) 192 | SAFE_RELEASE(m_pPSClassInstances[i]); 193 | m_numPSClassInstances = 0; 194 | SAFE_RELEASE(m_pHS); 195 | for(UINT i=0; i < m_numHSClassInstances; ++i) 196 | SAFE_RELEASE(m_pHSClassInstances[i]); 197 | m_numHSClassInstances = 0; 198 | SAFE_RELEASE(m_pDS); 199 | for(UINT i=0; i < m_numDSClassInstances; ++i) 200 | SAFE_RELEASE(m_pDSClassInstances[i]); 201 | m_numDSClassInstances = 0; 202 | SAFE_RELEASE(m_pVB); 203 | m_vertexStride = 0; 204 | m_vertexOffset = 0; 205 | SAFE_RELEASE(m_pIndexBuffer); 206 | m_indexFormat = DXGI_FORMAT_UNKNOWN; 207 | m_indexOffset = 0; 208 | 209 | SAFE_RELEASE(m_pContext); 210 | m_featureLevel = D3D_FEATURE_LEVEL_11_0; 211 | 212 | m_savedState = false; 213 | } 214 | 215 | 216 | }// namespace FW1FontWrapper 217 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1TextRendererInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1TextRendererInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1TextRenderer.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1TextRenderer::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IDWritePixelSnapping))) { 17 | *ppvObject = static_cast(m_pDWriteTextRendererProxy); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | else if(IsEqualIID(riid, __uuidof(IDWriteTextRenderer))) { 22 | *ppvObject = static_cast(m_pDWriteTextRendererProxy); 23 | AddRef(); 24 | return S_OK; 25 | } 26 | else if(IsEqualIID(riid, __uuidof(IFW1TextRenderer))) { 27 | *ppvObject = static_cast(this); 28 | AddRef(); 29 | return S_OK; 30 | } 31 | 32 | return CFW1Object::QueryInterface(riid, ppvObject); 33 | } 34 | 35 | 36 | // IDWritePixelSnapping method 37 | HRESULT CFW1TextRenderer::IsPixelSnappingDisabled( 38 | void *clientDrawingContext, 39 | BOOL *isDisabled 40 | ) { 41 | clientDrawingContext; 42 | 43 | *isDisabled = FALSE; 44 | 45 | return S_OK; 46 | } 47 | 48 | 49 | // IDWritePixelSnapping method 50 | HRESULT CFW1TextRenderer::GetCurrentTransform( 51 | void *clientDrawingContext, 52 | DWRITE_MATRIX *transform 53 | ) { 54 | clientDrawingContext; 55 | 56 | transform->dx = 0.0f; 57 | transform->dy = 0.0f; 58 | transform->m11 = 1.0f; 59 | transform->m12 = 0.0f; 60 | transform->m21 = 0.0f; 61 | transform->m22 = 1.0f; 62 | 63 | return S_OK; 64 | } 65 | 66 | 67 | // IDWritePixelSnapping method 68 | HRESULT CFW1TextRenderer::GetPixelsPerDip(void *clientDrawingContext, FLOAT *pixelsPerDip) { 69 | clientDrawingContext; 70 | 71 | *pixelsPerDip = 96.0f; 72 | 73 | return S_OK; 74 | } 75 | 76 | 77 | // IDWriteTextRenderer method 78 | // Convert a run of glyphs to vertices 79 | HRESULT CFW1TextRenderer::DrawGlyphRun( 80 | void *clientDrawingContext, 81 | FLOAT baselineOriginX, 82 | FLOAT baselineOriginY, 83 | DWRITE_MEASURING_MODE measuringMode, 84 | const DWRITE_GLYPH_RUN *glyphRun, 85 | const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, 86 | IUnknown *clientDrawingEffect 87 | ) { 88 | glyphRunDescription; 89 | measuringMode; 90 | 91 | const UINT flags = m_currentFlags; 92 | 93 | // Get glyph map for the current font 94 | const void *glyphMap; 95 | if(glyphRun->fontFace == m_pCachedGlyphMapFontFace && glyphRun->fontEmSize == m_cachedGlyphMapFontSize) 96 | glyphMap = m_cachedGlyphMap; 97 | else { 98 | glyphMap = m_pGlyphProvider->GetGlyphMapFromFont(glyphRun->fontFace, glyphRun->fontEmSize, flags); 99 | 100 | // Cache the glyph map as it's likely to be used in subsequent glyph runs 101 | m_cachedGlyphMap = glyphMap; 102 | m_pCachedGlyphMapFontFace = glyphRun->fontFace; 103 | m_cachedGlyphMapFontSize = glyphRun->fontEmSize; 104 | } 105 | 106 | // Skip if not interested in the actual glyphs 107 | if((flags & FW1_ANALYZEONLY) != 0) 108 | return S_OK; 109 | 110 | if((flags & FW1_CACHEONLY) != 0) { 111 | // Only request the glyphs from the provider to have them drawn to the atlas 112 | for(UINT i=0; i < glyphRun->glyphCount; ++i) { 113 | UINT atlasId = m_pGlyphProvider->GetAtlasIdFromGlyphIndex( 114 | glyphMap, 115 | glyphRun->glyphIndices[i], 116 | glyphRun->fontFace, 117 | flags 118 | ); 119 | atlasId; 120 | } 121 | } 122 | else { 123 | // Glyph vertex 124 | FW1_GLYPHVERTEX glyphVertex; 125 | glyphVertex.PositionY = floor(baselineOriginY + 0.5f); 126 | glyphVertex.GlyphColor = m_currentColor; 127 | 128 | float positionX = floor(baselineOriginX + 0.5f); 129 | 130 | // Optional drawing effect 131 | if(clientDrawingEffect != NULL) { 132 | IFW1ColorRGBA *pColor; 133 | HRESULT hResult = clientDrawingEffect->QueryInterface(&pColor); 134 | if(SUCCEEDED(hResult)) { 135 | glyphVertex.GlyphColor = pColor->GetColor32(); 136 | pColor->Release(); 137 | } 138 | } 139 | 140 | // Add a vertex for each glyph in the run 141 | IFW1TextGeometry *pTextGeometry = static_cast(clientDrawingContext); 142 | if(pTextGeometry != NULL) { 143 | for(UINT i=0; i < glyphRun->glyphCount; ++i) { 144 | glyphVertex.GlyphIndex = m_pGlyphProvider->GetAtlasIdFromGlyphIndex( 145 | glyphMap, 146 | glyphRun->glyphIndices[i], 147 | glyphRun->fontFace, 148 | flags 149 | ); 150 | 151 | if((glyphRun->bidiLevel & 0x1) != 0) 152 | positionX -= glyphRun->glyphAdvances[i]; 153 | 154 | glyphVertex.PositionX = floor(positionX + 0.5f); 155 | pTextGeometry->AddGlyphVertex(&glyphVertex); 156 | 157 | if((glyphRun->bidiLevel & 0x1) == 0) 158 | positionX += glyphRun->glyphAdvances[i]; 159 | } 160 | } 161 | } 162 | 163 | return S_OK; 164 | } 165 | 166 | 167 | // IDWriteTextRenderer method 168 | HRESULT CFW1TextRenderer::DrawUnderline( 169 | void *clientDrawingContext, 170 | FLOAT baselineOriginX, 171 | FLOAT baselineOriginY, 172 | const DWRITE_UNDERLINE *underline, 173 | IUnknown *clientDrawingEffect 174 | ) { 175 | clientDrawingContext; 176 | baselineOriginX; 177 | baselineOriginY; 178 | underline; 179 | clientDrawingEffect; 180 | 181 | return E_NOTIMPL; 182 | } 183 | 184 | 185 | // IDWriteTextRenderer method 186 | HRESULT CFW1TextRenderer::DrawStrikethrough( 187 | void *clientDrawingContext, 188 | FLOAT baselineOriginX, 189 | FLOAT baselineOriginY, 190 | const DWRITE_STRIKETHROUGH *strikethrough, 191 | IUnknown *clientDrawingEffect 192 | ) { 193 | clientDrawingContext; 194 | baselineOriginX; 195 | baselineOriginY; 196 | strikethrough; 197 | clientDrawingEffect; 198 | 199 | return E_NOTIMPL; 200 | } 201 | 202 | 203 | // IDWriteTextRenderer method 204 | HRESULT CFW1TextRenderer::DrawInlineObject( 205 | void *clientDrawingContext, 206 | FLOAT originX, 207 | FLOAT originY, 208 | IDWriteInlineObject *inlineObject, 209 | BOOL isSideways, 210 | BOOL isRightToLeft, 211 | IUnknown *clientDrawingEffect 212 | ) { 213 | clientDrawingContext; 214 | originX; 215 | originY; 216 | inlineObject; 217 | isSideways; 218 | isRightToLeft; 219 | clientDrawingEffect; 220 | 221 | return E_NOTIMPL; 222 | } 223 | 224 | 225 | // Get glyph provider 226 | HRESULT STDMETHODCALLTYPE CFW1TextRenderer::GetGlyphProvider(IFW1GlyphProvider **ppGlyphProvider) { 227 | if(ppGlyphProvider == NULL) 228 | return E_INVALIDARG; 229 | 230 | m_pGlyphProvider->AddRef(); 231 | *ppGlyphProvider = m_pGlyphProvider; 232 | 233 | return S_OK; 234 | } 235 | 236 | 237 | // Draw a text layout 238 | HRESULT STDMETHODCALLTYPE CFW1TextRenderer::DrawTextLayout( 239 | IDWriteTextLayout *pTextLayout, 240 | FLOAT OriginX, 241 | FLOAT OriginY, 242 | UINT32 Color, 243 | UINT Flags, 244 | IFW1TextGeometry *pTextGeometry 245 | ) { 246 | m_currentFlags = Flags; 247 | m_currentColor = Color; 248 | 249 | m_cachedGlyphMap = 0; 250 | m_pCachedGlyphMapFontFace = NULL; 251 | m_cachedGlyphMapFontSize = 0.0f; 252 | 253 | return pTextLayout->Draw(pTextGeometry, m_pDWriteTextRendererProxy, OriginX, OriginY); 254 | } 255 | 256 | 257 | }// namespace FW1FontWrapper 258 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphSheet.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphSheet.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphSheet.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1GlyphSheet::CFW1GlyphSheet() : 15 | m_sheetWidth(0), 16 | m_sheetHeight(0), 17 | m_hardwareCoordBuffer(false), 18 | m_allowOversizedGlyph(false), 19 | 20 | m_textureData(0), 21 | m_glyphCoords(0), 22 | m_maxGlyphCount(0), 23 | m_glyphCount(0), 24 | m_mipLevelCount(0), 25 | m_alignWidth(0), 26 | 27 | m_pDevice(NULL), 28 | 29 | m_pTexture(NULL), 30 | m_pTextureSRV(NULL), 31 | m_pCoordBuffer(NULL), 32 | m_pCoordBufferSRV(NULL), 33 | 34 | m_closed(false), 35 | m_static(false), 36 | 37 | m_heightRange(0), 38 | 39 | m_updatedGlyphCount(0) 40 | { 41 | ZeroMemory(&m_dirtyRect, sizeof(m_dirtyRect)); 42 | InitializeCriticalSection(&m_sheetCriticalSection); 43 | InitializeCriticalSection(&m_flushCriticalSection); 44 | } 45 | 46 | 47 | // Destruct 48 | CFW1GlyphSheet::~CFW1GlyphSheet() { 49 | delete[] m_textureData; 50 | delete[] m_glyphCoords; 51 | 52 | SAFE_RELEASE(m_pDevice); 53 | 54 | SAFE_RELEASE(m_pTexture); 55 | SAFE_RELEASE(m_pTextureSRV); 56 | SAFE_RELEASE(m_pCoordBuffer); 57 | SAFE_RELEASE(m_pCoordBufferSRV); 58 | 59 | delete m_heightRange; 60 | 61 | DeleteCriticalSection(&m_sheetCriticalSection); 62 | DeleteCriticalSection(&m_flushCriticalSection); 63 | } 64 | 65 | 66 | // Init 67 | HRESULT CFW1GlyphSheet::initGlyphSheet( 68 | IFW1Factory *pFW1Factory, 69 | ID3D11Device *pDevice, 70 | UINT sheetWidth, 71 | UINT sheetHeight, 72 | bool coordBuffer, 73 | bool allowOversizedGlyph, 74 | UINT maxGlyphCount, 75 | UINT mipLevelCount 76 | ) { 77 | HRESULT hResult = initBaseObject(pFW1Factory); 78 | if(FAILED(hResult)) 79 | return hResult; 80 | 81 | if(pDevice == NULL) 82 | return E_INVALIDARG; 83 | 84 | pDevice->AddRef(); 85 | m_pDevice = pDevice; 86 | 87 | // Sheet metrics 88 | m_sheetWidth = 512; 89 | if(sheetWidth > 0) 90 | m_sheetWidth = sheetWidth; 91 | m_sheetHeight = 512; 92 | if(sheetHeight > 0) 93 | m_sheetHeight = sheetHeight; 94 | 95 | if(coordBuffer) { 96 | D3D_FEATURE_LEVEL featureLevel = m_pDevice->GetFeatureLevel(); 97 | if(featureLevel >= D3D_FEATURE_LEVEL_10_0) 98 | m_hardwareCoordBuffer = true; 99 | } 100 | 101 | m_allowOversizedGlyph = allowOversizedGlyph; 102 | 103 | m_maxGlyphCount = 2048; 104 | if(maxGlyphCount > 0 && maxGlyphCount < 65535) 105 | m_maxGlyphCount = maxGlyphCount; 106 | 107 | if(mipLevelCount > 1) { 108 | m_mipLevelCount = std::min(mipLevelCount, 5U);// Reasonable mip limit considering borders 109 | m_alignWidth = (1 << (m_mipLevelCount - 1)); 110 | } 111 | else {// 0 defaults to 1 112 | m_mipLevelCount = 1; 113 | m_alignWidth = 1; 114 | } 115 | 116 | // Storage 117 | UINT textureSize = m_sheetWidth * m_sheetHeight; 118 | UINT mipSize = textureSize; 119 | for(UINT i=1;i>= 2; 121 | textureSize += mipSize; 122 | } 123 | 124 | m_textureData = new UINT8[textureSize]; 125 | ZeroMemory(m_textureData, textureSize); 126 | 127 | m_glyphCoords = new FW1_GLYPHCOORDS[m_maxGlyphCount]; 128 | 129 | m_heightRange = new HeightRange(m_sheetWidth / m_alignWidth); 130 | 131 | // Device texture/coord-buffer 132 | hResult = createDeviceResources(); 133 | 134 | if(SUCCEEDED(hResult)) 135 | hResult = S_OK; 136 | 137 | return hResult; 138 | } 139 | 140 | 141 | // Create sheet texture and (optionally) coord buffer 142 | HRESULT CFW1GlyphSheet::createDeviceResources() { 143 | // Create sheet texture 144 | D3D11_TEXTURE2D_DESC textureDesc; 145 | ID3D11Texture2D *pTexture; 146 | 147 | ZeroMemory(&textureDesc, sizeof(textureDesc)); 148 | textureDesc.Width = m_sheetWidth; 149 | textureDesc.Height = m_sheetHeight; 150 | textureDesc.ArraySize = 1; 151 | textureDesc.Format = DXGI_FORMAT_R8_UNORM; 152 | textureDesc.SampleDesc.Count = 1; 153 | textureDesc.Usage = D3D11_USAGE_DEFAULT; 154 | textureDesc.MipLevels = m_mipLevelCount; 155 | textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 156 | 157 | HRESULT hResult = m_pDevice->CreateTexture2D(&textureDesc, NULL, &pTexture); 158 | if(FAILED(hResult)) { 159 | m_lastError = L"Failed to create glyph sheet texture"; 160 | } 161 | else { 162 | ID3D11ShaderResourceView *pTextureSRV; 163 | 164 | hResult = m_pDevice->CreateShaderResourceView(pTexture, NULL, &pTextureSRV); 165 | if(FAILED(hResult)) { 166 | m_lastError = L"Failed to create shader resource view for glyph sheet texture"; 167 | } 168 | else { 169 | // Create coord buffer if enabled 170 | if(m_hardwareCoordBuffer) { 171 | D3D11_BUFFER_DESC bufferDesc; 172 | ID3D11Buffer *pBuffer; 173 | 174 | ZeroMemory(&bufferDesc, sizeof(bufferDesc)); 175 | bufferDesc.ByteWidth = m_maxGlyphCount * sizeof(FW1_GLYPHCOORDS); 176 | bufferDesc.Usage = D3D11_USAGE_DEFAULT; 177 | bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 178 | 179 | hResult = m_pDevice->CreateBuffer(&bufferDesc, NULL, &pBuffer); 180 | if(FAILED(hResult)) { 181 | m_lastError = L"Failed to create glyph coord buffer"; 182 | } 183 | else { 184 | D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; 185 | ID3D11ShaderResourceView *pBufferSRV; 186 | 187 | ZeroMemory(&bufferSRVDesc, sizeof(bufferSRVDesc)); 188 | bufferSRVDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; 189 | bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; 190 | bufferSRVDesc.Buffer.ElementOffset = 0; 191 | bufferSRVDesc.Buffer.ElementWidth = m_maxGlyphCount * 2;// Two float4 per glyphcoords 192 | 193 | hResult = m_pDevice->CreateShaderResourceView(pBuffer, &bufferSRVDesc, &pBufferSRV); 194 | if(FAILED(hResult)) { 195 | m_lastError = L"Failed to create shader resource view for glyph coord buffer"; 196 | } 197 | else { 198 | m_pCoordBuffer = pBuffer; 199 | m_pCoordBufferSRV = pBufferSRV; 200 | } 201 | 202 | if(FAILED(hResult)) 203 | pBuffer->Release(); 204 | } 205 | } 206 | 207 | if(SUCCEEDED(hResult)) { 208 | m_pTexture = pTexture; 209 | m_pTextureSRV = pTextureSRV; 210 | } 211 | else 212 | pTextureSRV->Release(); 213 | } 214 | 215 | if(FAILED(hResult)) 216 | pTexture->Release(); 217 | } 218 | 219 | return hResult; 220 | } 221 | 222 | 223 | // Height-range helper class, used to fit glyphs in the sheet 224 | 225 | CFW1GlyphSheet::HeightRange::HeightRange(UINT totalWidth) : m_totalWidth(totalWidth) { 226 | m_heights = new UINT[m_totalWidth]; 227 | ZeroMemory(m_heights, m_totalWidth * sizeof(UINT)); 228 | } 229 | 230 | CFW1GlyphSheet::HeightRange::~HeightRange() { 231 | delete[] m_heights; 232 | } 233 | 234 | UINT CFW1GlyphSheet::HeightRange::findMin(UINT width, UINT *outMin) { 235 | if(width > m_totalWidth) 236 | width = m_totalWidth; 237 | 238 | UINT currentMax = findMax(0, width); 239 | UINT currentMin = currentMax; 240 | UINT minX = 0; 241 | 242 | for(UINT i=1; i < m_totalWidth-width; ++i) { 243 | if(m_heights[i+width-1] >= currentMax) 244 | currentMax = m_heights[i+width-1]; 245 | else if(m_heights[i-1] == currentMax) { 246 | currentMax = findMax(i, width); 247 | if(currentMax < currentMin) { 248 | currentMin = currentMax; 249 | minX = i; 250 | } 251 | } 252 | } 253 | 254 | *outMin = currentMin; 255 | return minX; 256 | } 257 | 258 | void CFW1GlyphSheet::HeightRange::update(UINT startX, UINT width, UINT newHeight) { 259 | if(width > m_totalWidth) 260 | width = m_totalWidth; 261 | 262 | for(UINT i=0; i < width; ++i) 263 | m_heights[startX+i] = newHeight; 264 | } 265 | 266 | UINT CFW1GlyphSheet::HeightRange::findMax(UINT startX, UINT width) { 267 | UINT currentMax = m_heights[startX]; 268 | for(UINT i=1; i < width; ++i) 269 | currentMax = std::max(currentMax, m_heights[startX+i]); 270 | 271 | return currentMax; 272 | } 273 | 274 | 275 | }// namespace FW1FontWrapper 276 | -------------------------------------------------------------------------------- /dwmhook/dwmhook.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | {BF574599-3CE2-4360-B229-D747272D45CF} 16 | dwmhook 17 | 10.0 18 | 19 | 20 | 21 | DynamicLibrary 22 | true 23 | v142 24 | Unicode 25 | 26 | 27 | DynamicLibrary 28 | false 29 | v142 30 | true 31 | MultiByte 32 | false 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | 49 | 50 | false 51 | 52 | 53 | 54 | Level3 55 | true 56 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 57 | true 58 | true 59 | 60 | 61 | Console 62 | true 63 | 64 | 65 | 66 | 67 | Level3 68 | true 69 | false 70 | true 71 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 72 | true 73 | MultiThreaded 74 | stdcpp17 75 | true 76 | Full 77 | false 78 | stdc17 79 | 80 | 81 | Console 82 | true 83 | true 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /dwmhook/MinHook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) 32 | #error MinHook supports only x86 and x64 systems. 33 | #endif 34 | 35 | #include 36 | 37 | // MinHook Error Codes. 38 | typedef enum MH_STATUS 39 | { 40 | // Unknown error. Should not be returned. 41 | MH_UNKNOWN = -1, 42 | 43 | // Successful. 44 | MH_OK = 0, 45 | 46 | // MinHook is already initialized. 47 | MH_ERROR_ALREADY_INITIALIZED, 48 | 49 | // MinHook is not initialized yet, or already uninitialized. 50 | MH_ERROR_NOT_INITIALIZED, 51 | 52 | // The hook for the specified target function is already created. 53 | MH_ERROR_ALREADY_CREATED, 54 | 55 | // The hook for the specified target function is not created yet. 56 | MH_ERROR_NOT_CREATED, 57 | 58 | // The hook for the specified target function is already enabled. 59 | MH_ERROR_ENABLED, 60 | 61 | // The hook for the specified target function is not enabled yet, or already 62 | // disabled. 63 | MH_ERROR_DISABLED, 64 | 65 | // The specified pointer is invalid. It points the address of non-allocated 66 | // and/or non-executable region. 67 | MH_ERROR_NOT_EXECUTABLE, 68 | 69 | // The specified target function cannot be hooked. 70 | MH_ERROR_UNSUPPORTED_FUNCTION, 71 | 72 | // Failed to allocate memory. 73 | MH_ERROR_MEMORY_ALLOC, 74 | 75 | // Failed to change the memory protection. 76 | MH_ERROR_MEMORY_PROTECT, 77 | 78 | // The specified module is not loaded. 79 | MH_ERROR_MODULE_NOT_FOUND, 80 | 81 | // The specified function is not found. 82 | MH_ERROR_FUNCTION_NOT_FOUND 83 | } 84 | MH_STATUS; 85 | 86 | // Can be passed as a parameter to MH_EnableHook, MH_DisableHook, 87 | // MH_QueueEnableHook or MH_QueueDisableHook. 88 | #define MH_ALL_HOOKS NULL 89 | 90 | #ifdef __cplusplus 91 | extern "C" { 92 | #endif 93 | 94 | // Initialize the MinHook library. You must call this function EXACTLY ONCE 95 | // at the beginning of your program. 96 | MH_STATUS WINAPI MH_Initialize(VOID); 97 | 98 | // Uninitialize the MinHook library. You must call this function EXACTLY 99 | // ONCE at the end of your program. 100 | MH_STATUS WINAPI MH_Uninitialize(VOID); 101 | 102 | // Creates a Hook for the specified target function, in disabled state. 103 | // Parameters: 104 | // pTarget [in] A pointer to the target function, which will be 105 | // overridden by the detour function. 106 | // pDetour [in] A pointer to the detour function, which will override 107 | // the target function. 108 | // ppOriginal [out] A pointer to the trampoline function, which will be 109 | // used to call the original target function. 110 | // This parameter can be NULL. 111 | MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); 112 | 113 | // Creates a Hook for the specified API function, in disabled state. 114 | // Parameters: 115 | // pszModule [in] A pointer to the loaded module name which contains the 116 | // target function. 117 | // pszTarget [in] A pointer to the target function name, which will be 118 | // overridden by the detour function. 119 | // pDetour [in] A pointer to the detour function, which will override 120 | // the target function. 121 | // ppOriginal [out] A pointer to the trampoline function, which will be 122 | // used to call the original target function. 123 | // This parameter can be NULL. 124 | MH_STATUS WINAPI MH_CreateHookApi( 125 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); 126 | 127 | // Creates a Hook for the specified API function, in disabled state. 128 | // Parameters: 129 | // pszModule [in] A pointer to the loaded module name which contains the 130 | // target function. 131 | // pszTarget [in] A pointer to the target function name, which will be 132 | // overridden by the detour function. 133 | // pDetour [in] A pointer to the detour function, which will override 134 | // the target function. 135 | // ppOriginal [out] A pointer to the trampoline function, which will be 136 | // used to call the original target function. 137 | // This parameter can be NULL. 138 | // ppTarget [out] A pointer to the target function, which will be used 139 | // with other functions. 140 | // This parameter can be NULL. 141 | MH_STATUS WINAPI MH_CreateHookApiEx( 142 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); 143 | 144 | // Removes an already created hook. 145 | // Parameters: 146 | // pTarget [in] A pointer to the target function. 147 | MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); 148 | 149 | // Enables an already created hook. 150 | // Parameters: 151 | // pTarget [in] A pointer to the target function. 152 | // If this parameter is MH_ALL_HOOKS, all created hooks are 153 | // enabled in one go. 154 | MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); 155 | 156 | // Disables an already created hook. 157 | // Parameters: 158 | // pTarget [in] A pointer to the target function. 159 | // If this parameter is MH_ALL_HOOKS, all created hooks are 160 | // disabled in one go. 161 | MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); 162 | 163 | // Queues to enable an already created hook. 164 | // Parameters: 165 | // pTarget [in] A pointer to the target function. 166 | // If this parameter is MH_ALL_HOOKS, all created hooks are 167 | // queued to be enabled. 168 | MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); 169 | 170 | // Queues to disable an already created hook. 171 | // Parameters: 172 | // pTarget [in] A pointer to the target function. 173 | // If this parameter is MH_ALL_HOOKS, all created hooks are 174 | // queued to be disabled. 175 | MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); 176 | 177 | // Applies all queued changes in one go. 178 | MH_STATUS WINAPI MH_ApplyQueued(VOID); 179 | 180 | // Translates the MH_STATUS to its name as a string. 181 | const char * WINAPI MH_StatusToString(MH_STATUS status); 182 | 183 | #ifdef __cplusplus 184 | } 185 | #endif 186 | 187 | -------------------------------------------------------------------------------- /dwmhook/dwmhook.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {7989d646-c2e6-4bbb-8e6c-22be8b25e22b} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files\FW1 32 | 33 | 34 | Header Files\FW1 35 | 36 | 37 | Header Files\FW1 38 | 39 | 40 | Header Files\FW1 41 | 42 | 43 | Header Files\FW1 44 | 45 | 46 | Header Files\FW1 47 | 48 | 49 | Header Files\FW1 50 | 51 | 52 | Header Files\FW1 53 | 54 | 55 | Header Files\FW1 56 | 57 | 58 | Header Files\FW1 59 | 60 | 61 | Header Files\FW1 62 | 63 | 64 | Header Files\FW1 65 | 66 | 67 | Header Files\FW1 68 | 69 | 70 | Header Files\FW1 71 | 72 | 73 | Header Files\FW1 74 | 75 | 76 | Header Files\FW1 77 | 78 | 79 | Header Files\FW1 80 | 81 | 82 | Header Files\FW1 83 | 84 | 85 | Header Files\FW1 86 | 87 | 88 | Header Files\FW1 89 | 90 | 91 | Header Files\FW1 92 | 93 | 94 | Header Files\FW1 95 | 96 | 97 | Header Files\FW1 98 | 99 | 100 | Header Files\FW1 101 | 102 | 103 | Header Files\FW1 104 | 105 | 106 | Source Files 107 | 108 | 109 | Source Files 110 | 111 | 112 | Source Files 113 | 114 | 115 | Source Files 116 | 117 | 118 | Source Files 119 | 120 | 121 | Source Files 122 | 123 | 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files 130 | 131 | 132 | Header Files 133 | 134 | 135 | Header Files\FW1 136 | 137 | 138 | Header Files\FW1 139 | 140 | 141 | Header Files\FW1 142 | 143 | 144 | Header Files\FW1 145 | 146 | 147 | Header Files\FW1 148 | 149 | 150 | Header Files\FW1 151 | 152 | 153 | Header Files\FW1 154 | 155 | 156 | Header Files\FW1 157 | 158 | 159 | Header Files\FW1 160 | 161 | 162 | Header Files\FW1 163 | 164 | 165 | Header Files\FW1 166 | 167 | 168 | Header Files\FW1 169 | 170 | 171 | Header Files\FW1 172 | 173 | 174 | Header Files\FW1 175 | 176 | 177 | Header Files\FW1 178 | 179 | 180 | Header Files\FW1 181 | 182 | 183 | Header Files 184 | 185 | 186 | Header Files 187 | 188 | 189 | Header Files 190 | 191 | 192 | Header Files 193 | 194 | 195 | Header Files 196 | 197 | 198 | Header Files 199 | 200 | 201 | Header Files 202 | 203 | 204 | Header Files 205 | 206 | 207 | Header Files 208 | 209 | 210 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphProvider.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphProvider.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphProvider.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1GlyphProvider::CFW1GlyphProvider() : 15 | m_pGlyphAtlas(NULL), 16 | 17 | m_pDWriteFactory(NULL), 18 | m_maxGlyphWidth(0), 19 | m_maxGlyphHeight(0), 20 | 21 | m_pFontCollection(NULL) 22 | { 23 | InitializeCriticalSection(&m_renderTargetsCriticalSection); 24 | InitializeCriticalSection(&m_glyphMapsCriticalSection); 25 | InitializeCriticalSection(&m_fontsCriticalSection); 26 | InitializeCriticalSection(&m_insertGlyphCriticalSection); 27 | } 28 | 29 | 30 | // Destruct 31 | CFW1GlyphProvider::~CFW1GlyphProvider() { 32 | SAFE_RELEASE(m_pGlyphAtlas); 33 | 34 | SAFE_RELEASE(m_pDWriteFactory); 35 | 36 | while(!m_glyphRenderTargets.empty()) { 37 | m_glyphRenderTargets.top()->Release(); 38 | m_glyphRenderTargets.pop(); 39 | } 40 | 41 | SAFE_RELEASE(m_pFontCollection); 42 | for(size_t i=0; i < m_fonts.size(); ++i) 43 | SAFE_RELEASE(m_fonts[i].pFontFace); 44 | 45 | for(FontMap::iterator it = m_fontMap.begin(); it != m_fontMap.end(); ++it) { 46 | GlyphMap *glyphMap = (*it).second; 47 | 48 | delete[] glyphMap->glyphs; 49 | delete glyphMap; 50 | } 51 | 52 | DeleteCriticalSection(&m_renderTargetsCriticalSection); 53 | DeleteCriticalSection(&m_glyphMapsCriticalSection); 54 | DeleteCriticalSection(&m_fontsCriticalSection); 55 | DeleteCriticalSection(&m_insertGlyphCriticalSection); 56 | } 57 | 58 | 59 | // Init glyph provider 60 | HRESULT CFW1GlyphProvider::initGlyphProvider( 61 | IFW1Factory *pFW1Factory, 62 | IFW1GlyphAtlas *pGlyphAtlas, 63 | IDWriteFactory *pDWriteFactory, 64 | IDWriteFontCollection *pFontCollection, 65 | UINT maxGlyphWidth, 66 | UINT maxGlyphHeight 67 | ) { 68 | HRESULT hResult = initBaseObject(pFW1Factory); 69 | if(FAILED(hResult)) 70 | return hResult; 71 | 72 | if(pGlyphAtlas == NULL || pDWriteFactory == NULL || pFontCollection == NULL) 73 | return E_INVALIDARG; 74 | 75 | pGlyphAtlas->AddRef(); 76 | m_pGlyphAtlas = pGlyphAtlas; 77 | 78 | pDWriteFactory->AddRef(); 79 | m_pDWriteFactory = pDWriteFactory; 80 | 81 | m_maxGlyphWidth = 384; 82 | if(maxGlyphWidth > 0 && maxGlyphWidth <= 8192) 83 | m_maxGlyphWidth = maxGlyphWidth; 84 | m_maxGlyphHeight = 384; 85 | if(maxGlyphHeight > 0 && maxGlyphHeight <= 8192) 86 | m_maxGlyphHeight = maxGlyphHeight; 87 | 88 | pFontCollection->AddRef(); 89 | m_pFontCollection = pFontCollection; 90 | 91 | return S_OK; 92 | } 93 | 94 | 95 | // Get font index from DWrite font-face 96 | UINT CFW1GlyphProvider::getFontIndexFromFontFace(IDWriteFontFace *pFontFace) { 97 | UINT fontIndex = 0xffffffff; 98 | 99 | EnterCriticalSection(&m_fontsCriticalSection); 100 | 101 | // Search for a matching fontface by pointer 102 | for(size_t i=0; i < m_fonts.size(); ++i) { 103 | const FontInfo &fontInfo = m_fonts[i]; 104 | 105 | if(pFontFace == fontInfo.pFontFace) { 106 | fontIndex = static_cast(i); 107 | break; 108 | } 109 | } 110 | 111 | LeaveCriticalSection(&m_fontsCriticalSection); 112 | 113 | // Get font-face name 114 | if(fontIndex == 0xffffffff) { 115 | std::wstring uniqueName = getUniqueNameFromFontFace(pFontFace); 116 | if(uniqueName.size() > 0) { 117 | IDWriteFontFace *pOldFontFace = NULL; 118 | 119 | pFontFace->AddRef(); 120 | 121 | EnterCriticalSection(&m_fontsCriticalSection); 122 | 123 | // Search for a matching fontface by name 124 | for(size_t i=0; i < m_fonts.size(); ++i) { 125 | FontInfo &fontInfo = m_fonts[i]; 126 | 127 | if(fontInfo.uniqueName == uniqueName) { 128 | pOldFontFace = fontInfo.pFontFace; 129 | fontInfo.pFontFace = pFontFace; 130 | fontIndex = static_cast(i); 131 | break; 132 | } 133 | } 134 | 135 | // Add new font 136 | if(fontIndex == 0xffffffff) { 137 | FontInfo fontInfo; 138 | 139 | fontInfo.pFontFace = pFontFace; 140 | fontInfo.uniqueName = uniqueName; 141 | 142 | fontIndex = static_cast(m_fonts.size()); 143 | m_fonts.push_back(fontInfo); 144 | } 145 | 146 | LeaveCriticalSection(&m_fontsCriticalSection); 147 | 148 | SAFE_RELEASE(pOldFontFace); 149 | } 150 | else 151 | fontIndex = 0; 152 | } 153 | 154 | return fontIndex; 155 | } 156 | 157 | 158 | // Get unique name for a DWrite font-face 159 | std::wstring CFW1GlyphProvider::getUniqueNameFromFontFace(IDWriteFontFace *pFontFace) { 160 | std::wstring uniqueName; 161 | 162 | IDWriteFont *pFont; 163 | HRESULT hResult = m_pFontCollection->GetFontFromFontFace(pFontFace, &pFont); 164 | if(SUCCEEDED(hResult)) { 165 | // Family name 166 | IDWriteFontFamily *pFontFamily; 167 | hResult = pFont->GetFontFamily(&pFontFamily); 168 | if(SUCCEEDED(hResult)) { 169 | IDWriteLocalizedStrings *pFamilyNames; 170 | hResult = pFontFamily->GetFamilyNames(&pFamilyNames); 171 | if(SUCCEEDED(hResult)) { 172 | UINT32 index; 173 | BOOL exists; 174 | hResult = pFamilyNames->FindLocaleName(L"en-us", &index, &exists); 175 | if(FAILED(hResult) || !exists) 176 | index = 0; 177 | 178 | if(pFamilyNames->GetCount() > index) { 179 | UINT32 length; 180 | hResult = pFamilyNames->GetStringLength(index, &length); 181 | if(SUCCEEDED(hResult)) { 182 | std::vector str(length+1); 183 | 184 | hResult = pFamilyNames->GetString(index, &str[0], length+1); 185 | if(SUCCEEDED(hResult)) 186 | uniqueName = &str[0]; 187 | } 188 | } 189 | 190 | pFamilyNames->Release(); 191 | } 192 | 193 | pFontFamily->Release(); 194 | } 195 | 196 | // Face name 197 | IDWriteLocalizedStrings *pFaceNames; 198 | hResult = pFont->GetFaceNames(&pFaceNames); 199 | if(SUCCEEDED(hResult)) { 200 | UINT32 index; 201 | BOOL exists; 202 | hResult = pFaceNames->FindLocaleName(L"en-us", &index, &exists); 203 | if(FAILED(hResult) || !exists) 204 | index = 0; 205 | 206 | if(pFaceNames->GetCount() > index) { 207 | UINT32 length; 208 | hResult = pFaceNames->GetStringLength(index, &length); 209 | if(SUCCEEDED(hResult)) { 210 | std::vector str(length+1); 211 | 212 | hResult = pFaceNames->GetString(index, &str[0], length+1); 213 | if(SUCCEEDED(hResult)) 214 | uniqueName.append(&str[0]); 215 | } 216 | } 217 | 218 | pFaceNames->Release(); 219 | } 220 | 221 | // Simulations 222 | if(uniqueName.size() > 0) { 223 | DWRITE_FONT_SIMULATIONS simulations = pFontFace->GetSimulations(); 224 | if(simulations == DWRITE_FONT_SIMULATIONS_BOLD) 225 | uniqueName += L"SimBold"; 226 | else if(simulations == DWRITE_FONT_SIMULATIONS_OBLIQUE) 227 | uniqueName += L"SimOblique"; 228 | } 229 | } 230 | 231 | return uniqueName; 232 | } 233 | 234 | 235 | // Render and insert new glyph into a glyph-map 236 | UINT CFW1GlyphProvider::insertNewGlyph(GlyphMap *glyphMap, UINT16 glyphIndex, IDWriteFontFace *pFontFace) { 237 | UINT glyphAtlasId = 0xffffffff; 238 | 239 | // Get a render target 240 | IFW1DWriteRenderTarget *pRenderTarget = NULL; 241 | 242 | EnterCriticalSection(&m_renderTargetsCriticalSection); 243 | 244 | if(!m_glyphRenderTargets.empty()) { 245 | pRenderTarget = m_glyphRenderTargets.top(); 246 | m_glyphRenderTargets.pop(); 247 | } 248 | 249 | LeaveCriticalSection(&m_renderTargetsCriticalSection); 250 | 251 | if(pRenderTarget == NULL) { 252 | IFW1DWriteRenderTarget *pNewRenderTarget; 253 | HRESULT hResult = m_pFW1Factory->CreateDWriteRenderTarget( 254 | m_pDWriteFactory, 255 | m_maxGlyphWidth, 256 | m_maxGlyphHeight, 257 | &pNewRenderTarget 258 | ); 259 | if(FAILED(hResult)) { 260 | } 261 | else { 262 | pRenderTarget = pNewRenderTarget; 263 | } 264 | } 265 | 266 | if(pRenderTarget != NULL) { 267 | // Draw the glyph image 268 | DWRITE_RENDERING_MODE renderingMode = DWRITE_RENDERING_MODE_DEFAULT; 269 | DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL; 270 | if((glyphMap->fontFlags & FW1_ALIASED) != 0) { 271 | renderingMode = DWRITE_RENDERING_MODE_ALIASED; 272 | measuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC; 273 | } 274 | 275 | FW1_GLYPHIMAGEDATA glyphData; 276 | HRESULT hResult = pRenderTarget->DrawGlyphTemp( 277 | pFontFace, 278 | glyphIndex, 279 | glyphMap->fontSize, 280 | renderingMode, 281 | measuringMode, 282 | &glyphData 283 | ); 284 | if(FAILED(hResult)) { 285 | } 286 | else { 287 | // Insert into the atlas and the glyph-map 288 | EnterCriticalSection(&m_insertGlyphCriticalSection); 289 | 290 | glyphAtlasId = glyphMap->glyphs[glyphIndex]; 291 | if(glyphAtlasId == 0xffffffff) { 292 | glyphAtlasId = m_pGlyphAtlas->InsertGlyph( 293 | &glyphData.Metrics, 294 | glyphData.pGlyphPixels, 295 | glyphData.RowPitch, 296 | glyphData.PixelStride 297 | ); 298 | if(glyphAtlasId != 0xffffffff) 299 | glyphMap->glyphs[glyphIndex] = glyphAtlasId; 300 | } 301 | 302 | LeaveCriticalSection(&m_insertGlyphCriticalSection); 303 | } 304 | 305 | // Keep the render target for future use 306 | EnterCriticalSection(&m_renderTargetsCriticalSection); 307 | m_glyphRenderTargets.push(pRenderTarget); 308 | LeaveCriticalSection(&m_renderTargetsCriticalSection); 309 | } 310 | 311 | return glyphAtlasId; 312 | } 313 | 314 | 315 | }// namespace FW1FontWrapper 316 | -------------------------------------------------------------------------------- /dwmhook/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) 7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. 8 | //----------------------------------------------------------------------------- 9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp 10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 13 | //----------------------------------------------------------------------------- 14 | 15 | #pragma once 16 | 17 | //---- Define assertion handler. Defaults to calling assert(). 18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 21 | 22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() 25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. 26 | //#define IMGUI_API __declspec( dllexport ) 27 | //#define IMGUI_API __declspec( dllimport ) 28 | 29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 31 | 32 | //---- Disable all of Dear ImGui or don't implement standard windows. 33 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 34 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 35 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 36 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty. 37 | 38 | //---- Don't implement some functions to reduce linkage requirements. 39 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) 40 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) 41 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) 42 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 43 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 44 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 45 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 46 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) 47 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 48 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 49 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available 50 | 51 | //---- Include imgui_user.h at the end of imgui.h as a convenience 52 | //#define IMGUI_INCLUDE_IMGUI_USER_H 53 | 54 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 55 | //#define IMGUI_USE_BGRA_PACKED_COLOR 56 | 57 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) 58 | //#define IMGUI_USE_WCHAR32 59 | 60 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 61 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. 62 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 63 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 64 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 65 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 66 | 67 | //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) 68 | // Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 69 | // #define IMGUI_USE_STB_SPRINTF 70 | 71 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) 72 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). 73 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. 74 | //#define IMGUI_ENABLE_FREETYPE 75 | 76 | //---- Use stb_truetype to build and rasterize the font atlas (default) 77 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. 78 | //#define IMGUI_ENABLE_STB_TRUETYPE 79 | 80 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 81 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 82 | /* 83 | #define IM_VEC2_CLASS_EXTRA \ 84 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 85 | operator MyVec2() const { return MyVec2(x,y); } 86 | 87 | #define IM_VEC4_CLASS_EXTRA \ 88 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 89 | operator MyVec4() const { return MyVec4(x,y,z,w); } 90 | */ 91 | 92 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 93 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). 94 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 95 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 96 | //#define ImDrawIdx unsigned int 97 | 98 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) 99 | //struct ImDrawList; 100 | //struct ImDrawCmd; 101 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 102 | //#define ImDrawCallback MyImDrawCallback 103 | 104 | //---- Debug Tools: Macro to break in Debugger 105 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 106 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 107 | //#define IM_DEBUG_BREAK __debugbreak() 108 | 109 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 110 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 111 | // This adds a small runtime cost which is why it is not enabled by default. 112 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 113 | 114 | //---- Debug Tools: Enable slower asserts 115 | //#define IMGUI_DEBUG_PARANOID 116 | 117 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 118 | /* 119 | namespace ImGui 120 | { 121 | void MyFunction(const char* name, const MyMatrix44& v); 122 | } 123 | */ 124 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphSheetInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphSheetInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphSheet.h" 6 | 7 | 8 | namespace FW1FontWrapper { 9 | 10 | 11 | // Query interface 12 | HRESULT STDMETHODCALLTYPE CFW1GlyphSheet::QueryInterface(REFIID riid, void **ppvObject) { 13 | if(ppvObject == NULL) 14 | return E_INVALIDARG; 15 | 16 | if(IsEqualIID(riid, __uuidof(IFW1GlyphSheet))) { 17 | *ppvObject = static_cast(this); 18 | AddRef(); 19 | return S_OK; 20 | } 21 | 22 | return CFW1Object::QueryInterface(riid, ppvObject); 23 | } 24 | 25 | 26 | // Get the D3D11 device used by this sheet 27 | HRESULT STDMETHODCALLTYPE CFW1GlyphSheet::GetDevice(ID3D11Device **ppDevice) { 28 | if(ppDevice == NULL) 29 | return E_INVALIDARG; 30 | 31 | m_pDevice->AddRef(); 32 | *ppDevice = m_pDevice; 33 | 34 | return S_OK; 35 | } 36 | 37 | 38 | // Get sheet desc 39 | void STDMETHODCALLTYPE CFW1GlyphSheet::GetDesc(FW1_GLYPHSHEETDESC *pDesc) { 40 | pDesc->GlyphCount = m_glyphCount; 41 | pDesc->Width = m_sheetWidth; 42 | pDesc->Height = m_sheetHeight; 43 | pDesc->MipLevels = m_mipLevelCount; 44 | } 45 | 46 | 47 | // Get the sheet texture 48 | HRESULT STDMETHODCALLTYPE CFW1GlyphSheet::GetSheetTexture(ID3D11ShaderResourceView **ppSheetTextureSRV) { 49 | if(ppSheetTextureSRV == NULL) 50 | return E_INVALIDARG; 51 | 52 | m_pTextureSRV->AddRef(); 53 | *ppSheetTextureSRV = m_pTextureSRV; 54 | 55 | return S_OK; 56 | } 57 | 58 | 59 | // Get the glyph coordinate buffer 60 | HRESULT STDMETHODCALLTYPE CFW1GlyphSheet::GetCoordBuffer(ID3D11ShaderResourceView **ppCoordBufferSRV) { 61 | if(ppCoordBufferSRV == NULL) 62 | return E_INVALIDARG; 63 | 64 | if(m_pCoordBufferSRV != NULL) 65 | m_pCoordBufferSRV->AddRef(); 66 | *ppCoordBufferSRV = m_pCoordBufferSRV; 67 | 68 | return S_OK; 69 | } 70 | 71 | 72 | // Get glyph coordinate array for all glyphs in the sheet 73 | const FW1_GLYPHCOORDS* STDMETHODCALLTYPE CFW1GlyphSheet::GetGlyphCoords() { 74 | return m_glyphCoords; 75 | } 76 | 77 | 78 | // Set sheet shader resources 79 | HRESULT STDMETHODCALLTYPE CFW1GlyphSheet::BindSheet(ID3D11DeviceContext *pContext, UINT Flags) { 80 | pContext->PSSetShaderResources(0, 1, &m_pTextureSRV); 81 | if((Flags & FW1_NOGEOMETRYSHADER) == 0 && m_hardwareCoordBuffer) 82 | pContext->GSSetShaderResources(0, 1, &m_pCoordBufferSRV); 83 | 84 | return S_OK; 85 | } 86 | 87 | 88 | // Insert a new glyph in the sheet 89 | UINT STDMETHODCALLTYPE CFW1GlyphSheet::InsertGlyph( 90 | const FW1_GLYPHMETRICS *pGlyphMetrics, 91 | LPCVOID pGlyphData, 92 | UINT RowPitch, 93 | UINT PixelStride 94 | ) { 95 | if(m_closed) 96 | return 0xffffffff; 97 | if(m_glyphCount >= m_maxGlyphCount) 98 | return 0xffffffff; 99 | 100 | CriticalSectionLock lock(&m_sheetCriticalSection); 101 | 102 | if(m_closed) 103 | return 0xffffffff; 104 | if(m_glyphCount >= m_maxGlyphCount) 105 | return 0xffffffff; 106 | 107 | const UINT &width = pGlyphMetrics->Width; 108 | const UINT &height = pGlyphMetrics->Height; 109 | 110 | // Position the glyph if it fits 111 | UINT blockWidth = width / m_alignWidth + 1; 112 | if(width % m_alignWidth != 0) 113 | ++blockWidth; 114 | UINT blockHeight = height / m_alignWidth + 1; 115 | if(height % m_alignWidth != 0) 116 | ++blockHeight; 117 | 118 | UINT blockX; 119 | UINT blockY; 120 | UINT positionX; 121 | UINT positionY; 122 | 123 | if(m_glyphCount > 0 || !m_allowOversizedGlyph) { 124 | if(m_alignWidth + width + m_alignWidth > m_sheetWidth) 125 | return 0xffffffff; 126 | 127 | // Position the glyph at the lowest Y possible (fills reasonably well with different sized glyphs) 128 | blockX = m_heightRange->findMin(blockWidth, &blockY); 129 | 130 | positionX = m_alignWidth + blockX * m_alignWidth; 131 | positionY = m_alignWidth + blockY * m_alignWidth; 132 | 133 | if(positionY + height + m_alignWidth > m_sheetHeight) 134 | return 0xffffffff; 135 | } 136 | else { 137 | blockX = 0; 138 | blockY = 0; 139 | 140 | positionX = m_alignWidth; 141 | positionY = m_alignWidth; 142 | } 143 | 144 | m_heightRange->update(blockX, blockWidth, blockY + blockHeight); 145 | 146 | // Store glyph coordinates 147 | FLOAT coordOffset = static_cast(m_alignWidth) * 0.5f; 148 | 149 | UINT alignedWidth = (blockWidth - 1) * m_alignWidth; 150 | UINT alignedHeight = (blockHeight - 1) * m_alignWidth; 151 | 152 | FW1_GLYPHCOORDS glyphCoords; 153 | glyphCoords.TexCoordLeft = (static_cast(positionX) - coordOffset) / static_cast(m_sheetWidth); 154 | glyphCoords.TexCoordTop = (static_cast(positionY) - coordOffset) / static_cast(m_sheetHeight); 155 | glyphCoords.TexCoordRight = 156 | (static_cast(positionX + alignedWidth) + coordOffset) / static_cast(m_sheetWidth); 157 | glyphCoords.TexCoordBottom = 158 | (static_cast(positionY + alignedHeight) + coordOffset) / static_cast(m_sheetHeight); 159 | glyphCoords.PositionLeft = pGlyphMetrics->OffsetX - coordOffset; 160 | glyphCoords.PositionTop = pGlyphMetrics->OffsetY - coordOffset; 161 | glyphCoords.PositionRight = pGlyphMetrics->OffsetX + static_cast(alignedWidth) + coordOffset; 162 | glyphCoords.PositionBottom = pGlyphMetrics->OffsetY + static_cast(alignedHeight) + coordOffset; 163 | 164 | UINT glyphIndex = m_glyphCount; 165 | 166 | m_glyphCoords[glyphIndex] = glyphCoords; 167 | 168 | // Glyph pixels 169 | for(UINT i=0; i < height && i < m_sheetHeight-positionY; ++i) { 170 | const UINT8 *src = static_cast(pGlyphData) + i*RowPitch; 171 | UINT8 *dst = m_textureData + (positionY+i)*m_sheetWidth + positionX; 172 | for(UINT j=0; j < width && j < m_sheetWidth-positionX; ++j) 173 | dst[j] = src[j*PixelStride]; 174 | } 175 | 176 | // Update dirty rect to be flushed to device texture 177 | if(m_updatedGlyphCount == 0) { 178 | m_dirtyRect.left = positionX - m_alignWidth; 179 | m_dirtyRect.top = positionY - m_alignWidth; 180 | m_dirtyRect.right = std::min(positionX + width + m_alignWidth, m_sheetWidth); 181 | m_dirtyRect.bottom = std::min(positionY + height + m_alignWidth, m_sheetHeight); 182 | } 183 | else { 184 | m_dirtyRect.left = std::min(m_dirtyRect.left, positionX - m_alignWidth); 185 | m_dirtyRect.top = std::min(m_dirtyRect.top, positionY - m_alignWidth); 186 | m_dirtyRect.right = std::min(std::max(m_dirtyRect.right, positionX + width + m_alignWidth), m_sheetWidth); 187 | m_dirtyRect.bottom = std::min(std::max(m_dirtyRect.bottom, positionY + height + m_alignWidth), m_sheetHeight); 188 | } 189 | 190 | _WriteBarrier(); 191 | MemoryBarrier(); 192 | 193 | ++m_glyphCount; 194 | ++m_updatedGlyphCount; 195 | 196 | return glyphIndex; 197 | } 198 | 199 | 200 | // Disallow insertion of additional glyphs in this sheet 201 | void STDMETHODCALLTYPE CFW1GlyphSheet::CloseSheet() { 202 | EnterCriticalSection(&m_sheetCriticalSection); 203 | m_closed = true; 204 | LeaveCriticalSection(&m_sheetCriticalSection); 205 | } 206 | 207 | 208 | // Flush any inserted glyphs 209 | void STDMETHODCALLTYPE CFW1GlyphSheet::Flush(ID3D11DeviceContext *pContext) { 210 | EnterCriticalSection(&m_flushCriticalSection); 211 | if(!m_static) { 212 | EnterCriticalSection(&m_sheetCriticalSection); 213 | 214 | UINT glyphCount = m_glyphCount; 215 | RectUI dirtyRect = m_dirtyRect; 216 | 217 | UINT updatedGlyphCount = m_updatedGlyphCount; 218 | m_updatedGlyphCount = 0; 219 | 220 | if(m_closed) 221 | m_static = true; 222 | 223 | LeaveCriticalSection(&m_sheetCriticalSection); 224 | 225 | if(updatedGlyphCount > 0) { 226 | // Update coord buffer 227 | if(m_hardwareCoordBuffer) { 228 | UINT startIndex = glyphCount - updatedGlyphCount; 229 | UINT endIndex = glyphCount; 230 | 231 | D3D11_BOX dstBox; 232 | ZeroMemory(&dstBox, sizeof(dstBox)); 233 | dstBox.left = startIndex * sizeof(FW1_GLYPHCOORDS); 234 | dstBox.right = endIndex * sizeof(FW1_GLYPHCOORDS); 235 | dstBox.top = 0; 236 | dstBox.bottom = 1; 237 | dstBox.front = 0; 238 | dstBox.back = 1; 239 | 240 | pContext->UpdateSubresource( 241 | m_pCoordBuffer, 242 | 0, 243 | &dstBox, 244 | m_glyphCoords + startIndex, 245 | 0, 246 | 0 247 | ); 248 | } 249 | 250 | // Update texture 251 | if(dirtyRect.right > dirtyRect.left && dirtyRect.bottom > dirtyRect.top) { 252 | UINT8 *srcMem = m_textureData; 253 | 254 | D3D11_BOX dstBox; 255 | ZeroMemory(&dstBox, sizeof(dstBox)); 256 | dstBox.left = dirtyRect.left; 257 | dstBox.right = dirtyRect.right; 258 | dstBox.top = dirtyRect.top; 259 | dstBox.bottom = dirtyRect.bottom; 260 | dstBox.front = 0; 261 | dstBox.back = 1; 262 | 263 | // Update each mip-level 264 | for(UINT i=0; i < m_mipLevelCount; ++i) { 265 | pContext->UpdateSubresource( 266 | m_pTexture, 267 | D3D11CalcSubresource(i, 0, m_mipLevelCount), 268 | &dstBox, 269 | srcMem + dstBox.top * (m_sheetWidth >> i) + dstBox.left, 270 | m_sheetWidth >> i, 271 | 0 272 | ); 273 | 274 | if(i+1 < m_mipLevelCount) { 275 | UINT8 *nextMip = srcMem + (m_sheetWidth >> i) * (m_sheetHeight >> i); 276 | 277 | dstBox.left >>= 1; 278 | dstBox.right >>= 1; 279 | dstBox.top >>= 1; 280 | dstBox.bottom >>= 1; 281 | 282 | // Calculate the next mip-level for the current dirty-rect 283 | for(UINT j = dstBox.top; j < dstBox.bottom; ++j) { 284 | const UINT8 *src0 = srcMem + j * 2 * (m_sheetWidth >> i); 285 | const UINT8 *src1 = src0 + (m_sheetWidth >> i); 286 | UINT8 *dst = nextMip + j * (m_sheetWidth >> (i+1)); 287 | 288 | for(UINT k = dstBox.left; k < dstBox.right; ++k) { 289 | UINT src = src0[k*2] + src0[k*2+1] + src1[k*2] + src1[k*2+1]; 290 | dst[k] = static_cast(src >> 2); 291 | } 292 | } 293 | 294 | srcMem = nextMip; 295 | } 296 | } 297 | } 298 | } 299 | 300 | // This sheet is now static, save some memory 301 | if(m_static) { 302 | delete[] m_textureData; 303 | m_textureData = 0; 304 | } 305 | } 306 | 307 | LeaveCriticalSection(&m_flushCriticalSection); 308 | } 309 | 310 | 311 | }// namespace FW1FontWrapper 312 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1GlyphVertexDrawer.cpp: -------------------------------------------------------------------------------- 1 | // CFW1GlyphVertexDrawer.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1GlyphVertexDrawer.h" 6 | 7 | #define SAFE_RELEASE(pObject) { if(pObject) { (pObject)->Release(); (pObject) = NULL; } } 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Construct 14 | CFW1GlyphVertexDrawer::CFW1GlyphVertexDrawer() : 15 | m_pDevice(NULL), 16 | 17 | m_pVertexBuffer(NULL), 18 | m_pIndexBuffer(NULL), 19 | m_vertexBufferSize(0), 20 | m_maxIndexCount(0) 21 | { 22 | } 23 | 24 | 25 | // Destruct 26 | CFW1GlyphVertexDrawer::~CFW1GlyphVertexDrawer() { 27 | SAFE_RELEASE(m_pDevice); 28 | 29 | SAFE_RELEASE(m_pVertexBuffer); 30 | SAFE_RELEASE(m_pIndexBuffer); 31 | } 32 | 33 | 34 | // Init 35 | HRESULT CFW1GlyphVertexDrawer::initVertexDrawer( 36 | IFW1Factory *pFW1Factory, 37 | ID3D11Device *pDevice, 38 | UINT vertexBufferSize 39 | ) { 40 | HRESULT hResult = initBaseObject(pFW1Factory); 41 | if(FAILED(hResult)) 42 | return hResult; 43 | 44 | if(pDevice == NULL) 45 | return E_INVALIDARG; 46 | 47 | pDevice->AddRef(); 48 | m_pDevice = pDevice; 49 | D3D_FEATURE_LEVEL featureLevel = m_pDevice->GetFeatureLevel(); 50 | 51 | m_vertexBufferSize = 4096 * 16; 52 | if(vertexBufferSize >= 1024) { 53 | if(featureLevel < D3D_FEATURE_LEVEL_9_2) 54 | vertexBufferSize = std::min(vertexBufferSize, 512U*1024U); 55 | m_vertexBufferSize = vertexBufferSize; 56 | } 57 | 58 | m_maxIndexCount = (m_vertexBufferSize * 3) / (2 * sizeof(QuadVertex)); 59 | if(m_maxIndexCount < 64) 60 | m_maxIndexCount = 64; 61 | 62 | // Create device buffers 63 | hResult = createBuffers(); 64 | 65 | if(SUCCEEDED(hResult)) 66 | hResult = S_OK; 67 | 68 | return hResult; 69 | } 70 | 71 | 72 | // Create vertex/index buffers 73 | HRESULT CFW1GlyphVertexDrawer::createBuffers() { 74 | // Create vertex buffer 75 | D3D11_BUFFER_DESC vertexBufferDesc; 76 | ID3D11Buffer *pVertexBuffer; 77 | 78 | ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); 79 | vertexBufferDesc.ByteWidth = m_vertexBufferSize; 80 | vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; 81 | vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 82 | vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 83 | 84 | HRESULT hResult = m_pDevice->CreateBuffer(&vertexBufferDesc, NULL, &pVertexBuffer); 85 | if(FAILED(hResult)) { 86 | m_lastError = L"Failed to create vertex buffer"; 87 | } 88 | else { 89 | // Create index buffer 90 | D3D11_BUFFER_DESC indexBufferDesc; 91 | D3D11_SUBRESOURCE_DATA initData; 92 | ID3D11Buffer *pIndexBuffer; 93 | 94 | ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc)); 95 | indexBufferDesc.ByteWidth = sizeof(UINT16) * m_maxIndexCount; 96 | indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; 97 | indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; 98 | 99 | UINT16 *indices = new UINT16[m_maxIndexCount]; 100 | for(UINT i=0; i < m_maxIndexCount/6; ++i) { 101 | indices[i*6] = static_cast(i*4); 102 | indices[i*6+1] = static_cast(i*4+1); 103 | indices[i*6+2] = static_cast(i*4+2); 104 | indices[i*6+3] = static_cast(i*4+1); 105 | indices[i*6+4] = static_cast(i*4+3); 106 | indices[i*6+5] = static_cast(i*4+2); 107 | } 108 | 109 | ZeroMemory(&initData, sizeof(initData)); 110 | initData.pSysMem = indices; 111 | 112 | hResult = m_pDevice->CreateBuffer(&indexBufferDesc, &initData, &pIndexBuffer); 113 | if(FAILED(hResult)) { 114 | m_lastError = L"Failed to create index buffer"; 115 | } 116 | else { 117 | // Success 118 | m_pVertexBuffer = pVertexBuffer; 119 | m_pIndexBuffer = pIndexBuffer; 120 | 121 | hResult = S_OK; 122 | } 123 | 124 | delete[] indices; 125 | 126 | if(FAILED(hResult)) 127 | pVertexBuffer->Release(); 128 | } 129 | 130 | return hResult; 131 | } 132 | 133 | 134 | // Draw vertices 135 | UINT CFW1GlyphVertexDrawer::drawVertices( 136 | ID3D11DeviceContext *pContext, 137 | IFW1GlyphAtlas *pGlyphAtlas, 138 | const FW1_VERTEXDATA *vertexData, 139 | UINT preboundSheet 140 | ) { 141 | if(vertexData->SheetCount == 0 || vertexData->TotalVertexCount == 0) 142 | return preboundSheet; 143 | 144 | UINT maxVertexCount = m_vertexBufferSize / sizeof(FW1_GLYPHVERTEX); 145 | 146 | UINT currentSheet = 0; 147 | UINT activeSheet = preboundSheet; 148 | UINT currentVertex = 0; 149 | UINT nextSheetStart = vertexData->pVertexCounts[0]; 150 | 151 | while(currentVertex < vertexData->TotalVertexCount) { 152 | // Fill the vertex buffer 153 | UINT vertexCount = std::min(vertexData->TotalVertexCount - currentVertex, maxVertexCount); 154 | 155 | D3D11_MAPPED_SUBRESOURCE msr; 156 | HRESULT hResult = pContext->Map(m_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr); 157 | if(SUCCEEDED(hResult)) { 158 | CopyMemory(msr.pData, vertexData->pVertices + currentVertex, vertexCount * sizeof(FW1_GLYPHVERTEX)); 159 | 160 | pContext->Unmap(m_pVertexBuffer, 0); 161 | 162 | // Draw all glyphs in the buffer 163 | UINT drawnVertices = 0; 164 | while(drawnVertices < vertexCount) { 165 | while(currentVertex >= nextSheetStart) { 166 | ++currentSheet; 167 | nextSheetStart += vertexData->pVertexCounts[currentSheet]; 168 | } 169 | 170 | if(currentSheet != activeSheet) { 171 | // Bind sheet shader resources 172 | pGlyphAtlas->BindSheet(pContext, currentSheet, 0); 173 | activeSheet = currentSheet; 174 | } 175 | 176 | UINT drawCount = std::min(vertexCount - drawnVertices, nextSheetStart - currentVertex); 177 | pContext->Draw(drawCount, drawnVertices); 178 | 179 | drawnVertices += drawCount; 180 | currentVertex += drawCount; 181 | } 182 | } 183 | else 184 | break; 185 | } 186 | 187 | return activeSheet; 188 | } 189 | 190 | 191 | // Draw vertices as quads 192 | UINT CFW1GlyphVertexDrawer::drawGlyphsAsQuads( 193 | ID3D11DeviceContext *pContext, 194 | IFW1GlyphAtlas *pGlyphAtlas, 195 | const FW1_VERTEXDATA *vertexData, 196 | UINT preboundSheet 197 | ) { 198 | if(vertexData->SheetCount == 0 || vertexData->TotalVertexCount == 0) 199 | return preboundSheet; 200 | 201 | UINT maxVertexCount = m_vertexBufferSize / sizeof(QuadVertex); 202 | if(maxVertexCount > 4 * (m_maxIndexCount / 6)) 203 | maxVertexCount = 4 * (m_maxIndexCount / 6); 204 | if(maxVertexCount % 4 != 0) 205 | maxVertexCount -= (maxVertexCount % 4); 206 | 207 | UINT currentSheet = 0; 208 | UINT activeSheet = preboundSheet; 209 | const FW1_GLYPHCOORDS *sheetGlyphCoords = 0; 210 | if(activeSheet < vertexData->SheetCount) 211 | sheetGlyphCoords = pGlyphAtlas->GetGlyphCoords(activeSheet); 212 | UINT currentVertex = 0; 213 | UINT nextSheetStart = vertexData->pVertexCounts[0]; 214 | 215 | while(currentVertex < vertexData->TotalVertexCount) { 216 | // Fill the vertex buffer 217 | UINT vertexCount = std::min((vertexData->TotalVertexCount - currentVertex) * 4, maxVertexCount); 218 | 219 | D3D11_MAPPED_SUBRESOURCE msr; 220 | HRESULT hResult = pContext->Map(m_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr); 221 | if(SUCCEEDED(hResult)) { 222 | QuadVertex *bufferVertices = static_cast(msr.pData); 223 | 224 | // Convert to quads when filling the buffer 225 | UINT savedCurrentSheet = currentSheet; 226 | UINT savedActiveSheet = activeSheet; 227 | UINT savedNextSheetStart = nextSheetStart; 228 | UINT savedCurrentVertex = currentVertex; 229 | 230 | UINT drawnVertices = 0; 231 | while(drawnVertices < vertexCount) { 232 | while(currentVertex >= nextSheetStart) { 233 | ++currentSheet; 234 | nextSheetStart += vertexData->pVertexCounts[currentSheet]; 235 | } 236 | 237 | if(currentSheet != activeSheet) { 238 | sheetGlyphCoords = pGlyphAtlas->GetGlyphCoords(currentSheet); 239 | activeSheet = currentSheet; 240 | } 241 | 242 | UINT drawCount = std::min(vertexCount - drawnVertices, (nextSheetStart - currentVertex) * 4); 243 | 244 | for(UINT i=0; i < drawCount/4; ++i) { 245 | FW1_GLYPHVERTEX glyphVertex = vertexData->pVertices[currentVertex + i]; 246 | glyphVertex.PositionX = glyphVertex.PositionX; 247 | glyphVertex.PositionY = glyphVertex.PositionY; 248 | 249 | const FW1_GLYPHCOORDS &glyphCoords = sheetGlyphCoords[glyphVertex.GlyphIndex]; 250 | 251 | QuadVertex quadVertex; 252 | 253 | quadVertex.color = glyphVertex.GlyphColor; 254 | 255 | quadVertex.positionX = glyphVertex.PositionX + glyphCoords.PositionLeft; 256 | quadVertex.positionY = glyphVertex.PositionY + glyphCoords.PositionTop; 257 | quadVertex.texCoordX = glyphCoords.TexCoordLeft; 258 | quadVertex.texCoordY = glyphCoords.TexCoordTop; 259 | bufferVertices[drawnVertices + i*4 + 0] = quadVertex; 260 | 261 | quadVertex.positionX = glyphVertex.PositionX + glyphCoords.PositionRight; 262 | quadVertex.texCoordX = glyphCoords.TexCoordRight; 263 | bufferVertices[drawnVertices + i*4 + 1] = quadVertex; 264 | 265 | quadVertex.positionY = glyphVertex.PositionY + glyphCoords.PositionBottom; 266 | quadVertex.texCoordY = glyphCoords.TexCoordBottom; 267 | bufferVertices[drawnVertices + i*4 + 3] = quadVertex; 268 | 269 | quadVertex.positionX = glyphVertex.PositionX + glyphCoords.PositionLeft; 270 | quadVertex.texCoordX = glyphCoords.TexCoordLeft; 271 | bufferVertices[drawnVertices + i*4 + 2] = quadVertex; 272 | } 273 | 274 | drawnVertices += drawCount; 275 | currentVertex += drawCount / 4; 276 | } 277 | 278 | pContext->Unmap(m_pVertexBuffer, 0); 279 | 280 | // Draw all glyphs in the buffer 281 | currentSheet = savedCurrentSheet; 282 | activeSheet = savedActiveSheet; 283 | nextSheetStart = savedNextSheetStart; 284 | currentVertex = savedCurrentVertex; 285 | 286 | drawnVertices = 0; 287 | while(drawnVertices < vertexCount) { 288 | while(currentVertex >= nextSheetStart) { 289 | ++currentSheet; 290 | nextSheetStart += vertexData->pVertexCounts[currentSheet]; 291 | } 292 | 293 | if(currentSheet != activeSheet) { 294 | // Bind sheet shader resources 295 | pGlyphAtlas->BindSheet(pContext, currentSheet, FW1_NOGEOMETRYSHADER); 296 | activeSheet = currentSheet; 297 | } 298 | 299 | UINT drawCount = std::min(vertexCount - drawnVertices, (nextSheetStart - currentVertex) * 4); 300 | pContext->DrawIndexed((drawCount/2)*3, 0, drawnVertices); 301 | 302 | drawnVertices += drawCount; 303 | currentVertex += drawCount / 4; 304 | } 305 | } 306 | else 307 | break; 308 | } 309 | 310 | return activeSheet; 311 | } 312 | 313 | 314 | }// namespace FW1FontWrapper 315 | -------------------------------------------------------------------------------- /dwmhook/FW1/CFW1FontWrapperInterface.cpp: -------------------------------------------------------------------------------- 1 | // CFW1FontWrapperInterface.cpp 2 | 3 | #include "FW1Precompiled.h" 4 | 5 | #include "CFW1FontWrapper.h" 6 | 7 | #include "CFW1StateSaver.h" 8 | 9 | 10 | namespace FW1FontWrapper { 11 | 12 | 13 | // Query interface 14 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::QueryInterface(REFIID riid, void **ppvObject) { 15 | if(ppvObject == NULL) 16 | return E_INVALIDARG; 17 | 18 | if(IsEqualIID(riid, __uuidof(IFW1FontWrapper))) { 19 | *ppvObject = static_cast(this); 20 | AddRef(); 21 | return S_OK; 22 | } 23 | 24 | return CFW1Object::QueryInterface(riid, ppvObject); 25 | } 26 | 27 | 28 | // Get the factory that created this object 29 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetFactory(IFW1Factory **ppFactory) { 30 | if(ppFactory == NULL) 31 | return E_INVALIDARG; 32 | 33 | m_pFW1Factory->AddRef(); 34 | *ppFactory = m_pFW1Factory; 35 | 36 | return S_OK; 37 | } 38 | 39 | 40 | // Get D3D11 device 41 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetDevice(ID3D11Device **ppDevice) { 42 | if(ppDevice == NULL) 43 | return E_INVALIDARG; 44 | 45 | m_pDevice->AddRef(); 46 | *ppDevice = m_pDevice; 47 | 48 | return S_OK; 49 | } 50 | 51 | 52 | // Get DWrite factory 53 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetDWriteFactory(IDWriteFactory **ppDWriteFactory) { 54 | if(ppDWriteFactory == NULL) 55 | return E_INVALIDARG; 56 | 57 | m_pDWriteFactory->AddRef(); 58 | *ppDWriteFactory = m_pDWriteFactory; 59 | 60 | return S_OK; 61 | } 62 | 63 | 64 | // Get glyph atlas 65 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetGlyphAtlas(IFW1GlyphAtlas **ppGlyphAtlas) { 66 | if(ppGlyphAtlas == NULL) 67 | return E_INVALIDARG; 68 | 69 | m_pGlyphAtlas->AddRef(); 70 | *ppGlyphAtlas = m_pGlyphAtlas; 71 | 72 | return S_OK; 73 | } 74 | 75 | 76 | // Get glyph provider 77 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetGlyphProvider(IFW1GlyphProvider **ppGlyphProvider) { 78 | if(ppGlyphProvider == NULL) 79 | return E_INVALIDARG; 80 | 81 | m_pGlyphProvider->AddRef(); 82 | *ppGlyphProvider = m_pGlyphProvider; 83 | 84 | return S_OK; 85 | } 86 | 87 | 88 | // Get render states 89 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetRenderStates(IFW1GlyphRenderStates **ppRenderStates) { 90 | if(ppRenderStates == NULL) 91 | return E_INVALIDARG; 92 | 93 | m_pGlyphRenderStates->AddRef(); 94 | *ppRenderStates = m_pGlyphRenderStates; 95 | 96 | return S_OK; 97 | } 98 | 99 | 100 | // Get vertex drawer 101 | HRESULT STDMETHODCALLTYPE CFW1FontWrapper::GetVertexDrawer(IFW1GlyphVertexDrawer **ppVertexDrawer) { 102 | if(ppVertexDrawer == NULL) 103 | return E_INVALIDARG; 104 | 105 | m_pGlyphVertexDrawer->AddRef(); 106 | *ppVertexDrawer = m_pGlyphVertexDrawer; 107 | 108 | return S_OK; 109 | } 110 | 111 | 112 | // Draw text layout 113 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawTextLayout( 114 | ID3D11DeviceContext *pContext, 115 | IDWriteTextLayout *pTextLayout, 116 | FLOAT OriginX, 117 | FLOAT OriginY, 118 | UINT32 Color, 119 | UINT Flags 120 | ) { 121 | DrawTextLayout(pContext, pTextLayout, OriginX, OriginY, Color, NULL, NULL, Flags); 122 | } 123 | 124 | 125 | // Draw text layout 126 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawTextLayout( 127 | ID3D11DeviceContext *pContext, 128 | IDWriteTextLayout *pTextLayout, 129 | FLOAT OriginX, 130 | FLOAT OriginY, 131 | UINT32 Color, 132 | const FW1_RECTF *pClipRect, 133 | const FLOAT *pTransformMatrix, 134 | UINT Flags 135 | ) { 136 | IFW1TextGeometry *pTextGeometry = NULL; 137 | 138 | // If needed, get a text geometry to store vertices in 139 | if((Flags & FW1_ANALYZEONLY) == 0 && (Flags & FW1_CACHEONLY) == 0) { 140 | EnterCriticalSection(&m_textGeometriesCriticalSection); 141 | if(!m_textGeometries.empty()) { 142 | pTextGeometry = m_textGeometries.top(); 143 | m_textGeometries.pop(); 144 | } 145 | LeaveCriticalSection(&m_textGeometriesCriticalSection); 146 | 147 | if(pTextGeometry == NULL) { 148 | IFW1TextGeometry *pNewTextGeometry; 149 | HRESULT hResult = m_pFW1Factory->CreateTextGeometry(&pNewTextGeometry); 150 | if(FAILED(hResult)) { 151 | } 152 | else { 153 | pTextGeometry = pNewTextGeometry; 154 | } 155 | } 156 | 157 | if(pTextGeometry != NULL) 158 | pTextGeometry->Clear(); 159 | } 160 | 161 | // Draw 162 | AnalyzeTextLayout(pContext, pTextLayout, OriginX, OriginY, Color, Flags, pTextGeometry); 163 | if((Flags & FW1_ANALYZEONLY) == 0 && (Flags & FW1_CACHEONLY) == 0) { 164 | DrawGeometry(pContext, pTextGeometry, pClipRect, pTransformMatrix, Flags); 165 | } 166 | 167 | if(pTextGeometry != NULL) { 168 | // Keep the text geometry for future use 169 | EnterCriticalSection(&m_textGeometriesCriticalSection); 170 | m_textGeometries.push(pTextGeometry); 171 | LeaveCriticalSection(&m_textGeometriesCriticalSection); 172 | } 173 | } 174 | 175 | 176 | // Draw text 177 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawString( 178 | ID3D11DeviceContext *pContext, 179 | const WCHAR *pszString, 180 | FLOAT FontSize, 181 | FLOAT X, 182 | FLOAT Y, 183 | UINT32 Color, 184 | UINT Flags 185 | ) { 186 | FW1_RECTF rect; 187 | 188 | rect.Left = rect.Right = X; 189 | rect.Top = rect.Bottom = Y; 190 | 191 | DrawString(pContext, pszString, NULL, FontSize, &rect, Color, NULL, NULL, Flags | FW1_NOWORDWRAP); 192 | } 193 | 194 | 195 | // Draw text 196 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawString( 197 | ID3D11DeviceContext *pContext, 198 | const WCHAR *pszString, 199 | const WCHAR *pszFontFamily, 200 | FLOAT FontSize, 201 | FLOAT X, 202 | FLOAT Y, 203 | UINT32 Color, 204 | UINT Flags 205 | ) { 206 | FW1_RECTF rect; 207 | 208 | rect.Left = rect.Right = X; 209 | rect.Top = rect.Bottom = Y; 210 | 211 | DrawString(pContext, pszString, pszFontFamily, FontSize, &rect, Color, NULL, NULL, Flags | FW1_NOWORDWRAP); 212 | } 213 | 214 | 215 | // Draw text 216 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawString( 217 | ID3D11DeviceContext *pContext, 218 | const WCHAR *pszString, 219 | const WCHAR *pszFontFamily, 220 | FLOAT FontSize, 221 | const FW1_RECTF *pLayoutRect, 222 | UINT32 Color, 223 | const FW1_RECTF *pClipRect, 224 | const FLOAT *pTransformMatrix, 225 | UINT Flags 226 | ) { 227 | IDWriteTextLayout *pTextLayout = createTextLayout(pszString, pszFontFamily, FontSize, pLayoutRect, Flags); 228 | if(pTextLayout != NULL) { 229 | // Draw 230 | DrawTextLayout( 231 | pContext, 232 | pTextLayout, 233 | pLayoutRect->Left, 234 | pLayoutRect->Top, 235 | Color, 236 | pClipRect, 237 | pTransformMatrix, 238 | Flags 239 | ); 240 | 241 | pTextLayout->Release(); 242 | } 243 | } 244 | 245 | 246 | // Measure text 247 | FW1_RECTF STDMETHODCALLTYPE CFW1FontWrapper::MeasureString( 248 | const WCHAR *pszString, 249 | const WCHAR *pszFontFamily, 250 | FLOAT FontSize, 251 | const FW1_RECTF *pLayoutRect, 252 | UINT Flags 253 | ) { 254 | FW1_RECTF stringRect = {pLayoutRect->Left, pLayoutRect->Top, pLayoutRect->Left, pLayoutRect->Top}; 255 | 256 | IDWriteTextLayout *pTextLayout = createTextLayout(pszString, pszFontFamily, FontSize, pLayoutRect, Flags); 257 | if(pTextLayout != NULL) { 258 | // Get measurements 259 | DWRITE_OVERHANG_METRICS overhangMetrics; 260 | HRESULT hResult = pTextLayout->GetOverhangMetrics(&overhangMetrics); 261 | if(SUCCEEDED(hResult)) { 262 | stringRect.Left = floor(pLayoutRect->Left - overhangMetrics.left); 263 | stringRect.Top = floor(pLayoutRect->Top - overhangMetrics.top); 264 | stringRect.Right = ceil(pLayoutRect->Left + overhangMetrics.right); 265 | stringRect.Bottom = ceil(pLayoutRect->Top + overhangMetrics.bottom); 266 | } 267 | 268 | pTextLayout->Release(); 269 | } 270 | 271 | return stringRect; 272 | } 273 | 274 | 275 | // Create geometry from a string 276 | void STDMETHODCALLTYPE CFW1FontWrapper::AnalyzeString( 277 | ID3D11DeviceContext *pContext, 278 | const WCHAR *pszString, 279 | const WCHAR *pszFontFamily, 280 | FLOAT FontSize, 281 | const FW1_RECTF *pLayoutRect, 282 | UINT32 Color, 283 | UINT Flags, 284 | IFW1TextGeometry *pTextGeometry 285 | ) { 286 | IDWriteTextLayout *pTextLayout = createTextLayout(pszString, pszFontFamily, FontSize, pLayoutRect, Flags); 287 | if(pTextLayout != NULL) { 288 | AnalyzeTextLayout( 289 | pContext, 290 | pTextLayout, 291 | pLayoutRect->Left, 292 | pLayoutRect->Top, 293 | Color, 294 | Flags, 295 | pTextGeometry 296 | ); 297 | 298 | pTextLayout->Release(); 299 | } 300 | } 301 | 302 | 303 | // Create geometry from a text layout 304 | void STDMETHODCALLTYPE CFW1FontWrapper::AnalyzeTextLayout( 305 | ID3D11DeviceContext *pContext, 306 | IDWriteTextLayout *pTextLayout, 307 | FLOAT OriginX, 308 | FLOAT OriginY, 309 | UINT32 Color, 310 | UINT Flags, 311 | IFW1TextGeometry *pTextGeometry 312 | ) { 313 | // Get a text renderer 314 | IFW1TextRenderer *pTextRenderer = NULL; 315 | 316 | EnterCriticalSection(&m_textRenderersCriticalSection); 317 | if(!m_textRenderers.empty()) { 318 | pTextRenderer = m_textRenderers.top(); 319 | m_textRenderers.pop(); 320 | } 321 | LeaveCriticalSection(&m_textRenderersCriticalSection); 322 | 323 | if(pTextRenderer == NULL) { 324 | IFW1TextRenderer *pNewTextRenderer; 325 | HRESULT hResult = m_pFW1Factory->CreateTextRenderer(m_pGlyphProvider, &pNewTextRenderer); 326 | if(FAILED(hResult)) { 327 | } 328 | else { 329 | pTextRenderer = pNewTextRenderer; 330 | } 331 | } 332 | 333 | // Create geometry 334 | if(pTextRenderer != NULL) { 335 | HRESULT hResult = pTextRenderer->DrawTextLayout(pTextLayout, OriginX, OriginY, Color, Flags, pTextGeometry); 336 | if(FAILED(hResult)) { 337 | } 338 | 339 | // Flush the glyph atlas in case any new glyphs were added 340 | if((Flags & FW1_NOFLUSH) == 0) 341 | m_pGlyphAtlas->Flush(pContext); 342 | 343 | // Keep the text renderer for future use 344 | EnterCriticalSection(&m_textRenderersCriticalSection); 345 | m_textRenderers.push(pTextRenderer); 346 | LeaveCriticalSection(&m_textRenderersCriticalSection); 347 | } 348 | } 349 | 350 | 351 | // Draw vertices 352 | void STDMETHODCALLTYPE CFW1FontWrapper::DrawGeometry( 353 | ID3D11DeviceContext *pContext, 354 | IFW1TextGeometry *pGeometry, 355 | const FW1_RECTF *pClipRect, 356 | const FLOAT *pTransformMatrix, 357 | UINT Flags 358 | ) { 359 | FW1_VERTEXDATA vertexData = pGeometry->GetGlyphVerticesTemp(); 360 | if(vertexData.TotalVertexCount > 0 || (Flags & FW1_RESTORESTATE) == 0) { 361 | if(m_featureLevel < D3D_FEATURE_LEVEL_10_0 || m_pGlyphRenderStates->HasGeometryShader() == FALSE) 362 | Flags |= FW1_NOGEOMETRYSHADER; 363 | 364 | // Save state 365 | CFW1StateSaver stateSaver; 366 | bool restoreState = false; 367 | if((Flags & FW1_RESTORESTATE) != 0) { 368 | if(SUCCEEDED(stateSaver.saveCurrentState(pContext))) 369 | restoreState = true; 370 | } 371 | 372 | // Set shaders etc. 373 | if((Flags & FW1_STATEPREPARED) == 0) 374 | m_pGlyphRenderStates->SetStates(pContext, Flags); 375 | if((Flags & FW1_CONSTANTSPREPARED) == 0) 376 | m_pGlyphRenderStates->UpdateShaderConstants(pContext, pClipRect, pTransformMatrix); 377 | 378 | // Draw glyphs 379 | UINT temp = m_pGlyphVertexDrawer->DrawVertices(pContext, m_pGlyphAtlas, &vertexData, Flags, 0xffffffff); 380 | temp; 381 | 382 | // Restore state 383 | if(restoreState) 384 | stateSaver.restoreSavedState(); 385 | } 386 | } 387 | 388 | 389 | // Flush the glyph atlas 390 | void STDMETHODCALLTYPE CFW1FontWrapper::Flush(ID3D11DeviceContext *pContext) { 391 | m_pGlyphAtlas->Flush(pContext); 392 | } 393 | 394 | 395 | }// namespace FW1FontWrapper 396 | -------------------------------------------------------------------------------- /dwmhook/render.cpp: -------------------------------------------------------------------------------- 1 | #include "includes.hpp" 2 | #include "render.hpp" 3 | 4 | CRender2D render; 5 | 6 | static char D3D11FillShader[] = 7 | "struct VSOut" 8 | "{" 9 | " float4 Col : COLOR;" 10 | " float4 Pos : SV_POSITION;" 11 | "};" 12 | 13 | "VSOut VS(float4 Col : COLOR, float4 Pos : POSITION)" 14 | "{" 15 | " VSOut Output;" 16 | " Output.Pos = Pos;" 17 | " Output.Col = Col;" 18 | " return Output;" 19 | "}" 20 | 21 | "float4 PS(float4 Col : COLOR) : SV_TARGET" 22 | "{" 23 | " return Col;" 24 | "}"; 25 | 26 | bool CRender2D::Initialize( IFW1FontWrapper* pFontWrapper ) 27 | { 28 | HRESULT hr; 29 | 30 | if ( !pD3DXDevice ) 31 | return false; 32 | 33 | if ( !pD3DXDeviceCtx ) 34 | return false; 35 | 36 | if ( pFontWrapper ) 37 | this->font = pFontWrapper; 38 | 39 | ID3DBlob* VS, * PS; 40 | hr = D3DCompile( D3D11FillShader, sizeof( D3D11FillShader ), NULL, NULL, NULL, "VS", "vs_4_0", 0, 0, &VS, NULL ); 41 | if ( FAILED( hr ) ) 42 | return false; 43 | 44 | hr = pD3DXDevice->CreateVertexShader( VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &this->mVS ); 45 | if ( FAILED( hr ) ) 46 | { 47 | SAFE_RELEASE( VS ); 48 | return false; 49 | } 50 | 51 | D3D11_INPUT_ELEMENT_DESC layout[] = 52 | { 53 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 54 | { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } 55 | }; 56 | 57 | hr = pD3DXDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), VS->GetBufferPointer(), VS->GetBufferSize(), &this->mInputLayout ); 58 | SAFE_RELEASE( VS ); 59 | if ( FAILED( hr ) ) 60 | return false; 61 | 62 | D3DCompile( D3D11FillShader, sizeof( D3D11FillShader ), NULL, NULL, NULL, "PS", "ps_4_0", 0, 0, &PS, NULL ); 63 | if ( FAILED( hr ) ) 64 | return false; 65 | 66 | hr = pD3DXDevice->CreatePixelShader( PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &this->mPS ); 67 | if ( FAILED( hr ) ) 68 | { 69 | SAFE_RELEASE( PS ); 70 | return false; 71 | } 72 | 73 | D3D11_BUFFER_DESC bufferDesc{ }; 74 | bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 75 | bufferDesc.ByteWidth = 4 * sizeof( COLOR_VERTEX ); 76 | bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 77 | bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 78 | bufferDesc.MiscFlags = 0; 79 | 80 | hr = pD3DXDevice->CreateBuffer( &bufferDesc, NULL, &this->mVertexBuffer ); 81 | if ( FAILED( hr ) ) 82 | return false; 83 | 84 | D3D11_BLEND_DESC blendStateDescription{ }; 85 | blendStateDescription.RenderTarget[ 0 ].BlendEnable = TRUE; 86 | blendStateDescription.RenderTarget[ 0 ].SrcBlend = D3D11_BLEND_SRC_ALPHA; 87 | blendStateDescription.RenderTarget[ 0 ].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; 88 | blendStateDescription.RenderTarget[ 0 ].BlendOp = D3D11_BLEND_OP_ADD; 89 | blendStateDescription.RenderTarget[ 0 ].SrcBlendAlpha = D3D11_BLEND_ONE; 90 | blendStateDescription.RenderTarget[ 0 ].DestBlendAlpha = D3D11_BLEND_ZERO; 91 | blendStateDescription.RenderTarget[ 0 ].BlendOpAlpha = D3D11_BLEND_OP_ADD; 92 | blendStateDescription.RenderTarget[ 0 ].RenderTargetWriteMask = 0x0f; 93 | 94 | hr = pD3DXDevice->CreateBlendState( &blendStateDescription, &this->transparency ); 95 | if ( FAILED( hr ) ) 96 | return false; 97 | 98 | return true; 99 | } 100 | 101 | void CRender2D::FillRect( float x, float y, float w, float h, ULONG color ) 102 | { 103 | if ( pD3DXDeviceCtx == NULL ) 104 | return; 105 | 106 | auto a = ( ( color >> 24 ) & 255 ); 107 | auto r = ( ( color >> 16 ) & 255 ); 108 | auto g = ( ( color >> 12 ) & 255 ); 109 | auto b = ( color & 255 ); 110 | 111 | UINT viewportNumber = 1; 112 | 113 | D3D11_VIEWPORT vp; 114 | 115 | pD3DXDeviceCtx->RSGetViewports( &viewportNumber, &vp ); 116 | 117 | float x0 = x; 118 | float y0 = y; 119 | float x1 = x + w; 120 | float y1 = y + h; 121 | 122 | float xx0 = 2.0f * ( x0 - 0.5f ) / vp.Width - 1.0f; 123 | float yy0 = 1.0f - 2.0f * ( y0 - 0.5f ) / vp.Height; 124 | float xx1 = 2.0f * ( x1 - 0.5f ) / vp.Width - 1.0f; 125 | float yy1 = 1.0f - 2.0f * ( y1 - 0.5f ) / vp.Height; 126 | 127 | COLOR_VERTEX* v = NULL; 128 | D3D11_MAPPED_SUBRESOURCE mapData; 129 | 130 | if ( FAILED( pD3DXDeviceCtx->Map( this->mVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mapData ) ) ) 131 | return; 132 | 133 | v = ( COLOR_VERTEX* )mapData.pData; 134 | 135 | v[ 0 ].Position.x = ( float )x0; 136 | v[ 0 ].Position.y = ( float )y0; 137 | v[ 0 ].Position.z = 0; 138 | v[ 0 ].Color = XMFLOAT4( 139 | ( ( float )r / 255.0f ), 140 | ( ( float )g / 255.0f ), 141 | ( ( float )b / 255.0f ), 142 | ( ( float )a / 255.0f ) ); 143 | 144 | v[ 1 ].Position.x = ( float )x1; 145 | v[ 1 ].Position.y = ( float )y1; 146 | v[ 1 ].Position.z = 0; 147 | v[ 1 ].Color = XMFLOAT4( 148 | ( ( float )r / 255.0f ), 149 | ( ( float )g / 255.0f ), 150 | ( ( float )b / 255.0f ), 151 | ( ( float )a / 255.0f ) ); 152 | 153 | v[ 0 ].Position.x = xx0; 154 | v[ 0 ].Position.y = yy0; 155 | v[ 0 ].Position.z = 0; 156 | v[ 0 ].Color = XMFLOAT4( 157 | ( ( float )r / 255.0f ), 158 | ( ( float )g / 255.0f ), 159 | ( ( float )b / 255.0f ), 160 | ( ( float )a / 255.0f ) ); 161 | 162 | v[ 1 ].Position.x = xx1; 163 | v[ 1 ].Position.y = yy0; 164 | v[ 1 ].Position.z = 0; 165 | v[ 1 ].Color = XMFLOAT4( 166 | ( ( float )r / 255.0f ), 167 | ( ( float )g / 255.0f ), 168 | ( ( float )b / 255.0f ), 169 | ( ( float )a / 255.0f ) ); 170 | 171 | v[ 2 ].Position.x = xx0; 172 | v[ 2 ].Position.y = yy1; 173 | v[ 2 ].Position.z = 0; 174 | v[ 2 ].Color = XMFLOAT4( 175 | ( ( float )r / 255.0f ), 176 | ( ( float )g / 255.0f ), 177 | ( ( float )b / 255.0f ), 178 | ( ( float )a / 255.0f ) ); 179 | 180 | v[ 3 ].Position.x = xx1; 181 | v[ 3 ].Position.y = yy1; 182 | v[ 3 ].Position.z = 0; 183 | v[ 3 ].Color = XMFLOAT4( 184 | ( ( float )r / 255.0f ), 185 | ( ( float )g / 255.0f ), 186 | ( ( float )b / 255.0f ), 187 | ( ( float )a / 255.0f ) ); 188 | 189 | pD3DXDeviceCtx->Unmap( this->mVertexBuffer, NULL ); 190 | 191 | UINT Stride = sizeof( COLOR_VERTEX ); 192 | UINT Offset = 0; 193 | 194 | pD3DXDeviceCtx->IASetVertexBuffers( 0, 1, &this->mVertexBuffer, &Stride, &Offset ); 195 | pD3DXDeviceCtx->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); 196 | pD3DXDeviceCtx->IASetInputLayout( this->mInputLayout ); 197 | 198 | pD3DXDeviceCtx->VSSetShader( this->mVS, 0, 0 ); 199 | pD3DXDeviceCtx->PSSetShader( this->mPS, 0, 0 ); 200 | pD3DXDeviceCtx->GSSetShader( NULL, 0, 0 ); 201 | pD3DXDeviceCtx->Draw( 4, 0 ); 202 | } 203 | 204 | void CRender2D::OutlineRect( float x, float y, float w, float h, ULONG color ) 205 | { 206 | FillRect( x, ( y + h - 1 ), w, 1, color ); 207 | FillRect( x, y, 1, h, color ); 208 | FillRect( x, y, w, 1, color ); 209 | FillRect( ( x + w - 1 ), y, 1, h, color ); 210 | } 211 | 212 | void CRender2D::DrawLine( const XMFLOAT2& point_1, const XMFLOAT2& point_2, ULONG color ) 213 | { 214 | if ( pD3DXDeviceCtx == NULL ) 215 | return; 216 | 217 | auto a = ( ( color >> 24 ) & 255 ); 218 | auto r = ( ( color >> 16 ) & 255 ); 219 | auto g = ( ( color >> 12 ) & 255 ); 220 | auto b = ( color & 255 ); 221 | 222 | float x1 = point_1.x; 223 | float x2 = point_2.x; 224 | 225 | float y1 = point_1.y; 226 | float y2 = point_2.y; 227 | 228 | UINT viewportNumber = 1; 229 | 230 | D3D11_VIEWPORT vp; 231 | 232 | pD3DXDeviceCtx->RSGetViewports( &viewportNumber, &vp ); 233 | 234 | float xx0 = 2.0f * ( x1 - 0.5f ) / vp.Width - 1.0f; 235 | float yy0 = 1.0f - 2.0f * ( y1 - 0.5f ) / vp.Height; 236 | float xx1 = 2.0f * ( x2 - 0.5f ) / vp.Width - 1.0f; 237 | float yy1 = 1.0f - 2.0f * ( y2 - 0.5f ) / vp.Height; 238 | 239 | COLOR_VERTEX* v = NULL; 240 | 241 | D3D11_MAPPED_SUBRESOURCE mapData; 242 | 243 | if ( FAILED( pD3DXDeviceCtx->Map( this->mVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mapData ) ) ) 244 | return; 245 | 246 | v = ( COLOR_VERTEX* )mapData.pData; 247 | 248 | v[ 0 ].Position.x = xx0; 249 | v[ 0 ].Position.y = yy0; 250 | 251 | v[ 0 ].Position.z = 0; 252 | v[ 0 ].Color = XMFLOAT4( 253 | ( ( float )r / 255.0f ), 254 | ( ( float )g / 255.0f ), 255 | ( ( float )b / 255.0f ), 256 | ( ( float )a / 255.0f ) ); 257 | 258 | v[ 1 ].Position.x = xx1; 259 | v[ 1 ].Position.y = yy1; 260 | v[ 1 ].Position.z = 0; 261 | v[ 1 ].Color = XMFLOAT4( 262 | ( ( float )r / 255.0f ), 263 | ( ( float )g / 255.0f ), 264 | ( ( float )b / 255.0f ), 265 | ( ( float )a / 255.0f ) ); 266 | 267 | pD3DXDeviceCtx->Unmap( this->mVertexBuffer, NULL ); 268 | 269 | UINT Stride = sizeof( COLOR_VERTEX ); 270 | UINT Offset = 0; 271 | 272 | pD3DXDeviceCtx->IASetVertexBuffers( 0, 1, &this->mVertexBuffer, &Stride, &Offset ); 273 | pD3DXDeviceCtx->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP ); 274 | pD3DXDeviceCtx->IASetInputLayout( this->mInputLayout ); 275 | 276 | pD3DXDeviceCtx->VSSetShader( this->mVS, 0, 0 ); 277 | pD3DXDeviceCtx->PSSetShader( this->mPS, 0, 0 ); 278 | pD3DXDeviceCtx->GSSetShader( NULL, 0, 0 ); 279 | pD3DXDeviceCtx->Draw( 2, 0 ); 280 | } 281 | 282 | void CRender2D::DrawHealthBar( float x, float y, float w, float health, float max ) 283 | { 284 | this->DrawHealthBar( x, y, w, 2, health, max ); 285 | } 286 | 287 | void CRender2D::DrawHealthBar( float x, float y, float w, float h, float health, float max ) 288 | { 289 | /*if ( !max ) 290 | return; 291 | 292 | if ( w < 5 ) 293 | return; 294 | 295 | if ( health < 0 ) 296 | health = 0; 297 | 298 | float ratio = health / max; 299 | 300 | ULONG col = ULONG( 0, ( BYTE )( 255 - 255 * ratio ), ( BYTE )( 255 * ratio ), 255 ); 301 | 302 | float step = ( w / max ); 303 | float draw = ( step * health ); 304 | 305 | FillRect( x, y, w, h, ULONG( 0, 0, 0, 255 ) ); 306 | FillRect( x, y, draw, h, col );*/ 307 | } 308 | 309 | void CRender2D::RenderText( const wchar_t* txt, float x, float y, ULONG color, bool center, bool shadow ) 310 | { 311 | if ( !this->font ) 312 | return; 313 | 314 | if ( center ) 315 | { 316 | FW1_RECTF nullRect = { 0.f, 0.f, 0.f, 0.f }; 317 | FW1_RECTF rect = this->font->MeasureString( txt, L"Arial", 17.0f, &nullRect, FW1_NOWORDWRAP ); 318 | 319 | auto v = XMFLOAT2{ rect.Right, rect.Bottom }; 320 | 321 | x -= v.x / 2.f; 322 | } 323 | 324 | if ( shadow ) 325 | { 326 | this->font->DrawString( pD3DXDeviceCtx, txt, 17.0f, x - 1, y, 0xFF000000, FW1_RESTORESTATE ); 327 | this->font->DrawString( pD3DXDeviceCtx, txt, 17.0f, x + 1, y, 0xFF000000, FW1_RESTORESTATE ); 328 | this->font->DrawString( pD3DXDeviceCtx, txt, 17.0f, x, y - 1, 0xFF000000, FW1_RESTORESTATE ); 329 | this->font->DrawString( pD3DXDeviceCtx, txt, 17.0f, x, y + 1, 0xFF000000, FW1_RESTORESTATE ); 330 | } 331 | 332 | this->font->DrawString( pD3DXDeviceCtx, txt, 17.0f, x, y, color, FW1_RESTORESTATE ); 333 | } 334 | 335 | void CRender2D::RenderText( const char* txt, float x, float y, ULONG color, bool center, bool shadow ) 336 | { 337 | auto cb = MultiByteToWideChar( CP_UTF8, 0, txt, -1, nullptr, NULL ); 338 | 339 | wchar_t* wsText = new wchar_t[ cb + sizeof( wchar_t ) ]; 340 | MultiByteToWideChar( CP_UTF8, 0, txt, -1, wsText, cb ); 341 | 342 | this->RenderText( wsText, x, y, color, center, shadow ); 343 | 344 | delete[] wsText; 345 | } 346 | 347 | void CRender2D::BeginScene() 348 | { 349 | this->restoreState = false; 350 | 351 | if ( SUCCEEDED( this->stateSaver->saveCurrentState( pD3DXDeviceCtx ) ) ) 352 | this->restoreState = true; 353 | 354 | float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; 355 | pD3DXDeviceCtx->OMSetBlendState( this->transparency, blendFactor, 0xffffffff ); 356 | pD3DXDeviceCtx->IASetInputLayout( this->mInputLayout ); 357 | } 358 | 359 | void CRender2D::EndScene() 360 | { 361 | if ( this->restoreState ) 362 | this->stateSaver->restoreSavedState(); 363 | } 364 | 365 | void CRender2D::OnReset() 366 | { 367 | SAFE_RELEASE( this->mVS ); 368 | SAFE_RELEASE( this->mPS ); 369 | SAFE_RELEASE( this->transparency ); 370 | SAFE_RELEASE( this->mInputLayout ); 371 | SAFE_RELEASE( this->mVertexBuffer ); 372 | 373 | restoreState = false; 374 | } --------------------------------------------------------------------------------