Linux 下为 sans-serif、sans、monospace 字体别名设置指定的字体

字体别名是什么?

如果你使用 Linux 系统的话,你应该可以在应用程序的字体选择列表下找到 sans-serif、sans、monospace 这三个字体。它们并不是指定的字体,而是字体别名——指代了一些别的字体,而它们所指代的字体是系统指定的缺省字体。也就是说,当你的系统需要显示一种特定类型的字体,并且当你为应用程序设置的字体并不存在时,就会使用缺省字体来显示。当然也有一些特例,就比如 Emacs 的 eww 浏览器和一些主题中,会默认使用缺省字体来显示对应类型的字体。如果你的系统存在一些字体显示上的问题,那么设置字体别名就是一种解决问题的好方式。

无衬线、衬线和等宽字体

首先需要了解的是三种不同类型的字体——无衬线、衬线和等宽字体。sans-serif 对应无衬线字体,serif 对应衬线字体,monospace 对应等宽字体。我们日常生活中经常使用的黑体,Windows 系统上的微软雅黑,Linux 系统经常使用的思源黑体、文泉驿微米黑都是无衬线字体,而像宋体、思源宋体等字体就是衬线字体,等宽字体字体对于编程人员来说会很熟悉,比较知名的有:Consolas、DejVu Sans Mono,等宽字体最大的特点就是每个字符的宽度都是相等的。

如何设置?

可能你会在一些文章中看到文章的作者教你用“调整字体优先级”的方式来设置字体别名,他们通常会在 、~/.fonts.conf 文件中加入类似于下面的代码:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd**>
<fontconfig>
<alias>
<family>sans-serif</family>
<prefer>
<family>思源黑体 CN</family>
<family>Noto Sans CJK SC</family>
</prefer>
</alias>
</fontconfig>

但是,这种设置的方式这只有在原字体系统缺失的情况下才有效!也就是说,如果你在“设置界面”中设置的字体如果已经被安装了,那么上面的代码根本就没有用!所以,希望大家避开这个坑,具体可参考 ArchWiki 中的内容。应该使用下面的方法来修改字体别名:

  1. 编辑 ~/.fonts.conf~/.config/fontconfig/fonts.conf 文件(如果没有就新建)
  2. 在文件中加入下面的代码
1
2
3
4
5
6
<match target="pattern">
<test qual="any" name="family"><string>georgia</string></test>
<!-- 此处填写被替换的字体,填写相应的字体别名即可 -->
<edit name="family" mode="assign" binding="same"><string>Ubuntu</string></edit>
<!-- 此处填写用来替换的字体 -->
</match>
  1. 保存文件退出

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
<match target="pattern">
<test qual="any" name="family"><string>sans-serif</string></test>
<edit name="family" mode="assign" binding="same"><string>思源黑体 CN</string></edit>
</match>
<match target="pattern">
<test qual="any" name="family"><string>serif</string></test>
<edit name="family" mode="assign" binding="same"><string>思源宋体 CN</string></edit>
</match>
<match target="pattern">
<test qual="any" name="family"><string>monospace</string></test>
<edit name="family" mode="assign" binding="same"><string>Fira Code Retina</string></edit>
</match>

每一组 match 标签只能替换一个字体!

最后,如果需要验证字体别名是否修改成功,可以在终端中输入下面的命令进行验证。-a 后面是字体别名

1
fc-match -a sans-serif | head

本文参考了