├── dwm-overlay
├── third-party
│ ├── imgui
│ │ ├── misc
│ │ │ ├── fonts
│ │ │ │ ├── DroidSans.ttf
│ │ │ │ ├── ProggyClean.ttf
│ │ │ │ ├── ProggyTiny.ttf
│ │ │ │ ├── Karla-Regular.ttf
│ │ │ │ ├── Roboto-Medium.ttf
│ │ │ │ ├── Cousine-Regular.ttf
│ │ │ │ └── binary_to_compressed_c.cpp
│ │ │ ├── debuggers
│ │ │ │ ├── README.txt
│ │ │ │ ├── imgui.gdb
│ │ │ │ ├── imgui.natstepfilter
│ │ │ │ └── imgui.natvis
│ │ │ ├── cpp
│ │ │ │ ├── README.txt
│ │ │ │ ├── imgui_stdlib.h
│ │ │ │ └── imgui_stdlib.cpp
│ │ │ ├── README.txt
│ │ │ ├── single_file
│ │ │ │ └── imgui_single_file.h
│ │ │ └── freetype
│ │ │ │ ├── README.md
│ │ │ │ ├── imgui_freetype.h
│ │ │ │ └── imgui_freetype.cpp
│ │ ├── LICENSE.txt
│ │ ├── backends
│ │ │ ├── imgui_impl_dx11.h
│ │ │ ├── imgui_impl_win32.h
│ │ │ └── imgui_impl_dx11.cpp
│ │ ├── imconfig.h
│ │ └── imstb_rectpack.h
│ ├── vmprotect
│ │ ├── lib
│ │ │ ├── vmprotectsdk32.lib
│ │ │ └── vmprotectsdk64.lib
│ │ ├── license.txt
│ │ └── include
│ │ │ └── vmprotectsdk.h
│ └── vtablehook
│ │ ├── src
│ │ └── vtablehook.cpp
│ │ ├── license.txt
│ │ └── include
│ │ └── vtablehook.h
├── dwm-overlay.vcxproj.user
├── dwm-overlay.vcxproj.filters
├── include
│ └── dxgi
│ │ └── undocumented.h
├── src
│ └── dllmain
│ │ └── dllmain.cpp
└── dwm-overlay.vcxproj
├── license.txt
├── dwm-overlay.sln
└── readme.md
/dwm-overlay/third-party/imgui/misc/fonts/DroidSans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/DroidSans.ttf
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/ProggyClean.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/ProggyClean.ttf
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/ProggyTiny.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/ProggyTiny.ttf
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vmprotect/lib/vmprotectsdk32.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/vmprotect/lib/vmprotectsdk32.lib
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vmprotect/lib/vmprotectsdk64.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/vmprotect/lib/vmprotectsdk64.lib
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/Karla-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/Karla-Regular.ttf
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/Cousine-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aurenex/dwm-overlay/HEAD/dwm-overlay/third-party/imgui/misc/fonts/Cousine-Regular.ttf
--------------------------------------------------------------------------------
/dwm-overlay/dwm-overlay.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
6 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/debuggers/README.txt:
--------------------------------------------------------------------------------
1 |
2 | HELPER FILES FOR POPULAR DEBUGGERS
3 |
4 | imgui.gdb
5 | GDB: disable stepping into trivial functions.
6 | (read comments inside file for details)
7 |
8 | imgui.natstepfilter
9 | Visual Studio Debugger: disable stepping into trivial functions.
10 | (read comments inside file for details)
11 |
12 | imgui.natvis
13 | Visual Studio Debugger: describe Dear ImGui types for better display.
14 | With this, types like ImVector<> will be displayed nicely in the debugger.
15 | (read comments inside file for details)
16 |
17 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/debuggers/imgui.gdb:
--------------------------------------------------------------------------------
1 | # GDB configuration to aid debugging experience
2 |
3 | # To enable these customizations edit $HOME/.gdbinit (or ./.gdbinit if local gdbinit is enabled) and add:
4 | # add-auto-load-safe-path /path/to/imgui.gdb
5 | # source /path/to/imgui.gdb
6 | #
7 | # More Information at:
8 | # * https://sourceware.org/gdb/current/onlinedocs/gdb/gdbinit-man.html
9 | # * https://sourceware.org/gdb/current/onlinedocs/gdb/Init-File-in-the-Current-Directory.html#Init-File-in-the-Current-Directory
10 |
11 | # Disable stepping into trivial functions
12 | skip -rfunction Im(Vec2|Vec4|Strv|Vector|Span)::.+
13 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/cpp/README.txt:
--------------------------------------------------------------------------------
1 |
2 | imgui_stdlib.h + imgui_stdlib.cpp
3 | InputText() wrappers for C++ standard library (STL) type: std::string.
4 | This is also an example of how you may wrap your own similar types.
5 |
6 | imgui_scoped.h
7 | [Experimental, not currently in main repository]
8 | Additional header file with some RAII-style wrappers for common Dear ImGui functions.
9 | Try by merging: https://github.com/ocornut/imgui/pull/2197
10 | Discuss at: https://github.com/ocornut/imgui/issues/2096
11 |
12 | See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
13 | https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
14 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vtablehook/src/vtablehook.cpp:
--------------------------------------------------------------------------------
1 | #include "vtablehook/include/vtablehook.h"
2 |
3 | int unprotect(void* region)
4 | {
5 | MEMORY_BASIC_INFORMATION mbi;
6 | VirtualQuery((LPCVOID)region, &mbi, sizeof(mbi));
7 | VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect);
8 | return mbi.Protect;
9 | }
10 |
11 | void protect(void* region, int protection)
12 | {
13 | MEMORY_BASIC_INFORMATION mbi;
14 | VirtualQuery((LPCVOID)region, &mbi, sizeof(mbi));
15 | VirtualProtect(mbi.BaseAddress, mbi.RegionSize, protection, &mbi.Protect);
16 | }
17 |
18 | void* vtable::hook(void* instance, void* hook, int offset)
19 | {
20 | intptr_t vtable = *((intptr_t*)instance);
21 | intptr_t entry = vtable + sizeof(intptr_t) * offset;
22 | intptr_t original = *((intptr_t*)entry);
23 |
24 | int original_protection = unprotect((void*)entry);
25 | *((intptr_t*)entry) = (intptr_t)hook;
26 | protect((void*)entry, original_protection);
27 |
28 | return (void*)original;
29 | }
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/README.txt:
--------------------------------------------------------------------------------
1 |
2 | misc/cpp/
3 | InputText() wrappers for C++ standard library (STL) type: std::string.
4 | This is also an example of how you may wrap your own similar types.
5 |
6 | misc/debuggers/
7 | Helper files for popular debuggers.
8 | With the .natvis file, types like ImVector<> will be displayed nicely in Visual Studio debugger.
9 |
10 | misc/fonts/
11 | Fonts loading/merging instructions (e.g. How to handle glyph ranges, how to merge icons fonts).
12 | Command line tool "binary_to_compressed_c" to create compressed arrays to embed data in source code.
13 | Suggested fonts and links.
14 |
15 | misc/freetype/
16 | Font atlas builder/rasterizer using FreeType instead of stb_truetype.
17 | Benefit from better FreeType rasterization, in particular for small fonts.
18 |
19 | misc/single_file/
20 | Single-file header stub.
21 | We use this to validate compiling all *.cpp files in a same compilation unit.
22 | Users of that technique (also called "Unity builds") can generally provide this themselves,
23 | so we don't really recommend you use this in your projects.
24 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Aurenex
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/single_file/imgui_single_file.h:
--------------------------------------------------------------------------------
1 | // dear imgui: single-file wrapper include
2 | // We use this to validate compiling all *.cpp files in a same compilation unit.
3 | // Users of that technique (also called "Unity builds") can generally provide this themselves,
4 | // so we don't really recommend you use this in your projects.
5 |
6 | // Do this:
7 | // #define IMGUI_IMPLEMENTATION
8 | // Before you include this file in *one* C++ file to create the implementation.
9 | // Using this in your project will leak the contents of imgui_internal.h and ImVec2 operators in this compilation unit.
10 |
11 | #ifdef IMGUI_IMPLEMENTATION
12 | #define IMGUI_DEFINE_MATH_OPERATORS
13 | #endif
14 |
15 | #include "../../imgui.h"
16 | #ifdef IMGUI_ENABLE_FREETYPE
17 | #include "../../misc/freetype/imgui_freetype.h"
18 | #endif
19 |
20 | #ifdef IMGUI_IMPLEMENTATION
21 | #include "../../imgui.cpp"
22 | #include "../../imgui_demo.cpp"
23 | #include "../../imgui_draw.cpp"
24 | #include "../../imgui_tables.cpp"
25 | #include "../../imgui_widgets.cpp"
26 | #ifdef IMGUI_ENABLE_FREETYPE
27 | #include "../../misc/freetype/imgui_freetype.cpp"
28 | #endif
29 | #endif
30 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vtablehook/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Thordin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2024 Omar Cornut
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/cpp/imgui_stdlib.h:
--------------------------------------------------------------------------------
1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
2 | // This is also an example of how you may wrap your own similar types.
3 |
4 | // Changelog:
5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
6 |
7 | // See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
8 | // https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
9 |
10 | #pragma once
11 |
12 | #include
13 |
14 | namespace ImGui
15 | {
16 | // ImGui::InputText() with std::string
17 | // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
18 | IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
19 | IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
20 | IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
21 | }
22 |
--------------------------------------------------------------------------------
/dwm-overlay.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.8.34511.84
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dwm-overlay", "dwm-overlay\dwm-overlay.vcxproj", "{210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Debug|x64.ActiveCfg = Debug|x64
17 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Debug|x64.Build.0 = Debug|x64
18 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Debug|x86.ActiveCfg = Debug|Win32
19 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Debug|x86.Build.0 = Debug|Win32
20 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Release|x64.ActiveCfg = Release|x64
21 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Release|x64.Build.0 = Release|x64
22 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Release|x86.ActiveCfg = Release|Win32
23 | {210C8DB9-E1FA-4714-B18D-8129EAAB2E1D}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {6B4AF21A-1ABF-407C-8761-69CE2C8749C8}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vtablehook/include/vtablehook.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Thordin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include
25 |
26 | namespace vtable
27 | {
28 | /// pointer to an instance of a class
29 | /// function to overwrite with
30 | ///
31 | /// original function
32 | void* hook(void* instance, void* hook, int offset);
33 | }
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/debuggers/imgui.natstepfilter:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 | (ImVec2|ImVec4|ImStrv)::.+
24 | NoStepInto
25 |
26 |
27 | (ImVector|ImSpan).*::operator.+
28 | NoStepInto
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # dwm-overlay
2 |
3 | This may be the first DWM overlay project on GitHub that gets a pointer to the IDXGISwapChainDWMLegacy virtual function table without a memory scan, using undocumented GUIDs. By default, this project only works on Windows 10/11. To support older OS versions, you need to update the offsets for the virtual function table.
4 |
5 |
6 | Sorry for the shitty code, I'll do better later.
7 |
8 | 
9 |
10 | Subscribe to my Telegram [channel][tg-channel-link] or make a donation if you want to support me.
11 |
12 | ### Bugs
13 | - ~~Debug version causes system to freeze~~.
14 | - Duplicating an overlay in an area that is not updating.
15 | - The overlay disappears after reconnecting the monitor.
16 | - Doesn't work on Win11 24H2+ with NVIDIA graphics cards.
17 |
18 | ### Compilation
19 | - Clone or [download][repo-download-link] this repository.
20 | - Open the **dwm-overlay** solution file in [Visual Studio IDE][vs-download-link].
21 | - Select the target platform.
22 | - Press `ctrl + shift + b` to compile.
23 |
24 | ### Usage
25 | - Open any DLL-injector **as administrator**.
26 | - Find the **dwm.exe** process.
27 | - Inject the `dwm-overlay.dll` into process.
28 |
29 | Before use, we strongly recommend that you read the [license][license-link].
30 |
31 | [repo-download-link]:
32 | [vs-download-link]:
33 | [tg-channel-link]:
34 | [license-link]: <../master/license.txt>
35 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vmprotect/license.txt:
--------------------------------------------------------------------------------
1 | All copyrights and property rights to VMProtect are exclusively owned by VMProtect Software.
2 | VMProtect is a commercial software. To receive more detailed information on how to buy the software please email info@vmpsoft.com
3 | The author reserves the right to cancel the validity of the given license for any of the further version of demo version of VMProtect.
4 | Using VMProtect for commercial purposes is forbidden, including renting or selling it, incorporating it into other programs or systems, using it in third-party software, or providing software protection services to third parties.
5 | The author guarantees that our software does not contain viruses, trojans, or other malicious code. If an antivirus detects such code in software protected by VMProtect, it may be a false positive and should not be used as a reason for a refund.
6 | VMPROTECT IS DISTRIBUTED 'AS IS'. NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHOR WILL NOT BE RESPONSIBLE FOR DATA LOSS, DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS SOFTWARE.
7 | You are not allowed to modify, create new versions, rent, sell, decompile, disassemble, otherwise reverse engineer, alter, delete, or hide trademarks and notices of copyrights. Using VMProtect to hide viruses, trojans, key loggers, or other malicious code is not allowed. Using it in software that violates the intellectual property rights of third parties (such as key generators, cracks, patches, or loaders) is also not allowed.
8 | Installing and using VMProtect means that you accept the terms and conditions of this license. Any violation of the terms of this agreement will result in immediate and automatic termination of this license without compensation of any charges related to the use of VMProtect and may result in criminal and/or civil prosecution.
9 | If you do not agree with the terms of this license, you must remove VMProtect files from your storage devices and stop using VMProtect.
--------------------------------------------------------------------------------
/dwm-overlay/dwm-overlay.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;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 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 |
44 |
45 | Header Files
46 |
47 |
48 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/debuggers/imgui.natvis:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 | {{Size={Size} Capacity={Capacity}}}
18 |
19 |
20 | Size
21 | Data
22 |
23 |
24 |
25 |
26 |
27 | {{Size={DataEnd-Data} }}
28 |
29 |
30 | DataEnd-Data
31 | Data
32 |
33 |
34 |
35 |
36 |
37 | {{x={x,g} y={y,g}}}
38 |
39 |
40 |
41 | {{x={x,g} y={y,g} z={z,g} w={w,g}}}
42 |
43 |
44 |
45 | {{Min=({Min.x,g} {Min.y,g}) Max=({Max.x,g} {Max.y,g}) Size=({Max.x-Min.x,g} {Max.y-Min.y,g})}}
46 |
47 | - Min
48 | - Max
49 | - Max.x - Min.x
50 | - Max.y - Min.y
51 |
52 |
53 |
54 |
55 | {{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags & 0x01000000)?1:0,d} Popup {(Flags & 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}}
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/dwm-overlay/include/dxgi/undocumented.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Undocumented DXGI structures
3 | *
4 | * Windows 10 21H2 IoT LTSC
5 | * dxgi.dll 10.0.19041.5794
6 | *
7 | * https://t.me/rxznve
8 | * https://t.me/aurenex
9 | * https://github.com/aurenex
10 | */
11 |
12 | #ifndef DXGI_UNDOCUMENTED_H_GUARD
13 | #define DXGI_UNDOCUMENTED_H_GUARD
14 |
15 | // DXGI_SCROLL_RECT 24 (0x18) bytes
16 | typedef struct _DXGI_SCROLL_RECT
17 | {
18 | POINT offset;
19 | RECT region;
20 | } DXGI_SCROLL_RECT;
21 |
22 | // DXGI_PRESENT_MULTIPLANE_OVERLAY 136 (0x88) bytes
23 | typedef struct _DXGI_PRESENT_MULTIPLANE_OVERLAY
24 | {
25 | UINT LayerIndex;
26 | UINT Flags;
27 | char unknown1[0x14];
28 | RECT SrcRect;
29 | RECT DstRect;
30 | RECT ClipRect;
31 | DXGI_MODE_ROTATION Rotation;
32 | char unknown2[0x04]; // Maybe blend
33 | UINT DirtyRectsCount;
34 | RECT* pDirtyRects;
35 | char unknown3[0x28];
36 | } DXGI_PRESENT_MULTIPLANE_OVERLAY;
37 |
38 | MIDL_INTERFACE("f69f223b-45d3-4aa0-98c8-c40c2b231029")
39 | IDXGISwapChainDWMLegacy : public IDXGIDeviceSubObject
40 | {
41 | virtual HRESULT STDMETHODCALLTYPE Present
42 | (
43 | UINT SyncInterval,
44 | UINT Flags
45 | ) = 0;
46 |
47 | virtual HRESULT STDMETHODCALLTYPE GetBuffer
48 | (
49 | UINT Buffer,
50 | REFIID riid,
51 | void** ppSurface
52 | ) = 0;
53 | };
54 |
55 | MIDL_INTERFACE("713f394e-92ca-47e7-ab81-1159c2791e54")
56 | IDXGIFactoryDWM : public IUnknown
57 | {
58 | virtual HRESULT STDMETHODCALLTYPE CreateSwapChain
59 | (
60 | IUnknown* pDevice,
61 | DXGI_SWAP_CHAIN_DESC* pDesc,
62 | IDXGIOutput* pOutput,
63 | IDXGISwapChainDWMLegacy** ppSwapChainDWM
64 | ) = 0;
65 | };
66 |
67 | HRESULT (STDMETHODCALLTYPE* PresentDWM)
68 | (
69 | IDXGISwapChainDWMLegacy* pSwapChain,
70 | UINT SyncInterval,
71 | UINT PresentFlags,
72 | UINT DirtyRectsCount,
73 | const RECT* pDirtyRects,
74 | UINT ScrollRectsCount,
75 | const DXGI_SCROLL_RECT* pScrollRects,
76 | IDXGIResource* pResource,
77 | UINT FrameIndex // ???
78 | );
79 |
80 | HRESULT (STDMETHODCALLTYPE* PresentMultiplaneOverlay)
81 | (
82 | IDXGISwapChainDWMLegacy* pSwapChain,
83 | UINT SyncInterval,
84 | UINT PresentFlags,
85 | DXGI_HDR_METADATA_TYPE MetadataType,
86 | const VOID* pMetadata,
87 | UINT OverlayCount,
88 | const DXGI_PRESENT_MULTIPLANE_OVERLAY* pOverlays
89 | );
90 |
91 | #endif //DXGI_UNDOCUMENTED_H_GUARD
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/backends/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: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
7 | // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
8 |
9 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
10 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
11 | // Learn about Dear ImGui:
12 | // - FAQ https://dearimgui.com/faq
13 | // - Getting Started https://dearimgui.com/getting-started
14 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
15 | // - Introduction, links and more at the top of imgui.cpp
16 |
17 | #pragma once
18 | #include "imgui.h" // IMGUI_IMPL_API
19 | #ifndef IMGUI_DISABLE
20 |
21 | struct ID3D11Device;
22 | struct ID3D11DeviceContext;
23 | struct ID3D11SamplerState;
24 |
25 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
26 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
27 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
28 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
29 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
30 |
31 | // Use if you want to reset your rendering device without losing Dear ImGui state.
32 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
33 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
34 |
35 | // [BETA] Selected render state data shared with callbacks.
36 | // This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
37 | // (Please open an issue if you feel you need access to more data)
38 | struct ImGui_ImplDX11_RenderState
39 | {
40 | ID3D11Device* Device;
41 | ID3D11DeviceContext* DeviceContext;
42 | ID3D11SamplerState* SamplerDefault;
43 | };
44 |
45 | #endif // #ifndef IMGUI_DISABLE
46 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/freetype/README.md:
--------------------------------------------------------------------------------
1 | # imgui_freetype
2 |
3 | Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer).
4 |
by @vuhdo, @mikesart, @ocornut.
5 |
6 | ### Usage
7 |
8 | 1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype --triplet=x64-windows`, `vcpkg integrate install`).
9 | 2. Add imgui_freetype.h/cpp alongside your project files.
10 | 3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file
11 |
12 | ### About Gamma Correct Blending
13 |
14 | FreeType assumes blending in linear space rather than gamma space.
15 | See FreeType note for [FT_Render_Glyph](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_render_glyph).
16 | For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
17 | The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
18 |
19 | ### Testbed for toying with settings (for developers)
20 |
21 | See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
22 |
23 | ### Known issues
24 |
25 | - Oversampling settings are ignored but also not so much necessary with the higher quality rendering.
26 |
27 | ### Comparison
28 |
29 | Small, thin anti-aliased fonts typically benefit a lot from FreeType's hinting:
30 | 
31 |
32 | ### Colorful glyphs/emojis
33 |
34 | You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain colorful glyphs. See the
35 | ["Using Colorful Glyphs/Emojis"](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#using-colorful-glyphsemojis) section of FONTS.md.
36 |
37 | 
38 |
39 | ### Using OpenType SVG fonts (SVGinOT)
40 | - *SVG in Open Type* is a standard by Adobe and Mozilla for color OpenType and Open Font Format fonts. It allows font creators to embed complete SVG files within a font enabling full color and even animations.
41 | - Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT
42 | - Two alternatives are possible to render SVG fonts: use "lunasvg" or "plutosvg". plutosvg will support some more fonts (e.g. NotoColorEmoji-Regular) and may load them faster.
43 |
44 | #### Using lunasvg
45 | Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above
46 | - Add `#define IMGUI_ENABLE_FREETYPE_LUNASVG` in your `imconfig.h`.
47 | - Get latest lunasvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install lunasvg --triplet=x64-windows`.
48 |
49 | #### Using plutosvg (and plutovg)
50 | - Add `#define IMGUI_ENABLE_FREETYPE_PLUTOSVG` in your `imconfig.h`.
51 | - Compile and link with plutosvg *and* plutovg (which is required by plutosvg)
52 |
53 | _Compilation hints for plutovg_
54 | - Compile all source files in `plutovg/source/*.c`
55 | - Add include directory: `plutovg/include` + `plutovg/stb`
56 |
57 | _Compilation hints for plutosvg_
58 | - Compile `plutosvg/source/plutosvg.c`
59 | - Add include directory: `plutosvg/source`
60 | - Add define: `PLUTOSVG_HAS_FREETYPE`
61 | - Link with: plutovg, freetype
62 |
63 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/cpp/imgui_stdlib.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
2 | // This is also an example of how you may wrap your own similar types.
3 |
4 | // Changelog:
5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
6 |
7 | // See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
8 | // https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
9 |
10 | #include "imgui.h"
11 | #include "imgui_stdlib.h"
12 |
13 | // Clang warnings with -Weverything
14 | #if defined(__clang__)
15 | #pragma clang diagnostic push
16 | #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
17 | #endif
18 |
19 | struct InputTextCallback_UserData
20 | {
21 | std::string* Str;
22 | ImGuiInputTextCallback ChainCallback;
23 | void* ChainCallbackUserData;
24 | };
25 |
26 | static int InputTextCallback(ImGuiInputTextCallbackData* data)
27 | {
28 | InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData;
29 | if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
30 | {
31 | // Resize string callback
32 | // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
33 | std::string* str = user_data->Str;
34 | IM_ASSERT(data->Buf == str->c_str());
35 | str->resize(data->BufTextLen);
36 | data->Buf = (char*)str->c_str();
37 | }
38 | else if (user_data->ChainCallback)
39 | {
40 | // Forward to user callback, if any
41 | data->UserData = user_data->ChainCallbackUserData;
42 | return user_data->ChainCallback(data);
43 | }
44 | return 0;
45 | }
46 |
47 | bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
48 | {
49 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
50 | flags |= ImGuiInputTextFlags_CallbackResize;
51 |
52 | InputTextCallback_UserData cb_user_data;
53 | cb_user_data.Str = str;
54 | cb_user_data.ChainCallback = callback;
55 | cb_user_data.ChainCallbackUserData = user_data;
56 | return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
57 | }
58 |
59 | bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
60 | {
61 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
62 | flags |= ImGuiInputTextFlags_CallbackResize;
63 |
64 | InputTextCallback_UserData cb_user_data;
65 | cb_user_data.Str = str;
66 | cb_user_data.ChainCallback = callback;
67 | cb_user_data.ChainCallbackUserData = user_data;
68 | return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
69 | }
70 |
71 | bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
72 | {
73 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
74 | flags |= ImGuiInputTextFlags_CallbackResize;
75 |
76 | InputTextCallback_UserData cb_user_data;
77 | cb_user_data.Str = str;
78 | cb_user_data.ChainCallback = callback;
79 | cb_user_data.ChainCallbackUserData = user_data;
80 | return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
81 | }
82 |
83 | #if defined(__clang__)
84 | #pragma clang diagnostic pop
85 | #endif
86 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/backends/imgui_impl_win32.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits 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 support. Can discriminate Mouse/TouchScreen/Pen.
7 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 | // [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
10 |
11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
13 | // Learn about Dear ImGui:
14 | // - FAQ https://dearimgui.com/faq
15 | // - Getting Started https://dearimgui.com/getting-started
16 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
17 | // - Introduction, links and more at the top of imgui.cpp
18 |
19 | #pragma once
20 | #include "imgui.h" // IMGUI_IMPL_API
21 | #ifndef IMGUI_DISABLE
22 |
23 | // Follow "Getting Started" link and check examples/ folder to learn about using backends!
24 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
25 | IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
26 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
27 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
28 |
29 | // Win32 message handler your application need to call.
30 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper.
31 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
32 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
33 |
34 | #if 0
35 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
36 | #endif
37 |
38 | // DPI-related helpers (optional)
39 | // - Use to enable DPI awareness without having to create an application manifest.
40 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
41 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
42 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
43 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
44 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
45 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
46 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
47 |
48 | // Transparency related helpers (optional) [experimental]
49 | // - Use to enable alpha compositing transparency with the desktop.
50 | // - Use together with e.g. clearing your framebuffer with zero-alpha.
51 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
52 |
53 | #endif // #ifndef IMGUI_DISABLE
54 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/vmprotect/include/vmprotectsdk.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if defined(__APPLE__) || defined(__unix__)
4 | #define VMP_IMPORT
5 | #define VMP_API
6 | #define VMP_WCHAR unsigned short
7 | #else
8 | #define VMP_IMPORT __declspec(dllimport)
9 | #define VMP_API __stdcall
10 | #define VMP_WCHAR wchar_t
11 | #ifdef _M_IX86
12 | #pragma comment(lib, "vmprotect/lib/vmprotectsdk32.lib")
13 | #elif _M_X64
14 | #pragma comment(lib, "vmprotect/lib/vmprotectsdk64.lib")
15 | #elif _M_ARM64
16 | #pragma comment(lib, "vmprotect/lib/vmprotectarm64.lib")
17 | #else
18 | #error "Unsupported target architecture"
19 | #endif
20 | #endif // __APPLE__ || __unix__
21 |
22 | #ifdef __cplusplus
23 | extern "C" {
24 | #endif
25 |
26 | // protection
27 | VMP_IMPORT void VMP_API VMProtectBegin(const char *);
28 | VMP_IMPORT void VMP_API VMProtectBeginVirtualization(const char *);
29 | VMP_IMPORT void VMP_API VMProtectBeginMutation(const char *);
30 | VMP_IMPORT void VMP_API VMProtectBeginUltra(const char *);
31 | VMP_IMPORT void VMP_API VMProtectBeginVirtualizationLockByKey(const char *);
32 | VMP_IMPORT void VMP_API VMProtectBeginUltraLockByKey(const char *);
33 | VMP_IMPORT void VMP_API VMProtectEnd(void);
34 |
35 | // utils
36 | VMP_IMPORT bool VMP_API VMProtectIsProtected();
37 | VMP_IMPORT bool VMP_API VMProtectIsDebuggerPresent(bool);
38 | VMP_IMPORT bool VMP_API VMProtectIsVirtualMachinePresent(void);
39 | VMP_IMPORT bool VMP_API VMProtectIsValidImageCRC(void);
40 | VMP_IMPORT const char * VMP_API VMProtectDecryptStringA(const char *value);
41 | VMP_IMPORT const VMP_WCHAR * VMP_API VMProtectDecryptStringW(const VMP_WCHAR *value);
42 | VMP_IMPORT bool VMP_API VMProtectFreeString(const void *value);
43 |
44 | // licensing
45 | enum VMProtectSerialStateFlags
46 | {
47 | SERIAL_STATE_SUCCESS = 0,
48 | SERIAL_STATE_FLAG_CORRUPTED = 0x00000001,
49 | SERIAL_STATE_FLAG_INVALID = 0x00000002,
50 | SERIAL_STATE_FLAG_BLACKLISTED = 0x00000004,
51 | SERIAL_STATE_FLAG_DATE_EXPIRED = 0x00000008,
52 | SERIAL_STATE_FLAG_RUNNING_TIME_OVER = 0x00000010,
53 | SERIAL_STATE_FLAG_BAD_HWID = 0x00000020,
54 | SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED = 0x00000040,
55 | };
56 |
57 | #pragma pack(push, 1)
58 | typedef struct
59 | {
60 | unsigned short wYear;
61 | unsigned char bMonth;
62 | unsigned char bDay;
63 | } VMProtectDate;
64 |
65 | typedef struct
66 | {
67 | int nState; // VMProtectSerialStateFlags
68 | VMP_WCHAR wUserName[256]; // user name
69 | VMP_WCHAR wEMail[256]; // email
70 | VMProtectDate dtExpire; // date of serial number expiration
71 | VMProtectDate dtMaxBuild; // max date of build, that will accept this key
72 | int bRunningTime; // running time in minutes
73 | unsigned char nUserDataLength; // length of user data in bUserData
74 | unsigned char bUserData[255]; // up to 255 bytes of user data
75 | } VMProtectSerialNumberData;
76 | #pragma pack(pop)
77 |
78 | VMP_IMPORT int VMP_API VMProtectSetSerialNumber(const char *serial);
79 | VMP_IMPORT int VMP_API VMProtectGetSerialNumberState();
80 | VMP_IMPORT bool VMP_API VMProtectGetSerialNumberData(VMProtectSerialNumberData *data, int size);
81 | VMP_IMPORT int VMP_API VMProtectGetCurrentHWID(char *hwid, int size);
82 |
83 | // activation
84 | enum VMProtectActivationFlags
85 | {
86 | ACTIVATION_OK = 0,
87 | ACTIVATION_SMALL_BUFFER,
88 | ACTIVATION_NO_CONNECTION,
89 | ACTIVATION_BAD_REPLY,
90 | ACTIVATION_BANNED,
91 | ACTIVATION_CORRUPTED,
92 | ACTIVATION_BAD_CODE,
93 | ACTIVATION_ALREADY_USED,
94 | ACTIVATION_SERIAL_UNKNOWN,
95 | ACTIVATION_EXPIRED,
96 | ACTIVATION_NOT_AVAILABLE
97 | };
98 |
99 | VMP_IMPORT int VMP_API VMProtectActivateLicense(const char *code, char *serial, int size);
100 | VMP_IMPORT int VMP_API VMProtectDeactivateLicense(const char *serial);
101 | VMP_IMPORT int VMP_API VMProtectGetOfflineActivationString(const char *code, char *buf, int size);
102 | VMP_IMPORT int VMP_API VMProtectGetOfflineDeactivationString(const char *serial, char *buf, int size);
103 |
104 | #ifdef __cplusplus
105 | }
106 | #endif
107 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/freetype/imgui_freetype.h:
--------------------------------------------------------------------------------
1 | // dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
2 | // (headers)
3 |
4 | #pragma once
5 | #include "imgui.h" // IMGUI_API
6 | #ifndef IMGUI_DISABLE
7 |
8 | // Usage:
9 | // - Add '#define IMGUI_ENABLE_FREETYPE' in your imconfig to enable support for imgui_freetype in imgui.
10 |
11 | // Optional support for OpenType SVG fonts:
12 | // - Add '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG' to use plutosvg (not provided). See #7927.
13 | // - Add '#define IMGUI_ENABLE_FREETYPE_LUNASVG' to use lunasvg (not provided). See #6591.
14 |
15 | // Forward declarations
16 | struct ImFontAtlas;
17 | struct ImFontBuilderIO;
18 |
19 | // Hinting greatly impacts visuals (and glyph sizes).
20 | // - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
21 | // - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h
22 | // - The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
23 | // - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
24 | // You can set those flags globaly in ImFontAtlas::FontBuilderFlags
25 | // You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags
26 | enum ImGuiFreeTypeBuilderFlags
27 | {
28 | ImGuiFreeTypeBuilderFlags_NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
29 | ImGuiFreeTypeBuilderFlags_NoAutoHint = 1 << 1, // Disable auto-hinter.
30 | ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
31 | ImGuiFreeTypeBuilderFlags_LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
32 | ImGuiFreeTypeBuilderFlags_MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
33 | ImGuiFreeTypeBuilderFlags_Bold = 1 << 5, // Styling: Should we artificially embolden the font?
34 | ImGuiFreeTypeBuilderFlags_Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
35 | ImGuiFreeTypeBuilderFlags_Monochrome = 1 << 7, // Disable anti-aliasing. Combine this with MonoHinting for best results!
36 | ImGuiFreeTypeBuilderFlags_LoadColor = 1 << 8, // Enable FreeType color-layered glyphs
37 | ImGuiFreeTypeBuilderFlags_Bitmap = 1 << 9 // Enable FreeType bitmap glyphs
38 | };
39 |
40 | namespace ImGuiFreeType
41 | {
42 | // This is automatically assigned when using '#define IMGUI_ENABLE_FREETYPE'.
43 | // If you need to dynamically select between multiple builders:
44 | // - you can manually assign this builder with 'atlas->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()'
45 | // - prefer deep-copying this into your own ImFontBuilderIO instance if you use hot-reloading that messes up static data.
46 | IMGUI_API const ImFontBuilderIO* GetBuilderForFreeType();
47 |
48 | // Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE()
49 | // However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired.
50 | IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = nullptr);
51 |
52 | // Obsolete names (will be removed soon)
53 | #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
54 | //static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); } // Prefer using '#define IMGUI_ENABLE_FREETYPE'
55 | #endif
56 | }
57 |
58 | #endif // #ifndef IMGUI_DISABLE
59 |
--------------------------------------------------------------------------------
/dwm-overlay/src/dllmain/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #pragma comment(lib, "d3d11.lib")
6 |
7 | #include
8 | #pragma comment(lib, "dxgi.lib")
9 |
10 | #include "dxgi/undocumented.h"
11 |
12 | #include "vtablehook/include/vtablehook.h"
13 |
14 | #include "imgui/imgui.h"
15 | #include "imgui/backends/imgui_impl_win32.h"
16 | #include "imgui/backends/imgui_impl_dx11.h"
17 |
18 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler
19 | (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
20 |
21 | decltype(PresentDWM) fn_PresentDWM = nullptr;
22 | decltype(PresentMultiplaneOverlay) fn_PresentMultiplaneOverlay = nullptr;
23 |
24 | CComPtr g_Device = nullptr;
25 | CComPtr g_DeviceContext = nullptr;
26 | CComPtr g_RenderTargetView = nullptr;
27 |
28 | void draw(IDXGISwapChainDWMLegacy* pSwapChain)
29 | {
30 | if (!ImGui::GetCurrentContext())
31 | {
32 | pSwapChain->GetDevice(IID_PPV_ARGS(&g_Device));
33 | g_Device->GetImmediateContext(&g_DeviceContext);
34 |
35 | ImGui::CreateContext();
36 | ImGui_ImplWin32_Init(GetDesktopWindow());
37 | ImGui_ImplDX11_Init(g_Device, g_DeviceContext);
38 |
39 | CComPtr pRenderTargetTexture = nullptr;
40 | pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pRenderTargetTexture));
41 | g_Device->CreateRenderTargetView(pRenderTargetTexture, nullptr, &g_RenderTargetView);
42 | }
43 |
44 | // Using &g_RenderTargetView.p avoids the overridden & operator.
45 | // The '&' operator has a null check and if false it prints an error message.
46 | // Displaying any message on the main rendering thread causes a deadlock.
47 | g_DeviceContext->OMSetRenderTargets(1, &g_RenderTargetView.p, nullptr);
48 |
49 | //constexpr float clear_color[] { 1.0f, 1.0f, 1.0f, 1.0f };
50 | //g_DeviceContext->ClearRenderTargetView(g_RenderTargetView.p, clear_color);
51 |
52 | ImGui_ImplDX11_NewFrame();
53 | ImGui_ImplWin32_NewFrame();
54 | ImGui::NewFrame();
55 |
56 | ImGui::Begin("DWM overlay");
57 | ImGui::Text("Copyright (C) 2025 Aurenex");
58 | ImGui::Text("https://t.me/aurenex");
59 | ImGui::End();
60 |
61 | ImGui::Render();
62 | ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
63 | }
64 |
65 | HRESULT STDMETHODCALLTYPE hk_PresentDWM
66 | (
67 | IDXGISwapChainDWMLegacy* pSwapChain,
68 | UINT SyncInterval,
69 | UINT PresentFlags,
70 | UINT DirtyRectsCount,
71 | const RECT* pDirtyRects,
72 | UINT ScrollRectsCount,
73 | const DXGI_SCROLL_RECT* pScrollRects,
74 | IDXGIResource* pResource,
75 | UINT FrameIndex // ???
76 | )
77 | {
78 | if (!(PresentFlags & DXGI_PRESENT_TEST))
79 | draw(pSwapChain);
80 |
81 | return fn_PresentDWM(
82 | pSwapChain,
83 | SyncInterval,
84 | PresentFlags,
85 | DirtyRectsCount,
86 | pDirtyRects,
87 | ScrollRectsCount,
88 | pScrollRects,
89 | pResource,
90 | FrameIndex);
91 | }
92 |
93 | HRESULT STDMETHODCALLTYPE hk_PresentMultiplaneOverlay
94 | (
95 | IDXGISwapChainDWMLegacy* pSwapChain,
96 | UINT SyncInterval,
97 | UINT PresentFlags,
98 | DXGI_HDR_METADATA_TYPE MetadataType,
99 | const VOID* pMetadata,
100 | UINT OverlayCount,
101 | const DXGI_PRESENT_MULTIPLANE_OVERLAY* pOverlays
102 | )
103 | {
104 | if (!(PresentFlags & DXGI_PRESENT_TEST))
105 | draw(pSwapChain);
106 |
107 | return fn_PresentMultiplaneOverlay(
108 | pSwapChain,
109 | SyncInterval,
110 | PresentFlags,
111 | MetadataType,
112 | pMetadata,
113 | OverlayCount,
114 | pOverlays);
115 | }
116 |
117 | LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
118 | {
119 | const KBDLLHOOKSTRUCT* hookStruct = reinterpret_cast(lParam);
120 |
121 | // Prevent process crash if ImGui context is not created
122 | // Calling 'ImGui::GetIO' requires a created context
123 | // Which is created when the draw function is called
124 | if (ImGui::GetCurrentContext())
125 | {
126 | const ImGuiIO& io = ImGui::GetIO();
127 |
128 | ImGui_ImplWin32_WndProcHandler(GetDesktopWindow(),
129 | static_cast(wParam), hookStruct->vkCode, hookStruct->scanCode);
130 |
131 | if (io.WantCaptureKeyboard)
132 | return -1;
133 | }
134 |
135 | // Abnormal termination of the process if something went wrong.
136 | if (hookStruct->vkCode == VK_END)
137 | TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS);
138 |
139 | return CallNextHookEx(nullptr, nCode, wParam, lParam);
140 | }
141 |
142 | LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
143 | {
144 | const MSLLHOOKSTRUCT* hookStruct = reinterpret_cast(lParam);
145 |
146 | // Prevent process crash if ImGui context is not created
147 | // Calling 'ImGui::GetIO' requires a created context
148 | // Which is created when the draw function is called
149 | if (ImGui::GetCurrentContext())
150 | {
151 | const ImGuiIO& io = ImGui::GetIO();
152 |
153 | ImGui_ImplWin32_WndProcHandler(GetDesktopWindow(), static_cast(wParam),
154 | hookStruct->flags, MAKELPARAM(hookStruct->pt.x, hookStruct->pt.y));
155 |
156 | if (io.WantCaptureMouse and wParam != WM_MOUSEMOVE)
157 | return -1;
158 | }
159 |
160 | return CallNextHookEx(nullptr, nCode, wParam, lParam);
161 | }
162 |
163 | DWORD WINAPI MainThread(LPVOID lpParameter)
164 | {
165 | CComPtr pFactory = nullptr;
166 | CreateDXGIFactory(IID_PPV_ARGS(&pFactory));
167 |
168 | CComPtr pAdapter = nullptr;
169 | pFactory->EnumAdapters(0, &pAdapter);
170 |
171 | CComPtr pOutput = nullptr;
172 | pAdapter->EnumOutputs(0, &pOutput);
173 |
174 | CComPtr pFactoryDWM = nullptr;
175 | pFactory->QueryInterface(IID_PPV_ARGS(&pFactoryDWM));
176 |
177 | const D3D_FEATURE_LEVEL FeatureLevels []
178 | {
179 | D3D_FEATURE_LEVEL_10_0,
180 | D3D_FEATURE_LEVEL_11_0
181 | };
182 |
183 | CComPtr pDevice = nullptr;
184 | CComPtr pDeviceContext = nullptr;
185 |
186 | D3D11CreateDevice
187 | (
188 | pAdapter,
189 | D3D_DRIVER_TYPE_UNKNOWN,
190 | nullptr,
191 | D3D11_CREATE_DEVICE_SINGLETHREADED,
192 | FeatureLevels,
193 | ARRAYSIZE(FeatureLevels),
194 | D3D11_SDK_VERSION,
195 | &pDevice,
196 | nullptr,
197 | &pDeviceContext
198 | );
199 |
200 | DXGI_SWAP_CHAIN_DESC SwapChainDesc {};
201 | {
202 | SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
203 | SwapChainDesc.SampleDesc.Count = 1;
204 | SwapChainDesc.BufferCount = 1;
205 | }
206 |
207 | CComPtr pSwapChain = nullptr;
208 | pFactoryDWM->CreateSwapChain(pDevice, &SwapChainDesc, pOutput, &pSwapChain);
209 |
210 | // Current offsets are supported on Windows 10 - 11
211 | // Don't forget to update the offsets for your version
212 | fn_PresentDWM = reinterpret_cast
213 | (vtable::hook(pSwapChain, &hk_PresentDWM, 16));
214 | fn_PresentMultiplaneOverlay = reinterpret_cast
215 | (vtable::hook(pSwapChain, &hk_PresentMultiplaneOverlay, 23));
216 |
217 | const HHOOK hMouseHook = SetWindowsHookExW(WH_MOUSE_LL, &LowLevelMouseProc, nullptr, 0);
218 | const HHOOK hKeyboardHook = SetWindowsHookExW(WH_KEYBOARD_LL, &LowLevelKeyboardProc, nullptr, 0);
219 |
220 | // TODO: Add UnhookWindowsHookEx
221 | if (!hMouseHook or !hKeyboardHook)
222 | return EXIT_FAILURE;
223 |
224 | MSG message {};
225 |
226 | while (GetMessageW(&message, nullptr, 0, 0) > 0)
227 | {
228 | TranslateMessage(&message);
229 | DispatchMessageW(&message);
230 | }
231 |
232 | UnhookWindowsHookEx(hMouseHook);
233 | UnhookWindowsHookEx(hKeyboardHook);
234 |
235 | return EXIT_SUCCESS;
236 | }
237 |
238 | BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpReserved)
239 | {
240 | switch (fdwReason)
241 | {
242 | case DLL_PROCESS_ATTACH:
243 | CreateThread(nullptr, 0, &MainThread, nullptr, 0, nullptr);
244 | break;
245 |
246 | case DLL_PROCESS_DETACH:
247 | // TODO: Remove vtable hook
248 | break;
249 | }
250 |
251 | return TRUE;
252 | }
253 |
--------------------------------------------------------------------------------
/dwm-overlay/dwm-overlay.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 17.0
23 | Win32Proj
24 | {210c8db9-e1fa-4714-b18d-8129eaab2e1d}
25 | dwmoverlay
26 | 10.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | $(SolutionDir)build\bin\
75 | $(SolutionDir)build\obj\
76 |
77 |
78 | $(SolutionDir)build\bin\
79 | $(SolutionDir)build\obj\
80 |
81 |
82 | $(SolutionDir)build\bin\
83 | $(SolutionDir)build\obj\
84 |
85 |
86 | $(SolutionDir)build\bin\
87 | $(SolutionDir)build\obj\
88 |
89 |
90 |
91 | Level3
92 | true
93 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
94 | true
95 | stdcpp17
96 | include;third-party;third-party\imgui;%(AdditionalIncludeDirectories)
97 | MultiThreadedDebug
98 | OnlyExplicitInline
99 |
100 |
101 | Console
102 | true
103 | third-party;%(AdditionalLibraryDirectories)
104 |
105 |
106 |
107 |
108 | Level3
109 | true
110 | true
111 | true
112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
113 | true
114 | stdcpp17
115 | include;third-party;third-party\imgui;%(AdditionalIncludeDirectories)
116 | MultiThreaded
117 | OnlyExplicitInline
118 |
119 |
120 | Console
121 | true
122 | true
123 | true
124 | third-party;%(AdditionalLibraryDirectories)
125 |
126 |
127 |
128 |
129 | Level3
130 | true
131 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
132 | true
133 | stdcpp17
134 | include;third-party;third-party\imgui;%(AdditionalIncludeDirectories)
135 | MultiThreadedDebug
136 | OnlyExplicitInline
137 |
138 |
139 | Console
140 | true
141 | third-party;%(AdditionalLibraryDirectories)
142 |
143 |
144 |
145 |
146 | Level3
147 | true
148 | true
149 | true
150 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
151 | true
152 | stdcpp17
153 | include;third-party;third-party\imgui;%(AdditionalIncludeDirectories)
154 | MultiThreaded
155 | OnlyExplicitInline
156 |
157 |
158 | Console
159 | true
160 | true
161 | true
162 | third-party;%(AdditionalLibraryDirectories)
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/imconfig.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------------
2 | // DEAR IMGUI COMPILE-TIME OPTIONS
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 file 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 | // - Windows 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) // MSVC Windows: DLL export
27 | //#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
28 | //#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
29 |
30 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
31 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
32 |
33 | //---- Disable all of Dear ImGui or don't implement standard windows/tools.
34 | // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
37 | //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
38 |
39 | //---- Don't implement some functions to reduce linkage requirements.
40 | //#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)
41 | //#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)
42 | //#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)
43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
44 | //#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).
45 | //#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
46 | //#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)
47 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
48 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
49 | //#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.
50 | //#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().
51 | //#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
52 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
53 |
54 | //---- Enable Test Engine / Automation features.
55 | //#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
56 |
57 | //---- Include imgui_user.h at the end of imgui.h as a convenience
58 | // May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
59 | //#define IMGUI_INCLUDE_IMGUI_USER_H
60 | //#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
61 |
62 | //---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
63 | //#define IMGUI_USE_BGRA_PACKED_COLOR
64 |
65 | //---- 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...)
66 | //#define IMGUI_USE_WCHAR32
67 |
68 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
69 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
70 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
71 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
72 | //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
73 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
74 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
75 | //#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
76 |
77 | //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
78 | // 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.h.
79 | //#define IMGUI_USE_STB_SPRINTF
80 |
81 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
82 | // 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).
83 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
84 | //#define IMGUI_ENABLE_FREETYPE
85 |
86 | //---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
87 | // Only works in combination with IMGUI_ENABLE_FREETYPE.
88 | // - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
89 | // - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
90 | // - Both require headers to be available in the include path + program to be linked with the library code (not provided).
91 | // - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
92 | //#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
93 | //#define IMGUI_ENABLE_FREETYPE_LUNASVG
94 |
95 | //---- Use stb_truetype to build and rasterize the font atlas (default)
96 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
97 | //#define IMGUI_ENABLE_STB_TRUETYPE
98 |
99 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
100 | // This will be inlined as part of ImVec2 and ImVec4 class declarations.
101 | /*
102 | #define IM_VEC2_CLASS_EXTRA \
103 | constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
104 | operator MyVec2() const { return MyVec2(x,y); }
105 |
106 | #define IM_VEC4_CLASS_EXTRA \
107 | constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
108 | operator MyVec4() const { return MyVec4(x,y,z,w); }
109 | */
110 | //---- ...Or use Dear ImGui's own very basic math operators.
111 | //#define IMGUI_DEFINE_MATH_OPERATORS
112 |
113 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
114 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
115 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
116 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
117 | //#define ImDrawIdx unsigned int
118 |
119 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
120 | //struct ImDrawList;
121 | //struct ImDrawCmd;
122 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
123 | //#define ImDrawCallback MyImDrawCallback
124 |
125 | //---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
126 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
127 | //#define IM_DEBUG_BREAK IM_ASSERT(0)
128 | //#define IM_DEBUG_BREAK __debugbreak()
129 |
130 | //---- Debug Tools: Enable slower asserts
131 | //#define IMGUI_DEBUG_PARANOID
132 |
133 | //---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
134 | /*
135 | namespace ImGui
136 | {
137 | void MyFunction(const char* name, MyMatrix44* mtx);
138 | }
139 | */
140 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/fonts/binary_to_compressed_c.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui
2 | // (binary_to_compressed_c.cpp)
3 | // Helper tool to turn a file into a C array, if you want to embed font data in your source code.
4 |
5 | // The data is first compressed with stb_compress() to reduce source code size.
6 | // Then stored in a C array:
7 | // - Base85: ~5 bytes of source code for 4 bytes of input data. 5 bytes stored in binary (suggested by @mmalex).
8 | // - As int: ~11 bytes of source code for 4 bytes of input data. 4 bytes stored in binary. Endianness dependant, need swapping on big-endian CPU.
9 | // - As char: ~12 bytes of source code for 4 bytes of input data. 4 bytes stored in binary. Not endianness dependant.
10 | // Load compressed TTF fonts with ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF()
11 |
12 | // Build with, e.g:
13 | // # cl.exe binary_to_compressed_c.cpp
14 | // # g++ binary_to_compressed_c.cpp
15 | // # clang++ binary_to_compressed_c.cpp
16 | // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui
17 |
18 | // Usage:
19 | // binary_to_compressed_c.exe [-nocompress] [-nostatic] [-base85]
20 | // Usage example:
21 | // # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp
22 | // # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp
23 | // Note:
24 | // Base85 encoding will be obsoleted by future version of Dear ImGui!
25 |
26 | #define _CRT_SECURE_NO_WARNINGS
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | // stb_compress* from stb.h - declaration
33 | typedef unsigned int stb_uint;
34 | typedef unsigned char stb_uchar;
35 | stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len);
36 |
37 | enum SourceEncoding
38 | {
39 | SourceEncoding_U8, // New default since 2024/11
40 | SourceEncoding_U32,
41 | SourceEncoding_Base85,
42 | };
43 |
44 | static bool binary_to_compressed_c(const char* filename, const char* symbol, SourceEncoding source_encoding, bool use_compression, bool use_static);
45 |
46 | int main(int argc, char** argv)
47 | {
48 | if (argc < 3)
49 | {
50 | printf("Syntax: %s [-u8|-u32|-base85] [-nocompress] [-nostatic] \n", argv[0]);
51 | printf("Source encoding types:\n");
52 | printf(" -u8 = ~12 bytes of source per 4 bytes of data. 4 bytes in binary.\n");
53 | printf(" -u32 = ~11 bytes of source per 4 bytes of data. 4 bytes in binary. Need endianness swapping on big-endian.\n");
54 | printf(" -base85 = ~5 bytes of source per 4 bytes of data. 5 bytes in binary. Need decoder.\n");
55 | return 0;
56 | }
57 |
58 | int argn = 1;
59 | bool use_compression = true;
60 | bool use_static = true;
61 | SourceEncoding source_encoding = SourceEncoding_U8; // New default
62 | while (argn < (argc - 2) && argv[argn][0] == '-')
63 | {
64 | if (strcmp(argv[argn], "-u8") == 0) { source_encoding = SourceEncoding_U8; argn++; }
65 | else if (strcmp(argv[argn], "-u32") == 0) { source_encoding = SourceEncoding_U32; argn++; }
66 | else if (strcmp(argv[argn], "-base85") == 0) { source_encoding = SourceEncoding_Base85; argn++; }
67 | else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; }
68 | else if (strcmp(argv[argn], "-nostatic") == 0) { use_static = false; argn++; }
69 | else
70 | {
71 | fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]);
72 | return 1;
73 | }
74 | }
75 |
76 | bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], source_encoding, use_compression, use_static);
77 | if (!ret)
78 | fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]);
79 | return ret ? 0 : 1;
80 | }
81 |
82 | char Encode85Byte(unsigned int x)
83 | {
84 | x = (x % 85) + 35;
85 | return (char)((x >= '\\') ? x + 1 : x);
86 | }
87 |
88 | bool binary_to_compressed_c(const char* filename, const char* symbol, SourceEncoding source_encoding, bool use_compression, bool use_static)
89 | {
90 | // Read file
91 | FILE* f = fopen(filename, "rb");
92 | if (!f) return false;
93 | int data_sz;
94 | if (fseek(f, 0, SEEK_END) || (data_sz = (int)ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) { fclose(f); return false; }
95 | char* data = new char[data_sz + 4];
96 | if (fread(data, 1, data_sz, f) != (size_t)data_sz) { fclose(f); delete[] data; return false; }
97 | memset((void*)(((char*)data) + data_sz), 0, 4);
98 | fclose(f);
99 |
100 | // Compress
101 | int maxlen = data_sz + 512 + (data_sz >> 2) + sizeof(int); // total guess
102 | char* compressed = use_compression ? new char[maxlen] : data;
103 | int compressed_sz = use_compression ? stb_compress((stb_uchar*)compressed, (stb_uchar*)data, data_sz) : data_sz;
104 | if (use_compression)
105 | memset(compressed + compressed_sz, 0, maxlen - compressed_sz);
106 |
107 | // Output as Base85 encoded
108 | FILE* out = stdout;
109 | fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz);
110 | const char* static_str = use_static ? "static " : "";
111 | const char* compressed_str = use_compression ? "compressed_" : "";
112 | if (source_encoding == SourceEncoding_Base85)
113 | {
114 | fprintf(out, "// Exported using binary_to_compressed_c.exe -base85 \"%s\" %s\n", filename, symbol);
115 | fprintf(out, "%sconst char %s_%sdata_base85[%d+1] =\n \"", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
116 | char prev_c = 0;
117 | for (int src_i = 0; src_i < compressed_sz; src_i += 4)
118 | {
119 | // This is made a little more complicated by the fact that ??X sequences are interpreted as trigraphs by old C/C++ compilers. So we need to escape pairs of ??.
120 | unsigned int d = *(unsigned int*)(compressed + src_i);
121 | for (unsigned int n5 = 0; n5 < 5; n5++, d /= 85)
122 | {
123 | char c = Encode85Byte(d);
124 | fprintf(out, (c == '?' && prev_c == '?') ? "\\%c" : "%c", c);
125 | prev_c = c;
126 | }
127 | if ((src_i % 112) == 112 - 4)
128 | fprintf(out, "\"\n \"");
129 | }
130 | fprintf(out, "\";\n\n");
131 | }
132 | else if (source_encoding == SourceEncoding_U8)
133 | {
134 | // As individual bytes, not subject to endianness issues.
135 | fprintf(out, "// Exported using binary_to_compressed_c.exe -u8 \"%s\" %s\n", filename, symbol);
136 | fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz);
137 | fprintf(out, "%sconst unsigned char %s_%sdata[%d] =\n{", static_str, symbol, compressed_str, (int)compressed_sz);
138 | int column = 0;
139 | for (int i = 0; i < compressed_sz; i++)
140 | {
141 | unsigned char d = *(unsigned char*)(compressed + i);
142 | if (column == 0)
143 | fprintf(out, "\n ");
144 | column += fprintf(out, "%d,", d);
145 | if (column >= 180)
146 | column = 0;
147 | }
148 | fprintf(out, "\n};\n\n");
149 | }
150 | else if (source_encoding == SourceEncoding_U32)
151 | {
152 | // As integers
153 | fprintf(out, "// Exported using binary_to_compressed_c.exe -u32 \"%s\" %s\n", filename, symbol);
154 | fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz);
155 | fprintf(out, "%sconst unsigned int %s_%sdata[%d/4] =\n{", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
156 | int column = 0;
157 | for (int i = 0; i < compressed_sz; i += 4)
158 | {
159 | unsigned int d = *(unsigned int*)(compressed + i);
160 | if ((column++ % 14) == 0)
161 | fprintf(out, "\n 0x%08x, ", d);
162 | else
163 | fprintf(out, "0x%08x, ", d);
164 | }
165 | fprintf(out, "\n};\n\n");
166 | }
167 |
168 | // Cleanup
169 | delete[] data;
170 | if (use_compression)
171 | delete[] compressed;
172 | return true;
173 | }
174 |
175 | // stb_compress* from stb.h - definition
176 |
177 | //////////////////// compressor ///////////////////////
178 |
179 | static stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen)
180 | {
181 | const unsigned long ADLER_MOD = 65521;
182 | unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
183 | unsigned long blocklen, i;
184 |
185 | blocklen = buflen % 5552;
186 | while (buflen) {
187 | for (i=0; i + 7 < blocklen; i += 8) {
188 | s1 += buffer[0], s2 += s1;
189 | s1 += buffer[1], s2 += s1;
190 | s1 += buffer[2], s2 += s1;
191 | s1 += buffer[3], s2 += s1;
192 | s1 += buffer[4], s2 += s1;
193 | s1 += buffer[5], s2 += s1;
194 | s1 += buffer[6], s2 += s1;
195 | s1 += buffer[7], s2 += s1;
196 |
197 | buffer += 8;
198 | }
199 |
200 | for (; i < blocklen; ++i)
201 | s1 += *buffer++, s2 += s1;
202 |
203 | s1 %= ADLER_MOD, s2 %= ADLER_MOD;
204 | buflen -= blocklen;
205 | blocklen = 5552;
206 | }
207 | return (s2 << 16) + s1;
208 | }
209 |
210 | static unsigned int stb_matchlen(stb_uchar *m1, stb_uchar *m2, stb_uint maxlen)
211 | {
212 | stb_uint i;
213 | for (i=0; i < maxlen; ++i)
214 | if (m1[i] != m2[i]) return i;
215 | return i;
216 | }
217 |
218 | // simple implementation that just takes the source data in a big block
219 |
220 | static stb_uchar *stb__out;
221 | static FILE *stb__outfile;
222 | static stb_uint stb__outbytes;
223 |
224 | static void stb__write(unsigned char v)
225 | {
226 | fputc(v, stb__outfile);
227 | ++stb__outbytes;
228 | }
229 |
230 | //#define stb_out(v) (stb__out ? *stb__out++ = (stb_uchar) (v) : stb__write((stb_uchar) (v)))
231 | #define stb_out(v) do { if (stb__out) *stb__out++ = (stb_uchar) (v); else stb__write((stb_uchar) (v)); } while (0)
232 |
233 | static void stb_out2(stb_uint v) { stb_out(v >> 8); stb_out(v); }
234 | static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v); }
235 | static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16); stb_out(v >> 8 ); stb_out(v); }
236 |
237 | static void outliterals(stb_uchar *in, int numlit)
238 | {
239 | while (numlit > 65536) {
240 | outliterals(in,65536);
241 | in += 65536;
242 | numlit -= 65536;
243 | }
244 |
245 | if (numlit == 0) ;
246 | else if (numlit <= 32) stb_out (0x000020 + numlit-1);
247 | else if (numlit <= 2048) stb_out2(0x000800 + numlit-1);
248 | else /* numlit <= 65536) */ stb_out3(0x070000 + numlit-1);
249 |
250 | if (stb__out) {
251 | memcpy(stb__out,in,numlit);
252 | stb__out += numlit;
253 | } else
254 | fwrite(in, 1, numlit, stb__outfile);
255 | }
256 |
257 | static int stb__window = 0x40000; // 256K
258 |
259 | static int stb_not_crap(int best, int dist)
260 | {
261 | return ((best > 2 && dist <= 0x00100)
262 | || (best > 5 && dist <= 0x04000)
263 | || (best > 7 && dist <= 0x80000));
264 | }
265 |
266 | static stb_uint stb__hashsize = 32768;
267 |
268 | // note that you can play with the hashing functions all you
269 | // want without needing to change the decompressor
270 | #define stb__hc(q,h,c) (((h) << 7) + ((h) >> 25) + q[c])
271 | #define stb__hc2(q,h,c,d) (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d])
272 | #define stb__hc3(q,c,d,e) ((q[c] << 14) + (q[d] << 7) + q[e])
273 |
274 | static unsigned int stb__running_adler;
275 |
276 | static int stb_compress_chunk(stb_uchar *history,
277 | stb_uchar *start,
278 | stb_uchar *end,
279 | int length,
280 | int *pending_literals,
281 | stb_uchar **chash,
282 | stb_uint mask)
283 | {
284 | (void)history;
285 | int window = stb__window;
286 | stb_uint match_max;
287 | stb_uchar *lit_start = start - *pending_literals;
288 | stb_uchar *q = start;
289 |
290 | #define STB__SCRAMBLE(h) (((h) + ((h) >> 16)) & mask)
291 |
292 | // stop short of the end so we don't scan off the end doing
293 | // the hashing; this means we won't compress the last few bytes
294 | // unless they were part of something longer
295 | while (q < start+length && q+12 < end) {
296 | int m;
297 | stb_uint h1,h2,h3,h4, h;
298 | stb_uchar *t;
299 | int best = 2, dist=0;
300 |
301 | if (q+65536 > end)
302 | match_max = (stb_uint)(end-q);
303 | else
304 | match_max = 65536;
305 |
306 | #define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap((int)(b),(int)(d))))
307 |
308 | #define STB__TRY(t,p) /* avoid retrying a match we already tried */ \
309 | if (p ? dist != (int)(q-t) : 1) \
310 | if ((m = stb_matchlen(t, q, match_max)) > best) \
311 | if (stb__nc(m,q-(t))) \
312 | best = m, dist = (int)(q - (t))
313 |
314 | // rather than search for all matches, only try 4 candidate locations,
315 | // chosen based on 4 different hash functions of different lengths.
316 | // this strategy is inspired by LZO; hashing is unrolled here using the
317 | // 'hc' macro
318 | h = stb__hc3(q,0, 1, 2); h1 = STB__SCRAMBLE(h);
319 | t = chash[h1]; if (t) STB__TRY(t,0);
320 | h = stb__hc2(q,h, 3, 4); h2 = STB__SCRAMBLE(h);
321 | h = stb__hc2(q,h, 5, 6); t = chash[h2]; if (t) STB__TRY(t,1);
322 | h = stb__hc2(q,h, 7, 8); h3 = STB__SCRAMBLE(h);
323 | h = stb__hc2(q,h, 9,10); t = chash[h3]; if (t) STB__TRY(t,1);
324 | h = stb__hc2(q,h,11,12); h4 = STB__SCRAMBLE(h);
325 | t = chash[h4]; if (t) STB__TRY(t,1);
326 |
327 | // because we use a shared hash table, can only update it
328 | // _after_ we've probed all of them
329 | chash[h1] = chash[h2] = chash[h3] = chash[h4] = q;
330 |
331 | if (best > 2)
332 | assert(dist > 0);
333 |
334 | // see if our best match qualifies
335 | if (best < 3) { // fast path literals
336 | ++q;
337 | } else if (best > 2 && best <= 0x80 && dist <= 0x100) {
338 | outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
339 | stb_out(0x80 + best-1);
340 | stb_out(dist-1);
341 | } else if (best > 5 && best <= 0x100 && dist <= 0x4000) {
342 | outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
343 | stb_out2(0x4000 + dist-1);
344 | stb_out(best-1);
345 | } else if (best > 7 && best <= 0x100 && dist <= 0x80000) {
346 | outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
347 | stb_out3(0x180000 + dist-1);
348 | stb_out(best-1);
349 | } else if (best > 8 && best <= 0x10000 && dist <= 0x80000) {
350 | outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
351 | stb_out3(0x100000 + dist-1);
352 | stb_out2(best-1);
353 | } else if (best > 9 && dist <= 0x1000000) {
354 | if (best > 65536) best = 65536;
355 | outliterals(lit_start, (int)(q-lit_start)); lit_start = (q += best);
356 | if (best <= 0x100) {
357 | stb_out(0x06);
358 | stb_out3(dist-1);
359 | stb_out(best-1);
360 | } else {
361 | stb_out(0x04);
362 | stb_out3(dist-1);
363 | stb_out2(best-1);
364 | }
365 | } else { // fallback literals if no match was a balanced tradeoff
366 | ++q;
367 | }
368 | }
369 |
370 | // if we didn't get all the way, add the rest to literals
371 | if (q-start < length)
372 | q = start+length;
373 |
374 | // the literals are everything from lit_start to q
375 | *pending_literals = (int)(q - lit_start);
376 |
377 | stb__running_adler = stb_adler32(stb__running_adler, start, (stb_uint)(q - start));
378 | return (int)(q - start);
379 | }
380 |
381 | static int stb_compress_inner(stb_uchar *input, stb_uint length)
382 | {
383 | int literals = 0;
384 | stb_uint len,i;
385 |
386 | stb_uchar **chash;
387 | chash = (stb_uchar**) malloc(stb__hashsize * sizeof(stb_uchar*));
388 | if (chash == nullptr) return 0; // failure
389 | for (i=0; i < stb__hashsize; ++i)
390 | chash[i] = nullptr;
391 |
392 | // stream signature
393 | stb_out(0x57); stb_out(0xbc);
394 | stb_out2(0);
395 |
396 | stb_out4(0); // 64-bit length requires 32-bit leading 0
397 | stb_out4(length);
398 | stb_out4(stb__window);
399 |
400 | stb__running_adler = 1;
401 |
402 | len = stb_compress_chunk(input, input, input+length, length, &literals, chash, stb__hashsize-1);
403 | assert(len == length);
404 |
405 | outliterals(input+length - literals, literals);
406 |
407 | free(chash);
408 |
409 | stb_out2(0x05fa); // end opcode
410 |
411 | stb_out4(stb__running_adler);
412 |
413 | return 1; // success
414 | }
415 |
416 | stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length)
417 | {
418 | stb__out = out;
419 | stb__outfile = nullptr;
420 |
421 | stb_compress_inner(input, length);
422 |
423 | return (stb_uint)(stb__out - out);
424 | }
425 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/imstb_rectpack.h:
--------------------------------------------------------------------------------
1 | // [DEAR IMGUI]
2 | // This is a slightly modified version of stb_rect_pack.h 1.01.
3 | // Grep for [DEAR IMGUI] to find the changes.
4 | //
5 | // stb_rect_pack.h - v1.01 - public domain - rectangle packing
6 | // Sean Barrett 2014
7 | //
8 | // Useful for e.g. packing rectangular textures into an atlas.
9 | // Does not do rotation.
10 | //
11 | // Before #including,
12 | //
13 | // #define STB_RECT_PACK_IMPLEMENTATION
14 | //
15 | // in the file that you want to have the implementation.
16 | //
17 | // Not necessarily the awesomest packing method, but better than
18 | // the totally naive one in stb_truetype (which is primarily what
19 | // this is meant to replace).
20 | //
21 | // Has only had a few tests run, may have issues.
22 | //
23 | // More docs to come.
24 | //
25 | // No memory allocations; uses qsort() and assert() from stdlib.
26 | // Can override those by defining STBRP_SORT and STBRP_ASSERT.
27 | //
28 | // This library currently uses the Skyline Bottom-Left algorithm.
29 | //
30 | // Please note: better rectangle packers are welcome! Please
31 | // implement them to the same API, but with a different init
32 | // function.
33 | //
34 | // Credits
35 | //
36 | // Library
37 | // Sean Barrett
38 | // Minor features
39 | // Martins Mozeiko
40 | // github:IntellectualKitty
41 | //
42 | // Bugfixes / warning fixes
43 | // Jeremy Jaussaud
44 | // Fabian Giesen
45 | //
46 | // Version history:
47 | //
48 | // 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
49 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
50 | // 0.99 (2019-02-07) warning fixes
51 | // 0.11 (2017-03-03) return packing success/fail result
52 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings
53 | // 0.09 (2016-08-27) fix compiler warnings
54 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
55 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
56 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
57 | // 0.05: added STBRP_ASSERT to allow replacing assert
58 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support
59 | // 0.01: initial release
60 | //
61 | // LICENSE
62 | //
63 | // See end of file for license information.
64 |
65 | //////////////////////////////////////////////////////////////////////////////
66 | //
67 | // INCLUDE SECTION
68 | //
69 |
70 | #ifndef STB_INCLUDE_STB_RECT_PACK_H
71 | #define STB_INCLUDE_STB_RECT_PACK_H
72 |
73 | #define STB_RECT_PACK_VERSION 1
74 |
75 | #ifdef STBRP_STATIC
76 | #define STBRP_DEF static
77 | #else
78 | #define STBRP_DEF extern
79 | #endif
80 |
81 | #ifdef __cplusplus
82 | extern "C" {
83 | #endif
84 |
85 | typedef struct stbrp_context stbrp_context;
86 | typedef struct stbrp_node stbrp_node;
87 | typedef struct stbrp_rect stbrp_rect;
88 |
89 | typedef int stbrp_coord;
90 |
91 | #define STBRP__MAXVAL 0x7fffffff
92 | // Mostly for internal use, but this is the maximum supported coordinate value.
93 |
94 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
95 | // Assign packed locations to rectangles. The rectangles are of type
96 | // 'stbrp_rect' defined below, stored in the array 'rects', and there
97 | // are 'num_rects' many of them.
98 | //
99 | // Rectangles which are successfully packed have the 'was_packed' flag
100 | // set to a non-zero value and 'x' and 'y' store the minimum location
101 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left
102 | // if you imagine y increasing downwards). Rectangles which do not fit
103 | // have the 'was_packed' flag set to 0.
104 | //
105 | // You should not try to access the 'rects' array from another thread
106 | // while this function is running, as the function temporarily reorders
107 | // the array while it executes.
108 | //
109 | // To pack into another rectangle, you need to call stbrp_init_target
110 | // again. To continue packing into the same rectangle, you can call
111 | // this function again. Calling this multiple times with multiple rect
112 | // arrays will probably produce worse packing results than calling it
113 | // a single time with the full rectangle array, but the option is
114 | // available.
115 | //
116 | // The function returns 1 if all of the rectangles were successfully
117 | // packed and 0 otherwise.
118 |
119 | struct stbrp_rect
120 | {
121 | // reserved for your use:
122 | int id;
123 |
124 | // input:
125 | stbrp_coord w, h;
126 |
127 | // output:
128 | stbrp_coord x, y;
129 | int was_packed; // non-zero if valid packing
130 |
131 | }; // 16 bytes, nominally
132 |
133 |
134 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
135 | // Initialize a rectangle packer to:
136 | // pack a rectangle that is 'width' by 'height' in dimensions
137 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long
138 | //
139 | // You must call this function every time you start packing into a new target.
140 | //
141 | // There is no "shutdown" function. The 'nodes' memory must stay valid for
142 | // the following stbrp_pack_rects() call (or calls), but can be freed after
143 | // the call (or calls) finish.
144 | //
145 | // Note: to guarantee best results, either:
146 | // 1. make sure 'num_nodes' >= 'width'
147 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
148 | //
149 | // If you don't do either of the above things, widths will be quantized to multiples
150 | // of small integers to guarantee the algorithm doesn't run out of temporary storage.
151 | //
152 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm
153 | // may run out of temporary storage and be unable to pack some rectangles.
154 |
155 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
156 | // Optionally call this function after init but before doing any packing to
157 | // change the handling of the out-of-temp-memory scenario, described above.
158 | // If you call init again, this will be reset to the default (false).
159 |
160 |
161 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
162 | // Optionally select which packing heuristic the library should use. Different
163 | // heuristics will produce better/worse results for different data sets.
164 | // If you call init again, this will be reset to the default.
165 |
166 | enum
167 | {
168 | STBRP_HEURISTIC_Skyline_default=0,
169 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
170 | STBRP_HEURISTIC_Skyline_BF_sortHeight
171 | };
172 |
173 |
174 | //////////////////////////////////////////////////////////////////////////////
175 | //
176 | // the details of the following structures don't matter to you, but they must
177 | // be visible so you can handle the memory allocations for them
178 |
179 | struct stbrp_node
180 | {
181 | stbrp_coord x,y;
182 | stbrp_node *next;
183 | };
184 |
185 | struct stbrp_context
186 | {
187 | int width;
188 | int height;
189 | int align;
190 | int init_mode;
191 | int heuristic;
192 | int num_nodes;
193 | stbrp_node *active_head;
194 | stbrp_node *free_head;
195 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
196 | };
197 |
198 | #ifdef __cplusplus
199 | }
200 | #endif
201 |
202 | #endif
203 |
204 | //////////////////////////////////////////////////////////////////////////////
205 | //
206 | // IMPLEMENTATION SECTION
207 | //
208 |
209 | #ifdef STB_RECT_PACK_IMPLEMENTATION
210 | #ifndef STBRP_SORT
211 | #include
212 | #define STBRP_SORT qsort
213 | #endif
214 |
215 | #ifndef STBRP_ASSERT
216 | #include
217 | #define STBRP_ASSERT assert
218 | #endif
219 |
220 | #ifdef _MSC_VER
221 | #define STBRP__NOTUSED(v) (void)(v)
222 | #define STBRP__CDECL __cdecl
223 | #else
224 | #define STBRP__NOTUSED(v) (void)sizeof(v)
225 | #define STBRP__CDECL
226 | #endif
227 |
228 | enum
229 | {
230 | STBRP__INIT_skyline = 1
231 | };
232 |
233 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
234 | {
235 | switch (context->init_mode) {
236 | case STBRP__INIT_skyline:
237 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
238 | context->heuristic = heuristic;
239 | break;
240 | default:
241 | STBRP_ASSERT(0);
242 | }
243 | }
244 |
245 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
246 | {
247 | if (allow_out_of_mem)
248 | // if it's ok to run out of memory, then don't bother aligning them;
249 | // this gives better packing, but may fail due to OOM (even though
250 | // the rectangles easily fit). @TODO a smarter approach would be to only
251 | // quantize once we've hit OOM, then we could get rid of this parameter.
252 | context->align = 1;
253 | else {
254 | // if it's not ok to run out of memory, then quantize the widths
255 | // so that num_nodes is always enough nodes.
256 | //
257 | // I.e. num_nodes * align >= width
258 | // align >= width / num_nodes
259 | // align = ceil(width/num_nodes)
260 |
261 | context->align = (context->width + context->num_nodes-1) / context->num_nodes;
262 | }
263 | }
264 |
265 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
266 | {
267 | int i;
268 |
269 | for (i=0; i < num_nodes-1; ++i)
270 | nodes[i].next = &nodes[i+1];
271 | nodes[i].next = NULL;
272 | context->init_mode = STBRP__INIT_skyline;
273 | context->heuristic = STBRP_HEURISTIC_Skyline_default;
274 | context->free_head = &nodes[0];
275 | context->active_head = &context->extra[0];
276 | context->width = width;
277 | context->height = height;
278 | context->num_nodes = num_nodes;
279 | stbrp_setup_allow_out_of_mem(context, 0);
280 |
281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
282 | context->extra[0].x = 0;
283 | context->extra[0].y = 0;
284 | context->extra[0].next = &context->extra[1];
285 | context->extra[1].x = (stbrp_coord) width;
286 | context->extra[1].y = (1<<30);
287 | context->extra[1].next = NULL;
288 | }
289 |
290 | // find minimum y position if it starts at x1
291 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
292 | {
293 | stbrp_node *node = first;
294 | int x1 = x0 + width;
295 | int min_y, visited_width, waste_area;
296 |
297 | STBRP__NOTUSED(c);
298 |
299 | STBRP_ASSERT(first->x <= x0);
300 |
301 | #if 0
302 | // skip in case we're past the node
303 | while (node->next->x <= x0)
304 | ++node;
305 | #else
306 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
307 | #endif
308 |
309 | STBRP_ASSERT(node->x <= x0);
310 |
311 | min_y = 0;
312 | waste_area = 0;
313 | visited_width = 0;
314 | while (node->x < x1) {
315 | if (node->y > min_y) {
316 | // raise min_y higher.
317 | // we've accounted for all waste up to min_y,
318 | // but we'll now add more waste for everything we've visted
319 | waste_area += visited_width * (node->y - min_y);
320 | min_y = node->y;
321 | // the first time through, visited_width might be reduced
322 | if (node->x < x0)
323 | visited_width += node->next->x - x0;
324 | else
325 | visited_width += node->next->x - node->x;
326 | } else {
327 | // add waste area
328 | int under_width = node->next->x - node->x;
329 | if (under_width + visited_width > width)
330 | under_width = width - visited_width;
331 | waste_area += under_width * (min_y - node->y);
332 | visited_width += under_width;
333 | }
334 | node = node->next;
335 | }
336 |
337 | *pwaste = waste_area;
338 | return min_y;
339 | }
340 |
341 | typedef struct
342 | {
343 | int x,y;
344 | stbrp_node **prev_link;
345 | } stbrp__findresult;
346 |
347 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
348 | {
349 | int best_waste = (1<<30), best_x, best_y = (1 << 30);
350 | stbrp__findresult fr;
351 | stbrp_node **prev, *node, *tail, **best = NULL;
352 |
353 | // align to multiple of c->align
354 | width = (width + c->align - 1);
355 | width -= width % c->align;
356 | STBRP_ASSERT(width % c->align == 0);
357 |
358 | // if it can't possibly fit, bail immediately
359 | if (width > c->width || height > c->height) {
360 | fr.prev_link = NULL;
361 | fr.x = fr.y = 0;
362 | return fr;
363 | }
364 |
365 | node = c->active_head;
366 | prev = &c->active_head;
367 | while (node->x + width <= c->width) {
368 | int y,waste;
369 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
370 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
371 | // bottom left
372 | if (y < best_y) {
373 | best_y = y;
374 | best = prev;
375 | }
376 | } else {
377 | // best-fit
378 | if (y + height <= c->height) {
379 | // can only use it if it first vertically
380 | if (y < best_y || (y == best_y && waste < best_waste)) {
381 | best_y = y;
382 | best_waste = waste;
383 | best = prev;
384 | }
385 | }
386 | }
387 | prev = &node->next;
388 | node = node->next;
389 | }
390 |
391 | best_x = (best == NULL) ? 0 : (*best)->x;
392 |
393 | // if doing best-fit (BF), we also have to try aligning right edge to each node position
394 | //
395 | // e.g, if fitting
396 | //
397 | // ____________________
398 | // |____________________|
399 | //
400 | // into
401 | //
402 | // | |
403 | // | ____________|
404 | // |____________|
405 | //
406 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
407 | //
408 | // This makes BF take about 2x the time
409 |
410 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
411 | tail = c->active_head;
412 | node = c->active_head;
413 | prev = &c->active_head;
414 | // find first node that's admissible
415 | while (tail->x < width)
416 | tail = tail->next;
417 | while (tail) {
418 | int xpos = tail->x - width;
419 | int y,waste;
420 | STBRP_ASSERT(xpos >= 0);
421 | // find the left position that matches this
422 | while (node->next->x <= xpos) {
423 | prev = &node->next;
424 | node = node->next;
425 | }
426 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
427 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
428 | if (y + height <= c->height) {
429 | if (y <= best_y) {
430 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
431 | best_x = xpos;
432 | //STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
433 | best_y = y;
434 | best_waste = waste;
435 | best = prev;
436 | }
437 | }
438 | }
439 | tail = tail->next;
440 | }
441 | }
442 |
443 | fr.prev_link = best;
444 | fr.x = best_x;
445 | fr.y = best_y;
446 | return fr;
447 | }
448 |
449 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
450 | {
451 | // find best position according to heuristic
452 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
453 | stbrp_node *node, *cur;
454 |
455 | // bail if:
456 | // 1. it failed
457 | // 2. the best node doesn't fit (we don't always check this)
458 | // 3. we're out of memory
459 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
460 | res.prev_link = NULL;
461 | return res;
462 | }
463 |
464 | // on success, create new node
465 | node = context->free_head;
466 | node->x = (stbrp_coord) res.x;
467 | node->y = (stbrp_coord) (res.y + height);
468 |
469 | context->free_head = node->next;
470 |
471 | // insert the new node into the right starting point, and
472 | // let 'cur' point to the remaining nodes needing to be
473 | // stiched back in
474 |
475 | cur = *res.prev_link;
476 | if (cur->x < res.x) {
477 | // preserve the existing one, so start testing with the next one
478 | stbrp_node *next = cur->next;
479 | cur->next = node;
480 | cur = next;
481 | } else {
482 | *res.prev_link = node;
483 | }
484 |
485 | // from here, traverse cur and free the nodes, until we get to one
486 | // that shouldn't be freed
487 | while (cur->next && cur->next->x <= res.x + width) {
488 | stbrp_node *next = cur->next;
489 | // move the current node to the free list
490 | cur->next = context->free_head;
491 | context->free_head = cur;
492 | cur = next;
493 | }
494 |
495 | // stitch the list back in
496 | node->next = cur;
497 |
498 | if (cur->x < res.x + width)
499 | cur->x = (stbrp_coord) (res.x + width);
500 |
501 | #ifdef _DEBUG
502 | cur = context->active_head;
503 | while (cur->x < context->width) {
504 | STBRP_ASSERT(cur->x < cur->next->x);
505 | cur = cur->next;
506 | }
507 | STBRP_ASSERT(cur->next == NULL);
508 |
509 | {
510 | int count=0;
511 | cur = context->active_head;
512 | while (cur) {
513 | cur = cur->next;
514 | ++count;
515 | }
516 | cur = context->free_head;
517 | while (cur) {
518 | cur = cur->next;
519 | ++count;
520 | }
521 | STBRP_ASSERT(count == context->num_nodes+2);
522 | }
523 | #endif
524 |
525 | return res;
526 | }
527 |
528 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
529 | {
530 | const stbrp_rect *p = (const stbrp_rect *) a;
531 | const stbrp_rect *q = (const stbrp_rect *) b;
532 | if (p->h > q->h)
533 | return -1;
534 | if (p->h < q->h)
535 | return 1;
536 | return (p->w > q->w) ? -1 : (p->w < q->w);
537 | }
538 |
539 | static int STBRP__CDECL rect_original_order(const void *a, const void *b)
540 | {
541 | const stbrp_rect *p = (const stbrp_rect *) a;
542 | const stbrp_rect *q = (const stbrp_rect *) b;
543 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
544 | }
545 |
546 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
547 | {
548 | int i, all_rects_packed = 1;
549 |
550 | // we use the 'was_packed' field internally to allow sorting/unsorting
551 | for (i=0; i < num_rects; ++i) {
552 | rects[i].was_packed = i;
553 | }
554 |
555 | // sort according to heuristic
556 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
557 |
558 | for (i=0; i < num_rects; ++i) {
559 | if (rects[i].w == 0 || rects[i].h == 0) {
560 | rects[i].x = rects[i].y = 0; // empty rect needs no space
561 | } else {
562 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
563 | if (fr.prev_link) {
564 | rects[i].x = (stbrp_coord) fr.x;
565 | rects[i].y = (stbrp_coord) fr.y;
566 | } else {
567 | rects[i].x = rects[i].y = STBRP__MAXVAL;
568 | }
569 | }
570 | }
571 |
572 | // unsort
573 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
574 |
575 | // set was_packed flags and all_rects_packed status
576 | for (i=0; i < num_rects; ++i) {
577 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
578 | if (!rects[i].was_packed)
579 | all_rects_packed = 0;
580 | }
581 |
582 | // return the all_rects_packed status
583 | return all_rects_packed;
584 | }
585 | #endif
586 |
587 | /*
588 | ------------------------------------------------------------------------------
589 | This software is available under 2 licenses -- choose whichever you prefer.
590 | ------------------------------------------------------------------------------
591 | ALTERNATIVE A - MIT License
592 | Copyright (c) 2017 Sean Barrett
593 | Permission is hereby granted, free of charge, to any person obtaining a copy of
594 | this software and associated documentation files (the "Software"), to deal in
595 | the Software without restriction, including without limitation the rights to
596 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
597 | of the Software, and to permit persons to whom the Software is furnished to do
598 | so, subject to the following conditions:
599 | The above copyright notice and this permission notice shall be included in all
600 | copies or substantial portions of the Software.
601 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
602 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
603 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
604 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
605 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
606 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
607 | SOFTWARE.
608 | ------------------------------------------------------------------------------
609 | ALTERNATIVE B - Public Domain (www.unlicense.org)
610 | This is free and unencumbered software released into the public domain.
611 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
612 | software, either in source code form or as a compiled binary, for any purpose,
613 | commercial or non-commercial, and by any means.
614 | In jurisdictions that recognize copyright laws, the author or authors of this
615 | software dedicate any and all copyright interest in the software to the public
616 | domain. We make this dedication for the benefit of the public at large and to
617 | the detriment of our heirs and successors. We intend this dedication to be an
618 | overt act of relinquishment in perpetuity of all present and future rights to
619 | this software under copyright law.
620 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
621 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
622 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
623 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
624 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
625 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
626 | ------------------------------------------------------------------------------
627 | */
628 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/backends/imgui_impl_dx11.cpp:
--------------------------------------------------------------------------------
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: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
7 | // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
8 |
9 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
10 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
11 | // Learn about Dear ImGui:
12 | // - FAQ https://dearimgui.com/faq
13 | // - Getting Started https://dearimgui.com/getting-started
14 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
15 | // - Introduction, links and more at the top of imgui.cpp
16 |
17 | // CHANGELOG
18 | // (minor and older changes stripped away, please see git history for details)
19 | // 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
20 | // 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
21 | // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
22 | // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
23 | // 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
24 | // 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
25 | // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
26 | // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
27 | // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
28 | // 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
29 | // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
30 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
31 | // 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
32 | // 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
33 | // 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
34 | // 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
35 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
36 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
37 | // 2016-05-07: DirectX11: Disabling depth-write.
38 |
39 | #include "imgui.h"
40 | #ifndef IMGUI_DISABLE
41 | #include "imgui_impl_dx11.h"
42 |
43 | // DirectX
44 | #include
45 | #include
46 | #include
47 | #ifdef _MSC_VER
48 | #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
49 | #endif
50 |
51 | // DirectX11 data
52 | struct ImGui_ImplDX11_Data
53 | {
54 | ID3D11Device* pd3dDevice;
55 | ID3D11DeviceContext* pd3dDeviceContext;
56 | IDXGIFactory* pFactory;
57 | ID3D11Buffer* pVB;
58 | ID3D11Buffer* pIB;
59 | ID3D11VertexShader* pVertexShader;
60 | ID3D11InputLayout* pInputLayout;
61 | ID3D11Buffer* pVertexConstantBuffer;
62 | ID3D11PixelShader* pPixelShader;
63 | ID3D11SamplerState* pFontSampler;
64 | ID3D11ShaderResourceView* pFontTextureView;
65 | ID3D11RasterizerState* pRasterizerState;
66 | ID3D11BlendState* pBlendState;
67 | ID3D11DepthStencilState* pDepthStencilState;
68 | int VertexBufferSize;
69 | int IndexBufferSize;
70 |
71 | ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
72 | };
73 |
74 | struct VERTEX_CONSTANT_BUFFER_DX11
75 | {
76 | float mvp[4][4];
77 | };
78 |
79 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
80 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
81 | static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
82 | {
83 | return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
84 | }
85 |
86 | // Functions
87 | static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
88 | {
89 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
90 |
91 | // Setup viewport
92 | D3D11_VIEWPORT vp;
93 | memset(&vp, 0, sizeof(D3D11_VIEWPORT));
94 | vp.Width = draw_data->DisplaySize.x;
95 | vp.Height = draw_data->DisplaySize.y;
96 | vp.MinDepth = 0.0f;
97 | vp.MaxDepth = 1.0f;
98 | vp.TopLeftX = vp.TopLeftY = 0;
99 | device_ctx->RSSetViewports(1, &vp);
100 |
101 | // Setup shader and vertex buffers
102 | unsigned int stride = sizeof(ImDrawVert);
103 | unsigned int offset = 0;
104 | device_ctx->IASetInputLayout(bd->pInputLayout);
105 | device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
106 | device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
107 | device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
108 | device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
109 | device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
110 | device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
111 | device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
112 | device_ctx->GSSetShader(nullptr, nullptr, 0);
113 | device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
114 | device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
115 | device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
116 |
117 | // Setup blend state
118 | const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
119 | device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
120 | device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
121 | device_ctx->RSSetState(bd->pRasterizerState);
122 | }
123 |
124 | // Render function
125 | void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
126 | {
127 | // Avoid rendering when minimized
128 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
129 | return;
130 |
131 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
132 | ID3D11DeviceContext* device = bd->pd3dDeviceContext;
133 |
134 | // Create and grow vertex/index buffers if needed
135 | if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
136 | {
137 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
138 | bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
139 | D3D11_BUFFER_DESC desc;
140 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
141 | desc.Usage = D3D11_USAGE_DYNAMIC;
142 | desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
143 | desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
144 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
145 | desc.MiscFlags = 0;
146 | if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
147 | return;
148 | }
149 | if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
150 | {
151 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
152 | bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
153 | D3D11_BUFFER_DESC desc;
154 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
155 | desc.Usage = D3D11_USAGE_DYNAMIC;
156 | desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
157 | desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
158 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
159 | if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
160 | return;
161 | }
162 |
163 | // Upload vertex/index data into a single contiguous GPU buffer
164 | D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
165 | if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
166 | return;
167 | if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
168 | return;
169 | ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
170 | ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
171 | for (int n = 0; n < draw_data->CmdListsCount; n++)
172 | {
173 | const ImDrawList* draw_list = draw_data->CmdLists[n];
174 | memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
175 | memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
176 | vtx_dst += draw_list->VtxBuffer.Size;
177 | idx_dst += draw_list->IdxBuffer.Size;
178 | }
179 | device->Unmap(bd->pVB, 0);
180 | device->Unmap(bd->pIB, 0);
181 |
182 | // Setup orthographic projection matrix into our constant buffer
183 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
184 | {
185 | D3D11_MAPPED_SUBRESOURCE mapped_resource;
186 | if (device->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
187 | return;
188 | VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
189 | float L = draw_data->DisplayPos.x;
190 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
191 | float T = draw_data->DisplayPos.y;
192 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
193 | float mvp[4][4] =
194 | {
195 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
196 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
197 | { 0.0f, 0.0f, 0.5f, 0.0f },
198 | { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
199 | };
200 | memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
201 | device->Unmap(bd->pVertexConstantBuffer, 0);
202 | }
203 |
204 | // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
205 | struct BACKUP_DX11_STATE
206 | {
207 | UINT ScissorRectsCount, ViewportsCount;
208 | D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
209 | D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
210 | ID3D11RasterizerState* RS;
211 | ID3D11BlendState* BlendState;
212 | FLOAT BlendFactor[4];
213 | UINT SampleMask;
214 | UINT StencilRef;
215 | ID3D11DepthStencilState* DepthStencilState;
216 | ID3D11ShaderResourceView* PSShaderResource;
217 | ID3D11SamplerState* PSSampler;
218 | ID3D11PixelShader* PS;
219 | ID3D11VertexShader* VS;
220 | ID3D11GeometryShader* GS;
221 | UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
222 | ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
223 | D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
224 | ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
225 | UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
226 | DXGI_FORMAT IndexBufferFormat;
227 | ID3D11InputLayout* InputLayout;
228 | };
229 | BACKUP_DX11_STATE old = {};
230 | old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
231 | device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
232 | device->RSGetViewports(&old.ViewportsCount, old.Viewports);
233 | device->RSGetState(&old.RS);
234 | device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
235 | device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
236 | device->PSGetShaderResources(0, 1, &old.PSShaderResource);
237 | device->PSGetSamplers(0, 1, &old.PSSampler);
238 | old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
239 | device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
240 | device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
241 | device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
242 | device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
243 |
244 | device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
245 | device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
246 | device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
247 | device->IAGetInputLayout(&old.InputLayout);
248 |
249 | // Setup desired DX state
250 | ImGui_ImplDX11_SetupRenderState(draw_data, device);
251 |
252 | // Setup render state structure (for callbacks and custom texture bindings)
253 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
254 | ImGui_ImplDX11_RenderState render_state;
255 | render_state.Device = bd->pd3dDevice;
256 | render_state.DeviceContext = bd->pd3dDeviceContext;
257 | render_state.SamplerDefault = bd->pFontSampler;
258 | platform_io.Renderer_RenderState = &render_state;
259 |
260 | // Render command lists
261 | // (Because we merged all buffers into a single one, we maintain our own offset into them)
262 | int global_idx_offset = 0;
263 | int global_vtx_offset = 0;
264 | ImVec2 clip_off = draw_data->DisplayPos;
265 | for (int n = 0; n < draw_data->CmdListsCount; n++)
266 | {
267 | const ImDrawList* draw_list = draw_data->CmdLists[n];
268 | for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
269 | {
270 | const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
271 | if (pcmd->UserCallback != nullptr)
272 | {
273 | // User callback, registered via ImDrawList::AddCallback()
274 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
275 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
276 | ImGui_ImplDX11_SetupRenderState(draw_data, device);
277 | else
278 | pcmd->UserCallback(draw_list, pcmd);
279 | }
280 | else
281 | {
282 | // Project scissor/clipping rectangles into framebuffer space
283 | ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
284 | ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
285 | if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
286 | continue;
287 |
288 | // Apply scissor/clipping rectangle
289 | const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
290 | device->RSSetScissorRects(1, &r);
291 |
292 | // Bind texture, Draw
293 | ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
294 | device->PSSetShaderResources(0, 1, &texture_srv);
295 | device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
296 | }
297 | }
298 | global_idx_offset += draw_list->IdxBuffer.Size;
299 | global_vtx_offset += draw_list->VtxBuffer.Size;
300 | }
301 | platform_io.Renderer_RenderState = nullptr;
302 |
303 | // Restore modified DX state
304 | device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
305 | device->RSSetViewports(old.ViewportsCount, old.Viewports);
306 | device->RSSetState(old.RS); if (old.RS) old.RS->Release();
307 | device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
308 | device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
309 | device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
310 | device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
311 | device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
312 | for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
313 | device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
314 | device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
315 | device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
316 | for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
317 | device->IASetPrimitiveTopology(old.PrimitiveTopology);
318 | device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
319 | device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
320 | device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
321 | }
322 |
323 | static void ImGui_ImplDX11_CreateFontsTexture()
324 | {
325 | // Build texture atlas
326 | ImGuiIO& io = ImGui::GetIO();
327 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
328 | unsigned char* pixels;
329 | int width, height;
330 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
331 |
332 | // Upload texture to graphics system
333 | {
334 | D3D11_TEXTURE2D_DESC desc;
335 | ZeroMemory(&desc, sizeof(desc));
336 | desc.Width = width;
337 | desc.Height = height;
338 | desc.MipLevels = 1;
339 | desc.ArraySize = 1;
340 | desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
341 | desc.SampleDesc.Count = 1;
342 | desc.Usage = D3D11_USAGE_DEFAULT;
343 | desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
344 | desc.CPUAccessFlags = 0;
345 |
346 | ID3D11Texture2D* pTexture = nullptr;
347 | D3D11_SUBRESOURCE_DATA subResource;
348 | subResource.pSysMem = pixels;
349 | subResource.SysMemPitch = desc.Width * 4;
350 | subResource.SysMemSlicePitch = 0;
351 | bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
352 | IM_ASSERT(pTexture != nullptr);
353 |
354 | // Create texture view
355 | D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
356 | ZeroMemory(&srvDesc, sizeof(srvDesc));
357 | srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
358 | srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
359 | srvDesc.Texture2D.MipLevels = desc.MipLevels;
360 | srvDesc.Texture2D.MostDetailedMip = 0;
361 | bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
362 | pTexture->Release();
363 | }
364 |
365 | // Store our identifier
366 | io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
367 | }
368 |
369 | static void ImGui_ImplDX11_DestroyFontsTexture()
370 | {
371 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
372 | if (bd->pFontTextureView)
373 | {
374 | bd->pFontTextureView->Release();
375 | bd->pFontTextureView = nullptr;
376 | ImGui::GetIO().Fonts->SetTexID(0); // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
377 | }
378 | }
379 |
380 | bool ImGui_ImplDX11_CreateDeviceObjects()
381 | {
382 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
383 | if (!bd->pd3dDevice)
384 | return false;
385 | if (bd->pFontSampler)
386 | ImGui_ImplDX11_InvalidateDeviceObjects();
387 |
388 | // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
389 | // If you would like to use this DX11 sample code but remove this dependency you can:
390 | // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
391 | // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
392 | // See https://github.com/ocornut/imgui/pull/638 for sources and details.
393 |
394 | // Create the vertex shader
395 | {
396 | static const char* vertexShader =
397 | "cbuffer vertexBuffer : register(b0) \
398 | {\
399 | float4x4 ProjectionMatrix; \
400 | };\
401 | struct VS_INPUT\
402 | {\
403 | float2 pos : POSITION;\
404 | float4 col : COLOR0;\
405 | float2 uv : TEXCOORD0;\
406 | };\
407 | \
408 | struct PS_INPUT\
409 | {\
410 | float4 pos : SV_POSITION;\
411 | float4 col : COLOR0;\
412 | float2 uv : TEXCOORD0;\
413 | };\
414 | \
415 | PS_INPUT main(VS_INPUT input)\
416 | {\
417 | PS_INPUT output;\
418 | output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
419 | output.col = input.col;\
420 | output.uv = input.uv;\
421 | return output;\
422 | }";
423 |
424 | ID3DBlob* vertexShaderBlob;
425 | if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
426 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
427 | if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
428 | {
429 | vertexShaderBlob->Release();
430 | return false;
431 | }
432 |
433 | // Create the input layout
434 | D3D11_INPUT_ELEMENT_DESC local_layout[] =
435 | {
436 | { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
437 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
438 | { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
439 | };
440 | if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
441 | {
442 | vertexShaderBlob->Release();
443 | return false;
444 | }
445 | vertexShaderBlob->Release();
446 |
447 | // Create the constant buffer
448 | {
449 | D3D11_BUFFER_DESC desc;
450 | desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
451 | desc.Usage = D3D11_USAGE_DYNAMIC;
452 | desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
453 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
454 | desc.MiscFlags = 0;
455 | bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
456 | }
457 | }
458 |
459 | // Create the pixel shader
460 | {
461 | static const char* pixelShader =
462 | "struct PS_INPUT\
463 | {\
464 | float4 pos : SV_POSITION;\
465 | float4 col : COLOR0;\
466 | float2 uv : TEXCOORD0;\
467 | };\
468 | sampler sampler0;\
469 | Texture2D texture0;\
470 | \
471 | float4 main(PS_INPUT input) : SV_Target\
472 | {\
473 | float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
474 | return out_col; \
475 | }";
476 |
477 | ID3DBlob* pixelShaderBlob;
478 | if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
479 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
480 | if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
481 | {
482 | pixelShaderBlob->Release();
483 | return false;
484 | }
485 | pixelShaderBlob->Release();
486 | }
487 |
488 | // Create the blending setup
489 | {
490 | D3D11_BLEND_DESC desc;
491 | ZeroMemory(&desc, sizeof(desc));
492 | desc.AlphaToCoverageEnable = false;
493 | desc.RenderTarget[0].BlendEnable = true;
494 | desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
495 | desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
496 | desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
497 | desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
498 | desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
499 | desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
500 | desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
501 | bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
502 | }
503 |
504 | // Create the rasterizer state
505 | {
506 | D3D11_RASTERIZER_DESC desc;
507 | ZeroMemory(&desc, sizeof(desc));
508 | desc.FillMode = D3D11_FILL_SOLID;
509 | desc.CullMode = D3D11_CULL_NONE;
510 | desc.ScissorEnable = true;
511 | desc.DepthClipEnable = true;
512 | bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
513 | }
514 |
515 | // Create depth-stencil State
516 | {
517 | D3D11_DEPTH_STENCIL_DESC desc;
518 | ZeroMemory(&desc, sizeof(desc));
519 | desc.DepthEnable = false;
520 | desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
521 | desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
522 | desc.StencilEnable = false;
523 | desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
524 | desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
525 | desc.BackFace = desc.FrontFace;
526 | bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
527 | }
528 |
529 | // Create texture sampler
530 | // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
531 | {
532 | D3D11_SAMPLER_DESC desc;
533 | ZeroMemory(&desc, sizeof(desc));
534 | desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
535 | desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
536 | desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
537 | desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
538 | desc.MipLODBias = 0.f;
539 | desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
540 | desc.MinLOD = 0.f;
541 | desc.MaxLOD = 0.f;
542 | bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
543 | }
544 |
545 | ImGui_ImplDX11_CreateFontsTexture();
546 |
547 | return true;
548 | }
549 |
550 | void ImGui_ImplDX11_InvalidateDeviceObjects()
551 | {
552 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
553 | if (!bd->pd3dDevice)
554 | return;
555 |
556 | ImGui_ImplDX11_DestroyFontsTexture();
557 |
558 | if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
559 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
560 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
561 | if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
562 | if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
563 | if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
564 | if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
565 | if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
566 | if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
567 | if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
568 | }
569 |
570 | bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
571 | {
572 | ImGuiIO& io = ImGui::GetIO();
573 | IMGUI_CHECKVERSION();
574 | IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
575 |
576 | // Setup backend capabilities flags
577 | ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
578 | io.BackendRendererUserData = (void*)bd;
579 | io.BackendRendererName = "imgui_impl_dx11";
580 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
581 |
582 | // Get factory from device
583 | IDXGIDevice* pDXGIDevice = nullptr;
584 | IDXGIAdapter* pDXGIAdapter = nullptr;
585 | IDXGIFactory* pFactory = nullptr;
586 |
587 | if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
588 | if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
589 | if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
590 | {
591 | bd->pd3dDevice = device;
592 | bd->pd3dDeviceContext = device_context;
593 | bd->pFactory = pFactory;
594 | }
595 | if (pDXGIDevice) pDXGIDevice->Release();
596 | if (pDXGIAdapter) pDXGIAdapter->Release();
597 | bd->pd3dDevice->AddRef();
598 | bd->pd3dDeviceContext->AddRef();
599 |
600 | return true;
601 | }
602 |
603 | void ImGui_ImplDX11_Shutdown()
604 | {
605 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
606 | IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
607 | ImGuiIO& io = ImGui::GetIO();
608 |
609 | ImGui_ImplDX11_InvalidateDeviceObjects();
610 | if (bd->pFactory) { bd->pFactory->Release(); }
611 | if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
612 | if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
613 | io.BackendRendererName = nullptr;
614 | io.BackendRendererUserData = nullptr;
615 | io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
616 | IM_DELETE(bd);
617 | }
618 |
619 | void ImGui_ImplDX11_NewFrame()
620 | {
621 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
622 | IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
623 |
624 | if (!bd->pFontSampler)
625 | ImGui_ImplDX11_CreateDeviceObjects();
626 | }
627 |
628 | //-----------------------------------------------------------------------------
629 |
630 | #endif // #ifndef IMGUI_DISABLE
631 |
--------------------------------------------------------------------------------
/dwm-overlay/third-party/imgui/misc/freetype/imgui_freetype.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
2 | // (code)
3 |
4 | // Get the latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
5 | // Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
6 |
7 | // CHANGELOG
8 | // (minor and older changes stripped away, please see git history for details)
9 | // 2024/10/17: added plutosvg support for SVG Fonts (seems faster/better than lunasvg). Enable by using '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG'. (#7927)
10 | // 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
11 | // 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG'. (#6591)
12 | // 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
13 | // 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns nullptr.
14 | // 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
15 | // 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a preferred texture format.
16 | // 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
17 | // 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'. renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
18 | // 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
19 | // 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
20 | // 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
21 | // 2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
22 | // 2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
23 | // 2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
24 | // 2018/01/22: fix for addition of ImFontAtlas::TexUvscale member.
25 | // 2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement).
26 | // 2017/09/26: fixes for imgui internal changes.
27 | // 2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
28 | // 2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
29 |
30 | // About Gamma Correct Blending:
31 | // - FreeType assumes blending in linear space rather than gamma space.
32 | // - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
33 | // - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
34 | // - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
35 |
36 | // FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
37 |
38 | #include "imgui.h"
39 | #ifndef IMGUI_DISABLE
40 | #include "imgui_freetype.h"
41 | #include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
42 | #include
43 | #include
44 | #include FT_FREETYPE_H //
45 | #include FT_MODULE_H //
46 | #include FT_GLYPH_H //
47 | #include FT_SYNTHESIS_H //
48 |
49 | // Handle LunaSVG and PlutoSVG
50 | #if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) && defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
51 | #error "Cannot enable both IMGUI_ENABLE_FREETYPE_LUNASVG and IMGUI_ENABLE_FREETYPE_PLUTOSVG"
52 | #endif
53 | #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
54 | #include FT_OTSVG_H //
55 | #include FT_BBOX_H //
56 | #include
57 | #endif
58 | #ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
59 | #include
60 | #endif
61 | #if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined (IMGUI_ENABLE_FREETYPE_PLUTOSVG)
62 | #if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
63 | #error IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
64 | #endif
65 | #endif
66 |
67 | #ifdef _MSC_VER
68 | #pragma warning (push)
69 | #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
70 | #pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
71 | #endif
72 |
73 | #ifdef __GNUC__
74 | #pragma GCC diagnostic push
75 | #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
76 | #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
77 | #ifndef __clang__
78 | #pragma GCC diagnostic ignored "-Wsubobject-linkage" // warning: 'xxxx' has a field 'xxxx' whose type uses the anonymous namespace
79 | #endif
80 | #endif
81 |
82 | //-------------------------------------------------------------------------
83 | // Data
84 | //-------------------------------------------------------------------------
85 |
86 | // Default memory allocators
87 | static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
88 | static void ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
89 |
90 | // Current memory allocators
91 | static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc;
92 | static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
93 | static void* GImGuiFreeTypeAllocatorUserData = nullptr;
94 |
95 | // Lunasvg support
96 | #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
97 | static FT_Error ImGuiLunasvgPortInit(FT_Pointer* state);
98 | static void ImGuiLunasvgPortFree(FT_Pointer* state);
99 | static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state);
100 | static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state);
101 | #endif
102 |
103 | //-------------------------------------------------------------------------
104 | // Code
105 | //-------------------------------------------------------------------------
106 |
107 | namespace
108 | {
109 | // Glyph metrics:
110 | // --------------
111 | //
112 | // xmin xmax
113 | // | |
114 | // |<-------- width -------->|
115 | // | |
116 | // | +-------------------------+----------------- ymax
117 | // | | ggggggggg ggggg | ^ ^
118 | // | | g:::::::::ggg::::g | | |
119 | // | | g:::::::::::::::::g | | |
120 | // | | g::::::ggggg::::::gg | | |
121 | // | | g:::::g g:::::g | | |
122 | // offsetX -|-------->| g:::::g g:::::g | offsetY |
123 | // | | g:::::g g:::::g | | |
124 | // | | g::::::g g:::::g | | |
125 | // | | g:::::::ggggg:::::g | | |
126 | // | | g::::::::::::::::g | | height
127 | // | | gg::::::::::::::g | | |
128 | // baseline ---*---------|---- gggggggg::::::g-----*-------- |
129 | // / | | g:::::g | |
130 | // origin | | gggggg g:::::g | |
131 | // | | g:::::gg gg:::::g | |
132 | // | | g::::::ggg:::::::g | |
133 | // | | gg:::::::::::::g | |
134 | // | | ggg::::::ggg | |
135 | // | | gggggg | v
136 | // | +-------------------------+----------------- ymin
137 | // | |
138 | // |------------- advanceX ----------->|
139 |
140 | // A structure that describe a glyph.
141 | struct GlyphInfo
142 | {
143 | int Width; // Glyph's width in pixels.
144 | int Height; // Glyph's height in pixels.
145 | FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
146 | FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
147 | float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
148 | bool IsColored; // The glyph is colored
149 | };
150 |
151 | // Font parameters and metrics.
152 | struct FontInfo
153 | {
154 | uint32_t PixelHeight; // Size this font was generated with.
155 | float Ascender; // The pixel extents above the baseline in pixels (typically positive).
156 | float Descender; // The extents below the baseline in pixels (typically negative).
157 | float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
158 | float LineGap; // The spacing in pixels between one row's descent and the next row's ascent.
159 | float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font.
160 | };
161 |
162 | // FreeType glyph rasterizer.
163 | // NB: No ctor/dtor, explicitly call Init()/Shutdown()
164 | struct FreeTypeFont
165 | {
166 | bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
167 | void CloseFont();
168 | void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
169 | const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
170 | const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
171 | void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = nullptr);
172 | FreeTypeFont() { memset(this, 0, sizeof(*this)); }
173 | ~FreeTypeFont() { CloseFont(); }
174 |
175 | // [Internals]
176 | FontInfo Info; // Font descriptor of the current font.
177 | FT_Face Face;
178 | unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
179 | FT_Int32 LoadFlags;
180 | FT_Render_Mode RenderMode;
181 | float RasterizationDensity;
182 | float InvRasterizationDensity;
183 | };
184 |
185 | // From SDL_ttf: Handy routines for converting from fixed point
186 | #define FT_CEIL(X) (((X + 63) & -64) / 64)
187 |
188 | bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
189 | {
190 | FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
191 | if (error != 0)
192 | return false;
193 | error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
194 | if (error != 0)
195 | return false;
196 |
197 | // Convert to FreeType flags (NB: Bold and Oblique are processed separately)
198 | UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
199 |
200 | LoadFlags = 0;
201 | if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0)
202 | LoadFlags |= FT_LOAD_NO_BITMAP;
203 |
204 | if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
205 | LoadFlags |= FT_LOAD_NO_HINTING;
206 | if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
207 | LoadFlags |= FT_LOAD_NO_AUTOHINT;
208 | if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
209 | LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
210 | if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting)
211 | LoadFlags |= FT_LOAD_TARGET_LIGHT;
212 | else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting)
213 | LoadFlags |= FT_LOAD_TARGET_MONO;
214 | else
215 | LoadFlags |= FT_LOAD_TARGET_NORMAL;
216 |
217 | if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome)
218 | RenderMode = FT_RENDER_MODE_MONO;
219 | else
220 | RenderMode = FT_RENDER_MODE_NORMAL;
221 |
222 | if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
223 | LoadFlags |= FT_LOAD_COLOR;
224 |
225 | RasterizationDensity = cfg.RasterizerDensity;
226 | InvRasterizationDensity = 1.0f / RasterizationDensity;
227 |
228 | memset(&Info, 0, sizeof(Info));
229 | SetPixelHeight((uint32_t)cfg.SizePixels);
230 |
231 | return true;
232 | }
233 |
234 | void FreeTypeFont::CloseFont()
235 | {
236 | if (Face)
237 | {
238 | FT_Done_Face(Face);
239 | Face = nullptr;
240 | }
241 | }
242 |
243 | void FreeTypeFont::SetPixelHeight(int pixel_height)
244 | {
245 | // Vuhdo: I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
246 | // is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
247 | // NB: FT_Set_Pixel_Sizes() doesn't seem to get us the same result.
248 | FT_Size_RequestRec req;
249 | req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
250 | req.width = 0;
251 | req.height = (uint32_t)(pixel_height * 64 * RasterizationDensity);
252 | req.horiResolution = 0;
253 | req.vertResolution = 0;
254 | FT_Request_Size(Face, &req);
255 |
256 | // Update font info
257 | FT_Size_Metrics metrics = Face->size->metrics;
258 | Info.PixelHeight = (uint32_t)(pixel_height * InvRasterizationDensity);
259 | Info.Ascender = (float)FT_CEIL(metrics.ascender) * InvRasterizationDensity;
260 | Info.Descender = (float)FT_CEIL(metrics.descender) * InvRasterizationDensity;
261 | Info.LineSpacing = (float)FT_CEIL(metrics.height) * InvRasterizationDensity;
262 | Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * InvRasterizationDensity;
263 | Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * InvRasterizationDensity;
264 | }
265 |
266 | const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
267 | {
268 | uint32_t glyph_index = FT_Get_Char_Index(Face, codepoint);
269 | if (glyph_index == 0)
270 | return nullptr;
271 |
272 | // If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts.
273 | // - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076
274 | // - https://github.com/ocornut/imgui/issues/4567
275 | // - https://github.com/ocornut/imgui/issues/4566
276 | // You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version.
277 | FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
278 | if (error)
279 | return nullptr;
280 |
281 | // Need an outline for this to work
282 | FT_GlyphSlot slot = Face->glyph;
283 | #if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
284 | IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
285 | #else
286 | #if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
287 | IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
288 | #endif
289 | IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
290 | #endif // IMGUI_ENABLE_FREETYPE_LUNASVG
291 |
292 | // Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
293 | if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
294 | FT_GlyphSlot_Embolden(slot);
295 | if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique)
296 | {
297 | FT_GlyphSlot_Oblique(slot);
298 | //FT_BBox bbox;
299 | //FT_Outline_Get_BBox(&slot->outline, &bbox);
300 | //slot->metrics.width = bbox.xMax - bbox.xMin;
301 | //slot->metrics.height = bbox.yMax - bbox.yMin;
302 | }
303 |
304 | return &slot->metrics;
305 | }
306 |
307 | const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
308 | {
309 | FT_GlyphSlot slot = Face->glyph;
310 | FT_Error error = FT_Render_Glyph(slot, RenderMode);
311 | if (error != 0)
312 | return nullptr;
313 |
314 | FT_Bitmap* ft_bitmap = &Face->glyph->bitmap;
315 | out_glyph_info->Width = (int)ft_bitmap->width;
316 | out_glyph_info->Height = (int)ft_bitmap->rows;
317 | out_glyph_info->OffsetX = Face->glyph->bitmap_left;
318 | out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
319 | out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
320 | out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
321 |
322 | return ft_bitmap;
323 | }
324 |
325 | void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
326 | {
327 | IM_ASSERT(ft_bitmap != nullptr);
328 | const uint32_t w = ft_bitmap->width;
329 | const uint32_t h = ft_bitmap->rows;
330 | const uint8_t* src = ft_bitmap->buffer;
331 | const uint32_t src_pitch = ft_bitmap->pitch;
332 |
333 | switch (ft_bitmap->pixel_mode)
334 | {
335 | case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel.
336 | {
337 | if (multiply_table == nullptr)
338 | {
339 | for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
340 | for (uint32_t x = 0; x < w; x++)
341 | dst[x] = IM_COL32(255, 255, 255, src[x]);
342 | }
343 | else
344 | {
345 | for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
346 | for (uint32_t x = 0; x < w; x++)
347 | dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]);
348 | }
349 | break;
350 | }
351 | case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB.
352 | {
353 | uint8_t color0 = multiply_table ? multiply_table[0] : 0;
354 | uint8_t color1 = multiply_table ? multiply_table[255] : 255;
355 | for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
356 | {
357 | uint8_t bits = 0;
358 | const uint8_t* bits_ptr = src;
359 | for (uint32_t x = 0; x < w; x++, bits <<= 1)
360 | {
361 | if ((x & 7) == 0)
362 | bits = *bits_ptr++;
363 | dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0);
364 | }
365 | }
366 | break;
367 | }
368 | case FT_PIXEL_MODE_BGRA:
369 | {
370 | // FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good.
371 | #define DE_MULTIPLY(color, alpha) ImMin((ImU32)(255.0f * (float)color / (float)(alpha + FLT_MIN) + 0.5f), 255u)
372 | if (multiply_table == nullptr)
373 | {
374 | for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
375 | for (uint32_t x = 0; x < w; x++)
376 | {
377 | uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
378 | dst[x] = IM_COL32(DE_MULTIPLY(r, a), DE_MULTIPLY(g, a), DE_MULTIPLY(b, a), a);
379 | }
380 | }
381 | else
382 | {
383 | for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
384 | {
385 | for (uint32_t x = 0; x < w; x++)
386 | {
387 | uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
388 | dst[x] = IM_COL32(multiply_table[DE_MULTIPLY(r, a)], multiply_table[DE_MULTIPLY(g, a)], multiply_table[DE_MULTIPLY(b, a)], multiply_table[a]);
389 | }
390 | }
391 | }
392 | #undef DE_MULTIPLY
393 | break;
394 | }
395 | default:
396 | IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
397 | }
398 | }
399 | } // namespace
400 |
401 | #ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
402 | #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
403 | #define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0)
404 | #define STBRP_STATIC
405 | #define STB_RECT_PACK_IMPLEMENTATION
406 | #endif
407 | #ifdef IMGUI_STB_RECT_PACK_FILENAME
408 | #include IMGUI_STB_RECT_PACK_FILENAME
409 | #else
410 | #include "imstb_rectpack.h"
411 | #endif
412 | #endif
413 |
414 | struct ImFontBuildSrcGlyphFT
415 | {
416 | GlyphInfo Info;
417 | uint32_t Codepoint;
418 | unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
419 |
420 | ImFontBuildSrcGlyphFT() { memset((void*)this, 0, sizeof(*this)); }
421 | };
422 |
423 | struct ImFontBuildSrcDataFT
424 | {
425 | FreeTypeFont Font;
426 | stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position.
427 | const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF)
428 | int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
429 | int GlyphsHighest; // Highest requested codepoint
430 | int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
431 | ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
432 | ImVector GlyphsList;
433 | };
434 |
435 | // Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
436 | struct ImFontBuildDstDataFT
437 | {
438 | int SrcCount; // Number of source fonts targeting this destination font.
439 | int GlyphsHighest;
440 | int GlyphsCount;
441 | ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
442 | };
443 |
444 | bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
445 | {
446 | IM_ASSERT(atlas->ConfigData.Size > 0);
447 |
448 | ImFontAtlasBuildInit(atlas);
449 |
450 | // Clear atlas
451 | atlas->TexID = 0;
452 | atlas->TexWidth = atlas->TexHeight = 0;
453 | atlas->TexUvScale = ImVec2(0.0f, 0.0f);
454 | atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
455 | atlas->ClearTexData();
456 |
457 | // Temporary storage for building
458 | bool src_load_color = false;
459 | ImVector src_tmp_array;
460 | ImVector dst_tmp_array;
461 | src_tmp_array.resize(atlas->ConfigData.Size);
462 | dst_tmp_array.resize(atlas->Fonts.Size);
463 | memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
464 | memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
465 |
466 | // 1. Initialize font loading structure, check font data validity
467 | for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
468 | {
469 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
470 | ImFontConfig& cfg = atlas->ConfigData[src_i];
471 | FreeTypeFont& font_face = src_tmp.Font;
472 | IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
473 |
474 | // Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
475 | src_tmp.DstIndex = -1;
476 | for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
477 | if (cfg.DstFont == atlas->Fonts[output_i])
478 | src_tmp.DstIndex = output_i;
479 | IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
480 | if (src_tmp.DstIndex == -1)
481 | return false;
482 |
483 | // Load font
484 | if (!font_face.InitFont(ft_library, cfg, extra_flags))
485 | return false;
486 |
487 | // Measure highest codepoints
488 | src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
489 | ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
490 | src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
491 | for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
492 | {
493 | // Check for valid range. This may also help detect *some* dangling pointers, because a common
494 | // user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent,
495 | // or to forget to zero-terminate the glyph range array.
496 | IM_ASSERT(src_range[0] <= src_range[1] && "Invalid range: is your glyph range array persistent? it is zero-terminated?");
497 | src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
498 | }
499 | dst_tmp.SrcCount++;
500 | dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
501 | }
502 |
503 | // 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs.
504 | int total_glyphs_count = 0;
505 | for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
506 | {
507 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
508 | ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
509 | src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1);
510 | if (dst_tmp.GlyphsSet.Storage.empty())
511 | dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
512 |
513 | for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
514 | for (int codepoint = src_range[0]; codepoint <= (int)src_range[1]; codepoint++)
515 | {
516 | if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
517 | continue;
518 | uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
519 | if (glyph_index == 0)
520 | continue;
521 |
522 | // Add to avail set/counters
523 | src_tmp.GlyphsCount++;
524 | dst_tmp.GlyphsCount++;
525 | src_tmp.GlyphsSet.SetBit(codepoint);
526 | dst_tmp.GlyphsSet.SetBit(codepoint);
527 | total_glyphs_count++;
528 | }
529 | }
530 |
531 | // 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another)
532 | for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
533 | {
534 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
535 | src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
536 |
537 | IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(ImU32));
538 | const ImU32* it_begin = src_tmp.GlyphsSet.Storage.begin();
539 | const ImU32* it_end = src_tmp.GlyphsSet.Storage.end();
540 | for (const ImU32* it = it_begin; it < it_end; it++)
541 | if (ImU32 entries_32 = *it)
542 | for (ImU32 bit_n = 0; bit_n < 32; bit_n++)
543 | if (entries_32 & ((ImU32)1 << bit_n))
544 | {
545 | ImFontBuildSrcGlyphFT src_glyph;
546 | src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
547 | //src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
548 | src_tmp.GlyphsList.push_back(src_glyph);
549 | }
550 | src_tmp.GlyphsSet.Clear();
551 | IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
552 | }
553 | for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++)
554 | dst_tmp_array[dst_i].GlyphsSet.Clear();
555 | dst_tmp_array.clear();
556 |
557 | // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
558 | // (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity)
559 | ImVector buf_rects;
560 | buf_rects.resize(total_glyphs_count);
561 | memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes());
562 |
563 | // Allocate temporary rasterization data buffers.
564 | // We could not find a way to retrieve accurate glyph size without rendering them.
565 | // (e.g. slot->metrics->width not always matching bitmap->width, especially considering the Oblique transform)
566 | // We allocate in chunks of 256 KB to not waste too much extra memory ahead. Hopefully users of FreeType won't mind the temporary allocations.
567 | const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024;
568 | int buf_bitmap_current_used_bytes = 0;
569 | ImVector buf_bitmap_buffers;
570 | buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
571 |
572 | // 4. Gather glyphs sizes so we can pack them in our virtual canvas.
573 | // 8. Render/rasterize font characters into the texture
574 | int total_surface = 0;
575 | int buf_rects_out_n = 0;
576 | const int pack_padding = atlas->TexGlyphPadding;
577 | for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
578 | {
579 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
580 | ImFontConfig& cfg = atlas->ConfigData[src_i];
581 | if (src_tmp.GlyphsCount == 0)
582 | continue;
583 |
584 | src_tmp.Rects = &buf_rects[buf_rects_out_n];
585 | buf_rects_out_n += src_tmp.GlyphsCount;
586 |
587 | // Compute multiply table if requested
588 | const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
589 | unsigned char multiply_table[256];
590 | if (multiply_enabled)
591 | ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
592 |
593 | // Gather the sizes of all rectangles we will need to pack
594 | for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
595 | {
596 | ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
597 |
598 | const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
599 | if (metrics == nullptr)
600 | continue;
601 |
602 | // Render glyph into a bitmap (currently held by FreeType)
603 | const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info);
604 | if (ft_bitmap == nullptr)
605 | continue;
606 |
607 | // Allocate new temporary chunk if needed
608 | const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4;
609 | if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
610 | {
611 | buf_bitmap_current_used_bytes = 0;
612 | buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
613 | }
614 | IM_ASSERT(buf_bitmap_current_used_bytes + bitmap_size_in_bytes <= BITMAP_BUFFERS_CHUNK_SIZE); // We could probably allocate custom-sized buffer instead.
615 |
616 | // Blit rasterized pixels to our temporary buffer and keep a pointer to it.
617 | src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes);
618 | buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
619 | src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : nullptr);
620 |
621 | src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + pack_padding);
622 | src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + pack_padding);
623 | total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
624 | }
625 | }
626 | for (int i = 0; i < atlas->CustomRects.Size; i++)
627 | total_surface += (atlas->CustomRects[i].Width + pack_padding) * (atlas->CustomRects[i].Height + pack_padding);
628 |
629 | // We need a width for the skyline algorithm, any width!
630 | // The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
631 | // User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface.
632 | const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1;
633 | atlas->TexHeight = 0;
634 | if (atlas->TexDesiredWidth > 0)
635 | atlas->TexWidth = atlas->TexDesiredWidth;
636 | else
637 | atlas->TexWidth = (surface_sqrt >= 4096 * 0.7f) ? 4096 : (surface_sqrt >= 2048 * 0.7f) ? 2048 : (surface_sqrt >= 1024 * 0.7f) ? 1024 : 512;
638 |
639 | // 5. Start packing
640 | // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
641 | const int TEX_HEIGHT_MAX = 1024 * 32;
642 | const int num_nodes_for_packing_algorithm = atlas->TexWidth - atlas->TexGlyphPadding;
643 | ImVector pack_nodes;
644 | pack_nodes.resize(num_nodes_for_packing_algorithm);
645 | stbrp_context pack_context;
646 | stbrp_init_target(&pack_context, atlas->TexWidth - atlas->TexGlyphPadding, TEX_HEIGHT_MAX - atlas->TexGlyphPadding, pack_nodes.Data, pack_nodes.Size);
647 | ImFontAtlasBuildPackCustomRects(atlas, &pack_context);
648 |
649 | // 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
650 | for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
651 | {
652 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
653 | if (src_tmp.GlyphsCount == 0)
654 | continue;
655 |
656 | stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
657 |
658 | // Extend texture height and mark missing glyphs as non-packed so we won't render them.
659 | // FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?)
660 | for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
661 | if (src_tmp.Rects[glyph_i].was_packed)
662 | atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h);
663 | }
664 |
665 | // 7. Allocate texture
666 | atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
667 | atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
668 | if (src_load_color)
669 | {
670 | size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 4;
671 | atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(tex_size);
672 | memset(atlas->TexPixelsRGBA32, 0, tex_size);
673 | }
674 | else
675 | {
676 | size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 1;
677 | atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(tex_size);
678 | memset(atlas->TexPixelsAlpha8, 0, tex_size);
679 | }
680 |
681 | // 8. Copy rasterized font characters back into the main texture
682 | // 9. Setup ImFont and glyphs for runtime
683 | bool tex_use_colors = false;
684 | for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
685 | {
686 | ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
687 |
688 | // When merging fonts with MergeMode=true:
689 | // - We can have multiple input fonts writing into a same destination font.
690 | // - dst_font->ConfigData is != from cfg which is our source configuration.
691 | ImFontConfig& cfg = atlas->ConfigData[src_i];
692 | ImFont* dst_font = cfg.DstFont;
693 |
694 | const float ascent = src_tmp.Font.Info.Ascender;
695 | const float descent = src_tmp.Font.Info.Descender;
696 | ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
697 |
698 | if (src_tmp.GlyphsCount == 0)
699 | continue;
700 | const float font_off_x = cfg.GlyphOffset.x;
701 | const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
702 |
703 | const int padding = atlas->TexGlyphPadding;
704 | for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
705 | {
706 | ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
707 | stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
708 | IM_ASSERT(pack_rect.was_packed);
709 | if (pack_rect.w == 0 && pack_rect.h == 0)
710 | continue;
711 |
712 | GlyphInfo& info = src_glyph.Info;
713 | IM_ASSERT(info.Width + padding <= pack_rect.w);
714 | IM_ASSERT(info.Height + padding <= pack_rect.h);
715 | const int tx = pack_rect.x + padding;
716 | const int ty = pack_rect.y + padding;
717 |
718 | // Register glyph
719 | float x0 = info.OffsetX * src_tmp.Font.InvRasterizationDensity + font_off_x;
720 | float y0 = info.OffsetY * src_tmp.Font.InvRasterizationDensity + font_off_y;
721 | float x1 = x0 + info.Width * src_tmp.Font.InvRasterizationDensity;
722 | float y1 = y0 + info.Height * src_tmp.Font.InvRasterizationDensity;
723 | float u0 = (tx) / (float)atlas->TexWidth;
724 | float v0 = (ty) / (float)atlas->TexHeight;
725 | float u1 = (tx + info.Width) / (float)atlas->TexWidth;
726 | float v1 = (ty + info.Height) / (float)atlas->TexHeight;
727 | dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
728 |
729 | ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
730 | IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);
731 | if (src_glyph.Info.IsColored)
732 | dst_glyph->Colored = tex_use_colors = true;
733 |
734 | // Blit from temporary buffer to final texture
735 | size_t blit_src_stride = (size_t)src_glyph.Info.Width;
736 | size_t blit_dst_stride = (size_t)atlas->TexWidth;
737 | unsigned int* blit_src = src_glyph.BitmapData;
738 | if (atlas->TexPixelsAlpha8 != nullptr)
739 | {
740 | unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
741 | for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
742 | for (int x = 0; x < info.Width; x++)
743 | blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF);
744 | }
745 | else
746 | {
747 | unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx;
748 | for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
749 | for (int x = 0; x < info.Width; x++)
750 | blit_dst[x] = blit_src[x];
751 | }
752 | }
753 |
754 | src_tmp.Rects = nullptr;
755 | }
756 | atlas->TexPixelsUseColors = tex_use_colors;
757 |
758 | // Cleanup
759 | for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++)
760 | IM_FREE(buf_bitmap_buffers[buf_i]);
761 | src_tmp_array.clear_destruct();
762 |
763 | ImFontAtlasBuildFinish(atlas);
764 |
765 | return true;
766 | }
767 |
768 | // FreeType memory allocation callbacks
769 | static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
770 | {
771 | return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData);
772 | }
773 |
774 | static void FreeType_Free(FT_Memory /*memory*/, void* block)
775 | {
776 | GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
777 | }
778 |
779 | static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
780 | {
781 | // Implement realloc() as we don't ask user to provide it.
782 | if (block == nullptr)
783 | return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
784 |
785 | if (new_size == 0)
786 | {
787 | GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
788 | return nullptr;
789 | }
790 |
791 | if (new_size > cur_size)
792 | {
793 | void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
794 | memcpy(new_block, block, (size_t)cur_size);
795 | GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
796 | return new_block;
797 | }
798 |
799 | return block;
800 | }
801 |
802 | static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
803 | {
804 | // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
805 | FT_MemoryRec_ memory_rec = {};
806 | memory_rec.user = nullptr;
807 | memory_rec.alloc = &FreeType_Alloc;
808 | memory_rec.free = &FreeType_Free;
809 | memory_rec.realloc = &FreeType_Realloc;
810 |
811 | // https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library
812 | FT_Library ft_library;
813 | FT_Error error = FT_New_Library(&memory_rec, &ft_library);
814 | if (error != 0)
815 | return false;
816 |
817 | // If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
818 | FT_Add_Default_Modules(ft_library);
819 |
820 | #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
821 | // Install svg hooks for FreeType
822 | // https://freetype.org/freetype2/docs/reference/ft2-properties.html#svg-hooks
823 | // https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html#svg_fonts
824 | SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
825 | FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
826 | #endif // IMGUI_ENABLE_FREETYPE_LUNASVG
827 | #ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
828 | // With plutosvg, use provided hooks
829 | FT_Property_Set(ft_library, "ot-svg", "svg-hooks", plutosvg_ft_svg_hooks());
830 | #endif // IMGUI_ENABLE_FREETYPE_PLUTOSVG
831 |
832 | bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
833 | FT_Done_Library(ft_library);
834 |
835 | return ret;
836 | }
837 |
838 | const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType()
839 | {
840 | static ImFontBuilderIO io;
841 | io.FontBuilder_Build = ImFontAtlasBuildWithFreeType;
842 | return &io;
843 | }
844 |
845 | void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
846 | {
847 | GImGuiFreeTypeAllocFunc = alloc_func;
848 | GImGuiFreeTypeFreeFunc = free_func;
849 | GImGuiFreeTypeAllocatorUserData = user_data;
850 | }
851 |
852 | #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
853 | // For more details, see https://gitlab.freedesktop.org/freetype/freetype-demos/-/blob/master/src/rsvg-port.c
854 | // The original code from the demo is licensed under CeCILL-C Free Software License Agreement (https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/LICENSE.TXT)
855 | struct LunasvgPortState
856 | {
857 | FT_Error err = FT_Err_Ok;
858 | lunasvg::Matrix matrix;
859 | std::unique_ptr svg = nullptr;
860 | };
861 |
862 | static FT_Error ImGuiLunasvgPortInit(FT_Pointer* _state)
863 | {
864 | *_state = IM_NEW(LunasvgPortState)();
865 | return FT_Err_Ok;
866 | }
867 |
868 | static void ImGuiLunasvgPortFree(FT_Pointer* _state)
869 | {
870 | IM_DELETE(*(LunasvgPortState**)_state);
871 | }
872 |
873 | static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state)
874 | {
875 | LunasvgPortState* state = *(LunasvgPortState**)_state;
876 |
877 | // If there was an error while loading the svg in ImGuiLunasvgPortPresetSlot(), the renderer hook still get called, so just returns the error.
878 | if (state->err != FT_Err_Ok)
879 | return state->err;
880 |
881 | // rows is height, pitch (or stride) equals to width * sizeof(int32)
882 | lunasvg::Bitmap bitmap((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch);
883 | state->svg->setMatrix(state->svg->matrix().identity()); // Reset the svg matrix to the default value
884 | state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated
885 | state->err = FT_Err_Ok;
886 | return state->err;
887 | }
888 |
889 | static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state)
890 | {
891 | FT_SVG_Document document = (FT_SVG_Document)slot->other;
892 | LunasvgPortState* state = *(LunasvgPortState**)_state;
893 | FT_Size_Metrics& metrics = document->metrics;
894 |
895 | // This function is called twice, once in the FT_Load_Glyph() and another right before ImGuiLunasvgPortRender().
896 | // If it's the latter, don't do anything because it's // already done in the former.
897 | if (cache)
898 | return state->err;
899 |
900 | state->svg = lunasvg::Document::loadFromData((const char*)document->svg_document, document->svg_document_length);
901 | if (state->svg == nullptr)
902 | {
903 | state->err = FT_Err_Invalid_SVG_Document;
904 | return state->err;
905 | }
906 |
907 | lunasvg::Box box = state->svg->box();
908 | double scale = std::min(metrics.x_ppem / box.w, metrics.y_ppem / box.h);
909 | double xx = (double)document->transform.xx / (1 << 16);
910 | double xy = -(double)document->transform.xy / (1 << 16);
911 | double yx = -(double)document->transform.yx / (1 << 16);
912 | double yy = (double)document->transform.yy / (1 << 16);
913 | double x0 = (double)document->delta.x / 64 * box.w / metrics.x_ppem;
914 | double y0 = -(double)document->delta.y / 64 * box.h / metrics.y_ppem;
915 |
916 | // Scale and transform, we don't translate the svg yet
917 | state->matrix.identity();
918 | state->matrix.scale(scale, scale);
919 | state->matrix.transform(xx, xy, yx, yy, x0, y0);
920 | state->svg->setMatrix(state->matrix);
921 |
922 | // Pre-translate the matrix for the rendering step
923 | state->matrix.translate(-box.x, -box.y);
924 |
925 | // Get the box again after the transformation
926 | box = state->svg->box();
927 |
928 | // Calculate the bitmap size
929 | slot->bitmap_left = FT_Int(box.x);
930 | slot->bitmap_top = FT_Int(-box.y);
931 | slot->bitmap.rows = (unsigned int)(ImCeil((float)box.h));
932 | slot->bitmap.width = (unsigned int)(ImCeil((float)box.w));
933 | slot->bitmap.pitch = slot->bitmap.width * 4;
934 | slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
935 |
936 | // Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
937 | double metrics_width = box.w;
938 | double metrics_height = box.h;
939 | double horiBearingX = box.x;
940 | double horiBearingY = -box.y;
941 | double vertBearingX = slot->metrics.horiBearingX / 64.0 - slot->metrics.horiAdvance / 64.0 / 2.0;
942 | double vertBearingY = (slot->metrics.vertAdvance / 64.0 - slot->metrics.height / 64.0) / 2.0;
943 | slot->metrics.width = FT_Pos(IM_ROUND(metrics_width * 64.0)); // Using IM_ROUND() assume width and height are positive
944 | slot->metrics.height = FT_Pos(IM_ROUND(metrics_height * 64.0));
945 | slot->metrics.horiBearingX = FT_Pos(horiBearingX * 64);
946 | slot->metrics.horiBearingY = FT_Pos(horiBearingY * 64);
947 | slot->metrics.vertBearingX = FT_Pos(vertBearingX * 64);
948 | slot->metrics.vertBearingY = FT_Pos(vertBearingY * 64);
949 |
950 | if (slot->metrics.vertAdvance == 0)
951 | slot->metrics.vertAdvance = FT_Pos(metrics_height * 1.2 * 64.0);
952 |
953 | state->err = FT_Err_Ok;
954 | return state->err;
955 | }
956 |
957 | #endif // #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
958 |
959 | //-----------------------------------------------------------------------------
960 |
961 | #ifdef __GNUC__
962 | #pragma GCC diagnostic pop
963 | #endif
964 |
965 | #ifdef _MSC_VER
966 | #pragma warning (pop)
967 | #endif
968 |
969 | #endif // #ifndef IMGUI_DISABLE
970 |
--------------------------------------------------------------------------------