Files
luma-home/tools/font-weights.py
T
Kaloyan DanchevandClaude Opus 4.6 86191ba5f3
CI / Identify a merged version PR (push) Canceled after 0s
CI / Rust checks, rendering, and native package (push) Canceled after 0s
CI / Publish release and Homebrew feed (push) Canceled after 0s
Release PR / Maintain Version Packages PR (push) Canceled after 0s
Redesign panels, add 11 card fixes, new icons and app surfaces
Panel fixes: tall card row_span, room tab styling, vacuum card
image+value, AC airflow labels, AC fan speed sections (auto 3-btn
+ manual 5-step slider), light subtitle fallback, curtain pane
dividers, dimmable light presets, LED panel brightness + reorder.

New assets: 34 ui-icons (climate modes, cover, effects, battery,
led-strip, switch states), 3 logos, 90 app surface PNGs, design
system specs (components, ux-mechanics, tokens).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-10-27 23:29:32 +02:00

65 lines
3.1 KiB
Python

"""Freeze the bundled variable Inter font at the web UI's weights/optical sizes."""
import sys
import json
from pathlib import Path
from fontTools.ttLib import TTFont
from fontTools.varLib.instancer import instantiateVariableFont
from fontTools import subset
directory = Path(sys.argv[1])
font = TTFont(directory / "font.ttf")
axes = {axis.axisTag for axis in font["fvar"].axes} if "fvar" in font else set()
metrics = {}
for weight in (350, 400, 450, 500, 550, 600, 650, 700, 800):
for display in (False, True):
values = {"wght": weight} if "wght" in axes else {}
if "opsz" in axes:
values["opsz"] = 32 if display else 14
instance = instantiateVariableFont(font, values, inplace=False) if axes else font
instance.save(directory / f"font-{'display-' if display else ''}{weight}.ttf")
units = instance["head"].unitsPerEm
advances = instance["hmtx"].metrics
metrics[f"{'display-' if display else ''}{weight}"] = {
chr(codepoint): advances[glyph][0] / units
for codepoint, glyph in instance.getBestCmap().items()
}
def is_hangul(codepoint):
# Keep in sync with is_hangul() in src/renderer.rs, which routes these to font-kr.
return (0x1100 <= codepoint <= 0x11FF or 0x3130 <= codepoint <= 0x318F
or 0xA960 <= codepoint <= 0xA97F or 0xAC00 <= codepoint <= 0xD7A3
or 0xD7B0 <= codepoint <= 0xD7FF)
def fallback(path, keep, family, prefix):
font = TTFont(path)
options = subset.Options()
options.layout_features = []
options.name_IDs = ["*"]
subsetter = subset.Subsetter(options=options)
subsetter.populate(unicodes=[codepoint for codepoint in font.getBestCmap() if keep(codepoint)])
subsetter.subset(font)
advances_by_weight = {}
for weight in (400, 500):
instance = instantiateVariableFont(font, {"wght": weight}, inplace=False)
# Derived subsets use their own family name while retaining copyright/license tables.
style = "Regular" if weight == 400 else "Medium"
for name_id, value in [(1, family), (2, style), (4, f"{family} {style}"),
(6, f"{family.replace(' ', '')}-{style}"), (16, family), (17, style)]:
instance["name"].setName(value, name_id, 3, 1, 0x409)
instance.save(directory / f"{prefix}-{weight}.ttf")
units = instance["head"].unitsPerEm
advances = instance["hmtx"].metrics
advances_by_weight[weight] = {chr(cp): advances[glyph][0] / units
for cp, glyph in instance.getBestCmap().items()}
return advances_by_weight
cjk = fallback(sys.argv[2],
lambda cp: cp < 0xA000 or 0xF900 <= cp <= 0xFAFF or 0xFF00 <= cp <= 0xFFEF,
"Luma CJK", "font-cjk")
# Noto Sans SC carries no Hangul syllables; Korean comes from Noto Sans KR.
hangul = fallback(sys.argv[3], is_hangul, "Luma KR", "font-kr")
for weight in (400, 500):
metrics[f"fallback-{weight}"] = {**cjk[weight], **hangul[weight]}
(directory / "font-metrics.json").write_text(json.dumps(metrics, ensure_ascii=False), encoding="utf8")