Files
Scoreboard/vendor/fonts/tools/normalize-names.py
T
AskaEth bc8b1ee6c0 feat: M3-M7 全模块落地 + 集成接线
- M3 认证/权限/审计/限流 + 全部 REST 接口
- M4 管理面板(MIUIx + 成绩录入/积分榜下钻/大屏控制)
- M5a 大屏页面(六页 + 明细覆盖层 + 缩放适配)
- M6 WebSocket 实时同步中心
- M7 xlsx 导出 + 赛事包 zip + 备份
- 规则包 YAML 导入导出(差异预览)
- 字体 vendor 子集化(4 套 x2 字重)
- 集成:realtime/export/rules 接入 main+httpapi;backup 子命令
- 修复:中间件包装 ResponseWriter 丢失 Hijacker,导致 WS 握手 501
2026-09-09 19:02:24 +08:00

82 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""把子集字体内部的 name 表 / OS2 字重统一成 CSS 期望的规范值。
为什么需要:思源黑体的老版本 OTF 把每个字重写成独立族名
(`Source Han Sans CN Regular` / `Source Han Sans CN Bold`),
MiSans 的 usWeightClass 是 330/630 这类非标准值。
@font-face 的 `font-family` 描述符虽然能屏蔽内部族名,但保持一致更省心,
也避免字体被单独安装/引用时族名对不上。
用法(由 subset-fonts.sh 调用):
python3 vendor/fonts/tools/normalize-names.py
"""
from __future__ import annotations
import sys
from pathlib import Path
from fontTools.ttLib import TTFont
HERE = Path(__file__).resolve().parent
OUT_DIR = HERE.parent
CONF = HERE / "fonts.conf"
WEIGHTS = (("regular", "Regular", 400), ("bold", "Bold", 700))
STALE_NAME_IDS = (1, 2, 3, 4, 6, 16, 17, 21, 22)
PLATFORMS = ((3, 1, 0x409), (1, 0, 0)) # Windows / Mac,英文
def set_name(name, name_id: int, value: str) -> None:
for platform_id, plat_enc_id, lang_id in PLATFORMS:
name.setName(value, name_id, platform_id, plat_enc_id, lang_id)
def normalize(path: Path, family: str, style: str, weight: int) -> None:
font = TTFont(path)
name = font["name"]
for record in list(name.names):
if record.nameID in STALE_NAME_IDS:
name.removeNames(record.nameID, record.platformID, record.platEncID, record.langID)
full_name = family if style == "Regular" else f"{family} {style}"
set_name(name, 1, family) # family
set_name(name, 2, style) # subfamily
set_name(name, 3, f"{full_name}:subset") # unique id
set_name(name, 4, full_name) # full name
set_name(name, 6, full_name.replace(" ", "")) # postscript name
set_name(name, 16, family) # typographic family
set_name(name, 17, style) # typographic subfamily
os2 = font["OS/2"]
os2.usWeightClass = weight
if weight >= 700:
os2.fsSelection = (os2.fsSelection & ~0x40) | 0x20 # BOLD
font["head"].macStyle |= 0x01
else:
os2.fsSelection = (os2.fsSelection & ~0x20) | 0x40 # REGULAR
font["head"].macStyle &= ~0x01
font.flavor = "woff2"
font.save(path)
font.close()
def main() -> int:
for line in CONF.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
fid, _, family = [p.strip() for p in line.split("|")][:3]
for weight_name, style, weight_class in WEIGHTS:
path = OUT_DIR / f"{fid}-{weight_name}.woff2"
if not path.is_file():
print(f"缺少产物: {path}", file=sys.stderr)
return 1
normalize(path, family, style, weight_class)
print(f" {path.name:32s} -> {family} / {style} ({weight_class})")
return 0
if __name__ == "__main__":
raise SystemExit(main())