Table of Contents
Installation
Requirements
| HarfBuzz | the libharfbuzz shared library, 7.0 or newer, at load time |
| Lisp | SBCL |
| Lisp libraries | cl-ffi, uiop (plus cl-ft2 for cl-harfbuzz/ft2, parachute for the tests) |
| C toolchain | none: struct layouts are written by hand with cl-ffi's C-sized types, so nothing is compiled |
Linux
Install the runtime package. On Debian and Ubuntu:
apt install libharfbuzz0b
cl-harfbuzz loads libharfbuzz.so.0 (falling back to libharfbuzz.so). No -dev package is needed. For cl-harfbuzz/ft2, cl-ft2 also needs libfreetype6.
macOS
brew install harfbuzz. cl-harfbuzz looks for libharfbuzz.0.dylib, then libharfbuzz.dylib, on the dynamic linker's search path. Note that macOS is not tested in CI.
Windows
There is nothing to install. Windows ships no HarfBuzz, so cl-harfbuzz carries its own build in native/windows-x64/harfbuzz.dll (HarfBuzz 14.6.0, x86-64) and loads it by full path, so no other harfbuzz.dll on PATH gets in the way.
- The DLL is HarfBuzz's single-file build with hb-ft (FreeType integration, used by
cl-harfbuzz/ft2) and without glib, ICU, Graphite or the Uniscribe/DirectWrite shapers.(hb:shapers)lists"ot"and"fallback". - It delay-loads
freetype.dll, so plaincl-harfbuzzloads without FreeType. FreeType's functions are resolved the first time hb-ft calls one, by which time cl-ft2 has loaded its ownfreetype.dll. - Delivered applications. An image saved without cl-harfbuzz's source tree cannot use the full path, so it loads
harfbuzz.dllby name; Windows looks next to the executable first. Shipharfbuzz.dllbeside your.exe, together with cl-ft2'sfreetype.dllif you usecl-harfbuzz/ft2. HarfBuzz's license is innative/windows-x64/HARFBUZZ-COPYING. - The DLL is reproducible:
native/build-windows.shrebuilds it from the pinned source and--checkverifies the committed one. See Development.
If the library cannot be loaded, loading the system signals a harfbuzz-error that lists the files it tried and whose hint names what to install (on Windows, it tells you to restore the DLL from the repository). See Errors.
Loading
cl-harfbuzz is not in Quicklisp; its dependencies are pinned with stift. In a project of your own, stift get https://fakehacker.cc/dxtr/cl-harfbuzz.git requires cl-harfbuzz, and its stiftfile brings cl-ffi and cl-ft2 along. In a checkout of cl-harfbuzz, the repository's stiftfile pins them, and stift exec starts a Lisp that finds them:
stift exec sbcl
Then load the systems with ASDF:
(asdf:load-system :cl-harfbuzz) ; shaping, outlines, paint, OpenType data
(asdf:load-system :cl-harfbuzz/ft2) ; optional: HarfBuzz fonts on cl-ft2 faces
cl-harfbuzz/ft2 needs cl-ft2, which plain cl-harfbuzz does not load.
Checking it works
In a package that gives cl-harfbuzz the local nickname hb, as shown below the table of packages:
(hb:harfbuzz-version) ; => 12, 3, 2 (major, minor, micro as three values)
(hb:shapers) ; => ("graphite2" "ot" "fallback") on Debian's build
The packages:
| Package | Use |
|---|---|
cl-harfbuzz |
everything in this wiki unless stated otherwise |
cl-harfbuzz/ffi |
the raw layer, on cl-ffi, see FFI layer |
cl-harfbuzz/ft2 |
make-ft2-font, with-ft2-font, ft2-font, ft2-font-face |
The packages have no global nicknames, so they take no names from the rest of your image. The examples in this wiki are written in a package that gives them local nicknames, hb for cl-harfbuzz and ft2 for cl-ft2:
(defpackage #:my-text
(:use #:cl)
(:local-nicknames (#:hb #:cl-harfbuzz)
(#:ft2 #:cl-ft2))) ; only after loading cl-ft2
(in-package #:my-text)
Leave out cl-ft2 when you do not load it: a local nickname needs its package to exist.
With local nicknames nothing clashes. A package that :uses cl-harfbuzz together with another must shadow the names both export: glyph-index with cl-ft2, color with cl-svgread, script with sb-unicode, name-id, color and tag with cl-harfbuzz/ffi, whose struct slots have those names, and glyph-index, name-id and tag with cl-ft2/ffi, for the same reason.