解决 Linux 安装宋体后 UI 字体也变成宋体的问题

Posted by 王灿辉 on 2020-06-29

前言

现如今,有很多人选择使用 Linux 作为自己工作的主要操作系统,但是在 Linux 上使用 Office 软件时,如果没有微软 Word 上常见的几款字体的话,无论是在写作时还是排版时总会觉得有些别扭,因为诸如宋体、黑体、楷体、仿宋等等 Winsows 自带的字体实在是太常用了,几乎绝大多数 Word 文档中所用的字体都包含在其中了。

所以我将 Windows 上的几个常用字体拷贝到 Linux 上。可不料,安装好之后另一个问题却浮现出来:怎么我系统 UI 的字体也变成宋体了?

字体族

要搞清楚这个问题首先要了解一下关于计算机字体族的知识。目前主要的字体族共有 5 个:serif,sans-serif,monospace,cursive 和 fantasy,最常用的是前 3 个。他们的中文名分别是:衬线、无衬线和等宽字体族。

serif 衬线字体族

特点:

  • 具有修饰过的笔画,向外展开的或者尖细的末端,或者是带有实际衬线的末端
  • 一笔一划末端(两头)都带点变化装饰,比如宋体笔画末端有毛笔字的感觉
  • 文字末端有差异,在小字号下仍然容易辨认。但在大字号下笔画装饰部分可能会显得模糊或带有锯齿

示例:

  • Times New Roman、MS Georgia
  • 宋体、仿宋

sans-serif 无衬线字体族

sans-前缀是法语,发音为/san/,意为“无”。

特点:

  • 具有笔画清晰的末端–带有一点或者没有向外展开的,交错笔画,或者其它装饰
  • 与“衬线字体”相比,如果字号比较小,看起来就会有些难以分辨,尤其段落阅读时容易串行

示例:

  • MS Trebuchet、MS Arial、MS Verdana
  • 黑体、幼圆、隶书、楷体

monospace 等宽字体族

特点:

  • 每个字形都等宽,主要用于英文,中文方块字本来就等宽

示例:

  • Courier、Consolas、Droid Sans Mono
  • 大多数编程字体
  • 大多数中文字体

问题分析

于是我开始在系统上寻找蛛丝马迹。首先我设置的 UI 默认字体是 Ubuntu,Ubuntu 是一个西文非衬线字体,其中并不包含 UI 文本中使用的汉字部分。所以在需要显示汉字时,字体系统会找到第一个包含对应汉字的字体代替。

既然问题是安装宋体引发的,我就顺藤摸瓜,在字体系统配置文件中查询关于宋体(simsun)的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ grep -i simsun -B1 -A3 /etc/fonts/conf.d/*
/etc/fonts/conf.d/40-nonlatin.conf-     <alias>
/etc/fonts/conf.d/40-nonlatin.conf:             <family>SimSun</family>
/etc/fonts/conf.d/40-nonlatin.conf-             <default><family>serif</family></default>
/etc/fonts/conf.d/40-nonlatin.conf-     </alias>
/etc/fonts/conf.d/40-nonlatin.conf-<!--
--
/etc/fonts/conf.d/40-nonlatin.conf-     <alias>
/etc/fonts/conf.d/40-nonlatin.conf:             <family>NSimSun</family>
/etc/fonts/conf.d/40-nonlatin.conf-             <default><family>monospace</family></default>
/etc/fonts/conf.d/40-nonlatin.conf-     </alias>
/etc/fonts/conf.d/40-nonlatin.conf-     <alias>
--
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>MS Mincho</family> <!-- han (ja) -->
/etc/fonts/conf.d/65-nonlatin.conf:                     <family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>PMingLiu</family> <!-- han (zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
--
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>UmePlus Gothic</family> <!-- han (ja) -->
/etc/fonts/conf.d/65-nonlatin.conf:                     <family>NSimSun</family> <!-- han (zh-cn,zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>MingLiu</family> <!-- han (zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
/etc/fonts/conf.d/65-nonlatin.conf-                     <family>AR PL New Sung Mono</family> <!-- han (zh-cn,zh-tw) -->

可以结合字体系统配置目录下的 README 理解上面的输出结果。SimSun 出现在了 40-nonlatin.conf 和 65-nonlatin.conf 两个文件中。根据 README 中的描述,以 40~49 开头的配置文件中包含字体的通用标识,即字体族到该族的通用字体的映射;以 60~69 开头的配置文件中包含字体的通用别名,即通用字体到字体族的映射。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
conf.d/README

Each file in this directory is a fontconfig configuration file.  Fontconfig
scans this directory, loading all files of the form [0-9][0-9]*.conf.
These files are normally installed in /etc/fonts/conf.avail
and then symlinked here, allowing them to be easily installed and then
enabled/disabled by adjusting the symlinks.

The files are loaded in numeric order, the structure of the configuration
has led to the following conventions in usage:

 Files begining with:	Contain:
 
 00 through 09		Font directories
 10 through 19		system rendering defaults (AA, etc)
 20 through 29		font rendering options
 30 through 39		family substitution
 40 through 49		generic identification, map family->generic
 50 through 59		alternate config file loading
 60 through 69		generic aliases, map generic->family
 70 through 79		select font (adjust which fonts are available)
 80 through 89		match target="scan" (modify scanned patterns)
 90 through 99		font synthesis

查看文件 65-nonlatin.conf 可知,宋体在配置文件中出现的位置比其他包含汉字的字体都靠前。当我安装了宋体之后,宋体就是第一个能够匹配汉字的字体。因此当汉字显示 fallback 的时候,宋体就是第一候选。

解决方法

知道问题所在,那么解决的方法就很容易想出来了。因为字体系统配置文件的优先级是用户配置优先于系统配置的,我们可以在 ~/.config/fontconfig/ 目录下添加一个以 60~69 开头的配置文件,对中文字体部分进行配置。下面提供一份配置文件作为参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <description>Set preferable fonts for Chinese</description>
  <alias>
    <family>serif</family>
    <prefer>
      <family>Noto Serif CJK SC</family>  <!-- han (zh-cn) by wert -->
      <family>Noto Serif CJK TC</family>  <!-- han (zh-tw) by wert -->
    </prefer>
  </alias>
  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Sarasa Gothic SC</family>  <!-- han (zh-cn) by wert -->
      <family>Sarasa Gothic TC</family>  <!-- han (zh-tw) by wert -->
    </prefer>
  </alias>
  <alias>
    <family>monospace</family>
    <prefer>
      <family>Sarasa Mono SC</family>  <!-- han (zh-cn) by wert -->
      <family>Sarasa Mono TC</family>  <!-- han (zh-tw) by wert -->
    </prefer>
  </alias>
  <alias>
    <family>system-ui</family>
    <prefer>
      <family>Sarasa UI SC</family>  <!-- han (zh-cn) by wert -->
      <family>Sarasa UI TC</family>  <!-- han (zh-tw) by wert -->
    </prefer>
  </alias>
</fontconfig>

参考资料



赞赏支持
微信赞赏
微信赞赏
支付宝
支付宝