From c1801c8c3431f29707267445d0338d2062a0f9de Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 4 Sep 2026 11:37:08 +1000 Subject: [PATCH] fix(label): shrink text to fit before ellipsising it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fit() cut words the moment a line overran, so the style row printed as "Electro, Synth-…" -- the one line a customer scans for -- while the extension's own label engine printed it whole. Step the font down to ~70% of its authored size first (still legible at 203 dpi) and only ellipsise if it still will not fit. Returns (text, font) so callers draw with whatever size actually fitted. Verified on the rfid65 render: the full "Electro, Synth-pop" at a slightly smaller bold. Co-Authored-By: Claude Opus 5 --- mac/label.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/mac/label.py b/mac/label.py index c54562a..06b373a 100644 --- a/mac/label.py +++ b/mac/label.py @@ -96,13 +96,26 @@ def _w(d, s, f): def fit(d, s, f, maxw): - """Trim with an ellipsis until it fits maxw dots.""" + """Make `s` fit `maxw` dots. Returns (text, font). + + SHRINK before trimming. This used to ellipsise straight away, so a label read + "Electro, Synth-…" -- the one line a customer scans for, cut off while the extension's + own label engine printed it whole. Step the font down to ~70% of its authored size + (still legible at 203 dpi) and only ellipsise if it still will not fit.""" s = (s or '').strip() if not s or _w(d, s, f) <= maxw: - return s + return s, f + size, path = getattr(f, 'size', None), getattr(f, 'path', None) + if size and path: + floor = max(7, int(size * 0.7)) + for sz in range(size - 1, floor - 1, -1): + g = ImageFont.truetype(path, sz) + if _w(d, s, g) <= maxw: + return s, g + f = ImageFont.truetype(path, floor) while s and _w(d, s + '…', f) > maxw: s = s[:-1] - return (s + '…') if s else '' + return ((s.rstrip() + '…') if s else ''), f def _qr(data, maxpx): @@ -176,11 +189,13 @@ def render_art(fields, prof): if y + size > H - pad - info_h: break f = font(kind, size) - d.text((lx, y), fit(d, val, f, avail), font=f, fill=0) + tv, fv = fit(d, val, f, avail) + d.text((lx, y), tv, font=fv, fill=0) y += size + 2 if info: f = font('regular', S(0.095)) - d.text((lx, H - pad - S(0.095)), fit(d, info, f, avail), font=f, fill=0) + ti, fi = fit(d, info, f, avail) + d.text((lx, H - pad - S(0.095)), ti, font=fi, fill=0) return img