From a72754886f703fd73048afc86c3eb1fce844e259 Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 9 Jun 2020 16:10:37 +0200 Subject: [PATCH] Docs: Initial draft of fonts documentation (#2861) --- docs/{FONTS.txt => FONTS.md} | 282 ++++++++++++++++------------------- 1 file changed, 127 insertions(+), 155 deletions(-) rename docs/{FONTS.txt => FONTS.md} (59%) diff --git a/docs/FONTS.txt b/docs/FONTS.md similarity index 59% rename from docs/FONTS.txt rename to docs/FONTS.md index e3690f14..9f5c7d7f 100644 --- a/docs/FONTS.txt +++ b/docs/FONTS.md @@ -1,85 +1,134 @@ -dear imgui -FONTS DOCUMENTATION - -Also read https://www.dearimgui.org/faq for more fonts related infos. +## Fonts The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer), -a 13 pixels high, pixel-perfect font used by default. -We embed it font in source code so you can use Dear ImGui without any file system access. +a 13 pixels high, pixel-perfect font used by default. We embed it font in source code so you can use Dear ImGui without any file system access. -You may also load external .TTF/.OTF files. -The files in this folder are suggested fonts, provided as a convenience. +You may also load external .TTF/.OTF files. The files in this folder are suggested fonts, provided as a convenience. -Please read the FAQ: https://www.dearimgui.org/faq -Please use the Discord server: http://discord.dearimgui.org and not the Github issue tracker for basic font loading questions. +Fonts are rasterized in a single texture at the time of calling either of +- `io.Fonts->GetTexDataAsAlpha8()` ---------------------------------------- - INDEX: ---------------------------------------- +- `GetTexDataAsRGBA32()/Build()` -- Readme First / FAQ -- Fonts Loading Instructions -- Using Icons -- Using FreeType rasterizer -- Building Custom Glyph Ranges -- Using custom colorful icons -- Embedding Fonts in Source Code -- Credits/Licences for fonts included in repository -- Fonts Links +**Please read the FAQ:** https://www.dearimgui.org/faq +Please use the Discord server: http://discord.dearimgui.org and not the GitHub issue tracker for basic font loading questions. --------------------------------------- - README FIRST / FAQ +| Index | +|:---------------------------------------| +| [Readme First](#readme-first) | +| [Using Icons](#using-icons) | +| [Fonts Loading Instructions](#font-loading-instructions) | +| [FreeType Rasterizer, Small Font Sizes](#freeType-rasterizer-small-font-sizes) | +| [Building Custom Glyph Ranges](#building-custom-glyph-ranges) | +| [Using Custom Colorful Icons](#using-custom-colorful-icons) | +| [Embedding Fonts In Source Code](#embedding-fonts-in-source-code) | +| [Credits/Licenses For Fonts Included In This Folder](#creditslicenses-for-fonts-included-in-this-folder) | +| [Font Links](#font-links) | + + --------------------------------------- + ## Readme First - You can use the style editor ImGui::ShowStyleEditor() in the "Fonts" section to browse your fonts and understand what's going on if you have an issue. -- Fonts are rasterized in a single texture at the time of calling either of io.Fonts->GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). -- Make sure your font ranges data are persistent and available at the time the font atlas is being built. +- Make sure your font ranges data are persistent (available during the call to GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). - Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.: + ``` u8"hello" u8"こんにちは" // this will be encoded as UTF-8 -- If you want to include a backslash \ character in your string literal, you need to double them e.g. "folder\\filename". - Read FAQ for details. + ``` +- If you want to include a backslash \ character in your string literal, you need to double them e.g. "folder\\\filename". --------------------------------------- - FONTS LOADING INSTRUCTIONS ---------------------------------------- + ## Using Icons -Load default font: +- Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application. +- A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without having to change fonts back and forth. +- To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: + https://github.com/juliettef/IconFontCppHeaders + +**The C++11 version of those files uses the u8"" utf-8 encoding syntax + \u** + + ` #define ICON_FA_SEARCH u8"\uf002" ` +**The pre-C++11 version has the values directly encoded as utf-8:** + + ` #define ICON_FA_SEARCH "\xEF\x80\x82" ` + +Example Setup: +```cpp + // Merge icons into default tool font + #include "IconsFontAwesome.h" ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontDefault(); -Load .TTF/.OTF file with: + ImFontConfig config; + config.MergeMode = true; + config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced + static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; + io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); +``` +Example Usage: +```cpp + // Usage, e.g. + ImGui::Text("%s among %d items", ICON_FA_SEARCH, count); + ImGui::Button(ICON_FA_SEARCH " Search"); + // C string _literals_ can be concatenated at compilation time, e.g. "hello" " world" + // ICON_FA_SEARCH is defined as a string literal so this is the same as "A" "B" becoming "AB" +``` +See Links below for other icons fonts and related tools. - ImGuiIO& io = ImGui::GetIO(); - io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); -Load multiple fonts: +--------------------------------------- + ## Font Loading Instructions +Load default font: +```cpp + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->AddFontDefault(); +``` +Load .TTF/.OTF file with: +```cpp ImGuiIO& io = ImGui::GetIO(); ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels); // Select font at runtime - ImGui::Text("Hello"); // use the default font (which is the first loaded font) + ImGui::Text("Hello"); // use the default font (which is the first loaded font) ImGui::PushFont(font2); 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; config.OversampleH = 2; config.OversampleV = 1; config.GlyphExtraSpacing.x = 1.0f; ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); +``` +**Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample)** -Combine two fonts into one: +- If you have very 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 glyphs appears as white rectangles. +- In particular, using a large range such as GetGlyphRangesChineseSimplifiedCommon() is not recommended unless you set OversampleH/OversampleV to 1 and use a small font size. +- 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. + +Some solutions: + + 1. Reduce glyphs ranges by calculating them from source localization data. + You can use ImFontGlyphRangesBuilder for this purpose, this will be the biggest win! + 2. You may reduce oversampling, e.g. config.OversampleH = config.OversampleV = 1, this will largely reduce your texture size. + 3. Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function). + 4. Set io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight; to disable rounding the texture height to the next power of two. +Combine two fonts into one: +```cpp // Load a first font ImFont* font = io.Fonts->AddFontDefault(); @@ -92,28 +141,9 @@ Combine two fonts into one: io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 18.0f, &config, io.Fonts->GetGlyphRangesJapanese()); io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 18.0f, &config, icons_ranges); io.Fonts->Build(); - -Font atlas is too large? - -- If you have very 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 glyphs appears as white rectangles. -- In particular, using a large range such as GetGlyphRangesChineseSimplifiedCommon() is not recommended - unless you set OversampleH/OversampleV to 1 and use a small font size. -- Mind the fact that some graphics drivers have texture size limitation. -- If you are building a PC application, mind the fact that users may run on hardware with lower specs than yours. - -Some solutions: - - - 1) Reduce glyphs ranges by calculating them from source localization data. - You can use ImFontGlyphRangesBuilder for this purpose, this will be the biggest win! - - 2) You may reduce oversampling, e.g. config.OversampleH = config.OversampleV = 1, this will largely reduce your texture size. - - 3) Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function). - - 4) Set io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight; to disable rounding the texture height to the next power of two. - - Read about oversampling here: https://github.com/nothings/stb/blob/master/tests/oversample - - +``` 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()); @@ -122,79 +152,31 @@ Add a fourth parameter to bake specific font ranges only: // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); - -See "BUILDING CUSTOM GLYPH RANGES" section to create your own ranges. +``` +See [Building Custom Glyph Ranges](#building-custom-glyph-ranges) section to create your own ranges. Offset font vertically by altering the io.Font->DisplayOffset value: - +```cpp ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); font->DisplayOffset.y = 1; // Render 1 pixel down +``` - ---------------------------------------- - USING ICONS --------------------------------------- + ## Freetype Rasterizer, Small Font Sizes -Using an icon font (such as FontAwesome: http://fontawesome.io or OpenFontIcons. https://github.com/traverseda/OpenFontIcons) -is an easy and practical way to use icons in your Dear ImGui application. -A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without -having to change fonts back and forth. - -To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: - - https://github.com/juliettef/IconFontCppHeaders - -Those files contains a bunch of named #define which you can use to refer to specific icons of the font, e.g.: - - #define ICON_FA_MUSIC "\xef\x80\x81" - #define ICON_FA_SEARCH "\xef\x80\x82" - -Example Setup: +- Dear ImGui uses imstb\_truetype.h 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. +- There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder. +- FreeType supports auto-hinting which tends to improve the readability of small fonts. - // Merge icons into default tool font - #include "IconsFontAwesome.h" - ImGuiIO& io = ImGui::GetIO(); - io.Fonts->AddFontDefault(); - - ImFontConfig config; - config.MergeMode = true; - config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced - static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; - io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); - -Example Usage: - - // Usage, e.g. - ImGui::Text("%s among %d items", ICON_FA_SEARCH, count); - ImGui::Button(ICON_FA_SEARCH " Search"); - -Important to understand: C string _literals_ can be concatenated at compilation time, e.g. "hello" " world" -ICON_FA_SEARCH is defined as a string literal so this is the same as "A" "B" becoming "AB" - -See Links below for other icons fonts and related tools. +**Note** +- This code currently creates textures that are unoptimally too large (could be fixed with some work). +- Also note that correct sRGB space blending will have an important effect on your font rendering quality. --------------------------------------- - FREETYPE RASTERIZER, SMALL FONT SIZES ---------------------------------------- - -Dear ImGui uses imstb_truetype.h 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. - -There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder. - -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). -Also note that correct sRGB space blending will have an important effect on your font rendering quality. - - ---------------------------------------- - BUILDING CUSTOM GLYPH RANGES ---------------------------------------- - -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. + ## Building Custom Glyph Ranges +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 ranges; ImFontGlyphRangesBuilder builder; builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters) @@ -204,21 +186,18 @@ For example: for a game where your script is known, if you can feed your entire io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); io.Fonts->Build(); // Build the atlas while 'ranges' is still in scope and not deleted. +``` - ---------------------------------------- - USING CUSTOM COLORFUL ICONS --------------------------------------- +## Using Custom Colorful Icons -(This is a BETA api, use if you are familiar with dear imgui and with your rendering back-end) - -You can use the ImFontAtlas::AddCustomRect() and ImFontAtlas::AddCustomRectFontGlyph() api to register rectangles -that will be packed into the font atlas texture. Register them before building the atlas, then call Build(). -You can then use ImFontAtlas::GetCustomRectByIndex(int) to query the position/size of your rectangle within the -texture, and blit/copy any graphics data of your choice into those rectangles. +**(This is a BETA api, use if you are familiar with dear imgui and with your rendering back-end)** -Pseudo-code: +- You can use the ImFontAtlas::AddCustomRect() and ImFontAtlas::AddCustomRectFontGlyph() api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build(). +- You can then use ImFontAtlas::GetCustomRectByIndex(int) to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles. +#### Pseudo-code: +``` // Add font, then register two custom 13x13 rectangles mapped to glyph 'a' and 'b' of this font ImFont* font = io.Fonts->AddFontDefault(); int rect_ids[2]; @@ -247,29 +226,25 @@ Pseudo-code: } } } +``` - ---------------------------------------- - EMBEDDING FONTS IN SOURCE CODE --------------------------------------- + ## Embedding Fonts In Source Code -Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code. -See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool. -You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README). -The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the -actual binary will be about 20% bigger. +- Compile and use 'binary\_to\_compressed\_c.cpp' to create a compressed C style array that you can embed in source code. +- See the documentation in binary\_to\_compressed\_c.cpp for instruction on how to use the tool. +- You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README). +- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger. Then load the font with: - ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); -or: - ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); + ` ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); ` +or + `ImFont* font = io.Fonts- AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); + ` --------------------------------------- - CREDITS/LICENSES FOR FONTS INCLUDED IN REPOSITORY ---------------------------------------- - -Some fonts are available in the misc/fonts/ folder: + ## Credits/Licenses For Fonts Included In This Folder Roboto-Medium.ttf @@ -309,10 +284,9 @@ Karla-Regular.ttf --------------------------------------- - FONTS LINKS ---------------------------------------- + ## Font Links -ICON FONTS +#### ICON FONTS C/C++ header for icon fonts (#define with code points to use in source code string literals) https://github.com/juliettef/IconFontCppHeaders @@ -332,7 +306,7 @@ ICON FONTS IcoMoon - Custom Icon font builder https://icomoon.io/app -REGULAR FONTS +#### REGULAR FONTS Google Noto Fonts (worldwide languages) https://www.google.com/get/noto/ @@ -343,17 +317,15 @@ REGULAR FONTS (Japanese) M+ fonts by Coji Morishita are free http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html -MONOSPACE FONTS (PIXEL PERFECT) +#### MONOSPACE FONTS - Proggy Fonts, by Tristan Grimmer + (Pixel Perfect) Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperbounds.net - Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) + (Pixel Perfect) Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font Also include .inl file to use directly in dear imgui. -MONOSPACE FONTS (REGULAR) - Google Noto Mono Fonts https://www.google.com/get/noto/