Font Config is designed to locate and configure fonts for Linux systems. It’s widely used in many Linux distributions, including the Debian 11 Bullseye. In this post, I’ll show you how to configure font on Debian 11 Bullseye. You may also refer to this post (by Arch Linux) and this post (by Alynx in Chinese) for more information.
The configuration files are located in /etc/fonts and ~/.config/fontconfig. The former is for system-wide configuration, and the latter is for user-specific configuration. The configuration files are in XML format, and the main configuration file is fonts.conf. The configuration files are loaded in the following order:
The font configuration file is in XML format. It usually contains a group of match rules, and these match rules are executed from top to bottom. The match rules are used to match the font pattern, and the edit rules are used to modify the font pattern. For example, the following match rule matches the font pattern with the family name “sans-serif”, and the edit rule assigns the family name “DejaVu Sans”, “Noto Sans CJK SC”, and “Noto Color Emoji” to the font pattern.
<match target="pattern">
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>DejaVu Sans</string>
<string>Noto Sans CJK SC</string>
<string>Noto Color Emoji</string>
</edit>
</match>
To force reload the font configuration, you can use the fc-cache command to rebuild the font cache. For example, the following command rebuilds the font cache for the user-specific configuration.
$ fc-cache -f -v
To test the font configuration, you can use the fc-match command to find the best matching font for a given pattern. For example, the following command finds the best matching font for the family name “sans-serif”.
$ fc-match sans-serif
The output on my system is
DejaVuSans.ttf: "DejaVu Sans" "Book"
If you need more information for debugging, the command could be changed to
$ FC_DEBUG=4 fc-match -s sans-serif
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="scan">
<edit name="embeddedbitmap" mode="assign">
<bool>false</bool>
</edit>
<edit name="embolden" mode="assign">
<bool>false</bool>
</edit>
<edit name="rgba" mode="assign">
<const>rgb</const>
</edit>
<edit name="hinting" mode="assign">
<bool>true</bool>
</edit>
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
<edit name="hintstyle" mode="assign">
<const>hintslight</const>
</edit>
<edit name="antialias" mode="assign">
<bool>true</bool>
</edit>
</match>
<match target="scan">
<test name="family" qual="any">
<string>Noto Color Emoji</string>
</test>
<edit name="scalable" mode="assign">
<bool>true</bool>
</edit>
<edit name="embeddedbitmap" mode="assign">
<bool>true</bool>
</edit>
<edit name="hinting" mode="assign">
<bool>false</bool>
</edit>
<edit name="antialias" mode="assign">
<bool>false</bool>
</edit>
</match>
<match target="pattern">
<test name="family">
<string>system-ui</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<match target="pattern">
<test name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<match target="pattern">
<test name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>monospace</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="all" compare="not_eq">
<string>sans-serif</string>
</test>
<test name="family" qual="all" compare="not_eq">
<string>serif</string>
</test>
<test name="family" qual="all" compare="not_eq">
<string>monospace</string>
</test>
<test name="family" qual="all" compare="not_eq">
<string>emoji</string>
</test>
<edit name="family" mode="append_last" binding="weak">
<string>serif</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="same">
<string>DejaVu Sans</string>
<string>Noto Sans CJK SC</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="same">
<string>DejaVu Serif</string>
<string>Noto Serif CJK SC</string>
<string>ZhongHuaSongPlane00</string>
<string>ZhongHuaSongPlane02</string>
<string>ZhongHuaSongPlane15</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="same">
<string>Iosveka Alex Jiang</string>
<string>Fira Code</string>
<string>Noto Sans Mono CJK SC</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>emoji</string>
</test>
<edit name="family" mode="prepend" binding="same">
<string>Noto Color Emoji</string>
<string>Apple Color Emoji</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any" compare="contains">
<string>NanumGothic</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any" compare="contains">
<string>NanumMyeongjo</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>Microsoft YaHei</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK SC</string>
</edit>
</match>
<match>
<test name="family" qual="any">
<string>微软雅黑</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-HK</string>
</test>
<test name="family" qual="any">
<string>Noto Sans CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-HK</string>
</test>
<test name="family" qual="any">
<string>Noto Serif CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Serif CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-HK</string>
</test>
<test name="family" qual="any">
<string>Noto Sans Mono CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans Mono CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-TW</string>
</test>
<test name="family" qual="any">
<string>Noto Sans CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-TW</string>
</test>
<test name="family" qual="any">
<string>Noto Serif CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Serif CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>zh-TW</string>
</test>
<test name="family" qual="any">
<string>Noto Sans Mono CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans Mono CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ja</string>
</test>
<test name="family" qual="any">
<string>Noto Sans CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ja</string>
</test>
<test name="family" qual="any">
<string>Noto Serif CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Serif CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ja</string>
</test>
<test name="family" qual="any">
<string>Noto Sans Mono CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans Mono CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ko</string>
</test>
<test name="family">
<string>Noto Sans CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans CJK KR</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ko</string>
</test>
<test name="family" qual="any">
<string>Noto Serif CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Serif CJK KR</string>
</edit>
</match>
<match target="pattern">
<test name="lang">
<string>ko</string>
</test>
<test name="family" qual="any">
<string>Noto Sans Mono CJK SC</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Noto Sans Mono CJK KR</string>
</edit>
</match>
</fontconfig>