12# How the width tables in lib/diagrams.ts were made; the forge never runs3# this. Diagrams are drawn at build time, where there is no browser to4# measure text in, so a node's size comes from these: the advance width of5# each character the sans font has, regular (400) and bold (650, --fw-strong,6# which diagrams' bold text and titles are set in), in thousandths of an7# em. Run it again when the font changes, in the venv of8# site/assets/fonts/make-fonts.sh:9#10# PATH=/tmp/fonts-venv/bin:$PATH sh lib/text-widths.sh site/assets/fonts/open-sans.woff211#12# It prints the two tables: for U+0020-007E then U+00A0-017F, each width as13# two base-36 digits, the way Pele writes its own.14set -eu15font=${1:?usage: text-widths.sh <variable sans .woff2>}16python3 - "$font" <<'EOF'17import sys18from fontTools.ttLib import TTFont19from fontTools.varLib import instancer2021codes = list(range(0x20, 0x7F)) + list(range(0xA0, 0x180))2223def b36(n):24 digits = '0123456789abcdefghijklmnopqrstuvwxyz'25 return digits[n // 36] + digits[n % 36]2627for name, wght in (('REGULAR', 400), ('BOLD', 650)):28 f = instancer.instantiateVariableFont(TTFont(sys.argv[1]), {'wght': wght})29 cmap, hmtx, upm = f.getBestCmap(), f['hmtx'], f['head'].unitsPerEm30 # A character the font lacks comes from another font: 580, Pele's guess.31 print(name, ''.join(b36(round(hmtx[cmap[c]][0] * 1000 / upm) if c in cmap else 580) for c in codes))32EOF