Faces
A face is one typeface of a font file or in-memory font: its tables and everything that does not depend on size.
Opening
make-face source &key (index 0) → face
Opens face index of source, which is
- a native filename string (
"/usr/share/fonts/…/DejaVuSans.ttf"), - a pathname (converted with
uiop:native-namestring), or - a vector of octets
(unsigned-byte 8), which is copied, so you may reuse or drop the vector afterwards.
These three make up the type font-source, which face-count and with-face take too; anything else is a type-error.
TrueType, OpenType (CFF and CFF2) and collections (.ttc, .otc) are accepted. WOFF and WOFF2 are not: HarfBuzz does not decompress them, and face-count returns 0 for them. make-face recognises them and says so. Convert web fonts to plain TrueType/OpenType first, e.g. with fontTools.
Signals harfbuzz-error if the file cannot be read, the data is not a font, or index is not below the number of faces:
(hb:make-face "/no/such.ttf")
;; Could not read the font file /no/such.ttf: it does not exist or cannot be read.
;; Check the path and the file's permissions.
;; (HarfBuzz: hb_blob_create_from_file_or_fail failed)
(hb:make-face "font.woff2")
;; font.woff2 is a WOFF2 font, which HarfBuzz cannot read.
;; Convert it to TrueType or OpenType first, for example with fontTools.
(hb:make-face path :index 3)
;; The font has 1 face, so face 3 does not exist.
;; Pass an index below FACE-COUNT of the font.
with-face (var source &key index) &body body
Binds var to (make-face source :index index) and destroys it on exit.
face-count source → integer
The number of faces in source (same kinds as make-face): 1 for a plain font, more for a collection, 0 for data that is not a font. It does not signal for data that is not a font, so it is a cheap "is this a font?" test. (A file that cannot be read still signals.)
(loop for i below (hb:face-count "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc")
collect (hb:with-face (f "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc" :index i)
(hb:face-name f :full-name)))
destroy-face face
Releases the face. Fonts made from it remain usable. Destroying an already destroyed face does nothing.
face-live-p face → boolean
True unless the face has been destroyed.
Properties
| Function | Returns | DejaVu Sans |
|---|---|---|
face-index face |
index within its file | 0 |
face-units-per-em face |
units per EM | 2048 |
face-glyph-count face |
number of glyphs | 6253 |
face-table-tags face |
list of table tags, in file order | ("FFTM" "GDEF" "GPOS" "GSUB" "MATH" "OS/2" "cmap" "cvt " …) |
face-table face tag |
the raw table as an octet vector, or nil if absent |
(length (hb:face-table face "head")) → 54; (hb:face-table face "COLR") → nil |
Its tag is a tag, one to four printable ASCII characters; anything else is a type-error. face-table copies the table, so the vector is yours to keep. It is the way to read tables cl-harfbuzz does not parse (OS/2, head, post, MATH, STAT, …) with your own parser.
More face data is on other pages:
- names, layout script and feature tags: OpenType data
- variation axes and named instances: Font variations
- palettes, COLR, SVG, PNG: Color glyphs
Escape hatch
face-handle face → foreign pointer
The raw hb_face_t* for use with cl-harfbuzz/ffi. Valid until destroy-face. Signals harfbuzz-error if the face is destroyed. Do not destroy the pointer yourself.
Printing
#<CL-HARFBUZZ:FACE 6253 glyphs {120422CCE3}>
#<CL-HARFBUZZ:FACE destroyed {12046521E3}>