This document describes the optional FreeType font rasterizer integration in Dear ImGui. FreeType can be used as an alternative to the default STB TrueType backend to provide higher quality font rendering, advanced hinting options, and support for OpenType SVG fonts.
Related pages:
ImFontAtlas class, see Font Atlas and ManagementThe FreeType integration provides an optional font loader backend that replaces the default STB TrueType rasterizer. FreeType offers:
FreeType is not included in Dear ImGui by default. It requires external dependencies and manual integration.
Sources: misc/freetype/imgui_freetype.h1-16 misc/freetype/README.md1-11
The FreeType integration implements the ImFontLoader interface introduced in Dear ImGui 1.92. This interface abstracts font rasterization backends, allowing runtime or compile-time selection between STB TrueType and FreeType.
Sources: misc/freetype/imgui_freetype.cpp343-390 misc/freetype/imgui_freetype.h63-67 misc/freetype/imgui_freetype.cpp570-584 misc/freetype/imgui_freetype.cpp145-173
There are two methods to enable FreeType support:
Define IMGUI_ENABLE_FREETYPE in imconfig.h. This automatically sets FreeType as the default font loader at initialization.
When this define is set, ImFontAtlas will automatically use the FreeType loader without requiring manual setup.
Sources: imconfig.h85-89 misc/freetype/imgui_freetype.h8-11
Manually set the font loader at runtime:
This method is useful when you need to dynamically switch between loaders or when Dear ImGui is precompiled without IMGUI_ENABLE_FREETYPE.
Build Requirements:
misc/freetype/imgui_freetype.cpp must be compiled with your projectSources: misc/freetype/README.md6-10 misc/freetype/imgui_freetype.h63-67
FreeType behavior is controlled through ImGuiFreeTypeLoaderFlags, which can be set globally or per-font.
| Scope | Where to Set | Priority |
|---|---|---|
| Global (Atlas) | ImFontAtlas::FontLoaderFlags | Applied to all fonts as base flags |
| Per-Font (Source) | ImFontConfig::FontLoaderFlags | Per-font override, combined with global flags |
Flags are combined via bitwise OR in ImGui_ImplFreeType_FontSrcData::InitFont() at line 185: UserFlags = (ImGuiFreeTypeLoaderFlags)(src->FontLoaderFlags | extra_font_loader_flags).
Sources: misc/freetype/imgui_freetype.h26-28 misc/freetype/imgui_freetype.cpp185
</old_str> <new_str>
Flag Definitions:
| Flag | FreeType Equivalent | Description |
|---|---|---|
ImGuiFreeTypeLoaderFlags_NoHinting | FT_LOAD_NO_HINTING | Disables hinting, producing blurrier but more accurate glyphs |
ImGuiFreeTypeLoaderFlags_NoAutoHint | FT_LOAD_NO_AUTOHINT | Disables FreeType's auto-hinter |
ImGuiFreeTypeLoaderFlags_ForceAutoHint | FT_LOAD_FORCE_AUTOHINT | Uses auto-hinter instead of native hinter |
ImGuiFreeTypeLoaderFlags_LightHinting | FT_LOAD_TARGET_LIGHT | Lighter hinting (similar to ClearType) |
ImGuiFreeTypeLoaderFlags_MonoHinting | FT_LOAD_TARGET_MONO | Strong hinting for monochrome output |
ImGuiFreeTypeLoaderFlags_Bold | FT_GlyphSlot_Embolden() | Artificially emboldens glyphs (not true bold font) |
ImGuiFreeTypeLoaderFlags_Oblique | FT_GlyphSlot_Oblique() | Artificially slants glyphs (not true italic font) |
ImGuiFreeTypeLoaderFlags_Monochrome | FT_RENDER_MODE_MONO | Disables anti-aliasing, uses 1-bit rendering |
ImGuiFreeTypeLoaderFlags_LoadColor | FT_LOAD_COLOR | Enables color-layered glyphs (requires FreeType 2.10+) |
ImGuiFreeTypeLoaderFlags_Bitmap | N/A | Enables loading bitmap glyphs from fonts |
Recommended Combinations:
NoHintingLightHintingMonoHinting | MonochromeLoadColorSources: misc/freetype/imgui_freetype.h29-54 misc/freetype/imgui_freetype.cpp175-206 misc/freetype/imgui_freetype.cpp245-254 misc/freetype/imgui_freetype.cpp508
FreeType provides a helper function to edit flags at runtime via ImGuiFreeType::DebugEditFontLoaderFlags():
This function uses ImGui::CheckboxFlags() to toggle individual flag bits. Implementation creates checkboxes for all 10 loader flags.
Sources: misc/freetype/imgui_freetype.cpp593-607 misc/freetype/imgui_freetype.h74
FreeType 2.12+ supports OpenType SVG fonts (SVGinOT) when combined with an SVG rendering library. Dear ImGui supports two options: lunasvg and plutosvg.
| Feature | lunasvg | plutosvg |
|---|---|---|
| Define | IMGUI_ENABLE_FREETYPE_LUNASVG | IMGUI_ENABLE_FREETYPE_PLUTOSVG |
| Font Support | Most SVG fonts | More fonts (e.g., NotoColorEmoji) |
| Performance | Good | Better (faster loading) |
| Dependencies | lunasvg 2.3.2+ | plutosvg + plutovg |
| vcpkg | vcpkg install lunasvg | vcpkg install plutosvg |
| Recommended | Good default | Better compatibility/speed |
Important: Only one SVG backend can be enabled at a time. Attempting to enable both will result in a compile error.
Sources: misc/freetype/imgui_freetype.cpp52-68 misc/freetype/README.md39-54 imconfig.h91-97
Sources: misc/freetype/imgui_freetype.cpp365-371 misc/freetype/imgui_freetype.cpp619-730 misc/freetype/imgui_freetype.cpp612-617 misc/freetype/imgui_freetype.cpp630-648
The lunasvg integration uses FreeType's SVG rendering hooks, which are callback functions invoked during glyph loading:
LunasvgPortState to store SVG document and transformation matrixFT_SVG_DocumentLunasvgPortStateSources: misc/freetype/imgui_freetype.cpp99-104 misc/freetype/imgui_freetype.cpp615-620
The plutosvg backend is simpler to integrate as it provides pre-built hooks:
This leverages plutosvg's built-in FreeType integration, reducing code complexity.
Sources: misc/freetype/imgui_freetype.cpp372-375
The FreeType loader maintains three levels of data structures corresponding to the font system hierarchy:
Sources: misc/freetype/imgui_freetype.cpp145-173 misc/freetype/imgui_freetype.cpp343-381 misc/freetype/imgui_freetype.cpp392-407 misc/freetype/imgui_freetype.cpp417-462
Stored in ImFontAtlas::FontLoaderData. One instance per atlas. Defined at lines 145-150.
| Member | Type | Purpose |
|---|---|---|
Library | FT_Library | FreeType library instance, initialized via FT_New_Library() |
MemoryManager | FT_MemoryRec_ | Custom memory allocator callbacks (alloc, free, realloc) |
Lifecycle:
ImGui_ImplFreeType_LoaderInit() at line 343, calls FT_New_Library(&bd->MemoryManager, &bd->Library) at line 355ImGui_ImplFreeType_LoaderShutdown() at line 383, calls FT_Done_Library(bd->Library) at line 387Sources: misc/freetype/imgui_freetype.cpp145-150 misc/freetype/imgui_freetype.cpp343-381 misc/freetype/imgui_freetype.cpp383-390
Stored in ImFontConfig::FontLoaderData. One instance per font source. Defined at lines 153-166.
| Member | Type | Purpose |
|---|---|---|
FtFace | FT_Face | FreeType font face (parsed font file), created via FT_New_Memory_Face() |
UserFlags | ImGuiFreeTypeLoaderFlags | Combined loader flags (global + per-font), set at line 185 |
LoadFlags | FT_Int32 | Converted FreeType load flags (e.g., FT_LOAD_NO_HINTING), computed at lines 187-204 |
BakedLastActivated | ImFontBaked* | Cache for last activated size to minimize FT_Activate_Size() calls |
Lifecycle:
ImGui_ImplFreeType_FontSrcInit() at line 392, calls InitFont() which calls FT_New_Memory_Face() at line 177ImGui_ImplFreeType_FontSrcDestroy() at line 409, calls CloseFont() which calls FT_Done_Face() at line 213Sources: misc/freetype/imgui_freetype.cpp153-166 misc/freetype/imgui_freetype.cpp175-216 misc/freetype/imgui_freetype.cpp392-415
Stored in ImFontBaked::FontLoaderDatas[i] (array allocated by core). One instance per (font source × baked size) combination. Defined at lines 169-173.
| Member | Type | Purpose |
|---|---|---|
FtSize | FT_Size | FreeType size object (face configured for specific pixel height via FT_New_Size()) |
Note: FT_Size represents a FT_Face configured for a specific pixel size. Multiple FT_Size objects can exist for the same FT_Face, allowing efficient multi-size rendering. Each FT_Size must be activated via FT_Activate_Size() before loading glyphs (line 434, 486).
Lifecycle:
ImGui_ImplFreeType_FontBakedInit() at line 417, calls FT_New_Size() at line 433 and FT_Activate_Size() at line 434FT_Request_Size() at line 447 to set pixel heightImGui_ImplFreeType_FontBakedDestroy() at line 464, calls FT_Done_Size() at line 471Sources: misc/freetype/imgui_freetype.cpp169-173 misc/freetype/imgui_freetype.cpp417-473
The FreeType loader implements the ImFontLoader interface, which defines a callback-based lifecycle for font loading:
Sources: misc/freetype/imgui_freetype.cpp343-390 misc/freetype/imgui_freetype.cpp392-415 misc/freetype/imgui_freetype.cpp417-473 misc/freetype/imgui_freetype.cpp475-560
The FontBakedLoadGlyph() function performs the actual glyph rasterization:
Key Details:
Glyph Index Lookup: FreeType uses glyph indices internally, not Unicode codepoints directly. FT_Get_Char_Index() performs this mapping.
Size Activation: FreeType requires activating the correct FT_Size before loading glyphs. The loader caches the last activated size to minimize calls.
Metrics-Only Mode: If out_advance_x != NULL but out_glyph == NULL, only metrics are computed without rasterizing the glyph. This is used during pre-calculation passes.
Bitmap Formats: ImGui_ImplFreeType_BlitGlyph() handles three FreeType bitmap formats:
FT_PIXEL_MODE_GRAY: 8-bit grayscaleFT_PIXEL_MODE_MONO: 1-bit monochromeFT_PIXEL_MODE_BGRA: 32-bit BGRA (for color glyphs)Coordinate Systems: FreeType uses 26.6 fixed-point units (1/64th of a pixel). The loader converts these to float pixels using FT_SCALEFACTOR (64.0).
Sources: misc/freetype/imgui_freetype.cpp474-563 misc/freetype/imgui_freetype.cpp218-257 misc/freetype/imgui_freetype.cpp259-307
The FreeType loader supports custom memory allocators, which is useful for isolating FreeType's memory usage from Dear ImGui's main heap.
Function signature at line 586-591:
This sets global function pointers: GImGuiFreeTypeAllocFunc, GImGuiFreeTypeFreeFunc, and GImGuiFreeTypeAllocatorUserData (lines 94-96).
When to Use:
Important: Must be called before creating the ImFontAtlas or calling LoaderInit(), as the memory manager is initialized in ImGui_ImplFreeType_LoaderInit() at lines 349-352.
Sources: misc/freetype/imgui_freetype.cpp586-591 misc/freetype/imgui_freetype.cpp94-96 misc/freetype/imgui_freetype.cpp349-352 misc/freetype/imgui_freetype.h69-71
Default Behavior: If SetAllocatorFunctions() is not called, global pointers default to ImGuiFreeTypeDefaultAllocFunc and ImGuiFreeTypeDefaultFreeFunc (lines 94-95), which use IM_ALLOC() and IM_FREE() (lines 90-91).
Sources: misc/freetype/imgui_freetype.cpp90-96 misc/freetype/imgui_freetype.cpp310-341 misc/freetype/imgui_freetype.cpp349-352 misc/freetype/imgui_freetype.cpp586-591
FreeType assumes linear color space blending, not gamma space. This affects how anti-aliased glyphs blend with the background.
When rendering anti-aliased glyphs, FreeType generates alpha values assuming linear blending. If your renderer uses gamma-space blending (most do by default), text will appear too dark or too light.
To achieve correct results:
Enable sRGB framebuffer (if available):
GL_FRAMEBUFFER_SRGBVK_FORMAT_*_SRGB swapchain formatDXGI_FORMAT_*_SRGB render targetConvert to linear in pixel shader:
Adjust style alpha values: The default Dear ImGui styles may need tweaking when gamma-correct blending is enabled.
Note: The STB TrueType backend does not have this issue because it generates alpha values assuming gamma-space blending.
Sources: misc/freetype/imgui_freetype.cpp32-36 misc/freetype/README.md12-17
The FreeType loader implements all callbacks defined by the ImFontLoader interface:
| Callback | FreeType Implementation | Purpose |
|---|---|---|
LoaderInit | ImGui_ImplFreeType_LoaderInit() | Creates FT_Library and sets up SVG hooks |
LoaderShutdown | ImGui_ImplFreeType_LoaderShutdown() | Destroys FT_Library |
FontSrcInit | ImGui_ImplFreeType_FontSrcInit() | Creates FT_Face from font data |
FontSrcDestroy | ImGui_ImplFreeType_FontSrcDestroy() | Destroys FT_Face |
FontSrcContainsGlyph | ImGui_ImplFreetype_FontSrcContainsGlyph() | Checks if glyph exists via FT_Get_Char_Index() |
FontBakedInit | ImGui_ImplFreeType_FontBakedInit() | Creates FT_Size for specific pixel height |
FontBakedDestroy | ImGui_ImplFreeType_FontBakedDestroy() | Destroys FT_Size |
FontBakedLoadGlyph | ImGui_ImplFreeType_FontBakedLoadGlyph() | Loads and rasterizes single glyph |
Implementation at lines 570-584:
The FontBakedSrcLoaderDataSize field tells the core how much space to allocate in ImFontBaked::FontLoaderDatas[i] for each source's baked data (8 bytes on 64-bit systems for the FT_Size pointer).
Note: The loader is statically allocated and reused across calls. If you use hot-reloading that invalidates static data, consider deep-copying the loader as suggested in the header comment at line 66.
Sources: misc/freetype/imgui_freetype.cpp570-584 misc/freetype/imgui_freetype.h66 misc/freetype/imgui_freetype.cpp582
Sources: misc/freetype/README.md6-11 misc/freetype/imgui_freetype.h8-16
Oversampling Ignored: ImFontConfig::OversampleH and OversampleV are not used by FreeType. The high-quality hinting typically makes oversampling unnecessary.
FreeType 2.11.0 Bug: Some bitmap/colored fonts crash with FreeType 2.11.0. Use FreeType 2.10.x, 2.11.x (patched, e.g., vcpkg), or 2.12+.
SVG Requires FreeType 2.12+: OpenType SVG font support requires FreeType 2.12.0 or newer.
Mutually Exclusive SVG Backends: Only one of IMGUI_ENABLE_FREETYPE_LUNASVG or IMGUI_ENABLE_FREETYPE_PLUTOSVG can be defined.
Static Loader: The ImFontLoader returned by GetFontLoader() is statically allocated. If you use hot-reloading, deep-copy the loader.
Sources: misc/freetype/imgui_freetype.cpp38 misc/freetype/imgui_freetype.cpp224-228 misc/freetype/imgui_freetype.cpp52-68
misc/freetype/
├── imgui_freetype.h # Public API, flags, function declarations
├── imgui_freetype.cpp # Implementation, loader interface, SVG hooks
└── README.md # Usage instructions, comparison images
imconfig.h # Enable with IMGUI_ENABLE_FREETYPE
Refresh this wiki