• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC) • 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库) • 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo 增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
74 lines
2.6 KiB
Python
74 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""preview_glyphs.py — 从 atlas/font.png + font.idx 抽取若干字符,拼成带标注的接触表 PNG,
|
|
用于人工核对图集中字形正确、无漏字。用法: preview_glyphs.py <atlas_dir> <out.png>"""
|
|
import struct
|
|
import sys
|
|
from PIL import Image, ImageDraw
|
|
|
|
def load_idx(path):
|
|
d = open(path, "rb").read()
|
|
assert d[:4] == b"MFNI", d[:4]
|
|
depth = d[6]
|
|
nf = d[7]
|
|
faces = []
|
|
for i in range(nf):
|
|
fh = d[16 + i * 20:16 + i * 20 + 20]
|
|
px, px_, py, pw, ph, asc, dsc, gc = struct.unpack("<HHHHHhhH", fh[:16])
|
|
goff = struct.unpack("<I", fh[16:20])[0]
|
|
tabs = []
|
|
for k in range(gc):
|
|
g = d[goff + k * 16:goff + k * 16 + 16]
|
|
cp, x, y, w, h, adv, dx, dy = struct.unpack("<IHHHHHbB", g)
|
|
tabs.append((cp, x, y, w, h, adv, dx, dy))
|
|
faces.append({"px": px, "px_": px_, "py_": py, "pw": pw, "ph": ph, "asc": asc, "dsc": dsc, "tabs": tabs})
|
|
return depth, faces
|
|
|
|
def main():
|
|
atlas = sys.argv[1]
|
|
out = sys.argv[2]
|
|
depth, faces = load_idx(f"{atlas}/font.idx")
|
|
im = Image.open(f"{atlas}/font.png").convert("L")
|
|
pix = im.load()
|
|
|
|
# 取样字符
|
|
sample = "MeowOS 主屏关机设置播放器音乐电台返回背光时间应用关闭确认取消01472589 ABC.,。!?:;「」¥·—…%"
|
|
cell = 44
|
|
cols = 12
|
|
rows = (len(sample) + cols - 1) // cols
|
|
sheet = Image.new("RGB", (cols * cell, rows * cell), (28, 30, 34))
|
|
dr = ImageDraw.Draw(sheet)
|
|
for idx, ch in enumerate(sample):
|
|
cp = ord(ch)
|
|
r, c = divmod(idx, cols)
|
|
# 找 28 面,找不到用 20 面
|
|
box = None
|
|
for f in faces:
|
|
if f["px"] == 28:
|
|
for t in f["tabs"]:
|
|
if t[0] == cp and t[3] and t[4]:
|
|
box = (f, t)
|
|
break
|
|
if box is None:
|
|
for f in faces:
|
|
if f["px"] == 20:
|
|
for t in f["tabs"]:
|
|
if t[0] == cp and t[3] and t[4]:
|
|
box = (f, t)
|
|
break
|
|
oy, ox = r * cell + 2, c * cell + 4
|
|
if box:
|
|
f, t = box
|
|
_, x, y, w, h, adv, dx, dy = t
|
|
for yy in range(h):
|
|
for xx in range(w):
|
|
a = pix[f["px_"] + x + xx, f["py_"] + y + yy] # PIL: [x, y]
|
|
if a:
|
|
sheet.putpixel((ox + xx, oy + yy), (255, 255, 255))
|
|
dr.text((ox, oy + 26), ch, fill=(255, 180, 60))
|
|
sheet.save(out)
|
|
print(f"saved {out}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|