中文字体问题

之前在这个帖 [[已解决]Tumbleweed 下新的 noto-sans-cjk 字体包的问题) 下面讨论了我遇到的问题,但是感觉我的问题跟楼主不太一样,所以来新开一个帖。

问题描述:
自从 noto-sans-cjk 合包以后,系统中的中文文字变为以日文字体显示。用 fonts-config 指定中文字体优先级后,界面字体恢复正常,部分软件(包括:google-chrome, liferea, geary,网易云音乐,telegram )中中文依然以日文字体显示,貌似不受系统字体配置控制。

系统信息:

$ cat /etc/os-release 
NAME=openSUSE
VERSION="Tumbleweed"
VERSION_ID="20160626"
PRETTY_NAME="openSUSE Tumbleweed (20160626) (x86_64)"
ID=opensuse
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:opensuse:20160626"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
ID_LIKE="suse"


$ locale
LANG=en_US.utf8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC=zh_CN.utf8
LC_TIME=zh_CN.utf8
LC_COLLATE="en_US.utf8"
LC_MONETARY=zh_CN.utf8
LC_MESSAGES="en_US.utf8"
LC_PAPER=zh_CN.utf8
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT=zh_CN.utf8
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=

之前尝试了 @stecue 的脚本,效果不错,但是只能用在浏览器里,而且感觉还是治标不治本,毕竟系统字体还是有问题。

今天发现以 LC_ALL=zh_CN.UTF-8 环境变量启动 chrome 之后字体就正常了,telegram 也是。难道是系统语言设置会影响字体匹配列表?如果有一段未知语言的 CJK 的文字,以中文还是日文还是别的什么字体显示是由谁决定的呢?
:question:

你说的那几个软件好像用的都是 Electron 或者 nw.js 框架,至少也是 webkit 做渲染引擎。用 Electron 或者 nw.js 的软件(比说 atom 编辑器)就相当于是用 CSS/HTML/JavaScript 重写了界面的 Chromium/Chrome;而 chrome 的渲染引擎又是 webkit/blink。所以 webkit/blink/chrome 中存在的字体 bug 它们也一个不少。大家都知道,Chromium/Chrome 的任性是早已有之,对 fontconfig 的支持也是越来越差,所以出问题不奇怪。设定 locale 是官方的解决办法了,但是有时好像也 不太灵 ](https://bugs.chromium.org/p/chromium/issues/detail?id=403915) 。

另外,我的脚本已经更新到 1.0.7 了,标点、字体、自动空格都可以处理,没升级的可以试下哈。觉得不错的话强烈欢迎到 github 上打星星哈!

没错,fongconfig 的配置文件可以加入 Locale 相关的选项,玛噶给 noto-sans-cjk 写的配置文件好像就利用了这样的机制。
CJK 统一汉字区的每个汉字在 unicode 中只占用一个码点,不同的字形纯粹采用不同的字体来区分。这样单看一段汉字计算机是无法简单判断他是中文、日文还是韩文。如果没有 locale 信息,乱套字体很正常。

你的脚本真的很好用,十分感谢。但是可惜只能在浏览器里面用,虽然已经解决了大部分问题,可是另外那几个软件的字体显示依然蛋疼。

我现在的想法是,能否通过设置 locale 的方式解决这个问题(因为这几个软件不大支持 fontconfig )。目前我的测试结果是将 LC_CTYPE 设置为 zh_CN.UTF-8 即可(除了网易云音乐,为什么?),但是我不想改动系统级的环境变量,也不想改用户界面语言,所以目前我想只将用户的 LC_CTYPE 的默认值改掉。

按照网上找到的方法,我试过了在 ~/.i18n 里面加上 export LC_CTYPE=zh_CN.UTF-8 ,无效,是因为 gnome 的语言设置覆盖了吗?应该怎样才能达到我的目的?或者有什么别的好方法?谢谢。

你只要在启动这几个软件的时候改 locale 就可以了。比如说要启动 atom,不直接在 konsole 或者什么地方敲 atom,而是输入

LC_CTYPE=zh_CN.UTF-8 atom

就可以了。当然每次敲环境变量过于麻烦,最简单的简化办法是在.bashrc 里写成 alias;也可以单独写个启动脚本,比如~/bin/z-atom(别忘了传递命令行参数)都可以(我习惯于把~/bin 添加到 PATH 变量里)。

我推荐采用启动脚本的办法,因为这样可以在图标文件(.desktop 文件)等各个地方将原命令直接替代就可以,而且有些复杂的启动设置写成 alias 可能也不方便(实际上 /usr/bin/google-chrome 本身就是一个启动脚本),并且也不适合多用户共享。你甚至可以写一个同名的启动脚本,放在优先级比较高的路径里,这样大部分情况下可以直接替代。当然,你的启动脚本里要写绝对路径,要不然就是循环启动同一个脚本文件本身了。

有一个最简单高效的“不是办法的办法”:删掉 /usr/share/font/truetype 里面的 NotoSansCJK.ttc,到 Noto 的网站下载各个语言、各个地区的 otf 版本丢进去,解决。

个人推测,这是这些软件对 Super OTC 格式的字体支持不好导致的。(Super OTC 里面第一个字体就是字重 ExtraLight 的日文版)

因为 Noto Sans CJK 只是 Source Han Sans 的改名版本,所以后者同理。只要都是 1.004 版本就是最新版。(其实这个版本都一年多没更新了……)

而且,Super OTC、OTC 只是给 OTF 字体打了个包,所以本质上没什么区别。

至于系统界面也使用日文版的问题……我忘了装系统的时候是什么样。在字体方面,我折腾得实在太厉害。

然。对于这些很容易陷入到不完善的设计细节中的问题,快刀斩乱麻反而可能是最好的办法。