1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# imgui_freetype
This is an attempt to replace stb_truetype (the default imgui's font rasterizer) with FreeType.
Currently not optimal and probably has some limitations or bugs.
By [Vuhdo](https://github.com/Vuhdo) (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut.
**Usage**
1. Get latest FreeType binaries or build yourself.
2. Add imgui_freetype.h/cpp alongside your imgui sources.
3. Include imgui_freetype.h after imgui.h.
4. Call ImGuiFreeType::BuildFontAtlas() *BEFORE* calling ImFontAtlas::GetTexDataAsRGBA32() or ImFontAtlas::Build() (so normal Build() won't be called):
```cpp
// See ImGuiFreeType::RasterizationFlags
unsigned int flags = ImGuiFreeType::NoHinting;
ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
```
**Gamma Correct Blending**
FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
The default imgui styles will be impacted by this change (alpha values will need tweaking).
**Test code Usage**
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
// Load various small fonts
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 13.0f);
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 13.0f);
io.Fonts->AddFontDefault();
FreeTypeTest freetype_test;
// Main Loop
while (true)
{
if (freetype_test.UpdateRebuild())
{
// REUPLOAD FONT TEXTURE TO GPU
// e.g ImGui_ImplGlfwGL3_InvalidateDeviceObjects() + ImGui_ImplGlfwGL3_CreateDeviceObjects()
}
ImGui::NewFrame();
freetype_test.ShowFreetypeOptionsWindow();
...
}
}
```
**Test code**
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
struct FreeTypeTest
{
enum FontBuildMode
{
FontBuildMode_FreeType,
FontBuildMode_Stb,
};
FontBuildMode BuildMode;
bool WantRebuild;
float FontsMultiply;
unsigned int FontsFlags;
FreeTypeTest()
{
BuildMode = FontBuildMode_FreeType;
WantRebuild = true;
FontsMultiply = 1.0f;
FontsFlags = 0;
}
// Call _BEFORE_ NewFrame()
bool UpdateRebuild()
{
if (!WantRebuild)
return false;
ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < io.Fonts->Fonts.Size; n++)
{
io.Fonts->Fonts[n]->ConfigData->RasterizerMultiply = FontsMultiply;
io.Fonts->Fonts[n]->ConfigData->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
}
if (BuildMode == FontBuildMode_FreeType)
ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
else if (BuildMode == FontBuildMode_Stb)
io.Fonts->Build();
WantRebuild = false;
return true;
}
// Call to draw interface
void ShowFreetypeOptionsWindow()
{
ImGui::Begin("FreeType Options");
ImGui::ShowFontSelector("Fonts");
WantRebuild |= ImGui::RadioButton("FreeType", (int*)&BuildMode, FontBuildMode_FreeType);
ImGui::SameLine();
WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
if (BuildMode == FontBuildMode_FreeType)
{
WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting);
WantRebuild |= ImGui::CheckboxFlags("NoAutoHint", &FontsFlags, ImGuiFreeType::NoAutoHint);
WantRebuild |= ImGui::CheckboxFlags("ForceAutoHint", &FontsFlags, ImGuiFreeType::ForceAutoHint);
WantRebuild |= ImGui::CheckboxFlags("LightHinting", &FontsFlags, ImGuiFreeType::LightHinting);
WantRebuild |= ImGui::CheckboxFlags("MonoHinting", &FontsFlags, ImGuiFreeType::MonoHinting);
WantRebuild |= ImGui::CheckboxFlags("Bold", &FontsFlags, ImGuiFreeType::Bold);
WantRebuild |= ImGui::CheckboxFlags("Oblique", &FontsFlags, ImGuiFreeType::Oblique);
}
ImGui::End();
}
};
```
**Known issues**
- Output texture has excessive resolution (lots of vertical waste).
- FreeType's memory allocator is not overridden.
- `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).
**Obligatory comparison screenshots**
Using Windows built-in segoeui.ttf font. Open in new browser tabs, view at 1080p+.

|