如何让 xterm 中的中文引号双宽度?

由于中文标点左右单引号 ‘’、左右双引号 “”、省略号……和破折号——在 Unicode 中已经不属于中文范畴,西方文字也采用。因此那几个标点符号在西文字体中都是单宽度。除非使用传统的 GB locale, 否则在 UTF-8 环境下,字符终端 xterm 中的那几个标点都被认为是西文字体,显示单宽度。如果想让那几个标点符号变成双宽度,那么可以使用 xterm 提供的一个选项 -cjk_width:

Set the cjkWidth resource to “true”. When turned on, characters with East Asian Ambiguous (A) category in UTR 11 have a column width of 2. Otherwise, they have a column width of 1. This may be useful for some legacy CJK text terminal-based programs assuming box drawings and others to have a column width of 2. It also should be turned on when you specify a TrueType CJK double-width (bi-width/monospace) font either with -fa at the command line or faceName resource. The default is “false”

但是如此一来,许多其他符号也变成了双宽度,导致显示严重错乱。于是我用 FontForge 修改字体,将那几个标点符号的字体宽度加倍。不过修改后发现 xterm 似乎不能正确对待那几个字符,显示出错。似乎 xterm 认定了那几个字符就必须是单宽度,除非使用 -cjk_width 选项。

有无什么办法解决?哪怕修改 xterm 的代码也行。

去修改 glibc 的 wcswidth 函数的代码。

1赞

谢谢回复。

glibc 是底层核心库,改动的影响面太大。应该不至于一定要到 glibc 里去修改,因为 xterm 提供了一个选项 -cjk_width 可以让那些标点显示双宽度。只是一旦用了那个选项,其他的 Unicode 符号也会变成双宽度,导致显示错乱。如果只修改 xterm, 让那少数几个标点符号双宽度,而其他字符不变,就最好不过了。

另外在修改字体之后,我发现 GTK 程序能够感应到。也就是说:如果换上被我修改后的字体(将那几个标点符号的字体宽度加倍),那么 GTK 程序无需作任何修改,就获得了想要的双宽度效果。

你修改 xterm 调用 wcswidth 的地方吧。

一般的 GUI 程序是字体绘制多大,它就留多大的空白。终端程序需要严格的等宽,因此它只看字符有多宽(使用 glibc 的函数),然后留多少个格子。

根据您提供的线索,我修改了 xterm 的源代码。确实起到了效果,却引出了新问题。因为基于 ncurses 的应用程序几乎最终都要用上 libc 的 wcwidth/wcswidth 函数来判断字符该占据多少 “格”。如果只修改 xterm 的实现,那么 ncurses 程序却依然通过 libc 获得字符宽度,就会出现显示错乱。

这也就是为何 xterm 的文档不建议使用它提供的 -cjk_width 选项的原因。最终还是您上面说的,要去修改 libc 里的相关代码才是彻底的解决办法。

非常感谢您提供的帮助,这个问题已经解决。能否再帮我看一下刚刚提出的新问题:

或许您可以继续给我提供思路。