字体配置

来自 Arch Linux 中文维基
(重定向自Font configuration

Fontconfig 是一个用于向应用程序提供可用的字体列表,以及字体渲染配置的库。FreeType 库依此配置渲染字体。Arch 上的 freetype2 字体渲染库启用了字节码解释器(bytecode interpreter,BCI)以优化字体渲染,尤其是在 LCD 屏幕上。参见#预置字体配置/示例

尽管大多数类 Unix 系统现在使用 Fontconfig,但部分应用程序仍在使用原始的 X Logical Font Description 作为字体选择与显示方法。

字体路径[编辑 | 编辑源代码]

为了使字体能够被应用程序发现,必须对它们进行编目,以便快速访问。

Fontconfig 的默认字体路径是 /usr/share/fonts/~/.local/share/fonts(以及过时的 ~/.fonts/)。Fontconfig 将在这些路径下递归查找字体。为了便于安装与管理,在安装字体时,建议使用这些路径。

以下命令列出 Fontconfig 已知的字体文件:

$ fc-list ':' file

fc-list(1) 中有更多的输出格式。

Xorg 已知的字体路径可通过其日志了解:

$ grep /fonts ~/.local/share/xorg/Xorg.0.log
提示:
  • 也可使用 xset q 命令查看 Xorg 的已知字体。
  • 若 Xorg 以根用户权限运行,应查看 /var/log/Xorg.0.log
注意:

Xorg 不像 Fontconfig 一样递归查找 /usr/local/share/fonts。添加路径时,必须像这样添加绝对路径:

Section "Files"
    FontPath     "/usr/share/fonts/local/"
EndSection

有关 Xorg 读取配置的更多细节,请阅读Xorg#配置。如果要为用户单独配置字体路径,可以像这样修改对应的 ~/.xinitrc 来添加或移除默认的字体路径:

xset +fp /想要/添加的/字体/路径    # 将一个路径添加到 Xorg 的已知字体路径列表中
xset -fp /想要/移除的/字体/路径    # 将一个路径从 Xorg 的已知字体路径列表中移除

Fontconfig 配置[编辑 | 编辑源代码]

fonts-conf(5) 中有 Fontconfig 的配置文档。

用户配置文件位于 $XDG_CONFIG_HOME/fontconfig/fonts.conf 中(通常是 $HOME/.config/fontconfig/fonts.conf)。全局配置文件位于 /etc/fonts/local.conf。 用户配置优先级高于全局配置。两个文件使用相同的语法。

注意:
  • 需要启用 50-user.conf 预设才能让用户配置生效,启用 51-local.conf 预设才能让全局配置生效。阅读#预设一节了解如何启用这些预设。
  • ~/.fonts.conf/~/.fonts.conf.d/~/.fontconfig/*.cache-* 已过时,以后的包将不再读取这些路径和文件。对应的新路径分别是 $XDG_CONFIG_HOME/fontconfig/fonts.conf$XDG_CONFIG_HOME/fontconfig/conf.d/NN-name.conf$XDG_CACHE_HOME/fontconfig/*.cache-*。如果使用第二个路径,确保文件命名正确(NN 是两位数,如 001099

Fontconfig 把所有配置集中到一个单独的中心文件(/etc/fonts/fonts.conf)中。Fontconfig 升级时会替换这个文件,因此不应当直接修改它。支持 Fontconfig 的程序查看这个文件以获取可用的字体及如何渲染之;重启这类程序即可载入新的配置。该文件是全局配置(/etc/fonts/local.conf)、预设配置(/etc/fonts/conf.d/)、用户配置($XDG_CONFIG_HOME/fontconfig/fonts.conf)的组合。使用 fc-cache 命令重建 Fontconfig 的配置,但只有新运行的程序会使用新的配置。

注意:

某些桌面环境(如 GNOMEKDE)的字体设置界面会自动创建或覆盖用户的字体配置文件。对于此类桌面环境,最好让设置界面中的字体设置和配置文件相符合。同时请确定桌面的区域设置locale 受配置好的字体支持,否则字体配置可能被覆盖。

Fontconfig 配置文件使用 XML 格式,其需要的头部如下:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>

  <!-- settings go here -->

</fontconfig>

文中的配置示例省略了这些标签。

预设[编辑 | 编辑源代码]

预设存放在 /usr/share/fontconfig/conf.avail。可以通过创建符号链接到此处来启用,无论是单用户配置还是全局配置。这些预设会覆盖各自配置文件中的对应设置。

例如,以下命令启用全局次像素 RGB 渲染:

$ cd /etc/fonts/conf.d
# ln -s /usr/share/fontconfig/conf.avail/10-sub-pixel-rgb.conf

以下命令启用用户级次像素 RGB 渲染:

$ mkdir $XDG_CONFIG_HOME/fontconfig/conf.d
$ ln -s /usr/share/fontconfig/conf.avail/10-sub-pixel-rgb.conf $XDG_CONFIG_HOME/fontconfig/conf.d

抗锯齿(Anti aliasing)[编辑 | 编辑源代码]

字体光栅化将字体从向量数据(比如一个TrueType字体)转换为光栅或者位图数据。由于混叠现象,转换后的字体可能会出现锯齿状边缘。抗锯齿技术可以使边缘看起来更平滑。

Fontconfig默认启用抗锯齿,如要禁用:

  <match target="font">
    <edit name="antialias" mode="assign">
      <bool>false</bool>
    </edit>
  </match>
注意: 某些程序可能会覆盖默认的抗锯齿设置

字体微调(hinting)[编辑 | 编辑源代码]

字体微调使用数学指令来调整轮廓字体的显示,使其与光栅化网格(如显示器上的像素网格)对齐。它的预期效果是使字体看起来更清晰,从而使它们更容易阅读。当显示器拥有 300 左右的 DPI 时,字体即使不经微调也能正确排列。

字节码解释器(BCI)[编辑 | 编辑源代码]

TrueType 字体的微调指令由 FreeType 的解释器使用 BCI 微调渲染。通常来说,微调指令完备的字体使用 BCI 微调效果很好。

微调是默认启用的,如要禁用:

  <match target="font">
    <edit name="hinting" mode="assign">
      <bool>false</bool>
    </edit>
  </match>
注意: 具体的 BCI 实现可以在脚本 /etc/profile.d/freetype2.sh 中修改,通过传递参数 truetype:interpreter-version=NN 设置解释器。NN 对应所选择的版本,传递给脚本中的 FREETYPE_PROPERTIES 变量。一些流行的选项如下:
  • 35 - 经典模式,模拟 Windows 98
  • 36 - 经典 Windows ClearType 模式,Windows XP 以下的 Windows 使用
  • 38 - “无穷”模式,高定制性,被认为性能较低,已不再开发
  • 40 - 最小模式(精简版的无穷模式,默认值)
次像素渲染应该使用次像素 BCI。详见 [1]

自动微调(autohint)[编辑 | 编辑源代码]

自动微调依自己的算法尝试微调,无视字体内所有的微调指令。以前这是默认选项,因为 TrueType2 字体受专利保护,但现在专利已过期,基本不需要使用它。如果字体的微调指令很少或没有,它的效果会更好,否则效果是不如 BCI 的。常见字体都有完备的微调指令,因此自动微调用处不大,现在是默认关闭的。如要启用:

  <match target="font">
    <edit name="autohint" mode="assign">
      <bool>true</bool>
    </edit>
  </match>

微调风格(hint style)[编辑 | 编辑源代码]

微调风格是指对字体进行调整显示、使其与光栅化网格对齐的调整量。支持的值有 hintnonehintslighthintmediumhintfull,微调程度依次加深,即字形变得更扭曲、更清晰——hintslight 会使字体更模糊,无法与网格对齐,但在保留字体形状方面会更好(参见 [2]。),而 hintfull 会使字体更清晰,能很好地与像素网格对齐,但会让字体严重变形。对于非 CFF(.otf)字体,hintslight 设置会在竖直方向上隐式使用自动微调,以支持这类字体的原生字体信息。

默认选项是 hintslight,如要更改:

  <match target="font">
    <edit name="hintstyle" mode="assign">
      <const>hintnone</const>
    </edit>
  </match>
注意: 有些程序会覆盖默认的微调设置

像素排布(RGBA)[编辑 | 编辑源代码]

大多数显示器使用 RGB 方式排列像素,但也有例外。Fontconfig 需要知道显示器类型才能正确显示字体。这个选项的值有四个:RGBBGRV-RGB(纵向 RGB 排列)或 V-BGR。如果你的显示器旋转使用,可修改这个值。如果找不到相应的资料,这个网站 可协助测试。

  <match target="font">
    <edit name="rgba" mode="assign">
      <const>rgb</const>
    </edit>
  </match>
注意: 如果不开启次像素渲染(见下),Freetype 将只关心子像素方向,不关心像素排布。

次像素渲染[编辑 | 编辑源代码]

次像素渲染(英文维基百科页面)通过单独控制一个像素的三个分色,在一个方向上获得三倍分辨率,以使得字体看看起来更锐利。在 Windows 上,这项技术叫做 zhwp:ClearType

FreeType2 提供两种次像素渲染方式(FT_CONFIG_OPTION_SUBPIXEL_RENDERING),Harmony 和 ClearType [3]

若使用 ClearType 次像素渲染,建议启用 LCD 滤镜(见下)。使用 Harmony 次像素渲染则不需要

从 FreeType 2.10.3 起,Arch 默认启用 ClearType 次像素渲染。[4]

注意: 使用 lcdlight LCD 滤镜以获得 FreeType 2.10.3 以前的 Harmony 次像素渲染行为(而不是 ClearType)。

LCD 滤镜(LCD filter)[编辑 | 编辑源代码]

LCD 滤镜是用来减轻 ClearType 次像素渲染的色边现象的。这是 FreeType 2 API 文档对其的描述,其中 FT_LcdFilter 一节解释了各个选项。这个网页展示了各个 LCD 滤镜的测试效果。

大多数用户可使用 lcddefault。其他选项包括:适合太粗或模糊的字体使用的滤镜 lcdlight、原始的 Cairo 滤镜 lcdlegacy 、完全关闭 LCD 滤镜的选项 lcdnone

  <match target="font">
    <edit name="lcdfilter" mode="assign">
      <const>lcddefault</const>
    </edit>
  </match>

高级 LCD 滤镜选项[编辑 | 编辑源代码]

如果对内置的 LCD 过滤器不满意,可以通过构建一个自定义的 freetype2 软件包并修改硬编码的过滤器的方式,来非常具体地调整字体的渲染。Arch 构建系统 可用于从源代码构建和安装软件包。

查看 freetype2 的 PKGBUILD 并下载/解压构建文件。Arch 构建系统#通过 Git 获取 PKGBUILD 源码 列出了一些方法。假设使用 asp

$ asp checkout freetype2 
$ cd freetype2/trunk
$ makepkg --nobuild

编辑文件 src/freetype-VERSION/include/freetype/config/ftoption.h 并取消对 FT_CONFIG_OPTION_SUBPIXEL_RENDERING 宏的注释,启用 ClearType 次像素渲染。

然后,编辑文件 src/freetype-VERSION/src/base/ftlcdfil.c 并查找常量 default_filter[5] 的定义:

static const FT_Byte  default_filter[5] =
    { 0x10, 0x40, 0x70, 0x40, 0x10 };

这个常量定义了一个应用于渲染的字形的低通滤波器。根据需要对其进行修改。(参考 freetype 邮件列表的讨论

最后,保存文件,构建并安装自定义软件包:

$ makepkg --noextract
# pacman --remove --nodeps freetype2
# pacman --upgrade freetype2-VERSION-ARCH.pkg.tar.xz

重启系统或窗口系统。现在,lcddefault 过滤器应该会以不同方式渲染字体。

某些字体/字形的单独设置[编辑 | 编辑源代码]

自动微调使用复杂而巧妙的方法进行字体渲染,但它常常使粗体字变得太宽。幸运的是,可以关闭粗体字的自动微调,而对其他字形则保留它:

...
<match target="font">
    <test name="weight" compare="more">
        <const>medium</const>
    </test>
    <edit name="autohint" mode="assign">
        <bool>false</bool>
    </edit>
</match>
...

一些字体也许在 BCI 自动微调下外观不佳。可以为这些字体禁用微调:

...
<match target="font">
    <test name="family" qual="any">
        <string>My Font</string>
    </test>
    <edit name="hinting" mode="assign">
        <bool>false</bool>
    </edit>
</match>
...

设置默认和后备字体[编辑 | 编辑源代码]

匹配测试[编辑 | 编辑源代码]

设置默认或后备字体的一个可靠方法是添加一个 XML 片段来进行匹配测试。例如,通过设置 "binding" 属性,下面的设置将使 Georgia 回退到 Gentium

...
<match target="pattern">
  <test qual="any" name="family" compare="eq"><string>Georgia</string></test>
  <edit name="family" mode="assign" binding="same"><string>Gentium Book Plus</string></edit>
</match>
...

在上面的例子中,"compare" 属性可以是 "eq"(即完全等于 Georgia)、"contains"(例如,匹配 GeorgiaGeorgia Pro),或其他值。参见 [5]

别名[编辑 | 编辑源代码]

另一种方法是使用 <alias> 来设置“首选”字体。<family> 元素指定的字体在匹配到实际字体前,会被修改为 <prefer> 字体列表中的一个字体,顺序由上至下。下面的例子使 Helvetica 回退到 Bitstream Vera Sans

...
<alias>
    <family>Helvetica</family>
    <prefer>
        <family>Bitstream Vera Sans</family>
    </prefer>
</alias>
...

<alias> 也可以用来指定当缺少某些字形时使用的后备字体。例如,一个用户将 Noto Sans 设置为默认的无衬线字体后,安装了 Helvetica Neue,想用它书写拉丁文字。由于很多版本的 Helvetica Neue 并不包括希腊字符,这位用户希望使用 FreeSans 来书写希腊文字,因为它与 Helvetica 很像。但事实上,希腊文字将会回退到用户设置的默认字体 Noto Sans,而使用下面的方法则可以实现:

...
<alias>
    <family>Helvetica Neue LT Pro</family>
    <prefer>
        <family>Helvetica Neue LT Pro</family>
        <family>FreeSans</family>
    </prefer>
</alias>
...

如果用户只是想在使用的字体缺少相应字形时,回退到默认字体,则不需要上述设置。

字体白名单/黑名单[编辑 | 编辑源代码]

禁用位图字体[编辑 | 编辑源代码]

禁用位图字体缩放[编辑 | 编辑源代码]

自动生成粗体和斜体[编辑 | 编辑源代码]

规则优先级[编辑 | 编辑源代码]

Fontconfig 按数字顺序处理 /etc/fonts/conf.d 中的文件。因此,01-aaa.conf02-bbb.conf 的规则将与单个 01-aaabbb.conf 文件具有相同的效果——首先包含 01-aaa 的规则,然后是 02-bbb 的规则。

通常来说,这意味着前缀较小文件将具有较高的优先级。但是,Fontconfig 的语法很灵活,允许新规则优先于现有规则。因此,建议#查看当前设置来测试规则相互作用的结果。

Tango-inaccurate.png本文或本章节的事实准确性存在争议。Tango-inaccurate.png

原因: 实际行为似乎与下面描述的不同。(在 Talk:字体配置#规则优先级 中讨论)


注意:$XDG_CONFIG_HOME/fontconfig/fonts.conf 和目录 $XDG_CONFIG_HOME/fontconfig/conf.d 中定义的用户规则是通过文件 /etc/fonts/conf.d/50-user.conf 载入的,并且通常优先于以较大数字开头的文件中定义的规则。

查看当前设置[编辑 | 编辑源代码]

要查看当前生效的设置,可使用 fc-match --verbose。例如:

$ fc-match --verbose Sans
family: "DejaVu Sans"(s)
hintstyle: 3(i)(s)
hinting: True(s)
...

可在 font-config(5) 中查询数字的意义。例如,hintstyle: 3 代表 hintfull

不支持 Fontconfig 的程序[编辑 | 编辑源代码]

有些应用程序,如 Telegram,会忽略 Fontconfig 设置。你可以通过使用 ~/.Xresources 来解决这个问题,但它没有 Fontconfig 那么灵活。例如(#Fontconfig 配置 中有对各个选项的解释):

~/.Xresources
Xft.autohint: 0
Xft.lcdfilter: lcddefault
Xft.hintstyle: hintslight
Xft.hinting: 1
Xft.antialias: 1
Xft.rgba: rgb

确保 X 在通过 xrdb -q 启动时能正确加载设置(更多信息参见 X resources)。

疑难问题[编辑 | 编辑源代码]

某些字体(Calibri, Cambria, Monaco 等)不正常显示[编辑 | 编辑源代码]

程序无视微调或抗锯齿设置[编辑 | 编辑源代码]

一些应用程序或桌面环境可能会覆盖默认的 Fontconfig 微调和抗锯齿设置。这种情况可能发生在 GNOME 上,例如,当你使用 vlcsmplayer 等 Qt 应用程序时。在这种情况下,请使用该应用程序特定的配置程序。对于 GNOME,请尝试使用 gnome-tweaks

程序不遵循GNOME的微调设置[编辑 | 编辑源代码]

GTK 程序中微调不正确[编辑 | 编辑源代码]

生成 PDF 中 Helvetica 不正常显示[编辑 | 编辑源代码]

FreeType 不正确显示位图字体[编辑 | 编辑源代码]

Dejavu Monospace 不渲染下划线[编辑 | 编辑源代码]

调试 FreeType 字体[编辑 | 编辑源代码]

参见[编辑 | 编辑源代码]