Skip to content

Font: fall back to a host CJK font so Chinese text is not drawn as '?' - #45

Closed
ccxp wants to merge 1 commit into
Jetsku:mainfrom
ccxp:main
Closed

ccxp wants to merge 1 commit into
Jetsku:mainfrom
ccxp:main

Conversation

@ccxp

@ccxp ccxp commented Oct 14, 2026

Copy link
Copy Markdown

With the console language set to Chinese, some text showed up as "??". This is not an encoding bug: the emulator's font code draws '?' on purpose for any character it cannot find.

Root cause:

  • The game opens the PS5 system font sets (SC/TC/JP/KR) through FontOpenFontSet. Those fonts don't exist on the host, so libFont fell back to Roboto (3rdparty/tracy), which only has Latin glyphs.
  • stb_supported_codepoint() replaced every code point missing from the font with '?', and the bitmap fallback (normalize_bitmap_font_code) did the same for every code point above 255.
  • The font format check only accepted .ttf/.otf, so TrueType collections (.ttc), which most Windows CJK fonts are (e.g. msyh.ttc), were rejected.
  • The system overlay (trophy toasts, IME, system dialogs) used ImGui's default ASCII-only font, so Chinese trophy names also became '?'.

Changes:

  • Add Common::FindCjkFontFiles() (src/common/systemFonts.{h,cpp}). It tries KYTY_CJK_FONT first, then the usual system CJK fonts on Windows (msyh, Deng, simhei, simsun, ...), macOS (PingFang, Hiragino, STHeiti) and Linux (Noto Sans CJK, WenQuanYi, Droid Sans Fallback).
  • libFont: accept .ttc files and load face 0 through stbtt_GetFontOffsetForIndex().
  • libFont: add resolve_stb_glyph(), which picks the font per character: the font's own face first, then the host CJK fallback, and '?' only if neither has the glyph. Glyph metrics and bitmaps now use the face that was actually picked.
  • libFont: log which CJK fallback font is used, or warn when none is found.
  • systemOverlay: merge the host CJK font into ImGui's default font. The Vulkan backend has a dynamic atlas, so no glyph ranges are needed.

Not verified: this was not built or tested in game.

Known limitation: fill_writing_step() and fill_writing_metrics() still use a fixed 8px advance per character, so games that use the FontWriting* layout API may lay out CJK text with wrong spacing.

With the console language set to Chinese, some text showed up as "??".
This is not an encoding bug: the emulator's font code draws '?' on
purpose for any character it cannot find.

Root cause:
- The game opens the PS5 system font sets (SC/TC/JP/KR) through
  FontOpenFontSet. Those fonts don't exist on the host, so libFont fell
  back to Roboto (3rdparty/tracy), which only has Latin glyphs.
- stb_supported_codepoint() replaced every code point missing from the
  font with '?', and the bitmap fallback (normalize_bitmap_font_code)
  did the same for every code point above 255.
- The font format check only accepted .ttf/.otf, so TrueType
  collections (.ttc), which most Windows CJK fonts are (e.g. msyh.ttc),
  were rejected.
- The system overlay (trophy toasts, IME, system dialogs) used ImGui's
  default ASCII-only font, so Chinese trophy names also became '?'.

Changes:
- Add Common::FindCjkFontFiles() (src/common/systemFonts.{h,cpp}). It
  tries KYTY_CJK_FONT first, then the usual system CJK fonts on Windows
  (msyh, Deng, simhei, simsun, ...), macOS (PingFang, Hiragino, STHeiti)
  and Linux (Noto Sans CJK, WenQuanYi, Droid Sans Fallback).
- libFont: accept .ttc files and load face 0 through
  stbtt_GetFontOffsetForIndex().
- libFont: add resolve_stb_glyph(), which picks the font per character:
  the font's own face first, then the host CJK fallback, and '?' only if
  neither has the glyph. Glyph metrics and bitmaps now use the face that
  was actually picked.
- libFont: log which CJK fallback font is used, or warn when none is
  found.
- systemOverlay: merge the host CJK font into ImGui's default font. The
  Vulkan backend has a dynamic atlas, so no glyph ranges are needed.

Not verified: this was not built or tested in game.

Known limitation: fill_writing_step() and fill_writing_metrics() still
use a fixed 8px advance per character, so games that use the
FontWriting* layout API may lay out CJK text with wrong spacing.
Jetsku pushed a commit that referenced this pull request Oct 20, 2026
With the console language set to Chinese, some text showed up as "??".
This is not an encoding bug: the emulator's font code draws '?' on
purpose for any character it cannot find.

Root cause:
- The game opens the PS5 system font sets (SC/TC/JP/KR) through
  FontOpenFontSet. Those fonts don't exist on the host, so libFont fell
  back to Roboto (3rdparty/tracy), which only has Latin glyphs.
- stb_supported_codepoint() replaced every code point missing from the
  font with '?', and the bitmap fallback (normalize_bitmap_font_code)
  did the same for every code point above 255.
- The font format check only accepted .ttf/.otf, so TrueType
  collections (.ttc), which most Windows CJK fonts are (e.g. msyh.ttc),
  were rejected.
- The system overlay (trophy toasts, IME, system dialogs) used ImGui's
  default ASCII-only font, so Chinese trophy names also became '?'.

Changes:
- Add Common::FindCjkFontFiles() (src/common/systemFonts.{h,cpp}). It
  tries KYTY_CJK_FONT first, then the usual system CJK fonts on Windows
  (msyh, Deng, simhei, simsun, ...), macOS (PingFang, Hiragino, STHeiti)
  and Linux (Noto Sans CJK, WenQuanYi, Droid Sans Fallback).
- libFont: accept .ttc files and load face 0 through
  stbtt_GetFontOffsetForIndex().
- libFont: add resolve_stb_glyph(), which picks the font per character:
  the font's own face first, then the host CJK fallback, and '?' only if
  neither has the glyph. Glyph metrics and bitmaps now use the face that
  was actually picked.
- libFont: log which CJK fallback font is used, or warn when none is
  found.

Not verified: this was not built or tested in game.

Known limitation: fill_writing_step() and fill_writing_metrics() still
use a fixed 8px advance per character, so games that use the
FontWriting* layout API may lay out CJK text with wrong spacing.

Ported from Jetsku/KytyPS5 PR #45 without its systemOverlay hunk: the
overlay already merges locale-aware system fonts (AddSystemFontFallbacks).
Jetsku added a commit that referenced this pull request Oct 20, 2026
…into gtapipe

Co-Authored-By: Jetsku <59046009+Jetsku@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jetsku

Jetsku commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Has been merged and added to a release

@Jetsku Jetsku closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants