Typography: Building EB Garamond


Garamond typefaces is an embodiment of irresistable beauty. I confess, I cannot help it: whenever I see text that is set in a Garamond, I pause for a moment of pure, thoughtless visual enjoyment. I even regret that the miniscule long s is abandoned and miss the ct ligature :-) In 2011, I was very much pleased to hear the news of EB Garamond being released under the SIL Open Font License. Since then I use the font for occasional, amateur typesetting.

While EB Garamond is a work in progress, I was spared its minor technical imperfections for years until last week. This time I could not get XƎTEX to combine diacritics properly, no matter what I tried—to the point when I started to suspect the font. A short investigation confirmed that: I needed to fix EB Garamond Regular. The issue was trivial—an anchor was missing—and I could have patched the True Type binary using FontForge, but usually I attempt to fix problems at their source and I hoped that I shall be able to do so, having an open source font at hand.

An unpleasant surprise awaited for me: on the machine where I worked, the typeface was installed as a pre-built, binary-only package that provided generated fonts that originate at the GitHub repository of Octavio Pardo and he is a user of Glyphapp, a proprietary software. All the source in that repository is in Glyphapp's format. I felt awkward: not only that spending a week's worth of lunches for a program that I needed, apparently, for an odd job did not seem right, I was not sure that the ‘Mini’ edition of Glyphapp will suffice and I would not need to spend a month's worth of lunches for the complete version. Still, I could live with that, but ethically the situation felt like counterrevolution: how can one contribute to an open source project using an output in a proprietary format that was produced with a proprietary tool?

I turned to the original repository of Georg Duffner in the hope of finding the open source of the Regular font. Indeed, it was all there: I only needed a suitable set of tools for bulding a True Type from the source. Unfortunately, the OpenBSD port of FontForge is awfully old and the package is distributed without Python support that is required for building EB Garamond from the source.

So I ventured on revival of building the typeface using OpenBSD 6.5 (please see my notes regarding Linux at the very end of this article): All's well that ends well

Requirements

Several software packages mentioned below clone Git repositories during their configuration. It is best to perform the procedure while having permanent connection to the Internet.

The software packages that must be compiled are quite large, please allot at least 1Gb of storage for the procedure.

The packages all can be built using parallel make(1) jobs, therefore it is certainly possible to speed up the task by using a CPU having multiple cores.

To give you an idea, on a freshly installed OpenBSD 6.5 that runs on VirtualBox 5.1 with 4Gb of RAM and 8 cores of an Intel Xeon E5-2630 v4 @2.20GHz and has a fast Internet connection, the complete process takes one hour.

Conventions and Environment Variables

I assume that under your home directory ${HOME} there is a subdirectory called pkg where you store files that you download from other machines and another subdirectory called src where you work with source code.

To simplify the procedure, I propose having a script called eb-garamond-vars.sh that describes the above and sets a number of environment variables that are necessary for the proper operation of the routine. You can create this script this way:

cat <<EOF > "${HOME}/src/eb-garamond-vars.sh"
SRC="\${HOME}/src"
PKG="\${HOME}/pkg"
AUTOCONF_VERSION=2.69
AUTOMAKE_VERSION=1.16
MAKEFLAGS="-j$(sysctl hw.ncpuonline | cut -d= -f2)"
CC=clang
CXX=clang++
CPP_INCLUDE_PATH='/usr/local/include'
C_INCLUDE_PATH='/usr/local/include'
CXX_INCLUDE_PATH='/usr/local/include'
LIBRARY_PATH='/usr/local/lib'
export SRC PKG AUTOCONF_VERSION AUTOMAKE_VERSION CC CXX CPP_INCLUDE_PATH \
	C_INCLUDE_PATH CXX_INCLUDE_PATH LIBRARY_PATH MAKEFLAGS
EOF

You can source this script into you running shell when required as follows (please note the dot at the beginning of the line):

. "${HOME}/src/eb-garamond-vars.sh"

All the instructions given below assume that the script is sourced.

Required Tools

Almost all of the software that you are going to build requires Git, GNU Make, GNU Autotools, and Python:

doas pkg_add git gmake m4 autoconf-2.69p2 automake-1.16.1 libtool \
	gettext-tools python-3.6.8p0

libuninameslist

libuninameslist is a helper library that is developed by the FontForge project. This library maps Unicode codepoints to their annotations, probably most important—to their standard names:

cd "${SRC}"
git clone https://github.com/fontforge/libuninameslist.git
cd libuninameslist
sh build.sh && doas gmake install

libspiro

libspiro is a library for drawing curves, developed by Raph Levien and now hosted by the FontForge project at their GitHub repository:

cd "${SRC}"
git clone https://github.com/fontforge/libspiro.git
cd libspiro
autoreconf -i
automake --foreign -Wall
./configure
gmake && doas gmake install

FontForge

Dependencies

Building and running FontForge requires additional tools and libraries that can be installed from the OpenBSD's collection of pre-built software packages:

doas pkg_add gtar-1.32 glib2 pango libxml giflib jpeg tiff png woff2 gtk+3

The version of FontForge that you are going to build also depends on ZeroMQ which is required for real time collaboration functionality of FontForge. However the version of czmq (the C language API for ZeroMQ) that is distributed by OpenBSD is much newer than FontForge expects and it cannot be used for building. However that collaboration functionality seems to be going to be dropped in a more recent releases of FontForge and I decided not to support it. (Indeed, it seems to be one of those expensive ‘cool’ features that are used by a single-digit percentage of users in practice.)

Source

I decided to build the most recent tagged version of FontForge, 20190413.

cd "${SRC}"
git clone -b 20190413 https://github.com/fontforge/fontforge.git

Patches

There are two minor issues that need to be fixed in this version of FontForge before it can be built on OpenBSD. The development team kindly accepted relevant patches into the main development branch of the project, but they must be applied to this version of FontForge separately. Please download them as follows:

cd "${PKG}"
ftp https://penzin.net/eb-garamond/fontforge-0001.patch \
	https://penzin.net/eb-garamond/fontforge-0001.patch.asc \
	https://penzin.net/eb-garamond/fontforge-0002.patch \
	https://penzin.net/eb-garamond/fontforge-0002.patch.asc

(The signatures can be verified using gnupg-2.2.12. My key can be obtained as described here.)

Apply the patches:

cd "${SRC}/fontforge"
patch -p1 < "${PKG}/fontforge-0001.patch"
patch -p1 < "${PKG}/fontforge-0002.patch"

Installation

AMTAR=/usr/local/bin/gtar sh bootstrap
./configure --enable-woff2 --enable-write-pfm --enable-tile-path \
	--enable-debug-raw-points --enable-gdk=3
gmake && doas gmake install

ttfautohint

ttfautohint is a project led by Werner Lemberg. ttfautohint is a program for automatic font hinting which is used in the build process of EB Garamond. I would like to thank Werner for promptly fixing an issue with the configuration of ttfautohint that I reported. Currently the package builds right from the source control without much ado.

Dependencies

ttfautohint requires additional tools and libraries that can be installed from the OpenBSD's collection of pre-built software packages:

doas pkg_add bison qt5

Unfortunately, in the current version of the package qtbase-5.9.7p3 (a dependency of qt5) there is a trivial bug that must be fixed manually (I reported the bug and it is being dealt with.):

for la in $(grep '[0-9]# The name that we can dlopen(3).' /usr/local/lib/qt5/*.la | cut -d: -f1); do
	doas sed -e 's/# The name that we can dlopen(3)./ # The name that we can dlopen(3)./' -i "${la}"
done

(While the above may look truly frightening, it merely adds a single space before a comment that was omitted in a number of shell scripts. It will not damage your system, quite on the contrary.)

Installation

cd "${SRC}"
git clone https://repo.or.cz/ttfautohint.git
cd ttfautohint
sh bootstrap
./configure --without-doc
gmake && doas gmake install

sfntly

sfntly is a font manipulation library and a toolset from Google that is required for building EB Garamond.

Dependencies

sfntly requires the Java Development Kit and Apache Maven/ that can be installed from the OpenBSD's collection of pre-built software packages:

doas pkg_add maven

(Please note that maven installs jdk-1.8.0.202v0 as a dependency.)

Source

cd "${SRC}"
git clone https://github.com/rillig/sfntly.git

Preparations

The Maven's build script of sfntly performs various post-build tests that fail on OpenBSD because the location of the system directory with True Type fonts is hard-coded into the script. The easiest way o fix that is to create a temporary symbolic link:

doas ln -s /usr/X11R6/lib/X11/fonts /usr/share/fonts

Compilation and Packaging

cd sfntly/java && mvn package

Post Compilation

Remove the temporary symbolic link:

doas rm /usr/share/fonts

Maven will create the Java archive java/target/sfntly-sfnttool-0.0.1-SNAPSHOT.jar which is the required utility.

EB Garamond

Finally, the typeface itself.

Dependencies

The Makefile of EB Garamond uses zip(1) for packaging:

doas pkg_add zip

Source

cd "${SRC}"
git clone https://github.com/georgd/EB-Garamond.git

Patches

It appears that over years the project suffered some bit rot, there are several issues that need to be addressed. Please download the required patches and their signatures:

cd "${PKG}"
for x in 1 2 3 4 5; do
	ftp "https://penzin.net/eb-garamond/ebgaramond-000${x}.patch" \
		"https://penzin.net/eb-garamond/ebgaramond-000${x}.patch.asc"
done

(To remind you, the signatures can be verified using gnupg-2.2.12. My key can be obtained as described here.)

ebgardmond-0001.patch makes it possible to specify the name of the Python interpreter on the command line of make(1). ebgardmond-0002.patch fixes a bug that prevented the web directory from being created automatically. ebgardmond-0003.patch replaces a deprecated option of ttfautohint with the new recommended version. ebgardmond-0004.patch fixes several issues that prevented the dist target of the Makefile from working as expected. ebgardmond-0005.patch adds a make(1) rule that turns on tracking of changes in individual glyphs, thus ensuring that fonts will be rebuilt if an existing glyph is changed (I explain the mechanics of this tracking elsewhere).

Apply the patches:

cd "${SRC}/EB-Garamond"
for x in 1 2 3 4 5; do
	patch -p1 < "${PKG}/ebgaramond-000${x}.patch"
done

Install sfnttool

The build process requires the Java archive sfnttool.jar to be accessible:

ln -s "${SRC}/sfntly/java/target/sfntly-sfnttool-0.0.1-SNAPSHOT.jar" sfnttool.jar

Build

PATH="${PATH}:/usr/local/jdk-1.8.0/bin" gmake PYTHON=python3

Linux

Life is somewhat kinder to users of current versions of Debian derivatives (notably Debian GNU/Linux itself, Ubuntu, and Devuan). It is necessary to install git, make, zip, fontforge, python3, python-fontforge, and maven along with their dependencies using sudo(8) and apt-get(8)and then proceed to the described above, starting from sfntly (except that on Linux the temporary symbolic link /usr/share/fonts is not required).

Do not forget that on Linux GNU Make is called make and not gmake, that you should use curl(1) or wget(1) instead of OpenBSD's ftp(1), and you must skip all invocations of doas(8) for they are not applicable on Linux.

Vadim Penzin, June 25th, 2019


I hereby place this article along with the accompanying source code into the public domain.
I publish this information in the hope that it will be useful, but without ANY WARRANTY.
You are responsible for any and all consequences that may arise as the result of using this information.