Fontconfig

Date: , Updated: — Topic: — by Slatian

Some knowledge that makes your life easier when working with fonts on Linux.

What is Fontconfig?

Fontconfig is a library for configuring and customising font access.

It is built into almost every program that runs on Linux and has a GUI (even in into old java software!) and makes it very easy to make configure fonts and then forget about it.

You can find the Fontconfig documentation over on freedesktop.org.

Fontconfig CLI Tools

You average Linux distribution ships Fontconfig along with some commands to poke it.

fc-cache
for rebuilding the Fontconfig cache (after installing a font or changing configuration).
Usually used like this: fc-cache -f -v
fc-conflist
gives you a list of configuration files found by Fontconfig.
fc-match
for looking up which exact font a given name resolves to, very useful for debugging.
fc-query
to print out metadata for a font file.
fc-validate
can give a hint abut missing glyphs in a font file for a given language.
fc-cat
for having a look at the Fontconfig cache.
fc-list
to list all fonts Fontconfig knows about.
fc-pattern
helps you by parsing Fontconfig patterns , useful for debugging.
fc-scan
similar to fc-query but has the same output format as fc-pattern.

Font (Family) Names

What one usually calls the fonts name actually is the font family name. This is because of historical reasons from back when a font was a case of lead letters for printing and one needed an extra case full of letters for the bold or italic styles.

The family name is usually what is accepted whenever you have some configuration file and it wants a font name. Usually the postscript name works too. Both can be found out using fc-query on a given font file. fc-list also shows the family name by default.

Note: fc-query -b omits language and character set information resulting in a more readable output.

Note: Fontconfig also has a specific font name that includes the family name, size, style and every other possible font setting.

System Fonts

System fonts using Fontconfig are just configuration aliasing generic names to your favourite font.

The most common are monopace, sans or sans-serif and serif. If your desktop environment has a font preference dialog in the system settings it is changing which font names those aliases point to.

Note: There is also a convention to alias emoji to your preferred emoji font.

Configuration Files

You can find your Fontconfig configuration file in $XDG_CONFIG_DIR/fontconfig which in most cases is ~/.config/fontconfig/. In there you can either directly edit the fonts.conf file or a file in the conf.d folder.

Global Configuration is in /etc/fonts/. It usually consists of files linked from /usr/share/fontconfig/ where configuration snippets for common settings are installed.

Using Predefined Configuration

fc-conflist will list all configuration files for fontconfig, the active ones prefixed with + the inactive ones in /usr/share/fontconfig/ prefixed with a -.

To use the predefined configuration symlink it:

ln -s /usr/share/fontconfig/conf.avail/70-no-bitmaps.conf /etc/fonts/conf.d/
# Regenerate the fonconfig cache
fc-cache -fv

Note: The Void Linux Documentation on Fonts gives a similar example on linking the 70-no-bitmaps.conf to /etc/fonts/conf.d/ to mitigate the common issue that Firefox picks pixelated bitmap fonts over higher quality ones.

Writing Custom Configuration

To make a valid Fontconfig configuration file it needs some XML scaffolding:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
	<!-- actual configuration goes here -->
</fontconfig>

That scaffold can now be filled with some rules.

Note: In case you are in need of an example, have a look at the Fontconfig documentation examples or my Fontconfig.

Those rule could be disabling fonts without having to uninstall them, useful when one doesn't have root access or wants to keep the font files for some reason.

Example rule for disabling FontAwesome to prevent it from interfering with other icon-fonts.
<selectfont>
	<rejectfont>
		<pattern>
			<patelt name="family"><string>FontAwesome</string></patelt>
		</pattern>
		<!-- More pattern instances for other fonts can go here -->
	</rejectfont>
</selectfont>

Another application is to configure the system fonts mentioned before using alias rules. For setting the emoji (or any other) font one simply maps the family name emoji to the family name of the preferred font.

An example rule for aliasing emoji to Twemoji.
<alias>
	<family>emoji</family>
	<prefer>
		<family>Twemoji</family>
	</prefer>
</alias>
The same mechanism could be used to alias something like Helvetica to your favourite sans font family.

The prefer part of the alias also accepts multiple font families, this can be used to apply the emoji alias to system fonts by telling Fontconfig to prefer your favourite monospace, sans or serif font and whatever is aliased to emoji over all other installed fonts.

<alias>
	<family>monospace</family>
	<prefer>
		<family>Noto Sans Mono</family>
		<family>emoji</family>
	</prefer>
</alias>

Of course there are more applications for Fontconfig configurations, but those probably deserve more specific pages.

Note: I'm using Twemoji and Noto Sans, not because I like the companies that made them, but because they are under a permissive license are mostly complete, look okay and are one of the very few things those companies are actually doing good for humanity.

There are community made fonts like Inter and OpenMoji (plus some more) out there with an impressive coverage and feature set that shouldn't go unmentioned here.

Installing fonts

From packages

Usually the packages do everything for you and even install some sane Fontconfig rules.

If they don't, have a look at the Fontconfig files they install and check if they clash with your own configuration or if the package description, documentation or comment in its Fontconfig file mentions additional required configuration. This is usually the case for emoji fonts to get them as the default font.

From files

In case you have a modern Linux distribution you can install a font by dropping the ttf or otf file into ~/.local/share/fonts/ or ~/.fonts/, the latter works on older distributions too.

To apply the changes run fc-cache -f -v to rebuild the Fontconfig cache and restart your applications (or log out and back in).

Before restarting applications you could verify that the font was installed using the fc-match and fc-list commands.

Converting woff2 to ttf

Google (who else 🙄) made a tool for converting woff2 fonts to ttf and back, the package containing it is simply called woff2 in most Linux distributions.

It contains the woff2_decompress command, give it a path to a woff2 font file and it will convert it to ttf. There is also a woff2_compress that works in the other direction.