K1Guitar/tools/patch_chs_bi.py

93 lines
3.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Append missing GBK glyph 闭 (0xB1,0xD5) to all CHS* tables + Chinese_font_* arrays.
Settings autoclose label uses 「关闭」; 关 exists, 闭 was missing → blank second char.
Uses tools/gen_wqy_font.py rasterizer (WenQuanYi BDF).
"""
from __future__ import annotations
import os
import re
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(ROOT, "tools"))
import gen_wqy_font as wqy # noqa: E402
HEADER = os.path.join(ROOT, "device", "LCD_ILI9341", "Drv_ILI9341_Lcd_ChineseFont.h")
# size -> (table name, font array name, bytes per glyph)
SIZES = {
8: ("CHS8Table", "Chinese_font_8", 8),
9: ("CHS9Table", "Chinese_font_9", 18),
11: ("CHS11Table", "Chinese_font_11", 22),
12: ("CHS12Table", "Chinese_font_12", 24),
13: ("CHS13Table", "Chinese_font_13", 26),
15: ("CHS15Table", "Chinese_font_15", 30),
16: ("CHS16Table", "Chinese_font_16", 32),
24: ("CHS24Table", "Chinese_font_24", 72),
}
BI_H, BI_L = 0xB1, 0xD5
NEEDLE = "{0x%02X,0x%02X}" % (BI_H, BI_L)
def render_bi(size: int) -> list[int]:
"""Rasterize 闭; size 24 has no WQY map — nearest-neighbor upscale from 16."""
src = 16 if size == 24 else size
pixels = wqy.glyph_pixels("", src, latin=False)
if size == 24:
# 16x16 -> 24x24
up = []
for y in range(24):
sy = min(15, y * 16 // 24)
for x in range(24):
sx = min(15, x * 16 // 24)
up.append(pixels[sy * 16 + sx])
pixels = up
return wqy.cn_to_bytes_msb(pixels, size, size)
def main() -> None:
text = open(HEADER, encoding="utf-8", errors="replace").read()
for size, (tname, aname, nbytes) in SIZES.items():
tm = re.search(
rf"(const char {tname}\[\]\[2\] = \{{)(.*?)(\n\}};)", text, re.S
)
if not tm:
raise SystemExit(f"missing {tname}")
body = tm.group(2)
compact = re.sub(r"\s+", "", body).lower()
if NEEDLE.lower() in compact:
print(f"skip table {tname}: already has 闭")
continue
body = body.rstrip() + f"\n {{0x{BI_H:02X},0x{BI_L:02X}}}, // 闭\n"
text = text[: tm.start()] + tm.group(1) + body + tm.group(3) + text[tm.end() :]
print(f"append table {tname}")
am = re.search(
rf"(const unsigned char {aname}\[\]\[\d+\] = \{{)(.*?)(\n\}};)", text, re.S
)
if not am:
raise SystemExit(f"missing {aname}")
fbody = am.group(2)
idx = len(re.findall(r'/\*"', fbody))
data = render_bi(size)
if len(data) != nbytes:
raise SystemExit(
f"{aname}: expected {nbytes} bytes, got {len(data)} for size={size}"
)
arr = ",".join(f"0x{b:02X}" for b in data)
fbody = fbody.rstrip() + f"\n{{{arr}}},/*\"\",{idx}*/"
text = text[: am.start()] + am.group(1) + fbody + am.group(3) + text[am.end() :]
print(f"append font {aname} idx={idx}")
open(HEADER, "w", encoding="utf-8", newline="\n").write(text)
print("patched", HEADER)
if __name__ == "__main__":
main()