From 097b9d1d64737755325f14a48a90b4de1c38708c Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Wed, 8 Jul 2026 15:16:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=A8=E9=87=8F=E7=99=BE=E5=88=86?= =?UTF-8?q?=E6=AF=94=E6=95=B0=E5=AD=97=E8=A1=A5=E9=9B=B6=E5=B9=B6=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=97=B4=E8=B7=9D=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E4=B8=A4=E4=BD=8D=E6=95=B0=E8=B4=B4=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit F16(16/12x 非整数倍缩放)下数字字形墨迹宽度等于步进宽度、无侧边距, 两位数(如 12%/36%)几乎贴在一起;加统一补零格式 + 手动字符间距(track)修复。 Co-Authored-By: Claude Opus 4.6 --- renderer.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/renderer.py b/renderer.py index a9c39fe..c932db5 100644 --- a/renderer.py +++ b/renderer.py @@ -40,14 +40,26 @@ class DashboardRenderer: self.F48 = ImageFont.truetype(font_path, 48) # ---------- 基础绘制工具 ---------- - def _tw(self, s, ft): + def _tw(self, s, ft, track=0): + # track:额外字符间距(px)。非整数倍缩放字号(如 F16=16/12x)下,数字字形墨迹宽度 + # 等于步进宽度(无侧边距),相邻字符几乎零间隙,需手动加距才不会紧贴。 + if track: + return sum(self.d.textlength(c, font=ft) for c in s) + track * (len(s) - 1) return self.d.textlength(s, font=ft) - def _draw(self, x, y, s, ft, fill, bold): + def _draw(self, x, y, s, ft, fill, bold, track=0): # 伪粗体:点阵字体单一字重,按 1~bold px 偏移叠绘加粗笔画 - self.d.text((x, y), s, font=ft, fill=fill) - for dx in range(1, bold + 1): - self.d.text((x + dx, y), s, font=ft, fill=fill) + if not track: + self.d.text((x, y), s, font=ft, fill=fill) + for dx in range(1, bold + 1): + self.d.text((x + dx, y), s, font=ft, fill=fill) + return + cx = x + for ch in s: + self.d.text((cx, y), ch, font=ft, fill=fill) + for dx in range(1, bold + 1): + self.d.text((cx + dx, y), ch, font=ft, fill=fill) + cx += self.d.textlength(ch, font=ft) + track def text(self, x, y, s, ft, fill=BLACK, bold=0): self._draw(x, y, s, ft, fill, bold) @@ -102,17 +114,18 @@ class DashboardRenderer: if right: self.rtext(self.W - 10, y, right, self.F12) - def _mid(self, x, cy, s, ft, fill=BLACK, bold=0, align="l"): + def _mid(self, x, cy, s, ft, fill=BLACK, bold=0, align="l", track=0): """按字符串「墨迹竖直中心」对齐到 cy 绘制——跨字号(F12/F24)也能真正居中, - 避免不同字号按顶部对齐时的视觉错位。align: l 左对齐 / r 右对齐 / c 居中于 x。""" + 避免不同字号按顶部对齐时的视觉错位。align: l 左对齐 / r 右对齐 / c 居中于 x。 + track:见 _tw,用于给紧贴的字符手动加间距。""" _, t, _, b = ft.getbbox(s) # 该串墨迹在字身框内的上/下沿 y = cy - (t + b) / 2.0 - w = self._tw(s, ft) + w = self._tw(s, ft, track) if align == "r": x -= w + bold elif align == "c": x -= (w + bold) / 2.0 - self._draw(x, y, s, ft, fill, bold) + self._draw(x, y, s, ft, fill, bold, track) def _pace(self, xr, cy, diff): """时间维度对比(pace = 用量% − 时间%):>0 超前↑红;<0 节余↓黑;=0 持平。 @@ -137,6 +150,7 @@ class DashboardRenderer: pct = max(0, min(100, int(raw))) if ok else 0 color = RED if (ok and pct >= warn) else BLACK LABEL_W, G1, G2, H = 26, 13, 8, 15 # G1 进度条↔百分比、G2 百分比↔pace(视觉约 12/11) + PCT_TRACK = 2 # F16(16/12x 非整数倍缩放)数字墨迹无侧边距、紧贴,手动加字符间距 cy = y + 10 # 行竖直中心 self._mid(x0, cy, bar["k"], self.F13, bold=1) # 左标签 F13 # 右侧从右往左:pace(最右) → 百分比 → 进度条 @@ -144,10 +158,10 @@ class DashboardRenderer: if ok and "time_pct" in bar: pace_w = self._pace(x1, cy, pct - int(bar["time_pct"])) pct_r = x1 - pace_w - G2 - pct_txt = f"{pct}%" if ok else "--" - self._mid(pct_r, cy, pct_txt, self.F16, fill=color, bold=1, align="r") # 百分比 F16(主) + pct_txt = f"{pct:02d}%" if ok else "--" + self._mid(pct_r, cy, pct_txt, self.F16, fill=color, bold=1, align="r", track=PCT_TRACK) # 百分比 F16(主) bx0 = x0 + LABEL_W - bx1 = pct_r - self._tw(pct_txt, self.F16) - G1 + bx1 = pct_r - self._tw(pct_txt, self.F16, PCT_TRACK) - G1 by = cy - H // 2 self.d.rectangle([bx0, by, bx1, by + H], outline=color, width=1) # 轨道边框随条色 fw = (bx1 - bx0) * pct / 100.0