How to install and manage fonts on Linux

Fonts are a really important part of the user experience. On the most commonly used Linux-based distributions, there are many packaged fonts which can be installed using the native package manager. Sometimes, however, we may want to install some fonts manually. In this tutorial we see how to perform such operation, and, more generally, how fonts are managed on Linux.

In this tutorial you will learn:

  • How fonts are configured via the fontconfig library
  • How to generate and update the fonts cache
  • How to get the list of installed fonts with fc-list
  • How to install fonts manually
How to install and manage fonts on Linux
How to install and manage fonts on Linux

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software fontconfig, GNOME fonts or KFontView for graphical fonts installation
Other None
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

The fontconfig library

on Linux-based operating systems, fonts are managed via the fontconfig library. The directories where the fonts should be installed are declared in the /etc/fonts/font.conf configuration file:

<!-- Font directory list -->
        <dir>/usr/share/fonts</dir>
        <dir>/usr/share/X11/fonts/Type1</dir> <dir>/usr/share/X11/fonts/TTF</dir> <dir>/usr/local/share/fonts</dir>
        <dir prefix="xdg">fonts</dir>
        <!-- the following element will be removed in the future -->
        <dir>~/.fonts</dir>

As you can see, directories that are scanned for font files are declared using the <dir> tag. The following directories are set by default:

  • /usr/share/fonts
  • /usr/share/X11/fonts/Type1
  • /usr/share/X11/fonts/TTF
  • /usr/local/share/fonts
  • ~/.fonts



The prefix attribute of the <dir> tag, can be used to automatically prefix the passed directory with a certain prefix. In the following line, for example, the prefix attribute has the xdg value; this means that the passed directory will be prefixed by of XDG_DATA_HOME variable:

<dir prefix="xdg">fonts</dir>

The prefix attribute can also be set to default or cwd: in those cases the current working directory is used as prefix. Finally, if the value of prefix is relative the passed directory is prefixed by the path of the directory containing the configuration file.

This system-wide configuration file should not be modified in place, since it could be overwritten by future system updates. Custom settings, instead, should be put in the /etc/fonts/local.conf file, which should be created, if it doesn’t exist. Per user configurations can also be created:

  • $XDG_CONFIG_HOME/fontconfig/fonts.conf
  • ~/.fonts.conf

Font utilities

Included in the fontconfig package come some utilities which let us easily perform useful operations like re-generating the fonts cache or listing the installed fonts. Let’s see some example of their usage.

Generating and updating the fonts cache

To make the directories where fonts are stored re-scanned, and the font cache be re-created (typically we want to do this after we install a new font), we can use the fc-cache utility. If invoked without any argument, the utility re-scans all configured directories:

$ fc-cache

To make only a specific directory be scanned, instead, we can pass it as argument to the command. In the following example we re-scan only the /usr/share/fonts directory. The -v option is used to make the output more verbose:

$ fc-cache -v /usr/share/fonts
Font directories:
        /usr/share/fonts
/usr/share/fonts: skipping, existing cache is valid: 0 fonts, 37 dirs
/usr/share/fonts/adobe-source-code-pro: skipping, existing cache is valid: 14 fonts, 0 dirs
/usr/share/fonts/cantarell: skipping, existing cache is valid: 11 fonts, 0 dirs
/usr/share/fonts/dejavu-sans-fonts: skipping, existing cache is valid: 9 fonts, 0 dirs
[...]

In the example above, you can see that if the existing cache is considered valid, regeneration is skipped. If we want to force the process, we can pass the -f option to the command:

$ fc-cache -v -f /usr/share/fonts
fc-cache /usr/share/fonts -vf
Font directories:
        /usr/share/fonts
/usr/share/fonts: caching, new cache contents: 0 fonts, 37 dirs
/usr/share/fonts/adobe-source-code-pro: caching, new cache contents: 14 fonts, 0 dirs
/usr/share/fonts/cantarell: caching, new cache contents: 11 fonts, 0 dirs
/usr/share/fonts/dejavu-sans-fonts: caching, new cache contents: 9 fonts, 0 dirs
[...]

Getting a list of the available fonts with fc-list

To get the list of the current available fonts on our system from the command line, we can use the fc-list:

$ fc-list
/usr/share/fonts/google-droid-sans-fonts/DroidSansTamil-Bold.ttf: Droid Sans,Droid Sans Tamil:style=Bold
/usr/share/fonts/julietaula-montserrat-fonts/Montserrat-Bold.otf: Montserrat:style=Bold
/usr/share/fonts/google-droid-sans-fonts/DroidSansArmenian.ttf: Droid Sans,Droid Sans Armenian:style=Regular
/usr/share/fonts/google-noto/NotoSans-CondensedBlack.ttf: Noto Sans,Noto Sans Condensed Black:style=Condensed Black,Regular
/usr/share/fonts/google-noto/NotoSansMono-SemiCondensedLight.ttf: Noto Sans Mono,Noto Sans Mono SemiCondensed Light:style=SemiCondensed Light,Regular
/usr/share/fonts/google-noto/NotoSansMono-CondensedMedium.ttf: Noto Sans Mono,Noto Sans Mono Condensed Medium:style=Condensed Medium,Regular
/usr/share/fonts/urw-base35/NimbusMonoPS-Italic.otf: Nimbus Mono PS:style=Italic
[...]



As you can see above, for each installed font, the command returns:

  1. The path of the font file on the system
  2. The font family
  3. The font style(s)

Further information about the installed fonts can be obtain by invoking the utility with the -v option:

Pattern has 26 elts (size 32)
        family: "Cantarell"(s) "Cantarell Thin"(s)
        familylang: "en"(s) "en"(s)
        style: "Thin"(s) "Regular"(s)
        stylelang: "en"(s) "en"(s)
        fullname: "Cantarell Thin"(s)
        fullnamelang: "en"(s)
        slant: 0(i)(s)
        weight: 0(f)(s)
        width: 100(f)(s)
        foundry: "ABAT"(s)
        file: "/usr/share/fonts/cantarell/Cantarell-Thin.otf"(s)
        index: 0(i)(s)
        outline: True(s)
        scalable: True(s)
        charset:
        0000: 00000000 ffffffff ffffffff 7fffffff 00000000 ffffffff ffffffff ffffffff
        0001: ffffffff fff3ffff fffffdff 7fffffff 00048000 00018003 1ffffff0 fc000cc0
        0002: 0fffffff 008f3c00 02000000 00000000 00000000 de000000 3f001fc0 00000000
        0003: 0806bfdf 01e243d8 00000000 04200000 ffffd770 fffffffb 00807fff 00000000
        0004: ffffffff ffffffff ffffffff 003c0c0c 3fff0000 0fcfcc3f f3ff9807 03ffc3fc
        0005: 3c000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
        001e: 30f0f300 0cc3cc33 cc0ff3fc 0f00f3ff 408cc03f ffffffff ffffffff 03ffffff
        001f: 3f3fffff ffffffff aaff3f3f 3fffffff ffffffff ffdfffff 6fcfffdf 7fdcffff
        0020: 773f0fff 063d0047 00040010 03f10000 000003ff 37367ada 00000000 00000000
        0021: 00480000 00004044 ffff0000 00000000 000f0200 00000000 00000000 00000000
        0022: 46268064 00400800 00000100 00000037 00000000 00000000 00000000 00000000
        0024: 00000000 00000008 00000000 00000000 00000000 00000000 00000000 00000000
        0025: 00000000 00000000 00000000 00000000 00000000 00000000 00008c00 00000000
        0027: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000300
        00a7: 00000000 00000000 00000000 00000000 00001800 00000000 00000000 00000000
        00fb: 00000006 00000000 00000000 00000000 00000000 00000000 00000000 00000000
(s)
        lang: aa|ast|av|ay|az-az|ba|be|bg|bi|bin|br|bs|bua|ca|ce|ch|chm|co|cs|cv|cy|da|de|el|en|eo|es|et|eu|fi|fj|fo|fr|fur|fy|gd|gl|gn|gv|haw|ho|hr|hu|ia|ig|id|ie|ik|io|is|it|kaa|ki|kk|kl|ku-am|kum|kv|kw|ky|la|lb|lez|lt|lv|mg|mh|mk|mo|mt|nb|nds|nl|nn|no|nr|nso|ny|oc|om|os|pl|pt|rm|ro|ru|sah|se|sel|sh|sk|sl|sm|sma|smj|smn|so|sq|sr|ss|st|sv|sw|tg|tk|tl|tn|to|tr|ts|tt|tyv|uk|uz|vi|vo|vot|wa|wen|wo|xh|yap|zu|an|crh|csb|fil|hsb|ht|jv|kj|ku-tr|kwm|lg|li|mn-mn|ms|na|ng|nv|pap-an|pap-aw|qu|quz|rn|rw|sc|sg|sn|su|ty|za(s)
        fontversion: 19726(i)(s)
        capability: "otlayout:DFLT otlayout:latn"(s)
        fontformat: "CFF"(s)
        decorative: False(s)
        postscriptname: "Cantarell-Thin"(s)
        color: False(s)
        symbol: False(s)
        variable: False(s)
        fonthashint: False(s)
        order: 0(i)(s)

If we want to get information only about a specific font pattern, we can pass it as argument to the command. For example, to get information for the fonts matching “Cantarell”, we would run:

$ fc-list cantarell

We would obtain a result similar to the following, if the pattern is matched by any fonts:

usr/share/fonts/cantarell/Cantarell-Light.otf: Cantarell,Cantarell Light:style=Light,Regular
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell:style=Bold
/usr/share/fonts/cantarell/Cantarell-Bold.otf: Cantarell:style=Bold
/usr/share/fonts/cantarell/Cantarell-ExtraBold.otf: Cantarell,Cantarell Extra Bold:style=Extra Bold,Regular
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell:style=Light
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell:style=Regular
/usr/share/fonts/cantarell/Cantarell-Thin.otf: Cantarell,Cantarell Thin:style=Thin,Regular
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell:style=Extra Bold
/usr/share/fonts/cantarell/Cantarell-Regular.otf: Cantarell:style=Regular
/usr/share/fonts/cantarell/Cantarell-VF.otf: Cantarell:style=Thin

A method to check if a specific font is installed in the system is to use the -q option when invoking fc-list. When we do so, all the output of the application is suppressed, and 1 is returned as exit code if the passed pattern produces no matches. In the following example the “foo” font doesn’t exist on the system. As you probably know, the $? variable contains the exit code of the last command launched in the shell:

$ fc-list -q foo
echo $?
1

Installed fonts can be filtered also on the base of a specific property. For example, suppose we want to get information only about fonts which has the “DemiLight” style. We would run:

$ fc-list :style=Demilight



Once the command above is launched, the following output is produced on the system I am using:

/usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc: Noto Sans CJK TC,Noto Sans CJK TC DemiLight:style=DemiLight,Regular
/usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc: Noto Sans CJK JP,Noto Sans CJK JP DemiLight:style=DemiLight,Regular
/usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc: Noto Sans CJK HK,Noto Sans CJK HK DemiLight:style=DemiLight,Regular
/usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc: Noto Sans CJK KR,Noto Sans CJK KR DemiLight:style=DemiLight,Regular
/usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc: Noto Sans CJK SC,Noto Sans CJK SC DemiLight:style=DemiLight,Regular

In the same way, to obtain information only for fonts with support for a specific language, we would use the lang property:

$ fc-list :lang=it

Installing a new font

The JetBrains Mono font page
The JetBrains Mono font page

Fonts with a free and open source license are usually packaged and included in Linux distributions, however, sometimes we may want to install a specific font we downloaded from the web manually. In such cases, all we have to do is to place the font file in the appropriate directory. Let’s see an example. Suppose we want to install the “JetBrains Mono” google font. The first thing we do, is to navigate to the google font page:

Once we download and extracted the downloaded zip containing the font file, all we have to do, to make the font available only for our user, is to copy it in the ~/.fonts or ~/.local/share/fonts directory, and then refresh the font cache:

$ cp JetBrainsMono-Italic-VariableFont_wght.ttf ~/.local/share/fonts
$ fc-cache -vf
Gnome fonts viewer font preview
Gnome fonts viewer font preview

Fonts can also be installed using graphical applications like GNOME fonts (the package is called gnome-fonts-viewer). To install a font using such application, we open the font file with it: a preview of the font will be displayed. To proceed with the installation, we just click on the “install” button:

KFontView font preview
KFontView font preview

If KDE Plasma Desktop is our favorite environment, the native application to perform the same operation is called KFontView (sadly, the application doesn’t support Wayland yet, therefore can only be used on Xorg):

Conclusions

In this tutorial we saw how to manage and install fonts on Linux-based operating systems. We learned that fonts are managed via the “fontconfig” library, what are the configuration files that can be used, and what directories host fonts by default. We also saw how to list the available fonts on the system, how to regenerate the fonts cache, and how to install fonts both from the command line and via graphical applications such as “GNOME fonts” and “KFontView”.



Comments and Discussions
Linux Forum