reader R1: os.meow.reader 书架+TXT 垂直链路骨架

- core: 编码检测(BOM→UTF-8严格→GB18030/Big5统计, Big5与GB重叠按GB18030兜底, §3.5风险注明)
  + GB18030双字节码表(uint16[126][190]=47880B, tools/gen_gb18030_table.py 生成, 生成物入仓)
  + 流式排版器(贪心断行+Kinsoku避头尾+分页+重排锚定, rd_meas_fn 测量回调替 FreeType, 宿主可测)
  + TXT 流式加载器(按段读, 不整文件入内存, \n 恒独立换行可安全分段)
- engine: FreeType 封装(FT_New_Face 按需读文件, NO_HINTING/LIGHT 灰阶, LRU 512 key=码点+字号,
  blend565, rdft_advance 只测宽不栅格化)
- app: 书架(扫 Books/ 识别 5 后缀, 最近读置顶, 空态提示) + 阅读页(W_CUSTOM 画布 3 栏翻页
  +中央菜单占位(字号±/行距±/返回) +顶栏进度%/章节名) + 书桥(段表+flat 页索引, 渲染, 重排回锚)
  + 进度持久化(MeowData/os.meow.reader/progress/, path hash→seg/ch/fs/ls/ts)
- 取舍: 正文字体 FreeType 直读 TF MeowOS/fonts/ TTF/OTF; 无字体回退 SDK 位图字库(meow_ui_text,
  未打包字体(许可/体积), 全 glyph 兜底 R2); 页位图缓存当前+前后各1页(3×691KB), 翻页动画默认无
- 内存实测(宿主 --wrap malloc, 73页书): 书结构 130KB + 当前段刮擦~1.6MB(行/页容量按 n 偏高,R2 收紧)
  + 字形缓存~650KB + 3页位图 2.07MB ≈ 4.45MB 动态, 在 ≤8MB 阅读态预算内
- 测试: 宿主 core 58/58(enc/gb18030金标准/kinsoku/page/reflow/txt); qemu-mipsel ft_smoke PASS
  + book_smoke(12页/渲染有墨/翻页/重排回锚) PASS; reader 交叉 -Wall -Wextra 0 warning
- 产物: reader(mipsel 静态1.2MB)+build_reader.sh(vendor FreeType 可复现); vendor/二进制 gitignore
This commit is contained in:
MeowOS committed 2026-09-01 23:26:42 +08:00
1 parent 33d3059038
commit 553a7d5d9e
26 files changed
+6155

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
/* engine/rdft.h — FreeType 正文封装(meow_reader_ft_*)。
*
* 对齐 READER_ENGINE_NOTES §5:`FT_New_Face(path)` 按需读文件(不整文件载入 → 零大块 anon);
* 灰阶 `FT_LOAD_RENDER` + `FT_LOAD_NO_HINTING | FT_LOAD_TARGET_LIGHT`;LRU 字形缓存 512(key=码点+字号);
* blend565 灰阶位图混到 RGB565 缓冲。
*
* 依赖:freetype2 静态库(build_reader.sh 编 mipsel musl)。本 TU 只含封装逻辑,无 SDK 依赖。
*/
#ifndef RDFT_H
#define RDFT_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct rdft rdft; /* 不透明 */
/* 初始化 FreeType。0=成功。 */
int rdft_init(rdft **r);
/* 载入字体文件路径(TTF/OTF)。0=成功。同一 rdft 可换字体(重载清除 glyph 缓存)。 */
int rdft_load_font(rdft *r, const char *path);
/* 定字号(px;>0)。改字号会使 glyph 缓存失效(key 含字号,故等价重查但成本高,直接清)。 */
void rdft_set_px(rdft *r, int px);
/* 当前字号 ascender/descender(px);未载入字体返回 0。 */
int rdft_ascender(rdft *r);
int rdft_descender(rdft *r);
/* 字体族名(face->family_name UTF-8;无字体返回 "")。 */
const char *rdft_family(rdft *r);
/* 只测水平 advance(px),不栅格化、不进 glyph 缓存(排版器逐字测量用,省 rasterize 成本)。
* 缺字符返回缺字 advance。0=成功。 */
int rdft_advance(rdft *r, uint32_t cp, int *adv_x);
/* 取字形:cp→advance(px) + 灰阶位图(来自 LRU 缓存或本次光栅化)。
* 返回 0=成功;位图可能 bw==0(空白字形,仅 advance 有意义)。
* **注意**:返回的 bitmap 指针归缓存所有,调用方须在本次使用完毕后再调 rdft_glyph(避免被新
* 光栅化项逐出)。adv_x 为水平 advance(px,按 26.6 舍入)。 */
int rdft_glyph(rdft *r, uint32_t cp, int *adv_x,
const uint8_t **bitmap, int *bw, int *bh, int *left, int *top);
/* 灰阶位图 blend 到 RGB565 缓冲。
* fb = 目标缓冲首像素(565 小端);pitch_bytes = 每行字节数;tw/th = 目标像素区宽/高;
* x,y = 目标像素区原点(绝对像素);fg565/bg565 = 前景/背景 565 色值;
* bmp/left/top 为 rdft_glyph 返回值(bmp 为紧凑灰度,每行 = bw 字节);字画在 (x+left, y - top)
* (y 为基线)。越界像素被钳制跳过。 */
void rdft_blend565(uint16_t *fb, int pitch_bytes, int tw, int th,
int x, int y, const uint8_t *bmp, int bw, int bh, int left, int top,
uint16_t fg565, uint16_t bg565);
/* LRU 缓存容量(槽位数;默认 512;≥0 设)。 */
void rdft_cache_set_slots(rdft *r, int slots);
int rdft_cache_slots(rdft *r);
/* 当前缓存占用(条目数)。 */
int rdft_cache_used(rdft *r);
/* 释放。 */
void rdft_free(rdft *r);
#ifdef __cplusplus
}
#endif
#endif /* RDFT_H */