相较于我们熟悉的 Windows,用户在使用 Linux 发行版的过程中,或多或少会面对各种各样的字体显示问题,非常影响使用体验,相信也让包括我在内的不少用户苦不堪言。
缺少熟悉的宋体、楷体、仿宋等字体,无法顺畅地在 Linux 下办公 当系统语言并非简体中文时,简体中文字形变成日文、韩文的风格,很影响观感 Windows 下的「点阵字体」(字体的 hinting 优化)也出现在了 Linux 里 安装第三方字体后,系统显示的中文字体会变成刚刚安装的字体 还有其他潜伏着的问题……
注意:阅读本文,需要你了解 XML 文件的基础知识。
# Arch Linux。其中noto-fonts为西文字体,noto-fonts-cjk为中日韩文字体
sudo pacman -S noto-fonts noto-fonts-cjk
# Ubuntu
sudo apt install fonts-noto-core fonts-noto-cjk
# Alpine
sudo apk update
sudo apk add --upgrade font-noto font-noto-cjk
# Void Linux
sudo xbps-install -Su noto-fonts-ttf noto-fonts-cjk
注意:为便于管理,请将字体文件放到字体文件夹的二级目录里,例如 /usr/share/fonts/TTF(或 /usr/share/fonts/ 下的其他子目录)。
在终端应用(如 Konsole)里输入中文并按退格键时,文字还在,但只显示一半 Oh My Zsh 等使用特殊字符的终端扩展,在使用时会出现乱码 部分软件在显示中文时可能出现乱码
确保已经激活了目标区域
第一步:用 root 权限的文本编辑器打开/etc/locale.gen,找到以下几行,将它们前面的井号(「#」)删掉,然后保存:
#en_US.UTF-8 UTF-8
...
#zh_CN.UTF-8 UTF-8
第二步:在终端中运行以下命令,让系统重新激活区域支持:
sudo locale-gen 命令执行结果如下所示: sudo locale-gen
Generating locales...
en_US.UTF-8... done
zh_CN.UTF-8... done
Generation complete.
提示:如果你还需要其他区域的支持,就取消相应行前的注释。例如,想启用日文支持,就取消注释ja_JP.UTF-8 UTF-8这一行。
在桌面环境的设置里设置区域
Gnome:在「活动面板(Activities)」中,键入「Region & Language」 KDE:打开「系统设置(System Settings)」→「区域和语言(Region & Language)」→「语言(Language)」 Cinnamon:打开「系统设置(System Settings)」→「语言(Languages)」 Deepin、UOS:打开「控制中心」→「键盘和语言」
对于轻量级桌面环境
yay -S mintlocale
声明: 由于潜在的授权许可条款,使用 Windows 内置字体可能存在一定的法律风险。 这些字体应当用于个人及非商用场合;商用场合应当获得字体版权方的授权。
通用的方式:直接从 Windows 中复制
第一步,你可以直接进入 Windows 的字体目录(如C:\Windows\Fonts\),选中你需要的字体,然后按 Ctrl+C 复制,粘贴到可移动磁盘中,或者是刻录成光盘,等。
第二步,在你的 Linux 电脑上,插入你保存了字体的磁盘或光盘。打开文件管理器,浏览到磁盘或光盘的路径,右击空白处选择「打开终端」(或其他类似的选项)。 第三步,在终端中运行以下命令,将字体复制到 Linux 发行版的字体目录中。注意,你需要 root 权限。
# 建立一个专门的子目录,存放来自Windows的字体
sudo mkdir /usr/share/fonts/Windows_TTF/
# 由于Linux下的文件区分大小写,因此我们要兼顾大小写,以便所有字体都能复制到目标位置
sudo cp *.TTF *.ttf *.OTF *.otf /usr/share/fonts/Windows_TTF/
第四步,在终端中运行fc-cache,刷新字体缓存,使更改生效:
注意:
安装过程使用 httpdirfs 来远程在线挂载微软官方 ISO 镜像,因此需要全程保持网络畅通。视网络环境不同,安装速度也有所不同,请保持耐心。 AUR 还提供了不带 auto 字样的包(例如 ttf-ms-win11),但是笔者不建议安装,因为它们需要你自己下载安装镜像,并自行提取镜像里的文件,很麻烦。
「罪魁祸首」:Fontconfig 的后备字体机制
看看第一个问题。现在的桌面环境,设置的默认字体都为英文字体,例如 Noto Sans。这些字体是不包含中文字符的,一旦显示中文字符,就会触发 fontconfig 的后备字体机制。在安装 Windows 字体前,电脑没有其他中文字体,因此自然会选中 Noto Sans CJK;然而,安装仿宋、楷体这样的中文字体后,fontconfig 有了「新选择」,原先的后备字体就被顶掉了。 再看看第二个问题。对于多语言的环境,fontconfig 会根据系统语言选择对应语言的字体,例如,日文环境下就选择 Noto Sans CJK JP、MS Gothic 等。但是,日文字体没有收录简体汉字,因此在显示简体汉字的场合,同样会触发 fontconfig 的后备字体机制,优先选择新安装的中文字体。于是,同样会导致字体显示效果变得诡异。
如何配置后备字体?
第一步:在用户主目录的.config/fontconfig子目录下,创建文件fonts.conf。如果没有该目录,就新建一个。
注意:如果fonts.conf已有内容,就把<fontconfig>节点里的所有 XML 节点都追加到现有的<fontconfig>节点里。
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<!--
为你电脑上的字体配置后备字体序列。
每个字体对应一个<alias> 小节。
-->
<alias>
<!--
<family> 字段,是你要设置后备字体的字体名称。
【提示】字体名称可以是字体的中文名(在WPS等软件看到的名字),例如“宋体”
-->
<family>Cantarell</family> <!-- 这里的Cantarell是一个英文字体,我们需要为其配置后备中文字体。-->
<!--
<prefer> 字段,是一个后备字体的列表,可以包含多个<family>字段。
后备字体的显示顺序自上而下排列,优先显示排序靠前的字体,
如果靠前的字体没有可以显示的字符,那么后面的字体就会顶上。
-->
<prefer>
<family>DengXian</family>
<family>Noto Sans CJK SC</family> <!-- 建议使用 Noto Sans CJK SC 作为兜底 -->
</prefer>
</alias>
<!--
后面的设置项,格式都是一样的,这里不再赘述。
-->
<alias>
<family>Hack Nerd Font</family>
<prefer>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
<alias>
<family>Noto Sans</family>
<prefer>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
<alias>
<family>Noto Sans Mono</family>
<prefer>
<family>Noto Sans Mono CJK SC</family>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
<alias>
<family>Noto Serif</family>
<prefer>
<family>Noto Serif CJK SC</family>
</prefer>
</alias>
<!--
这里的MS Gothic是Windows自带的日文字体,相当于我们的黑体。
该字体没有收录简体中文字符,所以我们要设置中易黑体(SimHei)作为后备。
-->
<alias>
<family>MS Gothic</family>
<prefer>
<family>SimHei</family>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
</fontconfig>
第三步:写好 fonts.conf 之后,刷新字体缓存。注意这里的 fc-cache 需要带上 -f 参数,强制刷新,否则后备字体有可能不会生效。
注意:后备字体设置只对 fonts.conf 当中的字体生效。如果你还使用其他字体,你需要为这些字体增加相应的配置。
宋体、细明体(PMingLiU)、MS Gothic、MS Mincho 等东亚语言字体,统统显示为点阵
微软雅黑的显示效果与打印效果大相径庭
第一步:打开用户主目录的.config/fontconfig/fonts.conf。如果没有,那就新建一个。 第二步:在 <fontconfig> 节点中,补充与 hinting 设置相关的节点。同样是每个字体对应一个 <match> 节点。
<!--
禁用特定字体的Hinting功能。
下面的代码就是让Fontconfig匹配特定的字体,然后修改参数以禁用它们的Hinting功能。
-->
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<!-- <string>节点,在这里指定字体的名字。例如中易宋体就是SimSun -->
<!-- 【提示】字体名称可以是字体的中文名(在WPS等软件看到的名字),例如“宋体” -->
<string>宋体</string>
</test>
<edit name="hinting" mode="assign">
<bool>false</bool>
</edit>
</match>
第三步:设置完成后,更新字体缓存:
fc-cache -fv