imgui_freetype: Documentation, tweaks. (#618)

This commit is contained in:
omar 2018-02-04 12:44:31 +01:00
parent e9a617b22a
commit 7b005bd7de
4 changed files with 140 additions and 15 deletions

View File

@ -120,9 +120,7 @@ In this document:
Dear Imgui uses stb_truetype.h to rasterize fonts (with optional oversampling). Dear Imgui uses stb_truetype.h to rasterize fonts (with optional oversampling).
This technique and implementation are not ideal for fonts rendered at _small sizes_, which may appear a little blurry. This technique and implementation are not ideal for fonts rendered at _small sizes_, which may appear a little blurry.
There is an implementation of the ImFontAtlas builder using FreeType that you can use: There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder.
https://github.com/ocornut/imgui_club
FreeType supports auto-hinting which tends to improve the readability of small fonts. FreeType supports auto-hinting which tends to improve the readability of small fonts.
Note that this code currently creates textures that are unoptimally too large (could be fixed with some work) Note that this code currently creates textures that are unoptimally too large (could be fixed with some work)

126
misc/freetype/README.md Normal file
View File

@ -0,0 +1,126 @@
# 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::DisableHinting;
ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
```
**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.
**Obligatory comparison screenshots**
Using Windows built-in segoeui.ttf font. Open in new browser tabs, view at 1080p+.
![freetype rasterizer](https://raw.githubusercontent.com/wiki/ocornut/imgui_club/images/freetype_20170817.png)

View File

@ -1,16 +1,17 @@
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui // Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
// Get latest version at http://www.github.com/ocornut/imgui_club // Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @Vuhdo (Aleksei Skriabin) // Original code by @Vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut
// Changelog: // Changelog:
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype, updated for latest changes in ImFontAtlas, minor tweaks. // - 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.
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply. // - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// - v0.52: (2017/09/26) fixes for imgui internal changes // - v0.52: (2017/09/26) fixes for imgui internal changes
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement) // - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement)
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member // - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// Todo/Bugs: // TODO:
// - Font size has lots of waste. // - Output texture has excessive resolution (lots of vertical waste)
// - FreeType's memory allocator is not overridden. // - FreeType's memory allocator is not overridden.
#include "imgui_freetype.h" #include "imgui_freetype.h"

View File

@ -1,6 +1,6 @@
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui // Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
// Original code by @Vuhdo // Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Get latest version at http://www.github.com/ocornut/imgui_club // Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
#pragma once #pragma once
@ -8,10 +8,10 @@
namespace ImGuiFreeType namespace ImGuiFreeType
{ {
// Hinting greatly impacts visuals (and glyph sizes). // Hinting greatly impacts visuals (and glyph sizes).
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output. // When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way. // The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer. // The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags. // You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts. // Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
@ -24,7 +24,7 @@ namespace ImGuiFreeType
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. 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.
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output. MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
Bold = 1 << 5, // Styling: Should we artificially embolden the font? Bold = 1 << 5, // Styling: Should we artificially embolden the font?
Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style? Oblique = 1 << 6 // Styling: Should we slant the font, emulating italic style?
}; };
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0); IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);