Dusko Pijetlovic

My personal notes where I store things I find interesting or might need in the future.

Fonts in X11 - aka Fonts in X (Xorg)

17 Apr 2022 » font, freebsd, unix, x11, xorg, dotfiles

OS: FreeBSD 13
Shell: csh
Window Manager: FVWM


[TODO]:


Fonts in X11 (X Window System, aka X)

From “Linux in a Windows World” by Roderick W Smith (O’Reilly Media, Inc. February 2005) and “X Logical Font Description” (archlinux Wiki, Retrieved on Apr 17, 2022):

Two font systems:

  • The X core fonts; a.k.a. X fonts, a.k.a. XLFD (X Logical Font Description)
    • XLFD was originally designed for bitmap fonts and support for scalable fonts (Type1, TrueType and OpenType) was added later. XLFD does not support anti‑aliasing and sub‑pixel rasterization.
    • Designed with bitmap fonts in mind, meaning that individual characters were designed for display at a specific size in pixels.
      • To support scaleable fonts, which can be resized, multiple bitmap font files are required, one for each size. X servers ship with several bitmap fonts in a variety of sizes, designed for both 72 dots per inch (dpi) and 100-dpi displays.
      • Most modern fonts, though, use scaleable font (a.k.a. outline font) technologies, in which the font is described in terms of mathematical descriptions of lines and curves. These descriptions provide an outline of a character, which the font renderer can scale to any desired resolution and fill in.
        • The two most common scaleable font formats today are PostScript Type 1 (a.k.a. Adobe Type Manager or ATM) fonts and TrueType fonts (TTF).
  • Xft fonts (aka outline fonts or scalable fonts)
    • Designed around the FreeType library, which was originally a tool for rendering TrueType fonts. Today, though, Xft supports both TrueType and Type 1 fonts.
    • Xft uses the FreeType and Fontconfig libraries and is more suitable when the smooth appearance of fonts is desired.
    • Improved limitations in the X core fonts:
      • X core fonts can’t readily handle more than two colors per font (Required a font technology known as font smoothing or anti-aliasing. Font smoothing uses shades of gray to deliberately blur fonts, which has the subjective effect of improving the appearance of fonts because it tends to hide the jagged edges along diagonal lines and curves.)
    • Installing the X core fonts can be tricky.
    • X core fonts were not designed with printing in mind, and coordinating the display and print fonts can be a challenge when using these fonts.

NOTE: Individual X-based programs sometimes employ their own font-handling systems.

Installing X Core Fonts (aka “Traditional” X Fonts, aka XLFD)

KEYWORDS: core X X11 Xorg fonts monospaced bitmap pcf dpi dots per inch xdpyinfo resolution

  • Download and install the font; that is, copy its files
  • Run mkfontdir to recreate the font database
  • Run mkfontscale to recreate an index of scalable font files for X
  • Run xset fp+ /path/to/the/new/font to append it to the font path
  • Run xset fp rehash to reread the font databases in the font path

Environment: FreeBSD 13.1, Shell: csh, WM: FVWM

0. Before Font Installation

In this example, font to install will be: Raize monospaced bitmap font:

https://github.com/Tecate/bitmap-fonts
https://github.com/Tecate/bitmap-fonts/blob/master/archives/raize.tar.gz

XLD:

% xlsfonts | grep -i raize

Xft:

% fc-list | grep -i raize

1. Download Font Files

% mkdir tmpuntar
% cd tmpuntar
% pwd
/usr/home/dusko/tmpuntar
% fetch https://github.com/Tecate/bitmap-fonts/raw/master/archives/raize.tar.gz
% tar xf raize.tar.gz
% ls
raize-bold-14.pcf.gz    raize-normal-14.pcf.gz  raize.tar.gz
raize-bold-17.pcf.gz    raize-normal-17.pcf.gz
raize-bold-19.pcf.gz    raize-normal-19.pcf.gz
% ls -F /usr/local/share/fonts
100dpi/                 encodings/              OTF/
75dpi/                  firacode/               profont/
adobe-cmaps/            GentiumBasic/           raize/
atkinson-hyperlegible/  hermit/                 SourceCodePro/
b612/                   jmk-x11-fonts/          symbola/
Caladea/                Liberation/             terminus-font/
Carlito/                libertinus/             TerminusTTF/
courier-prime/          LinLibertineG/          TTF/
courierprimesans/       lucida/                 twemoji-color-font-ttf/
cyrillic/               misc/                   Type1/
dejavu/                 noto/                   xscreensaver/
% sudo mkdir /usr/local/share/fonts/raize
% sudo cp -i /usr/home/dusko/tmpuntar/*.pcf.gz /usr/local/share/fonts/raize/

2. Run mkfontdir and mkfontscale to recreate the font database

% cd /usr/local/share/fonts/raize

% pwd
/usr/local/share/fonts/raize
% sudo mkfontdir
% sudo mkfontscale
% ls /usr/local/share/fonts/raize/
fonts.dir               raize-bold-17.pcf.gz    raize-normal-17.pcf.gz
fonts.scale             raize-bold-19.pcf.gz    raize-normal-19.pcf.gz
raize-bold-14.pcf.gz    raize-normal-14.pcf.gz
% cd -
% pwd
/usr/home/dusko/tmpuntar

3. Run xset fp+ /path/to/the/new/font to Append it to the Font Path

Add FontPath to the fonts.conf (or xorg.conf)

% cat /usr/local/etc/X11/fontpath.d/fonts.conf
Section "Files"
    FontPath "/usr/local/share/fonts/dejavu/"
    ---- snip ---- 
    FontPath "/usr/local/share/fonts/lucida/"
EndSection
% tail -2 /usr/local/etc/X11/fontpath.d/fonts.conf
    FontPath "/usr/local/share/fonts/lucida/"
EndSection
% sudo sed -i'.SEDBAK' '/lucida/a \\
    FontPath "/usr/local/share/fonts/raize/" \
' /usr/local/etc/X11/fontpath.d/fonts.conf
% tail -2 /usr/local/etc/X11/fontpath.d/fonts.conf
    FontPath "/usr/local/share/fonts/raize/" 
EndSection
% xset q | grep -i raize
% xset fp+ /usr/local/share/fonts/raize

Refresh (rehash) the font databases.

% xset fp rehash
% xset q | grep -i raize
  /usr/local/share/fonts/misc/,/usr/local/share/fonts/TTF/, [ ... ]
---- snip ----
[ ... ],/usr/local/share/fonts/lucida,/usr/local/share/fonts/lucida,/usr/local/sh
are/fonts/raize

From the man page for xset(1):

fp rehash
        The rehash argument resets the font path to its current value,
        causing the server to reread the font databases in the current
        font path.  This is generally only used when adding new fonts
        to a font directory (after running mkfontdir to recreate the
        font database).

Note: To reset the font path to the server’s (that is, X server’s) default:

% xset fp default

4. xlsfonts(1) - List the New Font

xlsfonts(1) - Server Font List Displayer for X

List all X core fonts on the system:

% xlsfonts | wc -l
   25462
% sudo xlsfonts | wc -l
Password:
   25462

The newly installed ‘raize’ font is now displayed in xlsfonts output:

% xlsfonts | grep -i raize
-fontforge-raize-bold-r-normal--0-0-75-75-m-0-iso8859-1
-fontforge-raize-bold-r-normal--14-130-75-75-m-80-iso8859-1
-fontforge-raize-bold-r-normal--17-160-75-75-m-90-iso8859-1
-fontforge-raize-bold-r-normal--19-180-75-75-m-110-iso8859-1
-fontforge-raize-normal-r-normal--0-0-75-75-m-0-iso8859-1
-fontforge-raize-normal-r-normal--17-160-75-75-m-90-iso8859-1
-fontforge-raize-normal-r-normal--19-180-75-75-m-110-iso8859-1
-fontforge-raize-regular-r-normal--0-0-75-75-m-0-iso8859-1
-fontforge-raize-regular-r-normal--14-130-75-75-m-80-iso8859-1

To see all the characters in the newly installed font; for example, with Bold weight, pixel size 14, point size 130, dpi 75:

% xfd -fn -fontforge-raize-bold-r-normal--14-130-75-75-m-80-iso8859-1 

NOTE: Also see the man page for xfontsel(1).

Similarly, to start xterm with the newly installed font:

% xterm -fn -fontforge-raize-bold-r-normal--19-180-75-75-m-110-iso8859-1

NOTE: If the value for the ‘-fn’ option has white spaces, enclose it in quotes (").

NOTE: For Xft fonts, the option to use for specifying the font in xterm is -fa.

NOTE: Usually you don’t need to refresh Xft cache (by running fc-cache -fv).

% fc-list | grep -i raize
/usr/local/share/fonts/raize/raize-bold-17.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-bold-14.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-normal-17.pcf.gz: FontForge Raize:style=Regular
/usr/local/share/fonts/raize/raize-bold-19.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-normal-14.pcf.gz: FontForge Raize:style=Regular
/sr/local/shame/fonts/raize/raize-normal-19.pcf.gz: FontForge Raize:style=Regular
% fc-list : fullname | grep -i raize
:fullname=FontForge Raize Bold
:fullname=FontForge Raize Regular
% fc-list : postscriptname | grep -i raize
:postscriptname=FontForge-Raize
% xterm -fa "FontForge Raize Regular"

% xterm -fa "FontForge Raize Regular" -fs 12
 
% xterm -fa "FontForge-Raize"

% xterm -fa "FontForge-Raize" -fs 12

NOTE for fc-match(1): It best matches the whole pattern you are looking for:

On this system, the default font is DejaVuSans.

% fc-match default
DejaVuSans.ttf: "DejaVu Sans" "Book"

When the fc-match doesn’t find the font, it displays the default, which on this system is DejaVuSans:

% fc-match raize
DejaVuSans.ttf: "DejaVu Sans" "Book"

% fc-match Raize
DejaVuSans.ttf: "DejaVu Sans" "Book"

% fc-match "FontForge Raize Regular"
DejaVuSans.ttf: "DejaVu Sans" "Book"

% fc-match "FontForge Raize Bold"
DejaVuSans.ttf: "DejaVu Sans" "Book"

Only this works:

% fc-match "FontForge Raize"

Output:

raize-normal-14.pcf.gz: "FontForge Raize" "Regular"

Also, with fc-list : family:

% fc-list : family | grep -i raize
FontForge Raize
% fc-list "FontForge Raize"
/usr/local/share/fonts/raize/raize-bold-17.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-bold-14.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-normal-17.pcf.gz: FontForge Raize:style=Regular
/usr/local/share/fonts/raize/raize-bold-19.pcf.gz: FontForge Raize:style=Bold
/usr/local/share/fonts/raize/raize-normal-14.pcf.gz: FontForge Raize:style=Regular
/usr/local/share/fonts/raize/raize-normal-19.pcf.gz: FontForge Raize:style=Regular

Using :style=

% xterm -fa "FontForge-Raize:style=Regular" -fs 10
% xterm -fa "FontForge-Raize:style=Bold" -fs 10

For other options (for example, antialias or autohint), use fc-match(1):

% fc-match --verbose "FontForge Raize"
Pattern has 43 elts (size 48)
        family: "FontForge Raize"(s)
        familylang: "en"(s)
        style: "Regular"(s)
        stylelang: "en"(s)
        fullname: "FontForge Raize Regular"(w)
        fullnamelang: "en"(s)
        slant: 0(i)(s)
        weight: 80(f)(s)
        width: 100(f)(s)
        size: 13.44(f)(w)
        pixelsize: 14(f)(s)
        spacing: 100(i)(s)
        foundry: "FontForge"(s)
        antialias: True(w)
        hintstyle: 0(i)(w)
        hinting: False(w)
        verticallayout: False(s)
        autohint: False(s)
        globaladvance: True(s)
        file: "/usr/local/share/fonts/raize/raize-normal-14.pcf.gz"(s)
        index: 0(i)(w)
        outline: False(s)
        scalable: False(s)
        dpi: 100(f)(w)
        rgba: 5(i)(w)
        scale: 1(f)(s)
        matrix: [0.892857 0; 0 0.892857](w)
        charset: 
        0000: 00000000 ffffffff ffffffff ffffffff 00000000 ffffffff ffffffff ffffffff
(s)
        lang: aa|ay|bi|br|ch|da|de|en|es|eu|fj|fo|fur|fy|gd|gl|gv|ho|ia|id|ie|io|is|it|lb|mg|nb|nds|nl|nn|no|nr|oc|om|pt|rm|sma|smj|so|sq|ss|st|sv|sw|tl|ts|uz|vo|wa|xh|yap|zu|an|fil|ht|jv|kj|kwm|li|ms|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(s)
        fontversion: 0(i)(s)
        fontformat: "PCF"(s)
        embeddedbitmap: False(w)
        decorative: False(s)
        lcdfilter: 1(i)(w)
        namelang: "en"(s)
        prgname: "fc-match"(s)
        postscriptname: "FontForge-Raize"(s)
        color: False(s)
        symbol: False(s)
        variable: False(s)
        fonthashint: False(s)
        order: 0(i)(s)
        pixelsizefixupfactor: 0.892857(f)(w)

So, for example:

% fc-match --verbose "Monoid"
---- snip ----
% xterm -fa "Monoid:style=Regular:antialias=false" -fs 12
% xterm -fa "Monoid:style=Bold:autohint=true:antialias=false" -fs 12

For further customization (Xft so not aplicable for the Raize font) refer to Fontconfig rules, which are on FreeBSD 13 found in /usr/local/etc/fonts/ directory:

% ls -F /usr/local/etc/fonts/
conf.avail/             fonts.conf              fonts.dtd
conf.d/                 fonts.conf.sample
% ls /usr/local/etc/fonts/conf.avail/
05-reset-dirs-sample.conf               30-metric-aliases.conf
09-autohint-if-no-hinting.conf          35-lang-normalize.conf
10-autohint.conf                        40-nonlatin.conf
10-hinting-full.conf                    42-luxi-mono.conf
10-hinting-medium.conf                  45-generic.conf
10-hinting-none.conf                    45-latin.conf
10-hinting-slight.conf                  48-spacing.conf
10-no-antialias.conf                    49-sansserif.conf
10-scale-bitmap-fonts.conf              50-user.conf
10-sub-pixel-bgr.conf                   51-local.conf
10-sub-pixel-none.conf                  57-dejavu-sans-mono.conf
10-sub-pixel-rgb.conf                   57-dejavu-sans.conf
10-sub-pixel-vbgr.conf                  57-dejavu-serif.conf
10-sub-pixel-vrgb.conf                  60-generic.conf
10-unhinted.conf                        60-latin.conf
10-yes-antialias.conf                   65-fonts-persian.conf
11-lcdfilter-default.conf               65-khmer.conf
11-lcdfilter-legacy.conf                65-nonlatin.conf
11-lcdfilter-light.conf                 69-unifont.conf
20-unhint-small-dejavu-sans-mono.conf   70-no-bitmaps.conf
20-unhint-small-dejavu-sans.conf        70-yes-bitmaps.conf
20-unhint-small-dejavu-serif.conf       80-delicious.conf
20-unhint-small-vera.conf               90-synthetic.conf
25-unhint-nonlatin.conf

The otfinfo(1) is also useful otfinfo(1) but not in the case of a monspaced bitmap font, such as in the above examle (Raize font) as otfinfo reports information about OpenType fonts.

% otfinfo --help
‘Otfinfo’ reports information about an OpenType font to standard output.
Options specify what information to print.

Usage: otfinfo [-sfzpg | OPTIONS] [OTFFILES...]

Query options:
  -s, --scripts                Report font’s supported scripts.
  -f, --features               Report font’s GSUB/GPOS features.
  -z, --optical-size           Report font’s optical size information.
  -p, --postscript-name        Report font’s PostScript name.
  -a, --family                 Report font’s family name.
  -v, --font-version           Report font’s version information.
  -i, --info                   Report font’s names and designer/vendor info.
  -g, --glyphs                 Report font’s glyph names.
  -t, --tables                 Report font’s OpenType tables.
  -T, --dump-table NAME        Output font’s ‘NAME’ table.

Other options:
      --script=SCRIPT[.LANG]   Set script used for --features [latn].
  -V, --verbose                Print progress information to standard error.
  -h, --help                   Print this message and exit.
  -q, --quiet                  Do not generate any error messages.
      --version                Print version number and exit.

Report bugs to <ekohler@gmail.com>.

Tip - DPI

% xlsfonts -fn "-*-*-*-*-*-*-*-*-96-96-*-*-iso8859-1" | wc -l
     371
% xlsfonts -fn "-*-*-*-*-*-*-*-*-96-96-*-*-*-1" | wc -l
     783
% xlsfonts -fn "-*-*-*-*-*-*-*-*-96-96-*-*-*-*" | wc -l
    4528
% xrandr | grep -w connected
eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 276mm x 155mm
HDMI-2 connected 2560x1080+0+0 (normal left inverted right x axis y axis) 798mm x 334mm

eDP-1 is my laptop’s screen.
HDMI-2 is my external monitor’s screen.

% xrandr | grep -w disconnected
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)

Scaling - aka DPI Scaling

% xrandr --output eDP-1 --scale 0.8x0.8

My Distraction-Free Writing App

% xterm -fn "-*-dejavu sans mono-*-*-*-*-*-280-*-*-*-*-*-*"
% xterm -fn -xos4-terminus-medium-r-normal--32-320-72-72-c-316-iso8859-1 \
 -geometry 80x33

EXPLANATION:

% xlsfonts | wc -l
   13812
% xlsfonts | grep -i terminus | wc -l
     380
% xlsfonts | grep -i terminus | grep iso8859 | wc -l
     208
% xlsfonts | grep -i terminus | grep "iso8859-1" | wc -l
     100
% xlsfonts | grep -i terminus | grep -w "iso8859-1" | wc -l
      24
% xlsfonts | grep -i terminus | grep -w "iso8859-1" | tail -1
-xos4-terminus-medium-r-normal--32-320-72-72-c-160-iso8859-1

Test the last one:

% xterm -fn -xos4-terminus-medium-r-normal--32-320-72-72-c-160-iso8859-1

This one works:

% xterm -fn -xos4-terminus-medium-r-normal--32-320-72-72-c-316-iso8859-1

Launch xfontsel(1).

I use a dark Nord theme (configured in my ~/.Xresources) so my xfontsel window has a dark background.

Nord - An arctic, north-bluish color palette
Nord - Xresources port
The content of the nord file to be copied into the ```~/.Xresources

% xfontsel

Displaying xfontsel with a dark Nordic theme

To launch xfontsel with its usual colours:

% xfontsel -bg white -fg black

Displaying xfontsel

For example, to list all monospaced fonts; that is, all X core monospaced (XLFD) fonts:

% xlsfonts -fn "-*-*-*-*-*-*-*-*-*-*-m-*-*-*" | wc -l
    3918
% xlsfonts -fn "-*-*-*-*-*-*-*-*-*-*-m-*-*-*"
---- snip ----

Test changing the value of the avgWdth XLFD field name.

% xlsfonts -fn "-xos4-terminus-medium-*-*--*-*-*-*-*-*-*-*" | wc -l
     154
% xlsfonts -fn "-xos4-terminus-medium-*-*--*-*-*-*-*-*-*-*" | grep -w 'iso8859-1' | wc -l
      11
% xlsfonts -fn "-xos4-terminus-medium-*-*--*-*-*-*-*-*-*-*" | grep -w 'iso8859-1' 
-xos4-terminus-medium-r-normal--0-0-72-72-c-0-iso8859-1
-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1
-xos4-terminus-medium-r-normal--14-140-72-72-c-80-iso8859-1
-xos4-terminus-medium-r-normal--16-160-72-72-c-80-iso8859-1
-xos4-terminus-medium-r-normal--17-120-100-100-c-0-iso8859-1
-xos4-terminus-medium-r-normal--18-180-72-72-c-100-iso8859-1
-xos4-terminus-medium-r-normal--20-200-72-72-c-100-iso8859-1
-xos4-terminus-medium-r-normal--22-220-72-72-c-110-iso8859-1
-xos4-terminus-medium-r-normal--24-240-72-72-c-120-iso8859-1
-xos4-terminus-medium-r-normal--28-280-72-72-c-140-iso8859-1
-xos4-terminus-medium-r-normal--32-320-72-72-c-160-iso8859-1

Converting a File from an 8-bit Character Set (For Example ISO_8859-1) to UTF-8 without POSTing the File to a Remote server

Converting a file from an 8-bit character set (for example ISO_8859-1) to UTF-8 without POSTing the file to a remote server (Retrieved on Apr 17, 2022):

 In many cases, the most obvious way to solve such a problem is to save the file, open a terminal, move to the directory where the file resides (with cd …) and use iconv similarly to:

iconv -f iso88591 -t utf8 fileToConvert.txt > convertedFile.txt

Unfortunately, finding out how to start a terminal is not always easy in today’s GUI’s!

Here, you are given the opportunity to achieve such a conversion locally. Choose a character set (charset, encoding) in the list below and choose the file you wish to convert. The JavaScript program linked to by this page will try to make your browser convert the file to UTF-8. If the conversion succeeds, you will be given the opportunity to save the converted file.

You do not need any Internet connection to achieve this conversion. You can save this page locally together with (in the same directory than) the JavaScript program it is linked to and open it in a browser to achieve the conversions even without any Internet connection.

Comments and suggestions may be sent to saasha@acc.umu.se.

References

XLFD

X Logical Font Description (XLFD) - archlinux Wiki

X resources (Xresources) - archlinux Wiki

Fonts in X11R7.5 - x.org

Fonts in X11R7.5 (PDF) - x.org

Font HOWTO - faqs.org

Fonts in the X Window System

ProFont

Fonts in X11R6.8 - x.org – Section 2. Installing fonts

Using the X Window System - HP (Hewlett Packard Manual)

Solaris X Window System Reference Manual

Change font size - Tiny Core Linux Forums

Tecate/bitmap-fonts: Monospaced bitmap fonts for X11, good for terminal use

Bitmap fonts - Debian User Forums

Dejavu Sans not listed by xlsfonts and missing in xfontsel - Debian User Forums

Valid autohinting / hinting style options

Xft

An Xft Tutorial - Keith Packard - XFree86 Core Team, SuSE Inc.

XFT Support - What is XFT? - Tcler’s Wiki (Tcl/Tk Wiki)

X11 fonts - a tutorial

Texts Rasterization Exposures by Maxim Shemanarev (from archive.org)

https://vector-agg-general.narkive.com/1wMI33Jj/agg-r-i-p-maxim-shemanarev

Creature of habit

DPI

[SOLVED] Dpi issues on high resolution screen, mainly XTerm - linuxquestions.org Forums

HiDPI (High Dots Per Inch) Displays - archlinux Wiki

Display size and DPI - archlinux Wiki

Installing Xft Fonts (aka Fontconfig)

% ls -alh /usr/local/share/fonts/ | wc -l
      42

% ls -lh /usr/local/share/fonts/ | wc -l
      40
% ls -ld /usr/local/etc/fonts/
drwxr-xr-x  4 root  wheel  7 Feb  3  2022 /usr/local/etc/fonts/

% ls -alh /usr/local/etc/fonts/ | wc -l
       8

% ls -lh /usr/local/etc/fonts/ | wc -l
       6
% ls -lh /usr/local/etc/fonts/
total 79
drwxr-xr-x  2 root  wheel    51B Feb  3  2022 conf.avail
drwxr-xr-x  2 root  wheel    33B Feb  3  2022 conf.d
-rw-r--r--  1 root  wheel   2.6K Jan 21  2022 fonts.conf
-rw-r--r--  1 root  wheel   2.6K Jan 21  2022 fonts.conf.sample
-rw-r--r--  1 root  wheel   8.1K Dec  3  2020 fonts.dtd
% ls -alh /usr/local/etc/fonts/conf.avail/ | wc -l
      52

% ls -lh /usr/local/etc/fonts/conf.avail/ | wc -l
      50
% ls -alh /usr/local/etc/fonts/conf.d/ | wc -l
      34

% ls -lh /usr/local/etc/fonts/conf.d/ | wc -l
      32
% cat /usr/local/etc/fonts/conf.d/README
conf.d/README

Each file in this directory is a fontconfig configuration file.  Fontconfig
scans this directory, loading all files of the form [0-9][0-9]*.conf.
These files are normally installed in /usr/local/etc/fonts/conf.avail
and then symlinked here, allowing them to be easily installed and then
enabled/disabled by adjusting the symlinks.

The files are loaded in numeric order, the structure of the configuration
has led to the following conventions in usage:

 Files beginning with:  Contain:

 00 through 09          Font directories
 10 through 19          system rendering defaults (AA, etc)
 20 through 29          font rendering options
 30 through 39          family substitution
 40 through 49          generic identification, map family->generic
 50 through 59          alternate config file loading
 60 through 69          generic aliases, map generic->family
 70 through 79          select font (adjust which fonts are available)
 80 through 89          match target="scan" (modify scanned patterns)
 90 through 99          font synthesis
% ls -lh /usr/local/etc/fonts/fonts.conf*
-rw-r--r--  1 root  wheel   2.6K Jan 21  2022 /usr/local/etc/fonts/fonts.conf
-rw-r--r--  1 root  wheel   2.6K Jan 21  2022 /usr/local/etc/fonts/fonts.conf.sample
% diff /usr/local/etc/fonts/fonts.conf.sample /usr/local/etc/fonts/fonts.conf
% file /usr/local/etc/fonts/fonts.conf
/usr/local/etc/fonts/fonts.conf: XML 1.0 document, ASCII text
% wc -l /usr/local/etc/fonts/fonts.conf
     103 /usr/local/etc/fonts/fonts.conf

% sed '/^[[:space:]]*$/d' /usr/local/etc/fonts/fonts.conf | grep -v \# | wc -l
      87
% sed '/^[[:space:]]*$/d' /usr/local/etc/fonts/fonts.conf | grep -v \#
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<!-- /etc/fonts/fonts.conf file to configure system font access -->
<fontconfig>
        <description>Default configuration file</description>
<!--
        DO NOT EDIT THIS FILE.
        IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
        LOCAL CHANGES BELONG IN 'local.conf'.
        The intent of this standard configuration file is to be adequate for
        most environments.  If you have a reasonably normal environment and
        have found problems with this configuration, they are probably
        things that others will also want fixed.  Please submit any
        problems to the fontconfig bugzilla system located at fontconfig.org
        Note that the normal 'make install' procedure for fontconfig is to
        replace any existing fonts.conf file with the new version.  Place
        any local customizations in local.conf which this file references.
        Keith Packard
-->
<!-- Font directory list -->
        <dir>/usr/local/share/fonts</dir>
        <dir>/usr/local/lib/X11/fonts</dir>
        <dir prefix="xdg">fonts</dir>
        <!-- the following element will be removed in the future -->
        <dir>~/.fonts</dir>
<!--
  Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
        <match target="pattern">
                <test qual="any" name="family">
                        <string>mono</string>
                </test>
                <edit name="family" mode="assign" binding="same">
                        <string>monospace</string>
                </edit>
        </match>
<!--
  Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
-->
        <match target="pattern">
                <test qual="any" name="family">
                        <string>sans serif</string>
                </test>
                <edit name="family" mode="assign" binding="same">
                        <string>sans-serif</string>
                </edit>
        </match>
<!--
  Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
        <match target="pattern">
                <test qual="any" name="family">
                        <string>sans</string>
                </test>
                <edit name="family" mode="assign" binding="same">
                        <string>sans-serif</string>
                </edit>
        </match>
<!--
  Accept alternate 'system ui' spelling, replacing it with 'system-ui'
-->
        <match target="pattern">
                <test qual="any" name="family">
                        <string>system ui</string>
                </test>
                <edit name="family" mode="assign" binding="same">
                        <string>system-ui</string>
                </edit>
        </match>
<!--
  Load local system customization file
-->
        <include ignore_missing="yes">conf.d</include>
<!-- Font cache directory list -->
        <cachedir>/var/db/fontconfig</cachedir>
        <cachedir prefix="xdg">fontconfig</cachedir>
        <!-- the following element will be removed in the future -->
        <cachedir>~/.fontconfig</cachedir>
        <config>
<!--
  Rescan configuration every 30 seconds when FcFontSetList is called
 -->
                <rescan>
                        <int>30</int>
                </rescan>
        </config>
</fontconfig>
% ls -ld /etc/fonts/fonts.conf
ls: /etc/fonts/fonts.conf: No such file or directory

Font Directory List

% grep -n 'Font directory list' /usr/local/etc/fonts/fonts.conf
25:<!-- Font directory list -->
% sed -n 25,35p /usr/local/etc/fonts/fonts.conf
<!-- Font directory list -->

        <dir>/usr/local/share/fonts</dir>
        <dir>/usr/local/lib/X11/fonts</dir>


        <dir prefix="xdg">fonts</dir>
        <!-- the following element will be removed in the future -->
        <dir>~/.fonts</dir>

<!--

Note: ~/.fonts directory will be removed in the future:

% grep -n removed /usr/local/etc/fonts/fonts.conf
32:     <!-- the following element will be removed in the future -->
91:     <!-- the following element will be removed in the future -->
% sed -n 32,34p /usr/local/etc/fonts/fonts.conf
        <!-- the following element will be removed in the future -->
        <dir>~/.fonts</dir>
% ls -alh /usr/local/share/fonts/ | wc -l
      42

% ls -lh /usr/local/share/fonts/ | wc -l
      40
% ls /usr/local/share/fonts/
100dpi                  gnu-unifont             SourceHanSansK
75dpi                   ipamjm                  SourceHanSansSC
adobe-cmaps             jmk-x11-fonts           SourceHanSansTC
bitstream-vera          Liberation              SourceSansPro
Caladea                 LinLibertineG           symbola
cantarell               misc                    terminus-font
Carlito                 Monoid                  TerminusTTF
ChromeOS                nanum-coding-ttf        TTF
comic-neue              nanum-ttf               twemoji-color-font-ttf
cyrillic                noto                    Type1
dejavu                  OTF                     uw-ttyp0
encodings               SourceCodePro           vlgothic
GentiumBasic            SourceHanSans           wqy
% ls -ld /usr/local/lib/X11/fonts
ls: /usr/local/lib/X11/fonts: No such file or directory
% ls -ld ~/.fonts/
drwxr-xr-x  3 dusko  dusko  214 Nov 22  2021 /home/dusko/.fonts/

% ls -alh ~/.fonts/ | wc -l
     215

% ls -lh ~/.fonts/ | wc -l
     213

Font Cache Directory List

% grep -n -i list /usr/local/etc/fonts/fonts.conf
25:<!-- Font directory list -->
87:<!-- Font cache directory list -->
96:  Rescan configuration every 30 seconds when FcFontSetList is called
% sed -n 87,94p /usr/local/etc/fonts/fonts.conf
<!-- Font cache directory list -->

        <cachedir>/var/db/fontconfig</cachedir>
        <cachedir prefix="xdg">fontconfig</cachedir>
        <!-- the following element will be removed in the future -->
        <cachedir>~/.fontconfig</cachedir>

        <config>

Note: ~/.fontconfig directory will be removed in the future:

% grep -n removed /usr/local/etc/fonts/fonts.conf
32:     <!-- the following element will be removed in the future -->
91:     <!-- the following element will be removed in the future -->
% sed -n 91,92p /usr/local/etc/fonts/fonts.conf
        <!-- the following element will be removed in the future -->
        <cachedir>~/.fontconfig</cachedir>
% ls -ld /var/db/fontconfig/
drwxr-xr-x  2 root  wheel  57 Mar 31 13:49 /var/db/fontconfig/

% ls -alh /var/db/fontconfig/ | wc -l
      58

% ls -lh /var/db/fontconfig/ | wc -l
      56
% cat /var/db/fontconfig/CACHEDIR.TAG
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by fontconfig.
# For information about cache directory tags, see:
#       http://www.brynosaurus.com/cachedir/
% ls -ld ~/.fontconfig
ls: /home/dusko/.fontconfig: No such file or directory

File: fonts.alias

$ sudo locate fonts.alias
/usr/local/share/fonts/100dpi/fonts.alias
/usr/local/share/fonts/75dpi/fonts.alias
/usr/local/share/fonts/cyrillic/fonts.alias
/usr/local/share/fonts/misc/fonts.alias

List Information about Current Fonts Configuration, Font Path

$ xset -q | grep -n Font
22:Font Path:
$ xset -q | sed -n 22,23p
Font Path:
  /usr/local/share/fonts/misc/,/usr/local/share/fonts/TTF/,/usr/local/share/fonts/OTF/,/usr/local/share/fonts/Type1/,/usr/local/share/fonts/100dpi/,/usr/local/share/fonts/75dpi/,catalogue:/usr/local/etc/X11/fontpath.d,built-ins,/usr/local/share/fonts/100dpi,/usr/local/share/fonts/75dpi,/usr/local/share/fonts/adobe-cmaps,/usr/local/share/fonts/bitstream-vera,/usr/local/share/fonts/Caladea,/usr/local/share/fonts/cantarell,/usr/local/share/fonts/Carlito,/usr/local/share/fonts/ChromeOS,/usr/local/share/fonts/comic-neue,/usr/local/share/fonts/cyrillic,/usr/local/share/fonts/dejavu,/usr/local/share/fonts/GentiumBasic,/usr/local/share/fonts/gnu-unifont,/usr/local/share/fonts/ipamjm,/usr/local/share/fonts/jmk-x11-fonts,/usr/local/share/fonts/Liberation,/usr/local/share/fonts/LinLibertineG,/usr/local/share/fonts/misc,/usr/local/share/fonts/Monoid,/usr/local/share/fonts/nanum-coding-ttf,/usr/local/share/fonts/nanum-ttf,/usr/local/share/fonts/noto,/usr/local/share/fonts/OTF,/usr/local/share/fonts/SourceCodePro,/usr/local/share/fonts/SourceHanSans,/usr/local/share/fonts/SourceHanSansK,/usr/local/share/fonts/SourceHanSansSC,/usr/local/share/fonts/SourceHanSansTC,/usr/local/share/fonts/SourceSansPro,/usr/local/share/fonts/symbola,/usr/local/share/fonts/terminus-font,/usr/local/share/fonts/TerminusTTF,/usr/local/share/fonts/TTF,/usr/local/share/fonts/twemoji-color-font-ttf,/usr/local/share/fonts/Type1,/usr/local/share/fonts/uw-ttyp0,/usr/local/share/fonts/vlgothic,/usr/local/share/fonts/wqy,/usr/home/dusko/.fonts/knxt

fc-cache(1) - Build Font Information Cache Files

To refresh only system fonts:

% fc-cache -sv

From the man page for fc-cache(1):

DESCRIPTION
       fc-cache scans the font directories on the system and builds font
       information cache files for applications using fontconfig for their
       font handling.
-s     Only scan system-wide directories, omitting the places located
       in the user's home directory.

-v     Display status information while busy.

To force refresh fonts cache:

% fc-cache -fv
-f     Force re-generation of apparently up-to-date cache files,
       overriding the timestamp checking.

Erase all existing cache files and rescan:

% fc-cache -rv

fc-list(1) - List Available Fonts

From the man page for fc-list(1):

DESCRIPTION
       fc-list lists fonts and styles available on the system for applications
       using fontconfig.  If any elements are specified, only those are
       printed.  Otherwise family and style are printed, unless verbose output
       is requested.

Number of fontconfig fonts available to the user (lists all font faces):

% fc-list | wc -l
    3182

Number of fontconfig fonts available to root user (lists all font faces):

% sudo fc-list | wc -l
Password:
    2966

fc-conflist(1) - Show the ruleset files information on the system

% fc-conflist | wc -l
      51

% sudo fc-conflist | wc -l
      50
% fc-conflist | grep dusko
+ /home/dusko/.config/fontconfig/fonts.conf: No description
% sudo fc-conflist | grep dusko
% ls -lh /home/dusko/.config/fontconfig/fonts.conf
-rw-r--r--  1 dusko  dusko   1.8K Oct 21  2021 /home/dusko/.config/fontconfig/fonts.conf

[TODO]: Courtesy of vermaden:

% wc -l /home/dusko/.config/fontconfig/fonts.conf
      52 /home/dusko/.config/fontconfig/fonts.conf
% cat /home/dusko/.config/fontconfig/fonts.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">

<fontconfig>

  <!-- ANTIALIAS ALL FONTS -->
  <match target="font">
    <edit name="antialias" mode="assign"><bool>true</bool></edit>
    <edit name="hinting"   mode="assign"><bool>false</bool></edit>
    <edit name="hintstyle" mode="assign"><int>0</int></edit>
    <edit name="dpi"       mode="assign"><double>75</double></edit>
    <edit name="rgba"      mode="assign"><const>none</const></edit>
    </match>

  <!-- REPLACE THESE WITH A BETTER LOOKING FONT (MONO) -->
  <match target="pattern">
    <test name="family"    qual="any"><string>Courier [Adobe]</string></test>
    <edit name="family" mode="assign"><string>Courier 10 Pitch</string></edit>
    </match>

  <match target="pattern">
    <test name="family"    qual="any"><string>Fixed</string></test>
    <edit name="family" mode="assign"><string>Courier 10 Pitch</string></edit>
    </match>

  <match target="pattern">
    <test name="family"    qual="any"><string>courier</string></test>
    <edit name="family" mode="assign"><string>Courier 10 Pitch</string></edit>
    </match>

  <!-- REPLACE THESE WITH A BETTER LOOKING FONT (SANS) -->
  <match target="pattern">
    <test name="family"    qual="any"><string>helvetica</string></test>
    <edit name="family" mode="assign"><string>arial</string></edit>
    </match>

  <match target="pattern">
    <test name="family"    qual="any"><string>times</string></test>
    <edit name="family" mode="assign"><string>garamond</string></edit>
    </match>

  <match target="pattern">
    <test name="family"    qual="any"><string>lucida</string></test>
    <edit name="family" mode="assign"><string>trebuchet ms</string></edit>
    </match>

  <!-- DISABLE EMBEDDED BITMAPS -->
  <match target="font" >
    <edit name="embeddedbitmap" mode="assign"><bool>false</bool></edit>
    </match>

</fontconfig>

Useful Tools, Commands and Code Snippets for Exploring Fonts in X11

Start xterm with red cursor, font Source Code Pro and font size 18:

% xterm -cr red -fa 'Source Code Pro' -fs 18

Note: The -fa option enables xterm to render Xft fonts (a.k.a. fontconfig).

The venerable file(1):

% file /usr/local/share/fonts/SourceCodePro/SourceCodePro-Regular.ttf
/usr/local/share/fonts/SourceCodePro/SourceCodePro-Regular.ttf: TrueType Font data, digitally signed, 15 tables, 1st "BASE", 72 names, Microsoft, language 0x408, type 256 string, \261\300\273\314 a\261\300\273\314 gi & l \274\265 \261\272\301\265\274\314\275\265\302\243\254\

Report information about OpenType fonts with otfinfo(1):

% otfinfo --info /usr/local/share/fonts/SourceCodePro/SourceCodePro-Regular.ttf
% otfinfo --features /usr/local/share/fonts/SourceCodePro/SourceCodePro-Regular.ttf

Print supported scripts and languages:

% otfinfo --scripts /usr/local/share/fonts/SourceCodePro/SourceCodePro-Regular.ttf

Output:

DFLT            Default
cyrl            Cyrillic
cyrl.SRB        Cyrillic/Serbian
grek            Greek
latn            Latin
latn.ATH        Latin/Athapaskan
latn.NSM        Latin/Northern Sami
latn.SKS        Latin/Skolt Sami

Other interesting otfinfo’s options:

-g, --glyphs
     Print the name of every glyph in each font, one per line.

-u, --unicode
     Print each Unicode code point supported by the font, followed by
     the glyph number representing that code point (and, if present,
     the name of the corresponding glyph).

-t, --tables
     Print the size and name of every OpenType table in the font.
-z, --optical-size
     Print optical size information.

-p, --postscript-name
      Print each font's PostScript name.

-a, --family
     Print each font's family name.
$ xset -q
Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000000
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  660    repeat rate:  25
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  0    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  2/1    threshold:  4
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  600    cycle:  600
Colors:
  default colormap:  0x22    BlackPixel:  0x0    WhitePixel:  0xffffff
Font Path:
  /usr/local/share/fonts/misc/,/usr/local/share/fonts/TTF/,/usr/local/share/fonts/OTF/,/usr/local/share/fonts/Type1/,/usr/local/share/fonts/100dpi/,/usr/local/share/fonts/75dpi/,catalogue:/usr/local/etc/X11/fontpath.d,built-ins,/usr/local/share/fonts/100dpi,/usr/local/share/fonts/75dpi,/usr/local/share/fonts/adobe-cmaps,/usr/local/share/fonts/bitstream-vera,/usr/local/share/fonts/Caladea,/usr/local/share/fonts/cantarell,/usr/local/share/fonts/Carlito,/usr/local/share/fonts/ChromeOS,/usr/local/share/fonts/comic-neue,/usr/local/share/fonts/cyrillic,/usr/local/share/fonts/dejavu,/usr/local/share/fonts/GentiumBasic,/usr/local/share/fonts/gnu-unifont,/usr/local/share/fonts/ipamjm,/usr/local/share/fonts/jmk-x11-fonts,/usr/local/share/fonts/Liberation,/usr/local/share/fonts/LinLibertineG,/usr/local/share/fonts/misc,/usr/local/share/fonts/Monoid,/usr/local/share/fonts/nanum-coding-ttf,/usr/local/share/fonts/nanum-ttf,/usr/local/share/fonts/noto,/usr/local/share/fonts/OTF,/usr/local/share/fonts/politika-otf,/usr/local/share/fonts/politika-ttf,/usr/local/share/fonts/SourceCodePro,/usr/local/share/fonts/SourceHanSans,/usr/local/share/fonts/SourceHanSansK,/usr/local/share/fonts/SourceHanSansSC,/usr/local/share/fonts/SourceHanSansTC,/usr/local/share/fonts/SourceSansPro,/usr/local/share/fonts/symbola,/usr/local/share/fonts/terminus-font,/usr/local/share/fonts/TerminusTTF,/usr/local/share/fonts/TTF,/usr/local/share/fonts/twemoji-color-font-ttf,/usr/local/share/fonts/Type1,/usr/local/share/fonts/uw-ttyp0,/usr/local/share/fonts/vlgothic,/usr/local/share/fonts/wqy,/usr/home/dusko/.fonts/knxt
DPMS (Energy Star):
  Standby: 600    Suspend: 600    Off: 600
  DPMS is Enabled
  Monitor is On

NOTE the content of the Font Path: line.

$ xrdb -query
! screen-independent resources
XTerm*saveLines:        1048576
XTerm*loginShell:       true
XTerm*charClass:        33:48,35:48,37:48,43:48,45-47:48,64:48,95:48,126:48
XTerm*eightBitInput:    false
XTerm*borderWidth:      4
Xcursor.theme:  Vanilla-DMZ
XTerm*cursorBlink:      true
XTerm*scrollKey:        true
XTerm*colorUL:  Yellow
XTerm*colorULMode:      true
XTerm*cursorColor:      Cyan
XTerm*background:       Black
XTerm*foreground:       White
XTerm*locale:   UTF-8
XTerm*faceNameDoublesize:       Noto Serif CJK JP
XTerm*scrollTtyOutput:  false
XTerm*selectToClipboard:        true
Xft.autohint:   0
Xft.antialias:  1
Xft.hinting:    1
Xft.rgba:       rgb
Xft.hintstyle:  hintlight
Xft.lcdfilter:  lcddefault
*VT100.Translations:    #override Button1 <Btn3Down>: select-end(PRIMARY,CUT_BUFFER0,CLIPBOARD) \n !Shift <Btn2Up>: insert-selection(CLIPBOARD) \n ~Shift ~Ctrl ~Meta <Btn2Up>: insert-selection(PRIMARY,CUT_BUFFER0) \n <Key>F3: string("cd ~/scratch/tmpscratch2") string(0x0d) \n Alt <Key>t: string("date | dzen2 -xs 2 -p 5 -bg blue") string(0x0d)
Xmessage*Scrollbar.thumb:       vlines2
Xmessage*Scrollbar.width:       2

! screen 0 resources
#if SCREEN_NUM == 0
#endif

! screen 1 resources
#if SCREEN_NUM == 1
#endif

NOTE: This environment has two monitors so there are references to both of them: #if SCREEN_NUM == 0 and #if SCREEN_NUM == 1.

NOTE: The *VT100.Translations: is my own customization.


List all monospaced fonts:

$ fc-list | cut -f2 -d: | sort -u | grep -i Mono

Print out the fixed width fonts that are available: $ fc-list :scalable=true:spacing=mono:

Print out the fixed width fonts that are available with their family name: $ fc-list :scalable=true:spacing=mono: family

Sort and page through the available fonts - not only fixed width fonts:

$ fc-list | cut -f2 -d: | sort -u | less

To test the status of your colour support in XTerm:

$ tput colors
80

References:
(Retrieved on Apr 17, 2022)

XTerm introduction and TrueType fonts configuration

XTerm colour set-up and Molokai theme

Installing an Xft Font (aka Fontconfig) - A Full Example

OS: FreeBSD 13.0
Shell: csh

$ fc-list | wc -l
    3186
 
$ sudo fc-list | wc -l
    2968
$ fc-list | grep -i hermit
$ sudo fc-list | grep -i hermit
$ xlsfonts | wc -l
   25462
 
$ sudo xlsfonts | wc -l
   25462
$ xlsfonts | grep -i hermit
$ sudo xlsfonts | grep -i hermit
$ pkg search hermit
hermit-font-2.0_1      Monospaced font for programmers by a programmer
$ sudo pkg install hermit-font
$ fc-list | wc -l
    3192
 
$ sudo fc-list | wc -l
    2974
$ fc-list | grep -i hermit | wc -l
       6

$ sudo fc-list | grep -i hermit | wc -l
       6
$ fc-list | grep -i hermit
/usr/local/share/fonts/hermit/Hermit-LightItalic.otf: Hermit,Hermit LightItalic:style=LightItalic,Regular
/usr/local/share/fonts/hermit/Hermit-Bold.otf: Hermit:style=Bold
/usr/local/share/fonts/hermit/Hermit-Regular.otf: Hermit:style=Regular
/usr/local/share/fonts/hermit/Hermit-RegularItalic.otf: Hermit:style=RegularItalic,Italic
/usr/local/share/fonts/hermit/Hermit-Light.otf: Hermit,Hermit Light:style=Light,Regular
/usr/local/share/fonts/hermit/Hermit-BoldItalic.otf: Hermit:style=BoldItalic
$ xlsfonts | wc -l
   25462

$ sudo xlsfonts | wc -l
   25462
$ xlsfonts | grep -i hermit
$ sudo xlsfonts | grep -i hermit
$ fc-list : fullname | grep -i hermit | wc -l
       6

$ fc-list : fullname | grep -i hermit
:fullname=Hermit Bold
:fullname=Hermit Light
:fullname=Hermit RegularItalic
:fullname=Hermit BoldItalic
:fullname=Hermit LightItalic
:fullname=Hermit Regular
$ fc-list : postscriptname | grep -i hermit | wc -l
       6

$ fc-list : postscriptname | grep -i hermit
:postscriptname=Hermit-Regular
:postscriptname=Hermit-RegularItalic
:postscriptname=Hermit-LightItalic
:postscriptname=Hermit-Bold
:postscriptname=Hermit-Light
:postscriptname=Hermit-BoldItalic
$ fc-match hermit 
Hermit-Regular.otf: "Hermit" "Regular"
$ fc-match Hermit
Hermit-Regular.otf: "Hermit" "Regular"
$ fc-query /usr/local/share/fonts/hermit/Hermit-Regular.otf | wc -l
      41
$ fc-query /usr/local/share/fonts/hermit/Hermit-Regular.otf 
---- snip ----
$ file /usr/local/share/fonts/hermit/Hermit-Regular.otf
/usr/local/share/fonts/hermit/Hermit-Regular.otf: OpenType font data
$ otfinfo --info /usr/local/share/fonts/hermit/Hermit-Regular.otf
---- snip ----
$ otfinfo --features /usr/local/share/fonts/hermit/Hermit-Regular.otf
---- snip ----
$ otfinfo --scripts /usr/local/share/fonts/hermit/Hermit-Regular.otf
---- snip ----
$ otfinfo --glyphs /usr/local/share/fonts/hermit/Hermit-Regular.otf | wc -l
     393
$ otfinfo --glyphs /usr/local/share/fonts/hermit/Hermit-Regular.otf | wc -l
---- snip ----
$ otfinfo --unicode /usr/local/share/fonts/hermit/Hermit-Regular.otf | wc -l
     391
$ otfinfo --unicode /usr/local/share/fonts/hermit/Hermit-Regular.otf 
---- snip ----
$ otfinfo --font-version /usr/local/share/fonts/hermit/Hermit-Regular.otf
Version 2.000;PS 002.000;hotconv 1.0.88;makeotf.lib2.5.64775
$ otfinfo --optical-size /usr/local/share/fonts/hermit/Hermit-Regular.otf
$ otfinfo --postscript-name /usr/local/share/fonts/hermit/Hermit-Regular.otf
Hermit-Regular
$ fc-list -v Hermit-Regular charset 
---- snip ----
$ fc-list -v Hermit-Regular
---- snip ----
$ xfd -fa Hermit
$ xterm -fa Hermit -fs 14
$ xterm -fa 'Hermit:light' -fs 14

NOTE: Font face size (-fs option for xterm) and pixelsize are not the same so the following two are different:

$ xterm -fa 'Hermit:light:pixelsize=14:antialias=true:autohint=true'
$ xterm -fa 'Hermit:light:antialias=true:autohint=true' -fs 14

This table gives an approximate conversion between points and pixels:
Approximate conversion from points to pixels - ReedDesign:

Here’s a chart that converts points to pixels (and ems and %). It’s an approximation, which will depend on font, browser and OS, but it’s a good starting point.

As per that table, 14pt is approximately 19px:

$ xterm -fa 'Hermit:light:pixelsize=19:antialias=true:autohint=true'

and that’s the same (similar) to the font face size of 14:
$ xterm -fa 'Hermit:light:antialias=true:autohint=true' -fs 14

Hermit font setup reference:
Eric Radman - Workstation Notes (Retrieved on Apr 17, 2022)

Converting Unicode to UTF-8

A Short Introduction

NOTE: Not going into details about different operating systems, different shells, different fonts, locales, different editors, different ordering and byte format (7-bit, 8-bit, single byte, double byte, multi-byte), double-wide characters, collation, endianness, composing & decomposing, UTF-8 vs. UTF-16 vs. UTF-32 1, etc.

Here’s just a few references to illustrate how complex this area is:

Software requirements for different levels of Unicode Support (Retrieved on Apr 17, 2022):

Vim supports editing Unicode in the GUI version and in terminals that support UTF-8. Double-wide characters can be used, and up to two composing characters are supported. When reading a file, Vim can often detect how it is encoded and convert the text when necessary. UTF-8 files are edited without conversion. Other Unicode formats (16 bit and 32 bit) are converted internally. Conversion is also used to edit files in just about any encoding, using an external converter.

About Vim’s Unicode support - from What is ncurses? - by Thomas E. Dickey, developer and maintainer of xterm
(Updated on Mar 16, 2022) (Retrieved on Apr 17, 2022):

Vim
Vim’s developers provide their own termcap definitions, just in case there is nothing good enough on the system, and provide features for overriding the system’s termcap capabilities even when using the system definition as a starting point. Because of this, vim has had little impact on ncurses development; the change-log does not mention vim. On the other hand, unlike screen, the source-code for vim still contains a comment about a bug in ncurses which was addressed in late 1997, before ncurses 4.2 was released.

History of - What is the relation between vi, nvi and vim? - Vi and Vim Stack Exchange (Retrieved on Apr 17, 2022)

From The Traditional Vi (Retrieved on Apr 17, 2022):

This port of vi has generally preserved the original style, terminal control, and feature set. It adds support for international character sets, including multibyte encodings such as UTF-8 (emphasis mine), and some minor enhancements that were not present in BSD vi 3.7, but had been included in later vi versions for System V or in POSIX.2.

and

From The Traditional Vi README (Retrieved on Apr 17, 2022):

Welcome to the ex/vi port!
==========================

This implementation is derived from ex/vi 3.7 of 6/7/85 and the BSD
termcap library, originally from the 2.11BSD distribution. All of them
were changed to compile and run on newer POSIX compatible Unix systems.
Support for international character sets was added, including support
for multibyte locales (based on UTF-8 or East Asian encodings), and some
changes were made to get closer to the POSIX.2 guidelines for ex and
vi. Some issues that were clearly bugs and not features have also been
resolved; see the Changes file for details.

On FreeBSD 13.1 - RELEASE:

% command -v vi; type vi; whereis vi; which vi
/usr/bin/vi
vi is /usr/bin/vi
vi: /usr/bin/vi /usr/share/man/man1/vi.1.gz
/usr/bin/vi
% ls -lh /usr/bin/vi
-r-xr-xr-x  6 root  wheel   463K Jul 27 11:06 /usr/bin/vi
% command -v nvi; type nvi; whereis nvi; which nvi
/usr/bin/nvi
nvi is /usr/bin/nvi
nvi: /usr/bin/nvi /usr/share/man/man1/nvi.1.gz
/usr/bin/nvi
 
% ls -lh /usr/bin/nvi
-r-xr-xr-x  6 root  wheel   463K Jul 27 11:06 /usr/bin/nvi
% diff /usr/bin/vi /usr/bin/nvi

Reference:
From a FreeBSD Forum post started on Dec 24, 2014
How do I type in special characters, such as ∞ in the terminal in vi?, post #3 https://forums.FreeBSD.org/threads/how-do-i-type-in-special-characters-such-as-in-the-terminal-in-vi.49659/post-277491 (Retrieved on Apr 17, 2022): 2

For a complete and detailed list of differences and improvements, here’s the official Differences between Vim and Vi document at the Vim help files site (an HTML version of the Vim help pages).


Converting Unicode to UTF-8 When You Know Unicode Code Point

Note: Code point is also known as codepoint or code position.

Converting with od(1)

OS: FreeBSD 13.1
Shell: csh

For example, use the character U+02B7: MODIFIER LETTER SMALL W for testing:
U+02B7: MODIFIER LETTER SMALL W

Charbase - A visual Unicode database (Retrieved on Apr 17, 2022)

Charbase is a visual database of characters from the Unicode 6.1 standard, made available without clutter.

With uni.pl Perl script, obtained from Leah Neukirchen’s dotfiles and bin section:
uni PATTERN - list unicode symbols matching PATTERN) (Retrieved on Apr 17, 2022):

% ./uni.pl ʷ
ʷ       02B7    MODIFIER LETTER SMALL W

% printf ʷ > chartest
% cat chartest
ʷ% 
% od -ac chartest
0000000   ca  b7
           ʷ  **
0000002
% printf %s\\n ʷ > chartest
% cat chartest
ʷ
% od -ac chartest
0000000   ca  b7  nl
           ʷ  **  \n
0000003
% od -N 1 -ac chartest
0000000   ca
         312
0000001

This is a 2-byte character:

% od -N 2 -ac chartest
0000000   ca  b7
           ʷ  **
0000002

In UTF-8, this character is CA B7:

% od -N 2 -t x1 chartest
0000000    ca  b7
0000002
% od -N 2 -c -t x1 chartest
0000000    ʷ  **
           ca  b7
0000002
% od -N 2 -ab chartest
0000000   ca  b7
          312 267
0000002

TIP:
For POSIX compliance, use printf instead of echo.

Why is printf better than echo? (Retrieved on Apr 17, 2022)

echo(1) and printf(1) (Retrieved on Apr 17, 2022)

Rich’s sh (POSIX shell) tricks (Retrieved on Apr 17, 2022)

For POSIX compliance, for printf you need octal.

NOTE: Not going into details about different operating systems, different shells, different fonts, locales, etc.

% printf '\312\267'
ʷ%
% printf '\312\267\n'
ʷ

NOTE: On FreeBSD 13.1-RELEASE in csh:

% command -v printf; type printf; whereis printf; which printf
printf
printf is a shell builtin
printf: /usr/bin/printf /usr/share/man/man1/printf.1.gz
/usr/bin/printf
% freebsd-version
13.1-RELEASE

% ps $$
  PID TT  STAT    TIME COMMAND
22492  9  Ss   0:00.17 -csh (csh)

% printf %s\\n "$SHELL"
/bin/csh

TIP: You can use the Posix-standard command command to avoid the use of the printf builtin:
command printf

You can also do it directly by specifying the complete path to the non-builtin printf:
/usr/bin/printf

Discussion about this (retrieved on Apr 17, 2022):
What’s the best way to embed a Unicode character in a POSIX shell script?


Per this reference (retrieved on Apr 17, 2022):
https://askubuntu.com/questions/601137/how-to-print-an-octal-values-corresponding-utf-8-character-in-bash

% printf "%b\n" '\312\267'
ʷ
% awk 'BEGIN {print "\312\267"}'
ʷ

Converting Unicode to UTF-8 When You Don’t Know Unicode Code Point

From Does hexdump respect the endianness of its system? (Retrieved on Apr 17, 2022):

The traditional BSD hexdump utility uses the platform’s endianness so the output you see means your machine is little-endian.

TIP:

Use hexdump -C (or od -t x1) to get consistent byte-by-byte output irrespective of the platform’s endianness (emphasis mine).

Therefore:

% printf ʷ | hexdump -C
00000000  ca b7                                             |..|
00000002
% printf ʷ | od -t x1
0000000    ca  b7
0000002

From here, follow the instructions above for:
Converting Unicode to UTF-8 When You Know Unicode Code Point

Also, from the same question - different answer:
https://unix.stackexchange.com/questions/55770/does-hexdump-respect-the-endianness-of-its-system/55771#55771 (Retrieved on Apr 17, 2022):

Your output is little-endian (least significant byte first), which is also the endianness of the x86 and x86_64 architectures, which you are probably using.

Note: If no format strings are specified, the default display in hexdump(1) is equivalent to specifying the -x option – From the hexdump(1) manpage:

-x      Two-byte hexadecimal display.  Display the input offset in hexa‐
        decimal, followed by eight, space separated, four column, zero-
        filled, two-byte quantities of input data, in hexadecimal, per
        line.

... 

If no format strings are specified, the default display is equivalent 
to specifying the -x option.
% printf ʷ | hexdump
0000000 b7ca
0000002

Troubleshooting Fonts

Try a Different Application

Even though you can list a font with fc-list(1) and then grep for it, sometimes it will not be available in some applications, or if it’s available it will not work.

Possible fix: try a different app. For example, I had a problem with a font in TEA 3 and LibreOffice 4 – The fix was to use AbiWord 5, which worked fine with that font.

Useful Tools, Commands and Code Snippets for Troubleshooting Fonts in X11

Search for a font by its name: fc-list : fullname | grep -i FontNameHere

Search for a font by its PostScript name: fc-list : postscriptname | grep -i FontNameHere

Show the list of supported characters in a font: fc-list -v 'FontName: style=Regular' charset
fc-list -v 'FontName' charset

Query the font: fc-query /usr/local/share/fonts/FontNameHere/FontFile.ttf Number of elts (size) that pattern has, family, style (e.g. Regular), fullname, slant, weight, width, foundry, is it outline, is it scalable, charset, lang (supported languages), fontversion, postscriptname, is it color.

Display the font (display all the characters) in an X core font: xfd -fn FontName

Display the font (display all the characters) in an Xft font: xfd -fa FontName

Check if the current terminal and font support a Unicode character (with Perl) (e.g. “ʷ” U+02B7: Modifier Letter Small W): perl -C -e 'print chr 0x02B7' or perl -C -e 'print pack("U",0x02b7)."\n"'

Reference: Create unicode character with pack 6


A simple Perl one-liner:

% perl -e 'print chr(0x02b7); print "\n"'

Output:

Wide character in print at -e line 1.
ʷ

Alternatively:

% perl -e 'print "\x{02b7}\n"'

Output:

Wide character in print at -e line 1.
ʷ

Note: “Wide character in print at …” Perl warns you if you print a string that has a character with an ordinal value greater than 255 (hence it is a “wide” character that requires more than one byte of storage). Explicitly encode your output to avoid this warning:

% perl -e 'binmode STDOUT, ":encoding(utf8)"; print "\x{02b7}\n"'
ʷ
% perl -e 'binmode STDOUT, ":encoding(utf8)"; print chr(0x02b7); print "\n"'
ʷ

From perl pack a utf-8 Chinese Character how to unpack to get this Character? (Retrieved on Apr 17, 2022):

% cat unpack.pl
#!/usr/local/bin/perl

use utf8;
binmode STDOUT,":utf8";

my $packed = pack("U*", 0x02b7);
print "$packed\n";  # ʷ

my $unpacked = unpack("U*", "ʷ");
printf "0x%X\n", $unpacked;  # 0x02b7
% chmod 0744 unpack.pl
% ./unpack.pl
ʷ
0x2B7

Another useful Perl Unicode code snippet:

% perl -MDevel::Peek -e 'Dump(pack("U", 0x02b7));'

Output:

SV = PV(0x800e28060) at 0x800e5f7b0
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,PROTECT,pPOK,UTF8)
  PV = 0x800f16480 "\312\267"\0 [UTF8 "\x{2b7}"]
  CUR = 2
  LEN = 32

Check if the current terminal and font support a Unicode character (with Python):

% command -v python; which python
python: Command not found.

% command -v python2; which python2
python2: Command not found.

% command -v python3; which python3
python3: Command not found.

% command -v python3.7; which python3.7
python3.7: Command not found.
% command -v python3.8; which python3.8
/usr/local/bin/python3.8
/usr/local/bin/python3.8
% python3.8 -c 'print(u"\u02B7")'
ʷ
% python3.8 -c 'print(u"\u02B7\n")'
ʷ


From “Beyond Linux® From Scratch (System V Edition) - Version r11.1-906 - Chapter 24. Graphical Environments”, Tuning Fontconfig (retrieved on Apr 17, 2022):

fc-list | less: show a list of all available fonts (/path/to/filename: Font Name:style). If you installed a font more than 30 seconds ago but it does not show, then it or one of its directories is not readable by your user.

fc-match 'Font Name': will tell you which font will be used if the named font is requested. Typically you would use this to see what happens if a font you have not installed is requested, but you can also use it if the system is giving you a different font from what you expected (perhaps because fontconfig does not agree that the font supports your language).

fc-match -a 'Type' | less: will provide a list of all fonts which can be used for that type (Monospace, Sans, Serif). Note that in-extremis fontconfig will take a glyph from any available font, even if it is not of the specified type, and unless it knows about the font’s type it will assume it is Sans.

If you wish to know which font will be used for a string of text (i.e. one or more glyphs, preceded by a space), paste the following command and replace the xyz by the text you care about:

FC_DEBUG=4 pango-view --font=monospace -t xyz | grep family: this requires Pango-1.50.8 and ImageMagick-7.1.0-25 - it will invoke display to show the text in a tiny window, and after closing that the last line of the output will show which font was chosen. This is particularly useful for CJK languages, and you can also pass a language, e.g. PANGO_LANGUAGE=en;ja (English, then assume Japanese) or just zh-cn (or other variants - ‘zh’ on its own is not valid). – My Note: This works in bash and compatible shells. For csh/tcsh, use: env DISPLAY=:0 FC_DEBUG=4 pango-view --font=monospace -t xyz | grep family or env FC_DEBUG=4 pango-view --font=monospace -t xyz | grep family or (for no output, reduce debugging level to zero): env FC_DEBUG=0 pango-view --font=monospace -t xyz | grep family

Previewing an Xft Font

- Can also be used for Previewing XLFD (X Logical Font Description) Fonts

For example, to preview a font named Blippo:

$ fc-match Blippo
Blippo Bold.ttf: "Blippo" "Bold"
$ pango-view --font=Blippo --text "My test text"

OR:

$ pango-view --font=Blippo -t "My test text" 

For different font sizes, use the --dpi option:

$ pango-view --font=Blippo --text "My test text" --dpi 72
$ pango-view --font=Blippo --text "My test text" --dpi 96
$ pango-view --font=Blippo --text "My test text" --dpi 120

Tools and Test Pages Available Online: Unicode, UTF-8, Encodings

  • Test page for 8-bit encodings
    (Created on May 11, 2005 - Retrieved on Apr 17, 2022)

    The table contains alternating rows with octets in the range 128–255 (decimal) and ISO 8859-1 characters with the same code numbers. The first two rows for ISO 8859-1 have been greyed out, since those code positions do not contain printable characters but are reserved for control character purposes.

    This document has no character encoding information. This allows you to view it using various 8-bit encodings. On Internet Explorer, < for example, select View, then Encoding, and then for example Baltic (Windows) in order to compare Windows Baltic with ISO 8859-1.

  • Full Unicode Input utility (for Unicode version 14)
    (Created on Oct 2, 2012 - Retrieved on Apr 17, 2022)

    This utility can be characterized as an online extended character map oriented towards writing characters. It displays a table that looks like a set of keyboard buttons, and clicking on a button you enter the character in question. The characters will be appended to the text input area on the right.

    You can also type the Unicode number of a character in the box prefixed by “U+” and press Enter or click on the Add button.


And, of course, have in mind:

I stared into the fontconfig, and the fontconfig stared back at me - Posted: May 20, 2015 – Retrieved: Apr 17, 2022

I stared into the fontconfig, and the fontconfig stared back at me / fuzzy notepad - r/linux – Retrieved: Apr 17, 2022

I stared into the fontconfig, and the fontconfig stared back at me - r/programming – Retrieved: Apr 17, 2022


From blog post: I stared into the fontconfig, and the fontconfig stared back at me - Posted: May 20, 2015 – Retrieved: Apr 17, 2022:

Some hot parting tips

fc-cache will force fontconfig to pick up any changes. There’s a -f, but in all my fighting with fontconfig it never once made a difference.

As far as I can tell, there is no reason to ever run sudo fc-cache -vf. This has been floating around the Internet for years, but it seems to be apocryphal copy/paste. You don’t need to flush root’s fontconfig cache unless you’re running GUI stuff as root.

fc-match <font> will tell you what font will be used in practice. You might think that’s what fc-query does, and you’d be wrong. fc-query’s primary use is to produce bizarre error messages when you accidentally use it instead of fc-match.

It is really fxxxing difficult to figure out what font will be used for a specific glyph. There are two approaches:

1. Do it in a [web] browser. Make a URL like this (that is, enter it in the browser’s address bar): data:text/html,<meta charset="utf8"><p style="font-family: monospace;">☺</p>

Then pop open your dev tools, and look for where it tells you the fonts that are actually being used. Firefox’s Inspector has a dedicated “fonts” tab in the panel on the right; Chromium’s Elements lists fonts at the bottom of the “computed” tab.

Fair warning: this is one level removed from fontconfig, because CSS font rules may interfere. This bit me above when I tried to confirm my new cursive font in Firefox!

Another warning: while Firefox picks up fontconfig changes more or less instantly (after an fc-cache), Chromium does not. Worse, Chromium seems to outright ignore fontconfig when it feels like it, such as when it used a sans serif Japanese font for text styled as serif.

2. You can also do this nonsense in a terminal: DISPLAY=:0 FC_DEBUG=4 pango-view --font=monospace -t ☺ | grep family:

My note: -> for csh/tcsh: env DISPLAY=:0 FC_DEBUG=4 pango-view --font=monospace -t ☺ | grep family:

pango-view is a tiny program that just pops open a window containing some text in a particular font. FC_DEBUG is an environment variable to make fontconfig spit out mountains of fxxxing text on stdout. The grep cuts it down to something a little more manageable. Most likely the last family you see listed is the font actually being used to render your favourite glyph.

If you’re really curious how the <match> blocks work, good news: they are the one thing the fontconfig docs actually kind of explain. And of course your /etc/fonts/conf.d (my note: /usr/local/etc/fonts/conf.d on FreeBSD) is probably full of real-world practical examples.

From the same blog:

I haven’t put my fontconfig font config (…) in my rc.git; it seems pretty specific to my desktop’s particular setup. But here’s the whole thing in a gist, if you’re interested.


Footnotes

[1] A nice overview and discussion about UTF-8, UTF-16 and UTF-32 on StackOverflow: UTF-8, UTF-16, and UTF-32 (Posted on Jan 30, 2009; Retrieved on Apr 17, 2022)

[2] From a FreeBSD Forum post started on Dec 24, 2014 How do I type in special characters, such as ∞ in the terminal in vi?, post #3 https://forums.FreeBSD.org/threads/how-do-i-type-in-special-characters-such-as-in-the-terminal-in-vi.49659/post-277491 (Retrieved on Apr 17, 2022):

Which vi? vi on Linux is just a soft link to Vim. On BSDs vi is symbolic link to nvi (new vi) which is a re-implementation of the “classic Berkeley vi”. “Classical Berkeley vi” has multiple versions IIRC one of which is personal copy of Bill Joy. Solaris’ version of vi could also be considered classical as well as traditional vi http://ex-vi.sourceforge.net/. Reading documentation of traditional vi project is a good start.

To make matters more confusing BSD projects continue to use nvi version 1.79 due to licensing issues between Berkeley Database 1.85 and the later versions by Sleepycat Software. nvi has a support for Unicode but I am not sure if the version 1.79 includes or not as I have never used Unicode with nvi. Now scottro made a major mistake mentioning Unicode as $\infty$ as written in TeX is extended ASCII character and one doesn’t need Unicode to type it. I do not know how would you type $\infty$ in nvi as a professional mathematician I have never seen any mathematical symbols or mathematical text typing without serious text typing system such as TeX or Troff. TeX is de-facto standard for typing mathematics adopted since 1979 by AMS. Troff uses mathematical pre-processor and is definitely able to produce all special mathematical characters. On the web we use MathJax, a cross-browser JavaScript library that displays in web, using MathML, LaTeX and ASCIIMathML markup to write mathematics.

[3] Retrieved on Apr 17, 2022:
TEA - text editor
TEA (text editor) - Wikipedia
TEA: A Smooth Text Editor That Hits the Sweet Spot

[4] Retrieved on Apr 17, 2022:
LibreOffice

[5] Retrieved on Apr 17, 2022:
AbiWord

[6] Retrieved on Apr 17, 2022:
Create unicode character with pack