How to Handle Non-Latin Text Input (Chinese, Japanese, Korean, Cyrillic) in ImGui
To display Chinese, Japanese, Korean, Cyrillic, and other non-Latin scripts in Dear ImGui, load a Unicode font containing the required glyphs and specify the appropriate Unicode ranges via ImFontConfig::GlyphRanges before building the font atlas.
Dear ImGui (ocornut/imgui) ships with a complete Unicode font system capable of rendering virtually any script, from CJK (Chinese, Japanese, Korean) to Cyrillic, Greek, Thai, and Vietnamese. Handling non-Latin text input in ImGui requires configuring the ImFontAtlas to rasterize only the specific character ranges you need, ensuring efficient memory usage while supporting multilingual user interfaces.
Loading Fonts with Unicode Coverage
ImGui does not bundle fonts for non-Latin scripts. You must provide TrueType or OpenType files that contain the necessary glyphs, then instruct the atlas which Unicode blocks to load.
Choosing Compatible Font Files
Select fonts that explicitly include the target scripts:
- Noto Sans CJK – covers Chinese, Japanese, and Korean characters
- Noto Sans Cyrillic – supports Russian and Slavic languages
- GNU Unifont – contains glyphs for most Unicode blocks (large file size)
Place these files in your application directory or embed them as C headers using misc/fonts/binary_to_compressed_c.cpp for faster startup.
Using Built-in Glyph Range Helpers
The ImFontAtlas class declared in imgui.h provides helper methods that return const ImWchar* arrays defining common Unicode ranges. These are located around lines 3752–3765 in imgui.h:
GetGlyphRangesDefault()– Basic Latin + Extended LatinGetGlyphRangesCyrillic()– ~400 Cyrillic charactersGetGlyphRangesKorean()– Korean Hangul syllablesGetGlyphRangesJapanese()– Hiragana, Katakana, and 2,999 common KanjiGetGlyphRangesChineseFull()– Complete set of ~21,000 CJK Unified IdeographsGetGlyphRangesChineseSimplifiedCommon()– 2,500 most frequent simplified Chinese characters
Configuring Glyph Ranges for CJK and Cyrillic
Pass the glyph range pointer to ImFontConfig::GlyphRanges when calling AddFontFromFileTTF().
Loading a Full CJK Font
ImGuiIO& io = ImGui::GetIO();
ImFontAtlas* atlas = io.Fonts;
ImFontConfig cfg;
cfg.OversampleH = cfg.OversampleV = 2; // Improve rasterization quality
cfg.GlyphRanges = atlas->GetGlyphRangesChineseFull(); // Load full CJK set
ImFont* font = atlas->AddFontFromFileTTF(
"fonts/NotoSansCJK-Regular.otf",
18.0f,
&cfg,
atlas->GetGlyphRangesChineseFull());
io.FontDefault = font; // Set as default for all UI elements
Combining Multiple Scripts
Load separate fonts for different scripts. ImGui automatically falls back to the first font containing the requested glyph:
// Primary Latin font
ImFont* latin = atlas->AddFontFromFileTTF(
"fonts/Roboto-Regular.ttf",
16.0f,
nullptr,
atlas->GetGlyphRangesDefault());
// Cyrillic fallback
ImFont* cyrillic = atlas->AddFontFromFileTTF(
"fonts/NotoSansCyrillic-Regular.ttf",
16.0f,
nullptr,
atlas->GetGlyphRangesCyrillic());
// Korean fallback
ImFont* korean = atlas->AddFontFromFileTTF(
"fonts/NotoSansKR-Regular.otf",
16.0f,
nullptr,
atlas->GetGlyphRangesKorean());
atlas->Build();
Building Custom Glyph Ranges
When loading the full CJK set (~21,000 glyphs), the atlas can exceed 10 MiB. For production applications, use ImFontGlyphRangesBuilder (defined in imgui_internal.h) to create sparse ranges containing only characters used in your UI.
ImFontGlyphRangesBuilder builder;
builder.AddText(u8"你好,世界"); // Add only needed Chinese characters
builder.AddText(u8"Привет"); // Add specific Cyrillic text
ImVector<ImWchar> customRanges;
builder.BuildRanges(&customRanges); // Output compact range array
ImFont* font = atlas->AddFontFromFileTTF(
"fonts/NotoSans-Regular.ttf",
18.0f,
nullptr,
customRanges.Data);
Handling Text Input and IME
ImGui::InputText() accepts UTF-8 encoded strings. As long as the font atlas contains the corresponding glyphs, the text renders correctly without additional rendering code.
IME Support
Input Method Editors (IME) for Chinese, Japanese, and Korean work automatically on Windows, macOS, and Linux. The platform backends (imgui_impl_win32.cpp, imgui_impl_glfw.cpp, etc.) forward Unicode character events to ImGui's input queue. No special handling is required unless you need to filter specific character ranges.
Filtering Character Input
To restrict input to specific scripts (e.g., allow only CJK while blocking Latin), use the ImGuiInputTextFlags_CallbackCharFilter flag and inspect the UTF-32 code point in your callback function.
Performance Optimization with FreeType
For high-quality rendering of complex CJK glyphs or to reduce memory footprint with large fonts, enable the optional FreeType rasterizer located in misc/freetype/imgui_freetype.cpp.
- Define
IMGUI_ENABLE_FREETYPEin your build configuration - Link
misc/freetype/imgui_freetype.cpp - FreeType renders glyphs on demand at higher quality, especially beneficial for small font sizes
The FreeType backend supports dynamic glyph loading, making it ideal for applications that need access to full Unicode ranges without pre-rasterizing the entire atlas.
Summary
- Load Unicode fonts using
ImFontAtlas::AddFontFromFileTTF()with paths to fonts containing CJK or Cyrillic glyphs - Specify ranges via
ImFontConfig::GlyphRangesusing built-in helpers likeGetGlyphRangesChineseFull()orGetGlyphRangesCyrillic() - Optimize memory by building custom ranges with
ImFontGlyphRangesBuilderwhen full CJK coverage is unnecessary - Input handling works automatically with UTF-8; backends in
imgui_impl_*.cppfiles manage IME composition - Improve quality by enabling the FreeType backend in
misc/freetype/imgui_freetype.cppfor complex scripts
Frequently Asked Questions
Why do I see question marks or boxes instead of Chinese characters?
Question marks indicate the font atlas does not contain the requested glyphs. Ensure you loaded a font file that includes CJK characters (such as Noto Sans CJK) and specified the correct GlyphRanges (e.g., GetGlyphRangesChineseFull() or GetGlyphRangesChineseSimplifiedCommon()) when calling AddFontFromFileTTF().
Can I mix different fonts for Latin and CJK text in the same UI?
Yes. Load multiple fonts with different glyph ranges using separate AddFontFromFileTTF() calls. ImGui automatically selects the first font containing the required glyph when you call ImGui::Text() or ImGui::InputText(). The default font set via io.FontDefault handles text not present in fallback fonts.
How do I reduce the memory usage of CJK fonts?
Instead of loading the full CJK range (~21,000 glyphs), use ImFontGlyphRangesBuilder to create a custom range containing only the characters that appear in your application. Alternatively, enable the FreeType backend (misc/freetype/imgui_freetype.cpp) which rasterizes glyphs on demand rather than pre-building the entire atlas.
Does ImGui support right-to-left (RTL) text like Arabic or Hebrew?
Dear ImGui does not natively support RTL text shaping or bidirectional algorithms. While you can load Arabic or Hebrew fonts and display individual characters, proper text rendering requires external libraries such as HarfBuzz or FriBidi to handle glyph shaping and reordering before passing the final string to ImGui.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →