Skip to content

Instantly share code, notes, and snippets.

@MahdiMirzade
Last active May 13, 2024 19:23
Show Gist options
  • Save MahdiMirzade/f7fa9d9c419ead494126b802d7992d3a to your computer and use it in GitHub Desktop.
Save MahdiMirzade/f7fa9d9c419ead494126b802d7992d3a to your computer and use it in GitHub Desktop.
Font Configuration in Linux

Font Configuration in Linux

A computer font (or font) is an electronic data file containing a set of glyphs, characters, or symbols such as dingbats.

Most computer fonts used today are in either bitmap(BDF) or outline data(otf/ttf) formats.

Many non-English users have problems with their language's rendering, at least Persian users have problems with viewing Persian charactars that can happen because:

  1. Proper fonts are not installed/found by fontconfig. Click here
  2. Fontconfig order is wrong and the latin fonts are above Persian fonts and don't have a good support that causes problems. Click Here

Notes

  1. ArchLinux, Debian, Fedora, and lots of other distros use Fontconfig, it makes the configuration process mostly the same.
  2. Some sections are a little long, so they are collapsed by default, click to expand.
  3. CJK Refers to Chinese/Japanese/Korean which includes their fonts.
  4. ~ represents user's home directory or /home/[user].
  5. Be careful, Use each font for its family, for example don't use a serif font in monospace order, because monospace is mostly used in terminal/Text-Editos/IDEs and it's not suitable.
  6. We have many font packages and customization, don't be scared of trying them, you can always change your mind and change your applications configuration.

Installing Fonts

These are the various ways of installing fonts files, also there is another way of installing fonts using custom packages for yourself and your configuration which I'll explain the way for ArchLinux, for other distros mentioned above, I don't know how to make one so we'll just do a PKGBUILD for ArchLinux. (I'm not really familiar with others)

Installing with Package Manager

You can install your fonts using your distro's package manager, here are some examples for pacman, dnf and apt.

Search for Fonts

If you don't know what is the package's name, Search for it using "ttf/font" query:

$ pacman -Ss cjk fonts
$ dnf search cjk fonts
$ apt search cjk fonts

Example Results:

 ~ pacman -Ss cjk fonts
extra/noto-fonts-cjk 20201206-2 [installed]
    Google Noto CJK fonts
community/adobe-source-han-sans-otc-fonts 2.004-1
    Adobe Source Han Sans - Pan-CJK OpenType/CFF Collection fonts
community/adobe-source-han-serif-otc-fonts 1.001-5 [installed]
    Adobe Source Han Serif - Pan-CJK OpenType/CFF Collection fonts
 ~

Install the Fonts

Then you can install your selected font(s):

$ pacman -S noto-fonts-cjk
$ dnf install google-noto-cjk-fonts
$ apt install fonts-noto-cjk

Installing Fonts Manually

In this way you'll need to copy your files(ttf/otf) in some directories, if you want to install your fonts manually, for:

  • a single user: to install your fonts for your own user, you can copy your fonts to
~/.local/share/fonts/
  • all the system: to install your fonts globally, just copy your files to
/usr/local/share/fonts/

While modifying, it's better to keep each font to a different subdirectory with its own name(but it's optional), like this:

/usr/share/local/fonts
├── Icons
│   ├── sans-mono-regular-nerd-font.ttf
│   ├── feather.ttf
│   ├── iosevka-nerd-font.ttf
│   ├── iosevka-regular.ttf
│   ├── siji.bdf
│   └── waffle.bdf
├── Iosevka
│   ├── iosevka-bolditalic.ttf
│   ├── iosevka-boldoblique.ttf
│   ├── iosevka-bold.ttf
│   ├── iosevka-italic.ttf
│   ├── iosevka-oblique.ttf
│   └── iosevka-regular.ttf
├── JoyPixels
│   └── JoyPixels.ttf
└── PersianFontsCollection
    ├── ubvazir.ttf
    └── Vazir.ttf

Once you installed a font manually, update cache: (Just in case if it wasn't)

$ fc-cache -sv

Remember 1: While installing fonts don't use the path /usr/share/fonts/, this directory is used by the package manager and shouldn't be modified manually.

Remember 2: Your current fonts can also be found in ~/.fonts/, this is because Fontconfig used to use this path in the past for user's local configuration, but it's now deprecated and shall not be used.


Installing fonts with Custom Packages

This is a brief documantation and example of how I package my fonts, full documentation available at archlinux wiki. (This section is for pacman & PKGBUILD/ArchLinux Only)

Creating a PKGBUILD

You can create your ArchLinux package and publish it to AUR using ArchLinux Wiki, this is a summary and for full details, always refer to original documentation.

PKGBUILD Variables

Name Value
srcdir This points to the directory where makepkg extracts or symlinks all files in the source array.
pkgdir This points to the directory where makepkg bundles the installed package, which becomes the root directory of your built package.
pkgbase When building a split package, this variable can be used to explicitly specify the name to be used to refer to the group of packages in the output of makepkg and in the naming of source-only tarballs.
pkgname Either the name of the package, e.g. pkgname='foo', or, for split packages, an array of names, e.g. pkgname=('foo' 'bar').
pkgver The version of the package. This should be the same as the version published by the author of the upstream software. It can contain letters, numbers, periods and underscores.
pkgrel The release number. This is usually a positive integer number that allows to differentiate between consecutive builds of the same version of a package.
pkgdesc The description of the package. This is recommended to be 80 characters or less and should not include the package name in a self-referencing way, unless the application name differs from the package name.
arch An array of architectures that the PKGBUILD is intended to build and work on. Arch officially supports only x86_64, but other projects may support other architectures.
url The URL of the official site of the software being packaged.
license The license under which the software is distributed.
depends An array of packages that must be installed for the software to build and run. Dependencies defined inside the package() function are only required to run the software.
Creating the PKGBUILD for your fonts package

my-fonts/PKGBUILD:

# Maintainer: Mahdy Mirzade <[email protected]>

pkgname=my-fonts
pkgver=1.0
pkgrel=1
pkgdesc="Full Fonts for RostamLinux"
arch=('any')
license=('GPL3')
depends=('pango' 'adobe-source-sans-fonts' 'adobe-source-code-pro-fonts' 'adobe-source-serif-fonts' 'adobe-source-han-serif-otc-fonts' 'ttf-joypixels' 'ttf-dejavu' 'ttf-jetbrains-mono' 'ttf-opensans' 'ttf-hack' 'terminus-font')

package() {
    	(find * -type f -exec install -Dm 644 "{}" "$pkgdir/usr/share/fonts/{}" \;)
}

my-fonts/src/:

src
├── icons
│   ├── fantasque-sans-mono-regular-nerd-font.ttf
│   ├── feather.ttf
│   ├── iosevka-nerd-font.ttf
│   ├── iosevka-regular.ttf
│   ├── siji.bdf
│   └── waffle.bdf
├── Iosevka
│   ├── iosevka-bolditalic.ttf
│   ├── iosevka-boldoblique.ttf
│   ├── iosevka-bold.ttf
│   ├── iosevka-italic.ttf
│   ├── iosevka-oblique.ttf
│   └── iosevka-regular.ttf
└── PersianFontsCollection
    ├── ubvazir.ttf
    └── Vazir.ttf
  1. Make a custom empty directory and open it. (e.g. my-fonts)
  2. Make another directory in here named src, the copy your fonts in this directory.
  3. You need to edit the code, put the code into a file named PKGBUILD and open it with a text editor.
  4. Edit Mahdy Mirzade with your name and [email protected] with your email.
  5. Then you'll need to edit pkgname to your own custom name.
  6. Then you can modify pkgver to your packages version. (for updates)
  7. Now you can change pkgrel to your packages build release.
  8. The arch,license variables can remain untouched.
  9. If you have any fonts that are currently in repositories, you can put their names as an array in depends variable, it will install it automatically and your job will be easier.

Now you can build your package using:

$ makepkg -si

This will install your fonts, and also will make you a .pkg.tar.zst file named like mine (my-fonts-1.0-1-any.pkg.tar.zst), you can share this single file with others or store it so in other computers you can install your fonts using:

$ pacman -U my-fonts-1.0-1-any.pkg.tar.zst

Configuring Fonts

Fontconfig automatically chooses a font that matches the current requirement. However if someone is looking at a window containing English and Persian for example, it will switch to another font for the Persian text if the default one does not support it.

  • a single user: to configure your fontconfig for your own user, you can modify
~/.config/fontconfig/fonts.conf
  • all the system: to install fontconfig globally, just edit
/etc/fonts/local.conf

We set our fonts names in order of priority, first font from the top is the first matched font to be used, if the character wasn't set in that font it'll try the next one. we define our fonts in 3 main families:

  • serif
  • sans-serif
  • monospace
Example Configuration With My Fonts
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <!-- preferred fonts (first match will be used) -->
  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Source Sans Pro</family>
      <family>Source Han Sans</family>
      <family>Vazir</family>
      <family>DejaVu Sans</family>
      <family>JoyPixels</family>
    </prefer>
  </alias>
  <alias>
    <family>serif</family>
    <prefer>
      <family>Source Serif Pro</family>
      <family>Source Han Serif</family>
      <family>DejaVu Serif</family>
      <family>JoyPixels</family>
    </prefer>
  </alias>
  <alias>
    <family>monospace</family>
    <prefer>
      <family>Source Code Pro</family>
      <family>Source Han Mono</family>
      <family>DejaVu Sans Mono</family>
      <family>JoyPixels</family>
    </prefer>
  </alias>

  <!-- hinting/antialiasing settings -->
  <match target="font">
    <edit mode="assign" name="antialias">
      <bool>true</bool>
    </edit>
    <edit mode="assign" name="hinting">
      <bool>true</bool>
    </edit>
    <edit mode="assign" name="hintstyle">
      <const>hintslight</const>
    </edit>
    <edit mode="assign" name="lcdfilter">
      <const>lcddefault</const>
    </edit>
    <edit mode="assign" name="rgba">
      <const>rgb</const>
    </edit>
  </match>
</fontconfig>

As you noticed in Example Configuration With My Fonts, we set our fonts in sans-serif, serif, monospace families in order from top to bottom.

For instance my settings for sans-serif family-font is:

  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Source Sans Pro</family>
      <family>Source Han Sans</family>
      <family>Vazir</family>
      <family>DejaVu Sans</family>
      <family>JoyPixels</family>
    </prefer>
  </alias>

My Fonts

Packages' names which are told are in Arch Linux. (~230MB)

Font Packages
Bitmap Fonts terminus-font
Latin Fonts Families:
adobe-source-serif-fonts ttf-dejavu
Sans-Serif:
adobe-source-sans-fonts ttf-opensans ttf-hack
Monospaced:
adobe-source-code-pro-fonts ttf-jetbrains-mono
Non-Latin Fonts CJK:
adobe-source-han-serif-otc-fonts
Persian:
vazir-fonts (AUR)
Emoji/Symbols:
ttf-joypixels

Installing Fonts:

$ pacman -S adobe-source-serif-fonts adobe-source-sans-fonts \
  adobe-source-code-pro-fonts adobe-source-han-serif-otc-fonts \
  ttf-dejavu ttf-opensans ttf-hack ttf-jetbrains-mono ttf-joypixels

Installing AUR Font: (Persian Font)

$ git clone https://aur.archlinux.org/vazir-fonts.git
$ cd vazir-fonts
$ makepkg -si
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment