Table of Contents
OpenType data
Read-only access to font data beyond shaping. Metrics are on Fonts and metrics, variations on Font variations, color tables on Color glyphs, and raw tables through face-table.
Names (name table)
face-name face name-id &key language → string or nil
A name string, decoded to a Lisp string. name-id is a keyword or an integer ID (fonts may define their own IDs from 256 up, e.g. for axis and instance names). language is a BCP 47 string; by default HarfBuzz picks the best available, preferring English. nil if the face has no such name.
(hb:face-name face :font-family) ; => "DejaVu Sans"
(hb:face-name face :font-subfamily) ; => "Book"
(hb:face-name face :postscript-name) ; => "DejaVuSans"
(hb:face-name face 1 :language "en") ; => "DejaVu Sans"
| Keyword | ID | Keyword | ID | |
|---|---|---|---|---|
:copyright |
0 | :license |
13 | |
:font-family |
1 | :license-url |
14 | |
:font-subfamily |
2 | :typographic-family |
16 | |
:unique-id |
3 | :typographic-subfamily |
17 | |
:full-name |
4 | :mac-full-name |
18 | |
:version-string |
5 | :sample-text |
19 | |
:postscript-name |
6 | :cid-findfont-name |
20 | |
:trademark |
7 | :wws-family |
21 | |
:manufacturer |
8 | :wws-subfamily |
22 | |
:designer |
9 | :light-background |
23 | |
:description |
10 | :dark-background |
24 | |
:vendor-url |
11 | :variations-ps-prefix |
25 | |
:designer-url |
12 |
These keywords and the integers from 0 to #xFFFE make up the type name-id; anything else is a type-error.
For family names shown to users, prefer :typographic-family / :typographic-subfamily and fall back to :font-family / :font-subfamily when they are nil (as for DejaVu Sans Mono). IDs 1 and 2 follow the old four-style model (Regular, Italic, Bold, Bold Italic), so a family with more weights files its Light or Black styles under separate family names there; IDs 16 and 17 group them properly.
face-name-entries face → list of (name-id . language)
Every name the face has, with integer IDs and BCP 47 languages, so you can enumerate localized names:
(subseq (hb:face-name-entries face) 0 5)
;; => ((0 . "en") (1 . "en") (2 . "en") (3 . "en") (4 . "en"))
(loop for (id . lang) in (hb:face-name-entries face)
when (= id 1) collect (cons lang (hb:face-name face 1 :language lang)))
Layout tables
face-script-tags face &key (table :gsub) → list of strings
face-feature-tags face &key (table :gsub) → list of strings
The OpenType script tags and feature tags in the face's GSUB or GPOS table (table :gsub or :gpos, the type layout-table). Feature tags are deduplicated, in first-seen order.
(hb:face-script-tags face)
;; => ("DFLT" "arab" "armn" "brai" "cans" "cher" "cyrl" "geor" "grek" "hani"
;; "hebr" "kana" "lao " "latn" "math" "nko " "ogam" "runr" "tfng" "thai")
(hb:face-feature-tags face)
;; => (" RQD" "aalt" "case" "ccmp" "dlig" "fina" "hlig" "init" "liga" "locl"
;; "medi" "rlig" "salt")
(hb:face-feature-tags face :table :gpos)
;; => ("kern" "mark" "mkmk")
Notes:
- These are OpenType script tags (lowercase, sometimes padded:
"lao ","nko "; Indic scripts have v2 tags like"dev2"), not the ISO 15924 codes buffers use ("Laoo","Nkoo","Deva"). - Use
face-feature-tagsto build a font-features UI, or to check before relying on a discretionary feature (smcp,onum,ss01, …): features the font lacks are silently ignored when shaping. - The lists cover every script and language system; a feature may exist only for some scripts.
" RQD"is a private tag some fonts use for required features.- Kerning in an old-style
kerntable (noGPOS) does not show up here, but HarfBuzz still applies it.
Raw tables
Anything else is one call away as octets:
(let ((os2 (hb:face-table face "OS/2")))
;; usWeightClass is the big-endian uint16 at offset 4.
(+ (ash (aref os2 4) 8) (aref os2 5)))
;; => 400