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 Latin
  • GetGlyphRangesCyrillic() – ~400 Cyrillic characters
  • GetGlyphRangesKorean() – Korean Hangul syllables
  • GetGlyphRangesJapanese() – Hiragana, Katakana, and 2,999 common Kanji
  • GetGlyphRangesChineseFull() – Complete set of ~21,000 CJK Unified Ideographs
  • GetGlyphRangesChineseSimplifiedCommon() – 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.

  1. Define IMGUI_ENABLE_FREETYPE in your build configuration
  2. Link misc/freetype/imgui_freetype.cpp
  3. 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::GlyphRanges using built-in helpers like GetGlyphRangesChineseFull() or GetGlyphRangesCyrillic()
  • Optimize memory by building custom ranges with ImFontGlyphRangesBuilder when full CJK coverage is unnecessary
  • Input handling works automatically with UTF-8; backends in imgui_impl_*.cpp files manage IME composition
  • Improve quality by enabling the FreeType backend in misc/freetype/imgui_freetype.cpp for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →