Better font rendering in linux

— Updated on 30 jun 2019

If we're not running a full blown desktop environment like GNOME, KDE or XFCE, the chances of getting good font rendering in a post Xorg installation after a default linux base (think of arch or voidlinux) install is zero. This guide serves as a list of todo items to get decent font rendering with these sort of installs.

Install some good fonts

The default install in most distros come prepackaged with "decent" fonts like BitStream or Dejavu. However, installing a font set with more glyph coverage is needed in this day and age. The google font package has some nice fonts. Especially the Noto Series. I like this set as it comes with a Sans, Serif and Mono variant. Not to mention the large language coverage. In ubuntu, the set comes in a package called fonts-noto. Install it with $ sudo apt install fonts-noto.

If your distro's package manager doesn't find the font package(look for the keyword noto), download the font package from its website and put it in a folder in $HOME/.fonts/"fontname". Mine looks like

$ ls -l ~/.fonts
RobotoMono/  RobotoSlab/  msttcorefonts/  noto/
And those individual folders should contain the .ttf font files.
$ ls -a ~/.fonts/RobotoMono/
./			   RobotoMono-Italic.ttf	RobotoMono-Regular.ttf
../			   RobotoMono-Light.ttf		RobotoMono-Thin.ttf
.uuid			   RobotoMono-LightItalic.ttf	RobotoMono-ThinItalic.ttf
RobotoMono-Bold.ttf	   RobotoMono-Medium.ttf
RobotoMono-BoldItalic.ttf  RobotoMono-MediumItalic.ttf

Now do an $ fc-cache -vf and our font database would be updated. To see if a font is installed and registered, try a $ fc-list | grep "Noto"

Tweaking fontconfig

If you don't have it already, create $HOME/.config/fontconfig/fonts.conf and paste this in. Please read the comments inside before making the file. Now open up a tool like lxappearance and set your UI font to Sans. You'll see that programs like firefox start using the fonts mentioned in the fonts.conf file too.

Note: I've noticed that both chrome and firefox render the fonts.conf file. So a $ curl https://blog.aktsbot.in/files/fonts.conf > $HOME/.config/fontconfig/fonts.conf should download and set the file.

Xorg

Create a file called $HOME/.Xresources and paste this in

Xft.autohint: 0
Xft.antialias: 1
Xft.hinting: true
Xft.hintstyle: hintslight
Xft.dpi: 131
Xft.rgba: rgb
Xft.lcdfilter: lcddefault
As a side note, the dpi value changes from monitor to monitor. To figure out your ideal dpi, run $ xdpyinfo | grep -B 2 resolution. For me it gave the following. So, I went with 131
screen #0:
dimensions:    1600x900 pixels (310x174 millimeters)
resolution:    131x131 dots per inch
Make sure your dpi values in .Xresource and fonts.conf files are the same. Then when you start your window manager, make sure to source this file. I start my i3wm session from the tty by issuing a $ startx. So I add the source command to my $HOME/.xinitrc file
~$ cat .xinitrc
#!/bin/sh
xrdb -merge $HOME/.Xresources # <--- this line
xset b off &
# more config options ...
exec ck-launch-session dbus-launch i3
~$ 

The information regarding our monitor can be found by doing a

~$ xrandr --props | grep 'connected' | grep -v 'dis'
LVDS1 connected primary 1600x900+0+0 (normal left inverted right x axis y axis) 310mm x 170mm    
We now create a file /etc/X11/xorg.conf.d/20-monitor.conf as root with this info
$ cat /etc/X11/xorg.conf.d/20-monitor.conf
Section "Monitor"
  Identifier    "LVDS1"
  DisplaySize    310 170
EndSection

Now we toggle infinality by modifying/creating the file

~$ cat /etc/profile.d/freetype2.sh
# Subpixel hinting mode can be chosen by setting the right TrueType interpreter
# version. The available settings are:
#
# truetype:interpreter-version=35 # Classic mode (default in 2.6)
# truetype:interpreter-version=38 # Infinality mode
# truetype:interpreter-version=40 # Minimal mode (default in 2.7)
#
# There are more properties that can be set, separated by whitespace. Please
# refer to the FreeType documentation for details.

# Uncomment and configure below

export FREETYPE_PROPERTIES="truetype:interpreter-version=38"

Note:If you're unsure about the dpi setting, a value of 96 is usually a safe bet.

Firefox

If you're running firefox, type in about:config in the URL bar and make these changes. Each one is a separate entry. Again, match the dpi with your values

gfx.font_rendering.fontconfig.max_generic_substitutions = 127
layout.css.dpi = 131

Credits

Fin

With that we now have pixel perfect font rendering.

Happy Hacking & have a great day!