conhost.exe 无法显示 U+2717

我想在 Windows 的传统控制台(conhost)中显示 U+2717(✗,BALLOT X)。选中系统默认的等宽字体 Consolas,输出的却是一个带有方框的问号。

在 Stack Overflow 上也有人遇到了同样的问题:

https://stackoverflow.com/questions/27519142/is-it-possible-to-output-and-display-u2717-ballot-x-in-the-windows-console

问题的原因显而易见。 Consolas 不包含这个字形,换一个包含它的字体就好。查阅 fileformat.info 的字形支持列表后发现,DejaVu Sans Mono、Inconsolata 等开源等宽字体确实包含 U+2717 。

https://www.fileformat.info/info/unicode/char/2717/fontsupport.htm

在 Windows 10 较新版本中,conhost 已经可以直接读取已安装的等宽字体,无需像早期版本那样手动编辑注册表。

https://superuser.com/questions/1767614/possible-to-enable-additional-fonts-in-command-prompt-without-registry-edits

在安卓系统中, U+2717 可以正常显示。安卓默认使用的是 Roboto 。但 Roboto 并没有 U+2717 。安卓系统使用了字体回退机制。

https://www.fileformat.info/info/unicode/font/roboto/list.htm

Consolas 里面没有中文字符。

把字体设为 Consolas 时,输入中文却能正常显示。

这说明 conhost 并非只用单一字体渲染,也存在某种回退机制。按照这个逻辑,既然中文能回退到微软雅黑显示,U+2717 理应也能回退到包含它的系统字体(如 Segoe UI)来显示才对。

那为什么 U+2717 显示不出来?

查阅官方文档发现, conhost 的回退机制基于 GDI 的字体链接(Font Link),具体配置位于注册表的 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink 中。这个键值定义了每个字体的回退链条------Consolas 找不到中文字形时,会沿着这条链找到微软雅黑来渲染:https://learn.microsoft.com/zh-cn/dotnet/fundamentals/runtime-libraries/system-console

这里面没有 Segoe UI ,也没有任何一个链接字体包含 U+2717。

当然,这个问题并非无解。理论上可以通过在注册表中为 Consolas 手动添加指向 Segoe UI Symbol 的字体链接来修补,但这也意味着需要修改系统配置。GitHub 上也有报告指出 conhost 可能存在 Unicode 回退失效的问题:https://github.com/microsoft/terminal/issues/18024

想让符号显示,字体本身是否包含字形、字体链接表是否覆盖该字符范围、conhost 是否支持字体回退------三者缺一不可。日常习以为常的"输入即显示",底层远比想象中复杂。

此文章部分使用LLM辅助编写。