From e6bd943d79c70d3f693614c0e8c3883ce8c8baad Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Mon, 2 Mar 2026 13:50:08 +0100 Subject: [PATCH] Make outline fixes optional --- README.md | 4 ++-- build.py | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8bc4a77..f71769b 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ python3 -m pip install --user -U fonttools python3 build.py ``` -To customize the font family name or disable old-style kerning: +To customize the font family name, disable old-style kerning, or skip outline fixes: ``` python3 build.py --customize @@ -87,7 +87,7 @@ Several metadata scripts are applied via FontForge: #### Step 4: Export -The final fonts are exported from FontForge as TTF. A cleanup step removes zero-area contours that can cause missing glyphs on macOS. The build supports optional old-style kern tables, but this is off by default because it has no effect on device tests. +The final fonts are exported from FontForge as TTF. Outline fixes remove overlaps and zero-area contours that can cause missing glyphs on macOS; you can disable them via `--customize`. The build supports optional old-style kern tables, but this is off by default because it has no effect on device tests. #### TTF cleanup (manual exports) diff --git a/build.py b/build.py index 4631a85..d672460 100755 --- a/build.py +++ b/build.py @@ -254,16 +254,20 @@ def main(): family = DEFAULT_FAMILY old_kern = False + outline_fix = True if "--customize" in sys.argv: print() family = input(f" Font family name [{DEFAULT_FAMILY}]: ").strip() or DEFAULT_FAMILY old_kern_input = input(" Export with old-style kerning? [y/N]: ").strip().lower() old_kern = old_kern_input in ("y", "yes") + outline_input = input(" Apply outline fixes (remove overlaps + zero-area cleanup)? [Y/n]: ").strip().lower() + outline_fix = outline_input not in ("n", "no") print() print(f" Family: {family}") print(f" Old kern: {'yes' if old_kern else 'no'}") + print(f" Outline fix: {'yes' if outline_fix else 'no'}") print() tmp_dir = os.path.join(ROOT_DIR, "tmp") @@ -272,12 +276,12 @@ def main(): os.makedirs(tmp_dir) try: - _build(tmp_dir, family=family, old_kern=old_kern) + _build(tmp_dir, family=family, old_kern=old_kern, outline_fix=outline_fix) finally: shutil.rmtree(tmp_dir, ignore_errors=True) -def _build(tmp_dir, family=DEFAULT_FAMILY, old_kern=True): +def _build(tmp_dir, family=DEFAULT_FAMILY, old_kern=True, outline_fix=True): variants = [(f"{family}-{style}", vf, wght, opsz) for style, vf, wght, opsz in VARIANT_STYLES] variant_names = [name for name, _, _, _ in variants] @@ -320,11 +324,13 @@ def _build(tmp_dir, family=DEFAULT_FAMILY, old_kern=True): sfd_path = os.path.join(tmp_dir, f"{name}.sfd") print(f"Scaling: {name}") - script = build_per_font_script(ttf_path, sfd_path, [ + steps = [ ("Scaling Y", scale_code), ("Condensing X", condense_code), - ("Removing overlaps", overlap_code), - ]) + ] + if outline_fix: + steps.append(("Removing overlaps", overlap_code)) + script = build_per_font_script(ttf_path, sfd_path, steps) run_fontforge_script(script) # Step 3: Apply metrics and rename (opens SFD, saves as SFD) @@ -373,7 +379,8 @@ def _build(tmp_dir, family=DEFAULT_FAMILY, old_kern=True): # Export TTF script = build_export_script(sfd_path, ttf_path, old_kern=old_kern) run_fontforge_script(script) - clean_ttf_degenerate_contours(ttf_path) + if outline_fix: + clean_ttf_degenerate_contours(ttf_path) print("\n" + "=" * 60)