Added FAQ entry about DPI. Added Japanese font loading example.

This commit is contained in:
ocornut 2020-06-09 17:29:26 +02:00
parent 40b799023b
commit 53f0f97273
4 changed files with 64 additions and 3 deletions

View File

@ -69,6 +69,8 @@ Other Changes:
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after - ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after
a callback draw command would incorrectly override the callback draw command. a callback draw command would incorrectly override the callback draw command.
- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. - Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
- Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web.
Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut]
- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, - CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups,
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
Fixed a static contructor which led to this dependency on some compiler setups (unclear which). Fixed a static contructor which led to this dependency on some compiler setups (unclear which).

View File

@ -27,6 +27,7 @@ or view this file with any Markdown viewer.
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) | | [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
| [How can I display custom shapes? (using low-level ImDrawList API)](#q-how-can-i-display-custom-shapes-using-low-level-imdrawlist-api) | | [How can I display custom shapes? (using low-level ImDrawList API)](#q-how-can-i-display-custom-shapes-using-low-level-imdrawlist-api) |
| **Q&A: Fonts, Text** | | **Q&A: Fonts, Text** |
| [How should I handle DPi in my application?](#q-how-should-i-handle-dpi-in-my-application) |
| [How can I load a different font than the default?](#q-how-can-i-load-a-different-font-than-the-default) | | [How can I load a different font than the default?](#q-how-can-i-load-a-different-font-than-the-default) |
| [How can I easily use icons in my application?](#q-how-can-i-easily-use-icons-in-my-application) | | [How can I easily use icons in my application?](#q-how-can-i-easily-use-icons-in-my-application) |
| [How can I load multiple fonts?](#q-how-can-i-load-multiple-fonts) | | [How can I load multiple fonts?](#q-how-can-i-load-multiple-fonts) |
@ -441,10 +442,33 @@ ImGui::End();
# Q&A: Fonts, Text # Q&A: Fonts, Text
### Q: How should I handle DPI in my application?
The short answer is: obtain the desired DPI scale, load a suitable font resized with that scale (always round down font size to nearest integer), and scale your Style structure accordingly using `style.ScaleAllSizes()`.
Your application may want to detect DPI change and reload the font and reset style being frames.
Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
Down the line Dear ImGui will provide a variety of standardized reference values to facilitate using this.
Applications in the `examples/` folder are not DPI aware partly because they are unable to load a custom font from the file-system (may change that in the future).
The reason DPI is not auto-magically solved in stock examples is that we don't yet have a satisfying solution for the "multi-dpi" problem (using the `docking` branch: when multiple viewport windows are over multiple monitors using different DPI scale). The current way to handle this on the application side is:
- Create and maintain one font atlas per active DPI scale (e.g. by iterating `platform_io.Monitors[]` before `NewFrame()`).
- Hook `platform_io.OnChangedViewport()` to detect when a `Begin()` call makes a Dear ImGui window change monitor (and therefore DPI).
- In the hook: swap atlas, swap style with correctly sized one, remap the current font from one atlas to the other (may need to maintain a remapping table of your fonts at variying DPI scale).
This approach is relatively easy and functional but come with two issues:
- It's not possibly to reliably size or position a window ahead of `Begin()` without knowing on which monitor it'll land.
- Style override may be lost during the `Begin()` call crossing monitor boundaries. You may need to do some custom scaling mumbo-jumbo if you want your `OnChangedViewport()` handler to preserve style overrides.
Please note that if you are not using multi-viewports with multi-monitors using different DPI scale, you can ignore all of this and use the simpler technique recommended at the top.
### Q: How can I load a different font than the default? ### Q: How can I load a different font than the default?
Use the font atlas to load the TTF/OTF file you want: Use the font atlas to load the TTF/OTF file you want:
```c ```cpp
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
@ -459,7 +483,7 @@ Default is ProggyClean.ttf, monospace, rendered at size 13, embedded in dear img
New programmers: remember that in C/C++ and most programming languages if you want to use a New programmers: remember that in C/C++ and most programming languages if you want to use a
backslash \ within a string literal, you need to write it double backslash "\\": backslash \ within a string literal, you need to write it double backslash "\\":
```c ```cpp
io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escaping the M here!) io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escaping the M here!)
io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT
io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT

View File

@ -14,6 +14,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
## Index ## Index
- [Readme First](#readme-first) - [Readme First](#readme-first)
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
- [Fonts Loading Instructions](#font-loading-instructions) - [Fonts Loading Instructions](#font-loading-instructions)
- [Using Icons](#using-icons) - [Using Icons](#using-icons)
- [Using FreeType Rasterizer](#using-freetype-rasterizer) - [Using FreeType Rasterizer](#using-freetype-rasterizer)
@ -43,6 +44,13 @@ u8"こんにちは" // this will be encoded as UTF-8
##### [Return to Index](#index) ##### [Return to Index](#index)
## How should I handle DPI in my application?
See [FAQ entry](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-should-i-handle-dpi-in-my-application).
##### [Return to Index](#index)
## Font Loading Instructions ## Font Loading Instructions
**Load default font:** **Load default font:**
@ -51,6 +59,7 @@ ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontDefault(); io.Fonts->AddFontDefault();
``` ```
**Load .TTF/.OTF file with:** **Load .TTF/.OTF file with:**
```cpp ```cpp
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -58,6 +67,7 @@ io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
``` ```
If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read "[About filenames](#about-filenames)" carefully. If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read "[About filenames](#about-filenames)" carefully.
**Load multiple fonts:** **Load multiple fonts:**
```cpp ```cpp
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -71,6 +81,7 @@ ImGui::Text("Hello with another font");
ImGui::PopFont(); ImGui::PopFont();
``` ```
**For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):** **For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):**
```cpp ```cpp
ImFontConfig config; ImFontConfig config;
@ -80,6 +91,7 @@ config.GlyphExtraSpacing.x = 1.0f;
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
``` ```
**Combine multiple fonts into one:** **Combine multiple fonts into one:**
```cpp ```cpp
// Load a first font // Load a first font
@ -97,6 +109,7 @@ io.Fonts->Build();
``` ```
**Add a fourth parameter to bake specific font ranges only:** **Add a fourth parameter to bake specific font ranges only:**
```cpp ```cpp
// Basic Latin, Extended Latin // Basic Latin, Extended Latin
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesDefault()); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesDefault());
@ -109,6 +122,27 @@ io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRa
``` ```
See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges. See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges.
**Example loading and using a Japanese font:**
```cpp
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
```
```cpp
ImGui::Text(u8"こんにちは!テスト %d", 123);
if (ImGui::Button(u8"ロード"))
{
// do stuff
}
ImGui::InputText("string", buf, IM_ARRAYSIZE(buf));
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
```
![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png)
<br>_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_
**Offset font vertically by altering the `io.Font->DisplayOffset` value:** **Offset font vertically by altering the `io.Font->DisplayOffset` value:**
```cpp ```cpp
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);

View File

@ -765,11 +765,12 @@ CODE
Q&A: Fonts, Text Q&A: Fonts, Text
================ ================
Q: How should I handle DPI in my application?
Q: How can I load a different font than the default? Q: How can I load a different font than the default?
Q: How can I easily use icons in my application? Q: How can I easily use icons in my application?
Q: How can I load multiple fonts? Q: How can I load multiple fonts?
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?
>> See https://www.dearimgui.org/faq (docs/FAQ.md) docs/FONTS.md >> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md
Q&A: Concerns Q&A: Concerns
============= =============