fix: 12px 伪粗体文字自动加 1px 字距,消除相邻字粘连

- 12px 点阵字形间只有 1 列空隙,伪粗体右偏 1px 正好填满导致左右重叠;13/24px 空隙 2 列不受影响
- 基类新增 _track():12px 且加粗时自动加 k 字距,text/rtext/ctext/_mid 统一走它,宽版映射到 12px 的 F13/F16/FPACE 同样命中
- 新增 _tw_b() 取含粗体偏移与字距的实际占宽,替换环比/同比居中、金额前后缀、状态栏推进、BTC 涨跌幅、用量行进度条右端的手写宽度
- 夹具回归:小屏 F13/F16 部分逐像素不变,各行进度条右端仍齐平

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 17:34:41 +08:00
parent 3fa6bb5de6
commit 3656d8d933
3 changed files with 28 additions and 16 deletions

View File

@@ -75,14 +75,25 @@ class DashboardRenderer:
self.d.text((cx + dx, y), ch, font=ft, fill=fill)
cx += self.d.textlength(ch, font=ft) + track
def _track(self, ft, bold, track=0):
"""实际字距:显式 track 优先否则「12px 且加粗」自动加 k——12px 点阵字形之间只有 1 列空隙,伪粗体右偏 1px 正好填满、
相邻字左右粘连13/24px 空隙有 2 列所以正常2026-09-14 用户要求拉开一点点。宽版 F13/F16/FPACE 都映射到 12px同样命中。"""
if track or not bold:
return track
return self.k if getattr(ft, "size", 0) == 12 * self.k else 0
def _tw_b(self, s, ft, bold=0, track=0):
"""含伪粗体偏移与自动字距的实际占宽(手动推进 x / 居中时用它,别再手写 _tw + bold"""
return self._tw(s, ft, self._track(ft, bold, track)) + bold
def text(self, x, y, s, ft, fill=BLACK, bold=0):
self._draw(x, y, s, ft, fill, bold)
self._draw(x, y, s, ft, fill, bold, self._track(ft, bold))
def rtext(self, xr, y, s, ft, fill=BLACK, bold=0):
self._draw(xr - self._tw(s, ft) - bold, y, s, ft, fill, bold)
self._draw(xr - self._tw_b(s, ft, bold), y, s, ft, fill, bold, self._track(ft, bold))
def ctext(self, cx, y, s, ft, fill=BLACK, bold=0):
self._draw(cx - (self._tw(s, ft) + bold) / 2, y, s, ft, fill, bold)
self._draw(cx - self._tw_b(s, ft, bold) / 2, y, s, ft, fill, bold, self._track(ft, bold))
def hdash(self, x0, x1, y, dash=4, gap=4, fill=BLACK, width=1):
x = x0
@@ -108,8 +119,8 @@ class DashboardRenderer:
"""环比/同比一行的总宽度(标签 + 间隙 + 三角 + 数值),供居中/右对齐排布。"""
direction, val = pair
k = self.k
trw, tgap, vb = (8 * k, 4 * k, k) if direction else (0, 0, 0) # vb数值伪粗体的偏移宽度(占位 -- 不加粗)
return self._tw(label, self.F12) + 5 * k + trw + tgap + self._tw(val, self.F12) + vb
trw, tgap, vb = (8 * k, 4 * k, k) if direction else (0, 0, 0) # vb数值伪粗体占位 -- 不加粗)
return self._tw(label, self.F12) + 5 * k + trw + tgap + self._tw_b(val, self.F12, vb)
def _cmp_line(self, cx, y, label, pair, fg=BLACK):
"""环比/同比一行:标签 + 涨跌三角 + 数值,整体居中于 cx。direction 为 None 时不画三角。"""
@@ -151,9 +162,9 @@ class DashboardRenderer:
k = self.k
GAP = 1 * k # 小号段与主数字的间距
sb = bold # 小号段同样伪粗体,否则挨着粗体主数字显得单薄
wp = self._tw(pre, self.F12) + sb + GAP if pre else 0
ws = GAP + self._tw(suf, self.F12) + sb if suf else 0
wn = self._tw(num, self.F24) + bold
wp = self._tw_b(pre, self.F12, sb) + GAP if pre else 0
ws = GAP + self._tw_b(suf, self.F12, sb) if suf else 0
wn = self._tw_b(num, self.F24, bold)
x = cx - (wp + wn + ws) / 2.0
# 基线对齐F12/F24 数字墨迹底沿分别为 13k/26kgetbbox小号段下移其差值
ys = y + (self.F24.getbbox("0")[3] - self.F12.getbbox("0")[3])
@@ -182,6 +193,7 @@ class DashboardRenderer:
track见 _tw用于给紧贴的字符手动加间距。"""
_, t, _, b = ft.getbbox(s) # 该串墨迹在字身框内的上/下沿
y = cy - (t + b) / 2.0
track = self._track(ft, bold, track)
w = self._tw(s, ft, track)
if align == "r":
x -= w + bold
@@ -196,7 +208,7 @@ class DashboardRenderer:
up = diff > 0
color = self._pace_color(diff)
txt = f"{abs(int(diff)):02d}"
tw = self._tw(txt, self.FPACE)
tw = self._tw(txt, self.FPACE, self._track(self.FPACE, self.k)) # 宽版 FPACE=12px 加粗 → 含自动字距
self._mid(xr, cy, txt, self.FPACE, fill=color, bold=self.k, align="r")
TRI_GAP, TRI = 4 * self.k, 6 * self.k
cx = xr - tw - TRI_GAP - TRI / 2
@@ -234,7 +246,7 @@ class DashboardRenderer:
pct_txt = f"{pct:02d}%" if ok else "--"
self._mid(pct_r, cy, pct_txt, self.F16, fill=color, bold=k, align="r", track=PCT_TRACK) # 百分比 F16
bx0 = x0 + LABEL_W
bx1 = pct_r - self._tw(pct_txt, self.F16, PCT_TRACK) - G1
bx1 = pct_r - self._tw(pct_txt, self.F16, self._track(self.F16, k, PCT_TRACK)) - G1
by = cy - H // 2
self.d.rectangle([bx0, by, bx1, by + H], outline=outline, width=k) # 轨道边框随条色
fw = (bx1 - bx0) * pct / 100.0