2
0
Эх сурвалжийг харах

Fonts: (Breaking) Rename ImGuiFreeType:: flags to ImGuiFreeTypeBuilderFlags_XXX. Remove ImGuiFreeType::BuildFontAtlas() flags. Rename ImFontConfig::RasterizerFlags to FontBuilderFlags. Add ImFontBuilderIO (opaque). Amend 53d59f3 with a dozen of small fixes.

ocornut 4 жил өмнө
parent
commit
3867c6c5f0

+ 11 - 3
docs/CHANGELOG.txt

@@ -35,10 +35,21 @@ HOW TO UPDATE?
  VERSION 1.81 WIP (In Progress)
  VERSION 1.81 WIP (In Progress)
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
 
 
+Breaking Changes:
+
+- imgui_freetype: Removed ImGuiFreeType::BuildFontAtlas() extra flags, now stored in ImFontAtlas::FontBuilderFlags.
+- imgui_freetype: Renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags. 
+- imgui_freetyoe: Renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. 
+
 Other Changes:
 Other Changes:
 
 
 - Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no 
 - Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no 
   close button in the window. (#3731)
   close button in the window. (#3731)
+- imgui_freetype: Facilitated using FreeType integration: [@Xipiryon, @ocornut]
+  - Use '#define IMGUI_ENABLE_FREETYPE' in imconfig.h should make it work with no other modifications 
+    other than compiling misc/freetype/imgui_freetype.cpp and linking with FreeType.
+  - Use '#define IMGUI_ENABLE_STB_TRUETYPE' if you somehow need the stb_truetype rasterizer to be
+    compiled in along with the FreeType one, otherwise it is enabled by default.
 - ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738)
 - ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738)
   Would lead to a buffer read overflow.
   Would lead to a buffer read overflow.
 - Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilite compiling with 
 - Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilite compiling with 
@@ -142,9 +153,6 @@ Other Changes:
 - Style: Changed default style.WindowRounding value to 0.0f (matches default for multi-viewports).
 - Style: Changed default style.WindowRounding value to 0.0f (matches default for multi-viewports).
 - Style: Reduced the size of the resizing grip, made alpha less prominent.
 - Style: Reduced the size of the resizing grip, made alpha less prominent.
 - Style: Classic: Increase the default alpha value of WindowBg to be closer to other styles.
 - Style: Classic: Increase the default alpha value of WindowBg to be closer to other styles.
-- Fonts: Ease Freetype integration with IMGUI_ENABLE_FREETYPE: When enabled, it Will use the library to rasterize font by default.
-  Also renamed IMGUI_DISABLE_STB_TRUETYPE to IMGUI_ENABLE_STB_TRUETYPE, and making it the default rasterizer
-  if IMGUI_ENABLE_FREETYPE is not defined. [@Xipiryon]
 - Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width.
 - Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width.
 - Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
 - Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
   when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]
   when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]

+ 8 - 5
imconfig.h

@@ -53,20 +53,23 @@
 //#define IMGUI_USE_WCHAR32
 //#define IMGUI_USE_WCHAR32
 
 
 //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
 //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
-// By default the embedded implementations are declared static and not available outside of imgui cpp files.
+// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
 //#define IMGUI_STB_TRUETYPE_FILENAME   "my_folder/stb_truetype.h"
 //#define IMGUI_STB_TRUETYPE_FILENAME   "my_folder/stb_truetype.h"
 //#define IMGUI_STB_RECT_PACK_FILENAME  "my_folder/stb_rect_pack.h"
 //#define IMGUI_STB_RECT_PACK_FILENAME  "my_folder/stb_rect_pack.h"
+//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
+//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
 
 
 //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
 //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
 // Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
 // Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
 // #define IMGUI_USE_STB_SPRINTF
 // #define IMGUI_USE_STB_SPRINTF
 
 
-//---- Use Freetype to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
-// Requires Freetype headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the Freetype library (not provided)
+//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
+// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
+// On Windows you may use vcpkg with 'vcpkg install freetype' + 'vcpkg integrate install'.
 //#define IMGUI_ENABLE_FREETYPE
 //#define IMGUI_ENABLE_FREETYPE
 
 
-//---- Use stb_truetype to build and rasterize the font atlas (this is enabled by default)
-// The only purpose of this this define is if you want force compilation of the stb_truetype backend ALONG with the Freetype backend.
+//---- Use stb_truetype to build and rasterize the font atlas (default)
+// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
 //#define IMGUI_ENABLE_STB_TRUETYPE
 //#define IMGUI_ENABLE_STB_TRUETYPE
 
 
 //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
 //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.

+ 3 - 0
imgui.cpp

@@ -373,6 +373,9 @@ CODE
  When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
  When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
  You can read releases logs https://github.com/ocornut/imgui/releases for more details.
  You can read releases logs https://github.com/ocornut/imgui/releases for more details.
 
 
+ - 2021/01/26 (1.81) - imgui_freetype: removed ImGuiFreeType::BuildFontAtlas() extra flags, now stored in ImFontAtlas::FontBuilderFlags.
+                     - imgui_freetype: renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags.
+                     - imgui_freetype: renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API.
  - 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018):
  - 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018):
                         - ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit().
                         - ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit().
                         - ImGuiCol_ModalWindowDarkening       -> use ImGuiCol_ModalWindowDimBg
                         - ImGuiCol_ModalWindowDarkening       -> use ImGuiCol_ModalWindowDimBg

+ 6 - 2
imgui.h

@@ -125,6 +125,7 @@ struct ImDrawListSplitter;          // Helper to split a draw list into differen
 struct ImDrawVert;                  // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
 struct ImDrawVert;                  // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
 struct ImFont;                      // Runtime data for a single font within a parent ImFontAtlas
 struct ImFont;                      // Runtime data for a single font within a parent ImFontAtlas
 struct ImFontAtlas;                 // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
 struct ImFontAtlas;                 // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
+struct ImFontBuilderIO;             // Opaque interface to a font builder (stb_truetype or FreeType).
 struct ImFontConfig;                // Configuration data when adding a font or merging fonts
 struct ImFontConfig;                // Configuration data when adding a font or merging fonts
 struct ImFontGlyph;                 // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
 struct ImFontGlyph;                 // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
 struct ImFontGlyphRangesBuilder;    // Helper to build glyph ranges from text/string data
 struct ImFontGlyphRangesBuilder;    // Helper to build glyph ranges from text/string data
@@ -2488,7 +2489,7 @@ struct ImFontConfig
     float           GlyphMinAdvanceX;       // 0        // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
     float           GlyphMinAdvanceX;       // 0        // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
     float           GlyphMaxAdvanceX;       // FLT_MAX  // Maximum AdvanceX for glyphs
     float           GlyphMaxAdvanceX;       // FLT_MAX  // Maximum AdvanceX for glyphs
     bool            MergeMode;              // false    // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
     bool            MergeMode;              // false    // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
-    unsigned int    RasterizerFlags;        // 0x00     // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.
+    unsigned int    FontBuilderFlags;       // 0        // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
     float           RasterizerMultiply;     // 1.0f     // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.
     float           RasterizerMultiply;     // 1.0f     // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.
     ImWchar         EllipsisChar;           // -1       // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
     ImWchar         EllipsisChar;           // -1       // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
 
 
@@ -2634,7 +2635,6 @@ struct ImFontAtlas
     ImTextureID                 TexID;              // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
     ImTextureID                 TexID;              // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
     int                         TexDesiredWidth;    // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
     int                         TexDesiredWidth;    // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
     int                         TexGlyphPadding;    // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0.
     int                         TexGlyphPadding;    // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0.
-    const char*                 Builder;            // Select font builder/rasterizer. Default to "stb_truetype". Set to "freetype" to enable Freetype (default if IMGUI_ENABLE_FREETYPE is defined).
 
 
     // [Internal]
     // [Internal]
     // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
     // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
@@ -2649,6 +2649,10 @@ struct ImFontAtlas
     ImVector<ImFontConfig>      ConfigData;         // Configuration data
     ImVector<ImFontConfig>      ConfigData;         // Configuration data
     ImVec4                      TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1];  // UVs for baked anti-aliased lines
     ImVec4                      TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1];  // UVs for baked anti-aliased lines
 
 
+    // [Internal] Font builder
+    const ImFontBuilderIO*      FontBuilderIO;      // Opaque interface to a font builder (default to stb_truetype, can be changed to use FreeType by defining IMGUI_ENABLE_FREETYPE).
+    unsigned int                FontBuilderFlags;   // Shared flags (for all fonts) for custom font builder. THIS IS BUILD IMPLEMENTATION DEPENDENT. Per-font override is also available in ImFontConfig.
+
     // [Internal] Packing data
     // [Internal] Packing data
     int                         PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
     int                         PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
     int                         PackIdLines;        // Custom texture rectangle ID for baked anti-aliased lines
     int                         PackIdLines;        // Custom texture rectangle ID for baked anti-aliased lines

+ 31 - 22
imgui_draw.cpp

@@ -122,7 +122,7 @@ namespace IMGUI_STB_NAMESPACE
 #endif
 #endif
 
 
 #ifndef STB_RECT_PACK_IMPLEMENTATION                        // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
 #ifndef STB_RECT_PACK_IMPLEMENTATION                        // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
-#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
+#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION          // in case the user already have an implementation in another compilation unit
 #define STBRP_STATIC
 #define STBRP_STATIC
 #define STBRP_ASSERT(x)     do { IM_ASSERT(x); } while (0)
 #define STBRP_ASSERT(x)     do { IM_ASSERT(x); } while (0)
 #define STBRP_SORT          ImQsort
 #define STBRP_SORT          ImQsort
@@ -137,7 +137,7 @@ namespace IMGUI_STB_NAMESPACE
 
 
 #ifdef  IMGUI_ENABLE_STB_TRUETYPE
 #ifdef  IMGUI_ENABLE_STB_TRUETYPE
 #ifndef STB_TRUETYPE_IMPLEMENTATION                         // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
 #ifndef STB_TRUETYPE_IMPLEMENTATION                         // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
-#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
+#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION           // in case the user already have an implementation in another compilation unit
 #define STBTT_malloc(x,u)   ((void)(u), IM_ALLOC(x))
 #define STBTT_malloc(x,u)   ((void)(u), IM_ALLOC(x))
 #define STBTT_free(x,u)     ((void)(u), IM_FREE(x))
 #define STBTT_free(x,u)     ((void)(u), IM_FREE(x))
 #define STBTT_assert(x)     do { IM_ASSERT(x); } while(0)
 #define STBTT_assert(x)     do { IM_ASSERT(x); } while(0)
@@ -158,7 +158,7 @@ namespace IMGUI_STB_NAMESPACE
 #include "imstb_truetype.h"
 #include "imstb_truetype.h"
 #endif
 #endif
 #endif
 #endif
-#endif
+#endif // IMGUI_ENABLE_STB_TRUETYPE
 
 
 #if defined(__GNUC__)
 #if defined(__GNUC__)
 #pragma GCC diagnostic pop
 #pragma GCC diagnostic pop
@@ -1782,14 +1782,6 @@ ImFontAtlas::ImFontAtlas()
     memset(this, 0, sizeof(*this));
     memset(this, 0, sizeof(*this));
     TexGlyphPadding = 1;
     TexGlyphPadding = 1;
     PackIdMouseCursors = PackIdLines = -1;
     PackIdMouseCursors = PackIdLines = -1;
-
-#ifdef IMGUI_ENABLE_FREETYPE
-    Builder = "freetype";
-#else
-#   ifdef IMGUI_ENABLE_STB_TRUETYPE
-    Builder = "stb_truetype";
-#   endif
-#endif
 }
 }
 
 
 ImFontAtlas::~ImFontAtlas()
 ImFontAtlas::~ImFontAtlas()
@@ -2074,17 +2066,26 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
 bool    ImFontAtlas::Build()
 bool    ImFontAtlas::Build()
 {
 {
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
+
+    // Select builder
+    // - Note that we do not reassign to atlas->FontBuilderIO, since it is likely to point to static data which
+    //   may mess with some hot-reloading schemes. If you need to assign to this (for dynamic selection) AND are
+    //   using a hot-reloading scheme that messes up static data, store your own instance of ImFontBuilderIO somewhere
+    //   and point to it instead of pointing directly to return value of the GetBuilderXXX functions.
+    const ImFontBuilderIO* builder_io = FontBuilderIO;
+    if (builder_io == NULL)
+    {
 #ifdef IMGUI_ENABLE_FREETYPE
 #ifdef IMGUI_ENABLE_FREETYPE
-    if (strcmp(Builder, "freetype") == 0)
-        return ImGuiFreeType::BuildFontAtlas(this, 0);
-#endif
-    // Not doing "#else" here, since we could have both
-    // IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE defined.
-#ifdef IMGUI_ENABLE_STB_TRUETYPE
-    if (strcmp(Builder, "stb_truetype") == 0)
-        return ImFontAtlasBuildWithStbTruetype(this);
+        builder_io = ImGuiFreeType::GetBuilderForFreeType();
+#elif defined(IMGUI_ENABLE_STB_TRUETYPE)
+        builder_io = ImFontAtlasGetBuilderForStbTruetype();
+#else
+        IM_ASSERT(0); // Invalid Build function
 #endif
 #endif
-    return false;
+    }
+
+    // Build
+    return builder_io->FontBuilder_Build(this);
 }
 }
 
 
 void    ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor)
 void    ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor)
@@ -2142,7 +2143,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>*
                     out->push_back((int)(((it - it_begin) << 5) + bit_n));
                     out->push_back((int)(((it - it_begin) << 5) + bit_n));
 }
 }
 
 
-bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
+static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
 {
 {
     IM_ASSERT(atlas->ConfigData.Size > 0);
     IM_ASSERT(atlas->ConfigData.Size > 0);
 
 
@@ -2394,7 +2395,15 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
     ImFontAtlasBuildFinish(atlas);
     ImFontAtlasBuildFinish(atlas);
     return true;
     return true;
 }
 }
-#endif
+
+const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
+{
+    static ImFontBuilderIO io;
+    io.FontBuilder_Build = ImFontAtlasBuildWithStbTruetype;
+    return &io;
+}
+
+#endif // IMGUI_ENABLE_STB_TRUETYPE
 
 
 void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
 void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
 {
 {

+ 25 - 12
imgui_internal.h

@@ -29,7 +29,8 @@ Index of this file:
 // [SECTION] ImGuiWindowTempData, ImGuiWindow
 // [SECTION] ImGuiWindowTempData, ImGuiWindow
 // [SECTION] Tab bar, Tab item support
 // [SECTION] Tab bar, Tab item support
 // [SECTION] Table support
 // [SECTION] Table support
-// [SECTION] Internal API
+// [SECTION] ImGui internal API
+// [SECTION] ImFontAtlas internal API
 // [SECTION] Test Engine specific hooks (imgui_test_engine)
 // [SECTION] Test Engine specific hooks (imgui_test_engine)
 
 
 */
 */
@@ -83,7 +84,8 @@ Index of this file:
 #error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
 #error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
 #endif
 #endif
 
 
-// Enable stb_truetype by default unless Freetype is enable. User can compile both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE
+// Enable stb_truetype by default unless FreeType is enabled.
+// You can compile with both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE together.
 #ifndef IMGUI_ENABLE_FREETYPE
 #ifndef IMGUI_ENABLE_FREETYPE
 #define IMGUI_ENABLE_STB_TRUETYPE
 #define IMGUI_ENABLE_STB_TRUETYPE
 #endif
 #endif
@@ -2144,7 +2146,7 @@ struct ImGuiTableSettings
 #endif // #ifdef IMGUI_HAS_TABLE
 #endif // #ifdef IMGUI_HAS_TABLE
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-// [SECTION] Internal API
+// [SECTION] ImGui internal API
 // No guarantee of forward compatibility here!
 // No guarantee of forward compatibility here!
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
@@ -2490,15 +2492,26 @@ namespace ImGui
 
 
 } // namespace ImGui
 } // namespace ImGui
 
 
-// ImFontAtlas internals
-IMGUI_API bool              ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
-IMGUI_API void              ImFontAtlasBuildInit(ImFontAtlas* atlas);
-IMGUI_API void              ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
-IMGUI_API void              ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
-IMGUI_API void              ImFontAtlasBuildFinish(ImFontAtlas* atlas);
-IMGUI_API void              ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
-IMGUI_API void              ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
-IMGUI_API void              ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
+
+//-----------------------------------------------------------------------------
+// [SECTION] ImFontAtlas internal API
+//-----------------------------------------------------------------------------
+
+// This structure is likely to evolve as we add support for incremental atlas updates
+struct ImFontBuilderIO
+{
+    bool    (*FontBuilder_Build)(ImFontAtlas* atlas);
+};
+
+// Helper for font builder
+IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
+IMGUI_API void      ImFontAtlasBuildInit(ImFontAtlas* atlas);
+IMGUI_API void      ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
+IMGUI_API void      ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
+IMGUI_API void      ImFontAtlasBuildFinish(ImFontAtlas* atlas);
+IMGUI_API void      ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
+IMGUI_API void      ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
+IMGUI_API void      ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // [SECTION] Test Engine specific hooks (imgui_test_engine)
 // [SECTION] Test Engine specific hooks (imgui_test_engine)

+ 6 - 113
misc/freetype/README.md

@@ -1,131 +1,24 @@
 # imgui_freetype
 # imgui_freetype
 
 
-Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer in Dear ImGui).
+Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer).
 <br>by @vuhdo, @mikesart, @ocornut.
 <br>by @vuhdo, @mikesart, @ocornut.
 
 
 ### Usage
 ### Usage
 
 
 1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`, `vcpkg integrate install`).
 1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`, `vcpkg integrate install`).
-2. Add imgui_freetype.h/cpp alongside your imgui sources.
-3. Include imgui_freetype.h after imgui.h.
-4. Call `ImGuiFreeType::BuildFontAtlas()` *BEFORE* calling `ImFontAtlas::GetTexDataAsRGBA32()` or `ImFontAtlas::Build()` (so normal Build() won't be called):
+2. Add imgui_freetype.h/cpp alongside your project files.
+3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file
 
 
-```cpp
-// See ImGuiFreeType::RasterizationFlags
-unsigned int flags = ImGuiFreeType::NoHinting;
-ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
-io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
-```
-
-### Gamma Correct Blending
+### About Gamma Correct Blending
 
 
 FreeType assumes blending in linear space rather than gamma space.
 FreeType assumes blending in linear space rather than gamma space.
 See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
 See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
 For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
 For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
 The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
 The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
 
 
-### Test code Usage
-```cpp
-#include "misc/freetype/imgui_freetype.h"
-#include "misc/freetype/imgui_freetype.cpp"
-
-// Load various small fonts
-ImGuiIO& io = ImGui::GetIO();
-io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 13.0f);
-io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 13.0f);
-io.Fonts->AddFontDefault();
-
-FreeTypeTest freetype_test;
-
-// Main Loop
-while (true)
-{
-   if (freetype_test.UpdateRebuild())
-   {
-      // REUPLOAD FONT TEXTURE TO GPU
-      ImGui_ImplXXX_DestroyDeviceObjects();
-      ImGui_ImplXXX_CreateDeviceObjects();
-   }
-   ImGui::NewFrame();
-   freetype_test.ShowFreetypeOptionsWindow();
-   ...
-}
-```
-
-### Test code
-```cpp
-#include "misc/freetype/imgui_freetype.h"
-#include "misc/freetype/imgui_freetype.cpp"
-
-struct FreeTypeTest
-{
-    enum FontBuildMode
-    {
-        FontBuildMode_FreeType,
-        FontBuildMode_Stb
-    };
-
-    FontBuildMode BuildMode;
-    bool          WantRebuild;
-    float         FontsMultiply;
-    int           FontsPadding;
-    unsigned int  FontsFlags;
-
-    FreeTypeTest()
-    {
-        BuildMode = FontBuildMode_FreeType;
-        WantRebuild = true;
-        FontsMultiply = 1.0f;
-        FontsPadding = 1;
-        FontsFlags = 0;
-    }
-
-    // Call _BEFORE_ NewFrame()
-    bool UpdateRebuild()
-    {
-        if (!WantRebuild)
-            return false;
-        ImGuiIO& io = ImGui::GetIO();
-        io.Fonts->TexGlyphPadding = FontsPadding;
-        for (int n = 0; n < io.Fonts->ConfigData.Size; n++)
-        {
-            ImFontConfig* font_config = (ImFontConfig*)&io.Fonts->ConfigData[n];
-            font_config->RasterizerMultiply = FontsMultiply;
-            font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
-        }
-        if (BuildMode == FontBuildMode_FreeType)
-            ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
-        else if (BuildMode == FontBuildMode_Stb)
-            io.Fonts->Build();
-        WantRebuild = false;
-        return true;
-    }
+### Testbed for toying with settings (for developers)
 
 
-    // Call to draw interface
-    void ShowFreetypeOptionsWindow()
-    {
-        ImGui::Begin("FreeType Options");
-        ImGui::ShowFontSelector("Fonts");
-        WantRebuild |= ImGui::RadioButton("FreeType", (int*)&BuildMode, FontBuildMode_FreeType);
-        ImGui::SameLine();
-        WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
-        WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
-        WantRebuild |= ImGui::DragInt("Padding", &FontsPadding, 0.1f, 0, 16);
-        if (BuildMode == FontBuildMode_FreeType)
-        {
-            WantRebuild |= ImGui::CheckboxFlags("NoHinting",     &FontsFlags, ImGuiFreeType::NoHinting);
-            WantRebuild |= ImGui::CheckboxFlags("NoAutoHint",    &FontsFlags, ImGuiFreeType::NoAutoHint);
-            WantRebuild |= ImGui::CheckboxFlags("ForceAutoHint", &FontsFlags, ImGuiFreeType::ForceAutoHint);
-            WantRebuild |= ImGui::CheckboxFlags("LightHinting",  &FontsFlags, ImGuiFreeType::LightHinting);
-            WantRebuild |= ImGui::CheckboxFlags("MonoHinting",   &FontsFlags, ImGuiFreeType::MonoHinting);
-            WantRebuild |= ImGui::CheckboxFlags("Bold",          &FontsFlags, ImGuiFreeType::Bold);
-            WantRebuild |= ImGui::CheckboxFlags("Oblique",       &FontsFlags, ImGuiFreeType::Oblique);
-            WantRebuild |= ImGui::CheckboxFlags("Monochrome",    &FontsFlags, ImGuiFreeType::Monochrome);
-        }
-        ImGui::End();
-    }
-};
-```
+See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
 
 
 ### Known issues
 ### Known issues
 - `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).
 - `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).

+ 72 - 52
misc/freetype/imgui_freetype.cpp

@@ -1,25 +1,30 @@
-// dear imgui: wrapper to use FreeType (instead of stb_truetype)
+// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
+// (code)
+
 // Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
 // Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
-// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained and v0.60+ by @ocornut.
-
-// Changelog:
-// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
-// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
-// - v0.52: (2017/09/26) fixes for imgui internal changes.
-// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
-// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
-// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
-// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
-// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
-// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
-// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
-// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
-
-// Gamma Correct Blending:
-//  FreeType assumes blending in linear space rather than gamma space.
-//  See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
-//  For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
-//  The default imgui styles will be impacted by this change (alpha values will need tweaking).
+// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
+
+// CHANGELOG
+// (minor and older changes stripped away, please see git history for details)
+//  2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
+//              renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
+//  2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
+//  2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
+//  2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
+//  2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
+//  2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
+//  2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
+//  2018/01/22: fix for addition of ImFontAtlas::TexUvscale member.
+//  2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement).
+//  2017/09/26: fixes for imgui internal changes.
+//  2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
+//  2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
+
+// About Gamma Correct Blending:
+// - FreeType assumes blending in linear space rather than gamma space.
+// - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
+// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
+// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
 
 
 // FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
 // FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
 
 
@@ -41,6 +46,23 @@
 #pragma GCC diagnostic ignored "-Wunused-function"          // warning: 'xxxx' defined but not used
 #pragma GCC diagnostic ignored "-Wunused-function"          // warning: 'xxxx' defined but not used
 #endif
 #endif
 
 
+//-------------------------------------------------------------------------
+// Data
+//-------------------------------------------------------------------------
+
+// Default memory allocators
+static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
+static void  ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
+
+// Current memory allocators
+static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc;
+static void  (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
+static void* GImGuiFreeTypeAllocatorUserData = NULL;
+
+//-------------------------------------------------------------------------
+// Code
+//-------------------------------------------------------------------------
+
 namespace
 namespace
 {
 {
     // Glyph metrics:
     // Glyph metrics:
@@ -118,7 +140,7 @@ namespace
     // From SDL_ttf: Handy routines for converting from fixed point
     // From SDL_ttf: Handy routines for converting from fixed point
     #define FT_CEIL(X)  (((X + 63) & -64) / 64)
     #define FT_CEIL(X)  (((X + 63) & -64) / 64)
 
 
-    bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
+    bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
     {
     {
         FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
         FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
         if (error != 0)
         if (error != 0)
@@ -131,22 +153,22 @@ namespace
         SetPixelHeight((uint32_t)cfg.SizePixels);
         SetPixelHeight((uint32_t)cfg.SizePixels);
 
 
         // Convert to FreeType flags (NB: Bold and Oblique are processed separately)
         // Convert to FreeType flags (NB: Bold and Oblique are processed separately)
-        UserFlags = cfg.RasterizerFlags | extra_user_flags;
+        UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
         LoadFlags = FT_LOAD_NO_BITMAP;
         LoadFlags = FT_LOAD_NO_BITMAP;
-        if (UserFlags & ImGuiFreeType::NoHinting)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
             LoadFlags |= FT_LOAD_NO_HINTING;
             LoadFlags |= FT_LOAD_NO_HINTING;
-        if (UserFlags & ImGuiFreeType::NoAutoHint)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
             LoadFlags |= FT_LOAD_NO_AUTOHINT;
             LoadFlags |= FT_LOAD_NO_AUTOHINT;
-        if (UserFlags & ImGuiFreeType::ForceAutoHint)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
             LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
             LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
-        if (UserFlags & ImGuiFreeType::LightHinting)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting)
             LoadFlags |= FT_LOAD_TARGET_LIGHT;
             LoadFlags |= FT_LOAD_TARGET_LIGHT;
-        else if (UserFlags & ImGuiFreeType::MonoHinting)
+        else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting)
             LoadFlags |= FT_LOAD_TARGET_MONO;
             LoadFlags |= FT_LOAD_TARGET_MONO;
         else
         else
             LoadFlags |= FT_LOAD_TARGET_NORMAL;
             LoadFlags |= FT_LOAD_TARGET_NORMAL;
 
 
-        if (UserFlags & ImGuiFreeType::Monochrome)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome)
             RenderMode = FT_RENDER_MODE_MONO;
             RenderMode = FT_RENDER_MODE_MONO;
         else
         else
             RenderMode = FT_RENDER_MODE_NORMAL;
             RenderMode = FT_RENDER_MODE_NORMAL;
@@ -200,9 +222,9 @@ namespace
         IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
         IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
 
 
         // Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
         // Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
-        if (UserFlags & ImGuiFreeType::Bold)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
             FT_GlyphSlot_Embolden(slot);
             FT_GlyphSlot_Embolden(slot);
-        if (UserFlags & ImGuiFreeType::Oblique)
+        if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique)
         {
         {
             FT_GlyphSlot_Oblique(slot);
             FT_GlyphSlot_Oblique(slot);
             //FT_BBox bbox;
             //FT_BBox bbox;
@@ -320,7 +342,7 @@ struct ImFontBuildDstDataFT
     ImBitVector         GlyphsSet;          // This is used to resolve collision when multiple sources are merged into a same destination font.
     ImBitVector         GlyphsSet;          // This is used to resolve collision when multiple sources are merged into a same destination font.
 };
 };
 
 
-bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
+bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
 {
 {
     IM_ASSERT(atlas->ConfigData.Size > 0);
     IM_ASSERT(atlas->ConfigData.Size > 0);
 
 
@@ -605,50 +627,41 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
     return true;
     return true;
 }
 }
 
 
-// Default memory allocators
-static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data)   { IM_UNUSED(user_data); return IM_ALLOC(size); }
-static void  ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data)      { IM_UNUSED(user_data); IM_FREE(ptr); }
-
-// Current memory allocators
-static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
-static void  (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
-static void* GImFreeTypeAllocatorUserData = NULL;
-
 // FreeType memory allocation callbacks
 // FreeType memory allocation callbacks
 static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
 static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
 {
 {
-    return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
+    return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData);
 }
 }
 
 
 static void FreeType_Free(FT_Memory /*memory*/, void* block)
 static void FreeType_Free(FT_Memory /*memory*/, void* block)
 {
 {
-    GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
+    GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
 }
 }
 
 
 static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
 static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
 {
 {
     // Implement realloc() as we don't ask user to provide it.
     // Implement realloc() as we don't ask user to provide it.
     if (block == NULL)
     if (block == NULL)
-        return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
+        return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
 
 
     if (new_size == 0)
     if (new_size == 0)
     {
     {
-        GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
+        GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
         return NULL;
         return NULL;
     }
     }
 
 
     if (new_size > cur_size)
     if (new_size > cur_size)
     {
     {
-        void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
+        void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
         memcpy(new_block, block, (size_t)cur_size);
         memcpy(new_block, block, (size_t)cur_size);
-        GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
+        GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
         return new_block;
         return new_block;
     }
     }
 
 
     return block;
     return block;
 }
 }
 
 
-bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
+static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
 {
 {
     // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
     // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
     FT_MemoryRec_ memory_rec = {};
     FT_MemoryRec_ memory_rec = {};
@@ -666,15 +679,22 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
     // If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
     // If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
     FT_Add_Default_Modules(ft_library);
     FT_Add_Default_Modules(ft_library);
 
 
-    bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
+    bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
     FT_Done_Library(ft_library);
     FT_Done_Library(ft_library);
 
 
     return ret;
     return ret;
 }
 }
 
 
+const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType()
+{
+    static ImFontBuilderIO io;
+    io.FontBuilder_Build = ImFontAtlasBuildWithFreeType;
+    return &io;
+}
+
 void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
 void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
 {
 {
-    GImFreeTypeAllocFunc = alloc_func;
-    GImFreeTypeFreeFunc = free_func;
-    GImFreeTypeAllocatorUserData = user_data;
+    GImGuiFreeTypeAllocFunc = alloc_func;
+    GImGuiFreeTypeFreeFunc = free_func;
+    GImGuiFreeTypeAllocatorUserData = user_data;
 }
 }

+ 34 - 28
misc/freetype/imgui_freetype.h

@@ -1,36 +1,42 @@
-// dear imgui: wrapper to use FreeType (instead of stb_truetype)
-// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
-// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
+// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
+// (headers)
 
 
 #pragma once
 #pragma once
 
 
-#include "imgui.h"      // IMGUI_API, ImFontAtlas
+#include "imgui.h"      // IMGUI_API
 
 
-namespace ImGuiFreeType
-{
-    // Hinting greatly impacts visuals (and glyph sizes).
-    // When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
-    // The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
-    // The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
+// Forward declarations
+struct ImFontAtlas;
+struct ImFontBuilderIO;
 
 
-    // You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
-    // Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
-    enum RasterizerFlags
-    {
-        // By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
-        NoHinting       = 1 << 0,   // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
-        NoAutoHint      = 1 << 1,   // Disable auto-hinter.
-        ForceAutoHint   = 1 << 2,   // Indicates that the auto-hinter is preferred over the font's native hinter.
-        LightHinting    = 1 << 3,   // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
-        MonoHinting     = 1 << 4,   // Strong hinting algorithm that should only be used for monochrome output.
-        Bold            = 1 << 5,   // Styling: Should we artificially embolden the font?
-        Oblique         = 1 << 6,   // Styling: Should we slant the font, emulating italic style?
-        Monochrome      = 1 << 7    // Disable anti-aliasing. Combine this with MonoHinting for best results!
-    };
+// Hinting greatly impacts visuals (and glyph sizes).
+// - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
+// - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h
+// - The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
+// - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
+// You can set those flags globaly in ImFontAtlas::FontBuilderFlags
+// You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags
+enum ImGuiFreeTypeBuilderFlags
+{
+    ImGuiFreeTypeBuilderFlags_NoHinting     = 1 << 0,   // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
+    ImGuiFreeTypeBuilderFlags_NoAutoHint    = 1 << 1,   // Disable auto-hinter.
+    ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2,   // Indicates that the auto-hinter is preferred over the font's native hinter.
+    ImGuiFreeTypeBuilderFlags_LightHinting  = 1 << 3,   // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
+    ImGuiFreeTypeBuilderFlags_MonoHinting   = 1 << 4,   // Strong hinting algorithm that should only be used for monochrome output.
+    ImGuiFreeTypeBuilderFlags_Bold          = 1 << 5,   // Styling: Should we artificially embolden the font?
+    ImGuiFreeTypeBuilderFlags_Oblique       = 1 << 6,   // Styling: Should we slant the font, emulating italic style?
+    ImGuiFreeTypeBuilderFlags_Monochrome    = 1 << 7    // Disable anti-aliasing. Combine this with MonoHinting for best results!
+};
 
 
-    IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
+namespace ImGuiFreeType
+{
+    // This is automatically assigned when using '#define IMGUI_ENABLE_FREETYPE'.
+    // If you need to dynamically select between multiple builders:
+    // - you can manually assign this builder with 'atlas->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()'
+    // - prefer deep-copying this into your own ImFontBuilderIO instance if you use hot-reloading that messes up static data.
+    IMGUI_API const ImFontBuilderIO*    GetBuilderForFreeType();
 
 
-    // By default ImGuiFreeType will use IM_ALLOC()/IM_FREE().
-    // However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired:
-    IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
+    // Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE()
+    // However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired.
+    IMGUI_API void                      SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
 }
 }