1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-09 23:54:20 +00:00

Fonts: comments.

This commit is contained in:
ocornut 2025-06-25 12:08:00 +02:00
parent 89b5a2c3d5
commit d8c6953710
6 changed files with 35 additions and 40 deletions

View file

@ -12,7 +12,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKE
Dear ImGui is highly portable and only requires a few things to run and render, typically:
- Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure).
- Required: uploading the font atlas texture into graphics memory.
- Required: creating, updating and destroying textures.
- Required: rendering indexed textured triangles with a clipping rectangle.
Extra features are opt-in, our backends try to support as many as possible:

View file

@ -79,13 +79,14 @@ Breaking changes:
- PushFont(NULL, 20.0f) // Keep font and change current size
- PushFont(font, 20.0f) // Change font and set size to 20.0f
- PushFont(font, style.FontSizeBase * 2.0f) // Change font and set size to be twice bigger than current size.
- PushFont(font, font->LegacySize) // Change font and set size to size passed to AddFontXXX() function. Same as pre-1.92 behavor, for fixed size fonts.
- PushFont(font, font->LegacySize) // Change font and set size to size passed to AddFontXXX() function. Same as pre-1.92 behavior, for fixed size fonts.
- To use old behavior use 'ImGui::PushFont(font, font->LegacySize)' at call site.
We intentionally didn't add a default parameter because it would make the long-term
transition more difficult.
- Kept inline redirection font. Will obsolete.
- External scale factors may be applied over the provided size.
- Global scale factors may be applied over the provided size.
This is why it is called 'FontSizeBase' in the style structure.
- Global scale factors are: 'style.FontScaleMain', 'style.FontScaleDpi' and maybe more.
- ImFont::FontSize was removed and does not make sense anymore.
ImFont::LegacySize is the size passed to AddFont().
- Removed support for old PushFont(NULL) which was a shortcut for "revert to default font".

View file

@ -2,7 +2,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/FONTS
## Dear ImGui: Using Fonts
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer),
The code in imgui.cpp embeds a copy of [ProggyClean.ttf](http://proggyfonts.net) (by Tristan Grimmer),
a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions.
You may also load external .TTF/.OTF files.
@ -37,7 +37,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
### (1) Invalid filename due to use of `\` or unexpected working directory.
See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect.
See [About Filenames](#about-filenames). AddFontXXX() functions should assert if the filename is incorrect.
### (2) Invalid UTF-8 encoding of your non-ASCII strings.
@ -45,18 +45,18 @@ See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to co
### (3) Missing glyph ranges.
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is necessary.**
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary.**
You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges.
⏪ Before 1.92: you need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges.
This is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load.
This was a previous constraint of Dear ImGui (lifted in 1.92): when loading a font you need to specify which characters glyphs to load.
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
### (4) Font atlas texture fails to upload to GPU.
🆕 **Since 1.92, with an up to date backend: atlas is built incrementally and dynamically resized, this is less likely to happen**
This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty white rectangles.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
:rewind: This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty white rectangles.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
![empty squares](https://github.com/user-attachments/assets/68b50fb5-8b9d-4c38-baec-6ac384f06d26)
@ -67,8 +67,6 @@ Some solutions:
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
Future versions of Dear ImGui should solve this problem.
##### [Return to Index](#index)
---------------------------------------
@ -112,7 +110,7 @@ io.Fonts->AddFontDefault();
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("font.ttf");
```
**Before 1.92, or without an up to date backend:**
:rewind: **Before 1.92, or without an up to date backend:**
```cpp
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
@ -130,7 +128,7 @@ ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf");
In your application loop, select which font to use:
```cpp
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2);
ImGui::PushFont(font2, 0.0f); // change font, keep current size
ImGui::Text("Hello with another font");
ImGui::PopFont();
```
@ -154,7 +152,7 @@ io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 0.0f, &config); // Merge
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 0.0f, &config); // Merge into first font to add Icons
io.Fonts->Build();
```
**Before 1.92, or without an up to date backend:**
:rewind: **Before 1.92, or without an up to date backend:**
```cpp
// Load a first font
ImFont* font = io.Fonts->AddFontDefault();
@ -193,7 +191,7 @@ ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf");
```
**Before 1.92, or without an up to date backend:**
:rewind: **Before 1.92, or without an up to date backend:**
```cpp
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
@ -277,7 +275,7 @@ config.MergeMode = true;
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config);
```
**Before 1.92:**
:rewind: **Before 1.92:**
```cpp
// Merge icons into default tool font
#include "IconsFontAwesome.h"
@ -355,8 +353,8 @@ You can use `Metrics/Debugger->Fonts->Font->Input Glyphs Overlap Detection Tool`
## Using FreeType Rasterizer (imgui_freetype)
- Dear ImGui uses [stb_truetype.h](https://github.com/nothings/stb/) to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read.
- You can however use `imgui_freetype.cpp` from the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
- FreeType supports auto-hinting which tends to improve the readability of small fonts.
- You can however use `imgui_freetype.cpp` from the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder. Compile with this file and add `#define IMGUI_ENABLE_FREETYPE` to your imconfig.h file or build system to automatically activate it.
- FreeType supports auto-hinting which tends to improve the readability of small fonts. It makes a big difference especially at smaller resolutions.
- Read documentation in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
- Correct sRGB space blending will have an important effect on your font rendering quality.
@ -391,7 +389,7 @@ io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg);
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is necessary, so this is not needed.**
You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
:rewind: You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
```cpp
ImVector<ImWchar> ranges;
ImFontGlyphRangesBuilder builder;
@ -417,7 +415,7 @@ TL;DR; With the new system, it is recommended that you create a custom `ImFontLo
You can ask questions in [#8466](https://github.com/ocornut/imgui/issues/8466).
**Before 1.92:**
:rewind: **Before 1.92:**
As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)**

View file

@ -241,21 +241,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font: arbitrary line spacing. (#2945)
- font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype)
- font: free the Alpha buffer if user only requested RGBA.
!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
- font: for the purpose of RenderTextEllipsis(), it might be useful that CalcTextSizeA() can ignore the trailing padding?
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y
- font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
- font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data
- font: remove ID from CustomRect registration, it seems unnecessary!
- font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575)
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
- font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width
- font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs.
- font/demo: demonstrate use of ImFontGlyphRangesBuilder.
- font/atlas: add a missing Glyphs.reserve()
- font/atlas: incremental updates
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
- font/draw: need to be able to specify wrap start position.
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349.
@ -264,7 +257,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before atlas has been built.
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?

View file

@ -8540,7 +8540,9 @@ ImFontBaked* ImGui::GetFontBaked()
return GImGui->FontBaked;
}
// Get current font size (= height in pixels) of current font, with external scale factors applied. Use ImGui::GetStyle().FontSizeBase to get value before external scale factors.
// Get current font size (= height in pixels) of current font, with global scale factors applied.
// - Use style.FontSizeBase to get value before global scale factors.
// - recap: ImGui::GetFontSize() == style.FontSizeBase * (style.FontScaleMain * style.FontScaleDpi * other_scaling_factors)
float ImGui::GetFontSize()
{
return GImGui->FontSize;
@ -8858,7 +8860,7 @@ void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
{
final_size = g.FontSizeBase;
// External scale factors
// Global scale factors
final_size *= g.Style.FontScaleMain; // Main global scale factor
final_size *= g.Style.FontScaleDpi; // Per-monitor/viewport DPI scale factor, automatically updated when io.ConfigDpiScaleFonts is enabled.

20
imgui.h
View file

@ -501,16 +501,17 @@ namespace ImGui
// *IMPORTANT* before 1.92, fonts had a single size. They can now be dynamically be adjusted.
// - In 1.92 we have REMOVED the single parameter version of PushFont() because it seems like the easiest way to provide an error-proof transition.
// - PushFont(font) before 1.92 = PushFont(font, font->LegacySize) after 1.92 // Use default font size as passed to AddFontXXX() function.
// *IMPORTANT* external scale factors are applied over the provided size. If you want to scale an *existing* font size:
// - External scale factors are: 'style.FontScaleMain * style.FontScaleDpi' and maybe more.
// *IMPORTANT* global scale factors are applied over the provided size.
// - Global scale factors are: 'style.FontScaleMain', 'style.FontScaleDpi' and maybe more.
// - If you want to apply a factor to the _current_ font size:
// - CORRECT: PushFont(NULL, style.FontSizeBase) // use current unscaled size == does nothing
// - CORRECT: PushFont(NULL, style.FontSizeBase * 2.0f) // use current unscaled size x2 == make text twice bigger
// - INCORRECT: PushFont(NULL, GetFontSize()) // INCORRECT! use size after external factors applied == EXTERNAL SCALING FACTORS WILL APPLY TWICE!
// - INCORRECT: PushFont(NULL, GetFontSize() * 2.0f) // INCORRECT! use size after external factors applied == EXTERNAL SCALING FACTORS WILL APPLY TWICE!
// - INCORRECT: PushFont(NULL, GetFontSize()) // INCORRECT! using size after global factors already applied == GLOBAL SCALING FACTORS WILL APPLY TWICE!
// - INCORRECT: PushFont(NULL, GetFontSize() * 2.0f) // INCORRECT! using size after global factors already applied == GLOBAL SCALING FACTORS WILL APPLY TWICE!
IMGUI_API void PushFont(ImFont* font, float font_size_base_unscaled); // Use NULL as a shortcut to keep current font. Use 0.0f to keep current size.
IMGUI_API void PopFont();
IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API float GetFontSize(); // get current scaled font size (= height in pixels). AFTER external scale factors applied. *IMPORTANT* DO NOT PASS THIS VALUE TO PushFont()! Use ImGui::GetStyle().FontSizeBase to get value before external scale factors.
IMGUI_API float GetFontSize(); // get current scaled font size (= height in pixels). AFTER global scale factors applied. *IMPORTANT* DO NOT PASS THIS VALUE TO PushFont()! Use ImGui::GetStyle().FontSizeBase to get value before global scale factors.
IMGUI_API ImFontBaked* GetFontBaked(); // get current font bound at current size // == GetFont()->GetFontBaked(GetFontSize())
// Parameters stacks (shared)
@ -2229,10 +2230,11 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
struct ImGuiStyle
{
// ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors)
float FontSizeBase; // Current base font size before external scaling factors are applied. Use PushFont(NULL, size) to modify. Use ImGui::GetFontSize() to obtain scaled value.
float FontScaleMain; // Main scale factor. May be set by application once, or exposed to end-user.
float FontScaleDpi; // Additional scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
// Font scaling
// - recap: ImGui::GetFontSize() == FontSizeBase * (FontScaleMain * FontScaleDpi * other_scaling_factors)
float FontSizeBase; // Current base font size before external global factors are applied. Use PushFont(NULL, size) to modify. Use ImGui::GetFontSize() to obtain scaled value.
float FontScaleMain; // Main global scale factor. May be set by application once, or exposed to end-user.
float FontScaleDpi; // Additional global scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
float Alpha; // Global alpha applies to everything in Dear ImGui.
float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.