1# terminal fonts
2
3## Primary font
4
5The four WOFF2 files are a reproducible subset of **Iosevka Fixed Extended
6v34.8.1** (Renzhi Li / Belleve Invis), taken from the release's own WebFont
7package:
8
9`https://github.com/be5invis/Iosevka/releases/download/v34.8.1/PkgWebFont-IosevkaFixed-34.8.1.zip`
10
11The downloaded zip is 211,996,653 bytes with SHA-256
12`a3a03a7ce96f92403c8fa0e20ab24642553755c8fcf69ed3c74157f1ffdf8995`. The four
13`TTF/` members it is subset from:
14
15| Source member | SHA-256 |
16| --------------------------------------------- | ------------------------------------------------------------------ |
17| `TTF/IosevkaFixed-Extended.ttf` | `7182070f18c093a65f4c7861aecb454b6a33bfcd365e07e3521f03a1d6c79cd7` |
18| `TTF/IosevkaFixed-ExtendedSemiBold.ttf` | `a4bebd5003e7763684c232660da6579293e903605c77e2f4cc1791618db51cf6` |
19| `TTF/IosevkaFixed-ExtendedItalic.ttf` | `0defbf681658b460c4b4d4a43ef3145798f2485cdde5e8c06663e8b7c08d8062` |
20| `TTF/IosevkaFixed-ExtendedSemiBoldItalic.ttf` | `f3006b75315f3e5af68d992f227d1cf55feb31f3c74156c70780638b737af61a` |
21
22The zip is acquisition material and must remain outside the repository.
23
24**Fixed Extended, and neither half of that is cosmetic.** _Extended_ is the
250.600 em advance — the same one JetBrains Mono v2.304 shipped before it, so the
26cell geometry did not move; Iosevka's default width is 0.500 em and reads
27compressed at terminal sizes. _Fixed_ is the variant with no glyph wider than
28one cell: `Iosevka Term` carries 23 double-advance glyphs (the long arrows,
29`U+27F5-27FF`), and Ghostty reports those codepoints as one column, so in a
30renderer that owns the cell they paint into their neighbour.
31
32| File | Upstream file | Style | Weight | Bytes | SHA-256 |
33| ---------------------------------------------------- | --------------------------------------------- | ------ | ------ | ------: | ------------------------------------------------------------------ |
34| `__clo_terminal_primary_34_8_1-Regular.woff2` | `TTF/IosevkaFixed-Extended.ttf` | normal | 400 | 186,152 | `4a45de347bcb9ed97220ca20d8e0a33d6d926995208800fa57138bd54a9273bb` |
35| `__clo_terminal_primary_34_8_1-SemiBold.woff2` | `TTF/IosevkaFixed-ExtendedSemiBold.ttf` | normal | 600 | 186,040 | `1883786f7f33c891724b6dcae9ae22dcbe69336fc73d34f27ff352410d27f259` |
36| `__clo_terminal_primary_34_8_1-Italic.woff2` | `TTF/IosevkaFixed-ExtendedItalic.ttf` | italic | 400 | 210,368 | `2e143f2d688fbf3a815fe6dd31af3a74c0a5f71e2744fdecbb0b32ae543e99de` |
37| `__clo_terminal_primary_34_8_1-SemiBoldItalic.woff2` | `TTF/IosevkaFixed-ExtendedSemiBoldItalic.ttf` | italic | 600 | 210,340 | `d871135db2d8ec47cb3e3ffe6fa85d1e55e187f9bc81828f8a82afd6e76cbe8a` |
38
39Copyright (c) 2015-2026, Renzhi Li (aka. Belleve Invis, belleve@typeof.net).
40Distributed under the SIL Open Font License 1.1 in [`OFL.txt`](OFL.txt).
41Iosevka reserves no font name, so the subset carries no naming obligation; the
42private `__clo_terminal_primary_34_8_1` family name is this package's, not a
43claim about the upstream face.
44
45The checked-in manifest [`PRIMARY-CODEPOINTS.txt`](PRIMARY-CODEPOINTS.txt) is
46the sorted intersection of the source cmap with the retained ranges in
47[`subset-primary.py`](subset-primary.py). It contains 4,660 codepoints, is
4832,867 bytes, and has SHA-256
49`ebe06abbcb42d87fe2d2f37f805ab0413b69c8dbb438dded94e4a8f4c2832672`.
50The ranges are `U+0000-2BFF` and `U+1FB00-1FBFF`: every script and symbol block
51a cell can hold, plus Symbols for Legacy Computing. That keeps braille,
52technical, dingbats and the sextants the previous primary had none of, and drops
53mathematical alphanumerics, musical notation, emoji and the historic scripts —
542,899 of the source font's 7,559 codepoints, and most of its bytes.
55
56Regenerate the manifest and the four faces with these exact commands from
57`sys/lib/terminal`, given the extracted TTFs in approved temporary storage:
58
59```sh
60python fonts/subset-primary.py "$TTF_DIR/IosevkaFixed-Extended.ttf" \
61 "$CLEAN_DIR/PRIMARY-CODEPOINTS.txt"
62for pair in Extended:Regular ExtendedSemiBold:SemiBold \
63 ExtendedItalic:Italic ExtendedSemiBoldItalic:SemiBoldItalic; do
64 pyftsubset "$TTF_DIR/IosevkaFixed-${pair%%:*}.ttf" \
65 --output-file="$CLEAN_DIR/__clo_terminal_primary_34_8_1-${pair##*:}.woff2" \
66 --flavor=woff2 \
67 --unicodes-file="$CLEAN_DIR/PRIMARY-CODEPOINTS.txt" \
68 --layout-features='' \
69 --name-IDs=0,1,2,3,4,5,6 \
70 --name-languages=0x409 \
71 --no-name-legacy \
72 --no-harfbuzz-repacker \
73 --no-recalc-timestamp \
74 --canonical-order
75done
76```
77
78Two builds from separate clean directories produced byte-identical manifests
79and WOFF2 files. The recorded build used the exact pins in
80[`symbols-requirements.txt`](symbols-requirements.txt): `fonttools==4.51.0` and
81`brotli==1.1.0`. Run the commands twice with distinct empty `CLEAN_DIR` values
82and require byte equality plus the hashes above before replacing checked-in
83outputs.
84
85## Terminal symbols
86
87`__clo_terminal_symbols_3_4_0-Regular.woff2` is a subset of Symbols Nerd Font
88Mono v3.4.0. The v3.4.0 tag resolves to Nerd Fonts commit
89`fa7b859994228a9c8759f99c55a8d31ee92a1b5e`; the source artifact is Git blob
90`d898eea9dc37acee648303e15b13fea4eb437d8e` at:
91
92`https://raw.githubusercontent.com/ryanoasis/nerd-fonts/fa7b859994228a9c8759f99c55a8d31ee92a1b5e/patched-fonts/NerdFontsSymbolsOnly/SymbolsNerdFontMono-Regular.ttf`
93
94The downloaded TTF is 2,507,556 bytes with SHA-256
95`f0f624d9b474bea1662cf7e862d44aebe1ae1f6c7f9cb7a0ca5d0e5ac9561c60`.
96Its embedded unique id is `Symbols Nerd Font Mono 3.4.0` and its version is
97`Version 001.000;Nerd Fonts 3.4.0`. The input TTF is acquisition material and
98must remain outside the repository.
99
100The checked-in manifest [`SYMBOLS-CODEPOINTS.txt`](SYMBOLS-CODEPOINTS.txt) is
101the sorted intersection of the source cmap with the retained ranges in
102[`subset-symbols.py`](subset-symbols.py). It contains 10,273 codepoints, is
10378,807 bytes, and has SHA-256
104`128c0e17659bd21ea91edf73006304b368fb714d38f12c0d7b005d713052eac1`.
105The range policy excludes primary-owned box/block `U+2500-U+259F`, standard
106Powerline `U+E0A0-U+E0A2` and `U+E0B0-U+E0B3`, and unlicensed Font Logos
107`U+F300-U+F381`. The box/block exclusion has an empty intersection with this
108source cmap; the other exclusions remove 7 and 130 source codepoints.
109
110The output WOFF2 is 1,083,700 bytes with SHA-256
111`a41598870ee7b32226cc76fdaab59edca51ba04e30d2c9a0bfa453615e3cca8c`.
112Two builds from separate clean directories produced byte-identical manifests
113and WOFF2 files. The recorded build used Python 3.9.6 with the exact pins in
114[`symbols-requirements.txt`](symbols-requirements.txt): `fonttools==4.51.0`
115and `brotli==1.1.0`.
116
117Given an input TTF in approved temporary storage, regenerate the manifest and
118font with these exact commands from `sys/lib/terminal`:
119
120```sh
121python fonts/subset-symbols.py "$INPUT_TTF" "$CLEAN_DIR/SYMBOLS-CODEPOINTS.txt"
122pyftsubset "$INPUT_TTF" \
123 --output-file="$CLEAN_DIR/__clo_terminal_symbols_3_4_0-Regular.woff2" \
124 --flavor=woff2 \
125 --unicodes-file="$CLEAN_DIR/SYMBOLS-CODEPOINTS.txt" \
126 --layout-features='' \
127 --name-IDs=0,1,2,3,4,5,6 \
128 --name-languages=0x409 \
129 --no-name-legacy \
130 --no-harfbuzz-repacker \
131 --no-recalc-timestamp \
132 --canonical-order
133```
134
135Run both commands twice with distinct empty `CLEAN_DIR` values and require
136byte equality plus the hashes above before replacing checked-in outputs.
137
138Nerd Fonts marks Symbols Only as MIT, while its own audit assigns retained
139glyph components additional MIT, CC BY 4.0, Apache 2.0, and SIL OFL 1.1
140terms. The subset is distributed with every applicable component term rather
141than treated as MIT-only. [`NOTICES.md`](NOTICES.md) maps retained ranges to
142the exact notices under [`licenses/`](licenses/). Font Logos is absent because
143the pinned audit records that component as unlicensed.