Skip to content

Commit 7b005bd

Browse files
committed
imgui_freetype: Documentation, tweaks. (#618)
1 parent e9a617b commit 7b005bd

File tree

4 files changed

+140
-15
lines changed

4 files changed

+140
-15
lines changed

misc/fonts/README.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ In this document:
120120

121121
Dear Imgui uses stb_truetype.h to rasterize fonts (with optional oversampling).
122122
This technique and implementation are not ideal for fonts rendered at _small sizes_, which may appear a little blurry.
123-
There is an implementation of the ImFontAtlas builder using FreeType that you can use:
124-
125-
https://github.com/ocornut/imgui_club
123+
There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder.
126124

127125
FreeType supports auto-hinting which tends to improve the readability of small fonts.
128126
Note that this code currently creates textures that are unoptimally too large (could be fixed with some work)

misc/freetype/README.md

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

misc/freetype/imgui_freetype.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
2-
// Get latest version at http://www.github.com/ocornut/imgui_club
3-
// Original code by @Vuhdo (Aleksei Skriabin)
2+
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
3+
// Original code by @Vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut
44

55
// Changelog:
6-
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype, updated for latest changes in ImFontAtlas, minor tweaks.
6+
// - v0.50: (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.
77
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
88
// - v0.52: (2017/09/26) fixes for imgui internal changes
99
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement)
1010
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member
11+
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
1112

12-
// Todo/Bugs:
13-
// - Font size has lots of waste.
13+
// TODO:
14+
// - Output texture has excessive resolution (lots of vertical waste)
1415
// - FreeType's memory allocator is not overridden.
1516

1617
#include "imgui_freetype.h"

misc/freetype/imgui_freetype.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
2-
// Original code by @Vuhdo
3-
// Get latest version at http://www.github.com/ocornut/imgui_club
2+
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
3+
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
44

55
#pragma once
66

77
#include "imgui.h" // IMGUI_API, ImFontAtlas
88

99
namespace ImGuiFreeType
1010
{
11-
// Hinting greatly impacts visuals (and glyph sizes).
12-
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
13-
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
14-
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
11+
// Hinting greatly impacts visuals (and glyph sizes).
12+
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
13+
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
14+
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
1515

1616
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
1717
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
@@ -24,7 +24,7 @@ namespace ImGuiFreeType
2424
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.
2525
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
2626
Bold = 1 << 5, // Styling: Should we artificially embolden the font?
27-
Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
27+
Oblique = 1 << 6 // Styling: Should we slant the font, emulating italic style?
2828
};
2929

3030
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);

0 commit comments

Comments
 (0)