diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 459bf25c..90e06972 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -69,6 +69,8 @@ Other Changes: - ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after 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. +- 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, 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). diff --git a/docs/FAQ.md b/docs/FAQ.md index 15e2cd73..5e824b86 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -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 display custom shapes? (using low-level ImDrawList API)](#q-how-can-i-display-custom-shapes-using-low-level-imdrawlist-api) | | **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 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) | @@ -441,10 +442,33 @@ ImGui::End(); # 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? Use the font atlas to load the TTF/OTF file you want: -```c +```cpp ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); 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 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; // CORRECT io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT diff --git a/docs/FONTS.md b/docs/FONTS.md index d2f40f2b..158e08ab 100644 --- a/docs/FONTS.md +++ b/docs/FONTS.md @@ -14,6 +14,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo ## Index - [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) - [Using Icons](#using-icons) - [Using FreeType Rasterizer](#using-freetype-rasterizer) @@ -43,6 +44,13 @@ u8"こんにちは" // this will be encoded as UTF-8 ##### [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 **Load default font:** @@ -51,6 +59,7 @@ ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontDefault(); ``` + **Load .TTF/.OTF file with:** ```cpp 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. + **Load multiple fonts:** ```cpp ImGuiIO& io = ImGui::GetIO(); @@ -71,6 +81,7 @@ ImGui::Text("Hello with another font"); ImGui::PopFont(); ``` + **For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):** ```cpp ImFontConfig config; @@ -80,6 +91,7 @@ config.GlyphExtraSpacing.x = 1.0f; ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); ``` + **Combine multiple fonts into one:** ```cpp // Load a first font @@ -97,6 +109,7 @@ io.Fonts->Build(); ``` **Add a fourth parameter to bake specific font ranges only:** + ```cpp // Basic Latin, Extended Latin 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. + +**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) +
_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_ + + **Offset font vertically by altering the `io.Font->DisplayOffset` value:** ```cpp ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); diff --git a/imgui.cpp b/imgui.cpp index 2d740d1b..b05f969a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -765,11 +765,12 @@ CODE 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 easily use icons in my application? Q: How can I load multiple fonts? 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 =============