Skip to content

Demo, Examples/AppleMetal: add opt-in i18n runtime language switching with Simplified Chinese (zh_CN)#9438

Open
xuk3r wants to merge 12 commits into
ocornut:masterfrom
xuk3r:feat/i18n-zh-cn
Open

Demo, Examples/AppleMetal: add opt-in i18n runtime language switching with Simplified Chinese (zh_CN)#9438
xuk3r wants to merge 12 commits into
ocornut:masterfrom
xuk3r:feat/i18n-zh-cn

Conversation

@xuk3r

@xuk3r xuk3r commented Jun 10, 2026

Copy link
Copy Markdown

Adds a lightweight opt-in internationalization system for imgui_demo.cpp, with a
first translation for Simplified Chinese (zh_CN).
snapshot

Design

Fully opt-in via build flag. Define IMGUI_DEMO_ENABLE_I18N to activate. Without
it, Tr(s) expands to (s) at compile time — zero overhead, no extra dependencies,
all existing examples build unchanged.

New directory: misc/i18n/ (alongside existing optional modules misc/cpp/,
misc/fonts/, misc/freetype/)

File Role
misc/i18n/imgui_i18n.h Tr() macro; no-op stub when IMGUI_DEMO_ENABLE_I18N is
not defined
misc/i18n/imgui_i18n.cpp Lookup table (Meyers Singleton to avoid SIOF); missing
keys fall back to the English key
misc/i18n/locale/zh_CN.cpp Simplified Chinese translation table, auto-registered
before main() via static initializer
misc/i18n/tools/extract_strings.py Helper to extract translatable strings from a
line range of imgui_demo.cpp
misc/i18n/README.md Integration guide, how to add a new language, translation
guidelines

imgui_demo.cpp: all user-visible string literals wrapped with Tr(). Language
menu added to DemoWindowMenuBar(), guarded by #ifdef IMGUI_DEMO_ENABLE_I18N.
Strings intentionally kept in English per localization standards: "Hello, world!"
(universally recognized programming example), API function names, C++ type labels
("float"), intentional filler ("blah blah blah").

example_apple_metal (macOS only): RebuildFonts() loads CJK glyphs on language
switch. In English mode only 2 glyphs (中文, U+4E2D U+6587) are loaded for the
Language menu label; in zh_CN mode the full GetGlyphRangesChineseSimplifiedCommon()
range is used. Requires passing explicit SizePixels to AddFontDefault() to avoid
the ImplicitRefSize assertion introduced in v1.92 when using MergeMode. iOS target
does not enable i18n (macOS system font paths do not apply on device).

Adding a new language

  1. Copy misc/i18n/locale/zh_CN.cppmisc/i18n/locale/<locale_id>.cpp and fill in
    translations
  2. Add the new file to your build alongside misc/i18n/imgui_i18n.cpp
  3. Add a MenuItem in the Language menu in DemoWindowMenuBar() (search
    BeginMenu(Tr("Language")))
  4. For non-Latin scripts, extend RebuildFonts() in your platform main file with the
    appropriate font and glyph ranges

See misc/i18n/README.md for full details and translation guidelines.

Testing

  • example_apple_metal macOS (Makefile + Xcode): builds and runs with i18n enabled;
    language switch works at runtime ✓
  • example_apple_metal iOS Simulator (Xcode): builds cleanly without i18n ✓
  • example_null, example_glfw_opengl3, example_glfw_metal, example_glfw_opengl2,
    example_apple_opengl2, example_glut_opengl2: all build cleanly without any changes

xuk added 10 commits June 8, 2026 11:22
- Add i18n/ module: imgui_i18n.h (Tr() macro + stub when disabled),
  imgui_i18n.cpp (lookup table, Meyers singleton, placeholder substitution),
  locale/zh_CN.cpp (Simplified Chinese translation table),
  tools/extract_strings.py (helper to extract translatable strings)
- Opt-in via IMGUI_DEMO_ENABLE_I18N build flag; without it Tr(s) expands
  to (s) at compile time with zero overhead and no extra dependencies
- See i18n/README.md for integration guide and how to add a new language
… example

- imgui_demo.cpp: wrap all user-visible string literals with Tr(); add
  Language menu in DemoWindowMenuBar (guarded by IMGUI_DEMO_ENABLE_I18N);
  guard extern g_need_font_rebuild with IMGUI_DEMO_ENABLE_I18N + __APPLE__
- examples/example_apple_metal/main.mm: CJK font loading via RebuildFonts()
  (always loads 2-glyph stub in English, full range in zh_CN); Language menu
  triggers font atlas rebuild before next NewFrame(); wrap demo window strings
  with Tr(); fix v1.92 ImplicitRefSize assertion by passing explicit SizePixels
  to AddFontDefault()
- examples/example_apple_metal/Makefile: add i18n sources and
  -DIMGUI_DEMO_ENABLE_I18N flag
…BLE_I18N

Add imgui_i18n.cpp and locale/zh_CN.cpp to both iOS and macOS targets.
Set IMGUI_DEMO_ENABLE_I18N=1 in GCC_PREPROCESSOR_DEFINITIONS for all
four build configurations (iOS/macOS × Debug/Release).
…get opt-out

- Wrap RebuildFonts(), g_need_font_rebuild, and font rebuild calls in
  #ifdef IMGUI_DEMO_ENABLE_I18N so main.mm compiles cleanly without i18n
- Include imgui_i18n.h unconditionally (provides no-op Tr() stub when
  IMGUI_DEMO_ENABLE_I18N is not defined, enabling Tr() in the demo window)
- Remove IMGUI_DEMO_ENABLE_I18N and i18n sources from iOS Xcode target
  (untested on iOS; macOS-only system font paths would not work on device)
- Do not translate 'Hello, world!' (universally recognized programming example)
- Do not translate 'This is some useful text.' (standard example boilerplate)
- Do not translate 'float' / 'counter = %d' (C++ type/variable labels)
- Keep 'blah blah blah' as-is (intentional nonsense filler, not real content)
- Keep 'dear imgui' brand name untranslated in greeting message
- Fix 'Another bullet point' -> 正确翻译为项目符号而非叶节点
- Fix 'Metrics/Debugger' -> 指标/调试器 (Metrics = indicators, not performance)
- Remove redundant identity entries for API function names (IsItemXxx etc.)
Document what to translate and what not to translate, with examples
and quality rules (accuracy, format specifiers, redundant entries).
…nvention

misc/ already hosts optional supplemental modules (cpp/imgui_stdlib,
freetype/, fonts/). i18n fits the same pattern: opt-in, not part of
the core library. Update all include paths, Makefile, Xcode project
and README accordingly.
Wrap all BulletText() calls in ShowUserGuide() with Tr() and add
Simplified Chinese translations for all 20 user guide strings.
@ocornut

ocornut commented Jun 10, 2026

Copy link
Copy Markdown
Owner

GetGlyphRangesChineseSimplifiedCommon()
range is used. Requires passing explicit SizePixels to AddFontDefault() to avoid
the ImplicitRefSize assertion introduced in v1.92 when using MergeMode.

This place seems wrong. You should never have the specify glyph ranges since 1.92. In fact they are ignored if you are an updated backend. Please remove it and use normal MergeMode.

ImplicitRefSize assertion is to detect if you try to merge font B into font A and specify ref size only for font B. It doesn’t make sense, as font B need to use the size of font A multiplied by RefSizeB/RefSizeA.
Best to not use ref sizes at all, or everywhere.

xuk added 2 commits June 10, 2026 16:59
…around

In v1.92+ with an updated backend, glyph ranges are handled dynamically
and do not need to be specified. Remove GetGlyphRangesChineseSimplifiedCommon(),
the zh_label_ranges English stub, and the explicit SizePixels on AddFontDefault()
that was added to work around the ImplicitRefSize assertion. Use plain
MergeMode instead.
…K font

AddFontDefault() uses implicit ref size. Passing an explicit size (13.0f) to
AddFontFromFileTTF() in MergeMode triggers the assertion because the two fonts
use different ref size conventions. Pass 0.0f instead so both fonts share the
same implicit ref size and scale together with style.FontSizeBase.
@xuk3r

xuk3r commented Jun 10, 2026

Copy link
Copy Markdown
Author

Fixed in the two latest commits:

  1. Removed GetGlyphRangesChineseSimplifiedCommon() and the zh_label_ranges
    stub — using plain MergeMode as suggested.

  2. For the ImplicitRefSize assertion: passing 0.0f as the size to
    AddFontFromFileTTF() in MergeMode so both fonts share the same implicit
    ref size and scale together with style.FontSizeBase.
    The previous workaround (adding explicit SizePixels to AddFontDefault())
    was working around the symptom rather than the cause.

Feel free to let me know if there's anything else to address!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants