-
Notifications
You must be signed in to change notification settings - Fork 10
EN:Development Notes
English Version | 中文版
Practical notes for contributors, focused on test-font reproducibility. For architecture and the test system overview, see Development.
- The single source of truth is
scripts/font-manifest.json: immutable download URL, SHA-256, version, and license for every font. -
python3 scripts/download_fonts.py --allfetches them intotest/fonts/(gitignored); fonts are never installed into the system font library. -
regression_test.pypointsOSFONTDIRattest/fonts/so luaotfload can find them. - Regression comparison is pixel-exact with zero tolerance: with pinned fonts, macOS and CI (Linux) render byte-identically, so any pixel diff is a real regression.
This is the easiest pitfall to hit and the most confusing to diagnose.
Mechanism: fonts referenced by name in test .tex files (e.g. \setmainfont{Source Han Serif SC}) are resolved by luaotfload's name index, which prefers a copy installed on your system (e.g. ~/Library/Fonts/SourceHanSerif.ttc) over the pinned file in test/fonts/. If the versions differ, baselines saved on your machine will not match CI.
Real case (2026-08): a dev machine had Source Han Serif 2.002 installed while the manifest pins 2.003. Adobe changed the outlines of 91 URO glyphs between the two versions (including 大, 天, 女). Baselines re-saved under 2.002 made CI fail with ~0.005% pixel diffs on pages containing those glyphs.
Symptoms: CI fails with tiny diffs (<0.01%); diff images look identical to the eye; differing pixels cluster on stroke edges of a few CJK glyphs.
Diagnose:
luaotfload-tool --find="Source Han Serif SC" # which file the name resolves toand compare the name table version strings of the system copy vs test/fonts/SourceHanSerifSC-Regular.otf (fontTools).
Fix: upgrade/replace the locally installed font to the manifest version (currently Source Han Serif 2.003R; the Super OTC is 01_SourceHanSerif.ttc.zip in the adobe-fonts 2.003R release), then run luaotfload-tool --update. Machines without a system copy are unaffected.
Cases referencing fonts by filename (e.g.
hori.texwith\setmainfont{SourceHanSerifSC-Regular.otf}) are immune — file lookup only hits the pinned copy.
-
saveaccepts explicit files and routes each to its own suite (basic / past_issue / complete):python3 test/regression_test.py save test/regression_test/complete/tex/font.tex
-
Before saving, understand where the diff comes from: an intended effect of your change, or environment drift (font versions!). Only the former should be saved.
-
Re-run the full check afterwards:
python3 test/regression_test.py check --all. -
CI only runs the basic suite — past_issue and complete baselines are only guarded by local
--allruns.
texlua test/run_all.lua # 1. unit tests (first)
python3 test/regression_test.py check --all # 2. visual regression
python3 test/clreq_test.py # 3. clreq metric assertions
python3 test/geometry_test.py # 4. geometry self-check (baseline-free)Update unit tests together with any change that affects their results; never skip unit tests and run regression directly.
- Tests and examples only use fonts with verifiable origin and license (OFL, Arphic PL, CC0, government open licenses), always pinned via the manifest.
- Example PDFs embed font subsets and are distributed with the repo — check embedded fonts with
pdffontsbefore committing. - Adding a font: add a manifest entry (immutable URL, SHA-256, license); never copy files by hand. See
ai_must_read/docs/font-metrics.mdfor license assessments.
📜 LuaTeX-CN | Licensed under Apache License 2.0