Files
luma-home/tools/font-weights.py
T
Kaloyan DanchevandClaude Opus 4.6 cbea5a322f
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
Merge Luma launcher fork into monorepo
Move trampoline files (boot-hook, watcher, overlay) into trampoline/
subdirectory. Add upstream Luma v2.3.1 source at repo root with our
additions:

- Page::Ha (4th nav tab) with placeholder empty state
- HA tab config schema and default entity mapping (ha-home/)
- Nav keys renamed: "home" → "start", new "ha" tab between Apps and Settings
- All state.rs/view.rs/main.rs/tests.rs updated for 4-tab navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-10-24 11:52:55 +03: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, 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")