- 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
69 lines
2.9 KiB
C
69 lines
2.9 KiB
C
/* 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 */
|