From 5d9df61de075f07a4a0ddc1f9314371710375b09 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 27 Oct 2026 22:21:41 +0800 Subject: [PATCH] fix(fonttools): keep natural glyph proportions in the ASCII atlas build_ascii_atlas() used to scale every glyph to fill its cw x ch cell, so uppercase and lowercase had the same height and narrow shapes such as i/l/o became solid blobs. Use one uniform scale ((ch - 2) / units_per_em) for the whole font, keep the real cap/x-height/descender ratios, and only squeeze glyphs whose ink is wider than cw - 1. Center by ink width and place the baseline at ch - 4. --- vpsdk/fonttools/fonttools.vp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/vpsdk/fonttools/fonttools.vp b/vpsdk/fonttools/fonttools.vp index 2608b20..2649aba 100644 --- a/vpsdk/fonttools/fonttools.vp +++ b/vpsdk/fonttools/fonttools.vp @@ -522,10 +522,14 @@ def build_ascii_atlas(font: Font*, cw: int, ch: int) -> uint8*: bw: int = xmax - xmin bh: int = ymax - ymin if bw > 0 and bh > 0: - a: float = float(cw - 2) / float(bw) - d: float = float(ch - 4) / float(bh) - tx: float = 1.0 - float(xmin) * a - ty: float = -2.0 - float(ymax) * d + # Natural metrics: one uniform scale for the whole font, so + # cap/x-height and ascender/descender keep their real + # proportions. Only glyphs wider than the cell are squeezed. + scale: float = float(ch - 2) / float(font.units_per_em) + a: float = scale + if float(bw) * scale > float(cw - 1): + a = float(cw - 1) / float(bw) + tx: float = (float(cw) - float(bw) * a) / 2.0 - float(xmin) * a string.memset(&_ascii_tmp, 0, uint64(cw * ch * 4)) global _edge_count, _min_x, _max_x, _min_y, _max_y _edge_count = 0 @@ -533,7 +537,7 @@ def build_ascii_atlas(font: Font*, cw: int, ch: int) -> uint8*: _max_x = -1.0e30 _min_y = 1.0e30 _max_y = -1.0e30 - _add_glyph(font, gid, a, 0.0, 0.0, d, tx, ty, 0.0, 0.0, 1.0, 0) + _add_glyph(font, gid, a, 0.0, 0.0, scale, tx, 0.0, 0.0, float(ch - 4), 1.0, 0) _fill_edges(&_ascii_tmp[0], cw, ch, uint32(0x00FFFFFF)) py: int = 0 while py < ch: