SVG glyph → TTF compilation must be performed with the bundled script. Writing a new script each time subtly changes y-axis conversion and metric handling, contaminating comparisons between rounds.
Prerequisites
- fontTools required:
python3 -c "import fontTools"on failurepip3 install --user fonttools - Input SVG must follow the glyph-design skill conventions (viewBox 0 0 1000 1000, top-level path only, no stroke, baseline y=880)
manifest conventions
The build input is not an SVG directory but a manifest. In each glyph directory manifest.json:
{
"glyphs": {
"한": "han.svg",
"A": { "file": "A.svg", "advance": 620 }
}
}
- Keys must be 1 character. Paths are relative to the manifest location
advanceif omitted, 1000 (Hangul full-width). Latin and symbols must specify advance explicitly
Build procedure
- Pre-build validation (violating glyphs are returned to the creator):
grep -l 'stroke' _workspace/glyphs/{콘셉트}/**/*.svg # 결과가 있으면 규약 위반
- Compile:
python3 .claude/skills/font-build/scripts/build_font.py \
--manifest _workspace/glyphs/{콘셉트}/generated/manifest.json \
--family "Cheonjiin" --family-ko "천지인" --version 0.{N} \
--out _workspace/build/Cheonjiin-v0.{N}.ttf
--familymust be ASCII. Reason: PostScript names (nameID 6) allow only ASCII, and a non-ASCII default name causes macOS Font Book to reject installation with "no font name" (actually occurred in v0.4). The Korean display name goes in--family-ko— it goes into the localization record (0x0412) and is displayed as the Korean name in Korean environments- The license (SIL OFL 1.1) and copyright name records are automatically embedded by the script
- Output validation:
python3 -m fontTools.ttx -l _workspace/build/{파일}.ttf # 테이블 목록 확인
- Check that the glyph count equals the manifest total +1 (.notdef)
- Check that the failure list output by the script is empty — failed glyphs are replaced with empty glyphs, so leaving them unattended results in transparent characters
- Installation instructions: macOS는
open _workspace/build/{파일}.ttf→ install in Font Book. Tell the user the path
Version rules
- Synchronize with rounds: round-3 draft → v0.3
- Do not overwrite previous builds —
_workspace/build/preserve per version (for regression comparison)
Known pitfalls
- Strokes drawn with stroke are lost at compile time — pre-build validation catches this
- If a counter (the inner space of ㅇ) comes out filled, the inner and outer contour directions are the same — the glyph needs fixing (fill-rule does not exist in fonts)
- transform attributes and nested groups may be ignored — top-level path only, per the conventions
- Cubic Béziers (C) are automatically converted by the script with cu2qu (TrueType glyf allows only quadratic) — no separate handling needed
- 비ASCII
--familycauses macOS installation errors — the script outputs a warning, so do not ignore it
Release procedure (when the user requests distribution/upload)
- Copy the latest version TTF to
fonts/—fonts/is the distribution folder, keep only 1 latest release (older versions are preserved in_workspace/build/and git history) - Update README.md: add a one-line change to the filename in the installation path and the version table
- Record in CLAUDE.md change history
- After committing (message in Korean),
git push— Repository: github.com/revfactory/font-harness (public, OFL 1.1) - When changing the license, update both OFL.txt and the name table strings in the script