From e8ea8d204b0aa9fe722d76da57fc76bb12054070 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Mon, 2 Mar 2026 02:03:41 +0100 Subject: [PATCH] Further tweaking This is already an exceptional result. I need to verify this on an actual device, but I'm pretty happy with the results so far! --- build.py | 4 ++-- scripts/metrics.py | 21 +++++++++++++++++---- scripts/scale.py | 33 +++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/build.py b/build.py index 779ea06..960ec59 100755 --- a/build.py +++ b/build.py @@ -133,8 +133,8 @@ def main(): print(f" Copied: {f}") print(f" {len(sfd_files)} font(s) ready.") - # Step 2: Apply vertical scale to all glyphs - print("\n── Step 2: Vertical scale ──\n") + # Step 2: Apply vertical scale to lowercase glyphs + print("\n── Step 2: Scale lowercase ──\n") scale_code = load_script_as_function(os.path.join(SCRIPTS_DIR, "scale.py")) diff --git a/scripts/metrics.py b/scripts/metrics.py index 95233af..cc43d57 100644 --- a/scripts/metrics.py +++ b/scripts/metrics.py @@ -135,11 +135,24 @@ if design_top is None or design_bot is None: # lineGap absorbs all extra leading. This keeps the text vertically # centred on the line, which matters for UI / web layout. -typo_ascender = int(round(design_top)) -typo_descender = int(round(design_bot)) # negative -typo_extent = typo_ascender - typo_descender # total ink span (positive) desired_lh = int(round(upm * LINE_HEIGHT)) -typo_linegap = max(0, desired_lh - typo_extent) +ink_ascender = int(round(design_top)) +ink_descender = int(round(design_bot)) # negative +ink_extent = ink_ascender - ink_descender # total ink span (positive) + +if ink_extent <= desired_lh: + # Ink fits within desired line height — use ink boundaries, gap absorbs rest + typo_ascender = ink_ascender + typo_descender = ink_descender + typo_linegap = desired_lh - ink_extent +else: + # Ink exceeds desired line height — cap to UPM, split proportionally + ratio = ink_ascender / ink_extent + typo_ascender = int(round(desired_lh * ratio)) + typo_descender = typo_ascender - desired_lh # negative + typo_linegap = 0 + +typo_extent = typo_ascender - typo_descender # ── OS/2 Win metrics ───────────────────────────────────────────────────────── # Clipping boundaries on Windows. Must cover every glyph or Windows clips them. diff --git a/scripts/scale.py b/scripts/scale.py index 6a2b83c..8cda262 100644 --- a/scripts/scale.py +++ b/scripts/scale.py @@ -1,7 +1,7 @@ """ -FontForge: Scale all glyphs vertically -─────────────────────────────────────── -Applies a vertical scale to all glyphs from glyph origin, +FontForge: Scale lowercase glyphs vertically +───────────────────────────────────────────── +Applies a vertical scale to lowercase glyphs only, from glyph origin, matching the Transform dialog with all options checked: - Transform All Layers @@ -16,6 +16,7 @@ Run inside FontForge (or via build.py which sets `f` before running this). import fontforge import psMat +import unicodedata f = fontforge.activeFont() @@ -24,7 +25,7 @@ f = fontforge.activeFont() # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SCALE_X = 1.0 -SCALE_Y = 1.0 +SCALE_Y = 1.10 # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # APPLY @@ -32,17 +33,21 @@ SCALE_Y = 1.0 mat = psMat.scale(SCALE_X, SCALE_Y) -# Select all glyphs -f.selection.all() +# Select only lowercase glyphs +f.selection.none() +count = 0 +for g in f.glyphs(): + if g.unicode < 0: + continue + try: + cat = unicodedata.category(chr(g.unicode)) + except (ValueError, OverflowError): + continue + if cat == "Ll" or g.unicode in (0x00AA, 0x00BA): + f.selection.select(("more",), g.glyphname) + count += 1 -# Transform with all options enabled. -# FontForge flag names: -# partialTrans — transform selected points only (we don't want this) -# round — Round To Int -# The font-level transform handles layers, widths, kerning, and positioning -# when called on the full selection. f.transform(mat, ("round",)) -count = sum(1 for g in f.glyphs() if g.isWorthOutputting()) -print(f" Scaled {count} glyphs by X={SCALE_X:.0%}, Y={SCALE_Y:.0%}") +print(f" Scaled {count} lowercase glyphs by X={SCALE_X:.0%}, Y={SCALE_Y:.0%}") print("Done.")