feat: add Chinese 12x12 bitmap font (21075 glyphs) and fix boot gate
- Add ChineseFont12x12.h: U+4E00-U+9FFF CJK coverage, 535KB flash - Add gen_chinese_font.mjs: @napi-rs/canvas based font generator tool - Enable CJK rendering in MessageRenderer and CannedMessageModule - Remove boot confirmation gate (required 2s button hold, caused shutdown loop) - Update partition table: app 2.75MB, OTA 192KB, spiffs 1MB - Update CHANGELOG
This commit is contained in:
@@ -136,3 +136,61 @@
|
||||
4. `commitMultiTap()` 简化:不再有 index 0 是数字的特殊情况
|
||||
5. `drawFrame` preview 逻辑同步简化 + 光标 +1
|
||||
- 编译验证通过(SUCCESS 36s)
|
||||
|
||||
## UTF8 常用中文字库
|
||||
- **需求**:ESP32-C3 + SH1106 OLED 上显示中文文本
|
||||
- **方案**:12×12 点阵位图字库,XBM 格式(row-major, MSB first)
|
||||
- **生成工具**:`tools/gen_chinese_font.mjs`(Node.js + @napi-rs/canvas)
|
||||
- 字体源:Windows msyh.ttc(微软雅黑)
|
||||
- 字符集:U+4E00-U+74FF(CJK 常用汉字)+ 中文标点 + 全角数字/字母 = 10067 字形
|
||||
- 每字形 2 bytes codepoint + 24 bytes bitmap = 26 bytes
|
||||
- **输出文件**:`src/graphics/fonts/ChineseFont12x12.h`
|
||||
- 数据数组:`cfont12_data[]`(PROGMEM,按 codepoint 升序排列)
|
||||
- 查找函数:`cfont12_find(cp)` — 二分搜索,O(log n)
|
||||
- 渲染函数:`cfont12_draw(display, x, y, cp)` — 用 setPixel 逐像素绘制
|
||||
- UTF-8 解码:`cfont12_utf8(p, &len)` — 返回 codepoint 和字节长度
|
||||
- 混合绘制:`cfont12_drawStr(display, x, y, s)` — ASCII 用 drawString,CJK 用 cfont12
|
||||
- **集成点**:`CannedMessageModule.cpp` drawFrame FREETEXT 部分
|
||||
- text token 渲染:逐字符判断是否 CJK,CJK 用 cfont12_draw,ASCII 用 drawString
|
||||
- word wrap 宽度计算:CJK 字符宽度 = CFONT_W(12),ASCII 用 getStringWidth
|
||||
- **Flash 占用**:+256 KB(data 段),剩余 ~1.59 MB(4MB flash)
|
||||
- 编译验证通过(SUCCESS 51s)
|
||||
|
||||
## ⚠️ 分区表修复 — 固件超出 app 分区无法启动
|
||||
- **现象**:烧录后 ESP32-C3 反复重启,卡在 ROM bootloader,无用户程序日志
|
||||
- **根因**:256KB 中文字库使固件从 ~2.31MB 增长到 ~2.57MB,超出原 app 分区 0x250000 (2.375MB)
|
||||
- **修复**:调整 `partition-table.csv`
|
||||
- app: 0x250000 → 0x2C0000 (2.75MB)
|
||||
- flashApp (OTA): 0x0A0000 → 0x030000 (192KB)
|
||||
- spiffs: 0x100000 不变 (1MB)
|
||||
- 编译验证通过(SUCCESS 34s)
|
||||
|
||||
## ⚠️ 中文字形像素错乱修复(完整历程)
|
||||
- **现象**:中文字形隐约可见但局部像素缺失/多余 → 改 alpha 后变全白方块 → 修复后字体太粗
|
||||
- **根因**:字库生成判断像素的逻辑有误
|
||||
- 第一版用 R 通道 `< 128`(白色背景 + 黑色前景):抗锯齿边缘灰度 ≈128 在阈值边界,不稳定
|
||||
- 第二版用 alpha `> 40`(透明背景 + 黑色前景):alpha 40 太低,抗锯齿边缘全被纳入 → 字体太粗
|
||||
- **最终修复**:透明背景 + 黑色前景,alpha 阈值从 40 提高到 **128**
|
||||
- 透明区域 alpha=0 → 不标记
|
||||
- 黑色字形 alpha=255 → 标记
|
||||
- 抗锯齿边缘 alpha<128 → 不标记(去掉毛边,字形更锐利)
|
||||
- ⚠️ 关键:`imageSmoothingEnabled` 对 canvas fillText 无效,不能用它关抗锯齿
|
||||
- **Unicode 覆盖扩展**:U+4E00-U+74FF(10067字) → U+4E00-U+9FFF(21075字)
|
||||
- 修复"鬼"(U+9B3C)、"界"(U+754C)等常用字缺失
|
||||
- 覆盖 GB2312 全集 6763 字 + CJK 统一汉字扩展
|
||||
- Flash: 535KB, 固件总大小 2.65MB / 2.75MB (92%)
|
||||
- **问题**:收到的消息包含中文时无法正常显示
|
||||
- **根因**:`MessageRenderer.cpp` 的 `generateLines()` 逐字节处理 UTF-8,CJK 三字节字符被拆散;`drawStringWithEmotes()` 用 `drawString()` 渲染,不支持 CJK
|
||||
- **修复**(3处改动):
|
||||
1. 添加辅助函数 `measureMixedWidth()`(混合宽度计算)和 `drawMixedString()`(混合渲染)
|
||||
2. `generateLines()` 改为 UTF-8 感知的逐字符循环:CJK 字符作为独立 word 处理,宽度用 `measureMixedWidth()`
|
||||
3. `drawStringWithEmotes()` 文本段渲染改用 `drawMixedString()`
|
||||
4. `calculateLineHeights()` 检测 CJK 字符,行高取 max(FONT_HEIGHT_SMALL, CFONT_H)
|
||||
- 编译通过,flash 仅增 ~1KB(固件 2.57MB < app 分区 2.75MB)
|
||||
|
||||
## ⚠️ 开机确认逻辑导致无法启动
|
||||
- **现象**:`TCA9535: Boot not confirmed, shutting down` → deep sleep → 开不了机
|
||||
- **根因**:main.cpp 中 Wire.begin() 后的"开机确认窗口"要求用户在 3 秒内持续按住按键 2 秒,否则主动关机
|
||||
- 这违背了物理开机设计:按下按键 → MOS 得电 → ESP32 启动 → 用户很快松手
|
||||
- 3 秒窗口内几乎不可能持续按住 2 秒
|
||||
- **修复**:删除开机确认窗口代码,只保留 `tca9535PowerEn(true)` 立即锁住供电
|
||||
|
||||
@@ -101,3 +101,14 @@
|
||||
- 排除了大量 RadioLib 不用的协议(AX25/LoRaWAN/APRS 等)以节省 flash
|
||||
- MAX_THREADS=40
|
||||
- 默认 env:tbeam(需要切换到 esp32c3_moonshine 系列时要指定 env)
|
||||
- **Flash 占用**(esp32c3_moonshine_travelers):text≈1.92MB, data≈0.63MB, 总≈2.57MB / 4MB
|
||||
- **分区表**(partition-table.csv):app=0x2C0000(2.75MB), OTA=0x030000(192KB), spiffs=0x100000(1MB)
|
||||
- **中文 12×12 字库**:`src/graphics/fonts/ChineseFont12x12.h`,21075 字形,535KB flash
|
||||
- 生成工具:`tools/gen_chinese_font.mjs`(需 npm install @napi-rs/canvas)
|
||||
- 覆盖:U+4E00-U+9FFF(CJK 统一汉字全集,含 GB2312 6763 字)
|
||||
- 像素判定:透明背景 + 黑色前景,alpha > 128 阈值(去掉抗锯齿毛边,字形锐利)
|
||||
- ⚠️ 阈值 40 太低→字体膨胀变粗;128 合适→清晰锐利
|
||||
- ⚠️ `imageSmoothingEnabled` 对 canvas fillText 无效
|
||||
- 渲染函数:`cfont12_find()` / `cfont12_draw()` / `cfont12_utf8()` / `cfont12_drawStr()`
|
||||
- 集成点:CannedMessageModule drawFrame FREETEXT 部分(混合 ASCII+CJK 渲染)
|
||||
- MessageRenderer(收到消息显示)也已支持:generateLines + drawStringWithEmotes + calculateLineHeights 均改为 CJK 感知
|
||||
|
||||
Reference in New Issue
Block a user