ImFontAtlas: heuristic increase texture width up to 4096 with 4000+ glyphs. Various comments (#491)

This commit is contained in:
ocornut 2016-01-20 10:30:28 +00:00
parent 3922988dea
commit e585204d82
3 changed files with 15 additions and 6 deletions

View File

@ -2,6 +2,8 @@
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files. The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files.
Those are only provided as a convenience, you can load your own .TTF files. Those are only provided as a convenience, you can load your own .TTF files.
Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
--------------------------------- ---------------------------------
LOADING INSTRUCTIONS LOADING INSTRUCTIONS
--------------------------------- ---------------------------------
@ -20,10 +22,17 @@
ImFontConfig config; ImFontConfig config;
config.OversampleH = 3; config.OversampleH = 3;
config.OversampleV = 3; config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f; config.GlyphExtraSpacing.x = 1.0f;
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
If you have very large number of glyphs or multiple fonts:
- Mind the fact that some graphics drivers have texture size limitation.
- Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function).
- You may reduce oversampling, e.g. config.OversampleH = 2 or 1.
- Reduce glyphs ranges, consider calculating them based on your source data if this is possible.
Combine two fonts into one: Combine two fonts into one:
// Load main font // Load main font

View File

@ -359,6 +359,7 @@
Q: How can I load multiple fonts? Q: How can I load multiple fonts?
A: Use the font atlas to pack them into a single texture: A: Use the font atlas to pack them into a single texture:
(Read extra_fonts/README.txt and the code in ImFontAtlas for more details.)
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImFont* font0 = io.Fonts->AddFontDefault(); ImFont* font0 = io.Fonts->AddFontDefault();
@ -371,7 +372,7 @@
// Options // Options
ImFontConfig config; ImFontConfig config;
config.OversampleH = 3; config.OversampleH = 3;
config.OversampleV = 3; config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f; config.GlyphExtraSpacing.x = 1.0f;
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config); io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config);
@ -383,8 +384,6 @@
io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges);
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese()); io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
Read extra_fonts/README.txt or ImFontAtlas class for more details.
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board. A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board.
Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.

View File

@ -1244,8 +1244,9 @@ bool ImFontAtlas::Build()
} }
} }
// Start packing // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth if they wish.
TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters much but some API/GPU have texture size limitations, and increasing width can decrease height. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512;
TexHeight = 0; TexHeight = 0;
const int max_tex_height = 1024*32; const int max_tex_height = 1024*32;
stbtt_pack_context spc; stbtt_pack_context spc;