Files
RawMark/scripts/prepare-maple-font.py
eezd 6cbd604a28
Development CI / check-and-package (push) Successful in 3m48s
GitHub Git mirror / mirror (push) Successful in 5s
Development CI / image (push) Successful in 20s
Development CI / deploy-development (push) Successful in 15s
fix: keep the interface visible while fonts load
Render fallback fonts immediately and preload regular Maple in the background. Cache public fonts after use without eagerly downloading every font during PWA installation.
2026-10-30 18:28:00 +08:00

46 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""Rebuild local fonts from the specified v7.9 ZIP: python3 scripts/prepare-maple-font.py /path/to/MapleMonoNormalNL-NF-CN.zip.
Use --css-only to regenerate declarations from checked-in chunks.
Only font regeneration requires fonttools[woff]; application builds use the checked-in WOFF2 files.
Source: https://github.com/subframe7536/maple-font/releases/tag/v7.9
"""
import io
from pathlib import Path
import sys
import zipfile
root = Path(__file__).resolve().parents[1] / 'web/src/common/appearance'
output = root / 'fonts/maple'
output.mkdir(exist_ok=True)
family = 'Maple Mono Normal NL NF CN'
if sys.argv[1:] != ['--css-only']:
from fontTools import subset
from fontTools.ttLib import TTFont
with zipfile.ZipFile(sys.argv[1]) as archive:
(output / 'LICENSE.txt').write_bytes(archive.read('LICENSE.txt'))
for variant, weight, style in [('Regular', 400, 'normal'), ('Bold', 700, 'normal'), ('Italic', 400, 'italic'), ('BoldItalic', 700, 'italic')]:
data = archive.read('MapleMonoNormalNL-NF-CN-' + variant + '.ttf')
source = TTFont(io.BytesIO(data))
points = sorted(source.getBestCmap())
# Split by Unicode range so Chinese and Nerd Font glyphs need not download alongside Latin text.
for block in sorted({cp // 4096 for cp in points}):
unicodes = [cp for cp in points if cp // 4096 == block]
font = TTFont(io.BytesIO(data), recalcTimestamp=False)
options = subset.Options()
options.flavor = 'woff2'
subsetter = subset.Subsetter(options=options)
subsetter.populate(unicodes=unicodes)
subsetter.subset(font)
font.flavor = 'woff2'
name = f'{variant.lower()}-{block:02x}.woff2'
font.save(output / name)
css = ['/* Maple Mono v7.9; generated by scripts/prepare-maple-font.py. See fonts/maple/LICENSE.txt for licensing. */']
for variant, weight, style in [('regular', 400, 'normal'), ('bold', 700, 'normal'), ('italic', 400, 'italic'), ('bolditalic', 700, 'italic')]:
files = sorted(output.glob(f'{variant}-*.woff2'))
if not files:
raise ValueError(f'Missing checked-in font chunks: {variant}')
for file in files:
block = int(file.stem.split('-')[1], 16)
css.append(f"@font-face {{ font-family: '{family}'; font-style: {style}; font-weight: {weight}; font-display: swap; src: url('./fonts/maple/{file.name}') format('woff2'); unicode-range: U+{block * 4096:X}-{(block + 1) * 4096 - 1:X}; }}")
(root / 'maple-font.css').write_text('\n'.join(css) + '\n')