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:
1 parent
33d3059038
commit
553a7d5d9e
26 files changed
+6155
No files matched your search
@@ -0,0 +1,71 @@
|
||||
/* test/rdft_smoke.c — os.meow.reader FreeType 封装 qemu-mipsel 冒烟。
|
||||
* 在 mipsel 上初始化 rdft → 载入思源黑体/MiSans OTF → 定字号 → 取 CJK/拉丁字形度量 →
|
||||
* blend565 到 RGB565 缓冲 → 校验像素变化 → LRU 缓存 512 上限。可跑于 qemu-mipsel(静态)。
|
||||
*
|
||||
* 用法:qemu-mipsel ./test/rdft_smoke <font.otf> (缺省用仓库 font/src/MiSans-Regular.otf)
|
||||
*/
|
||||
#include "rdft.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int fails = 0;
|
||||
#define CHECK(c, m) do { if (c) { printf(" ok %s\n", m); } else { printf("FAIL %s\n", m); fails++; } } while (0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *font = (argc > 1) ? argv[1] : "/home/Aska/Project/R3ProII/font/src/MiSans-Regular.otf";
|
||||
rdft *r = NULL;
|
||||
CHECK(rdft_init(&r) == 0, "rdft_init");
|
||||
CHECK(r != NULL, "rdft non-null");
|
||||
|
||||
CHECK(rdft_load_font(r, font) == 0, "rdft_load_font");
|
||||
CHECK(rdft_ascender(r) > 0, "ascender>0");
|
||||
printf(" family=%s ascender=%d descender=%d\n", rdft_family(r), rdft_ascender(r), rdft_descender(r));
|
||||
|
||||
rdft_set_px(r, 20);
|
||||
/* 字形度量:你(U+4F60)/好(U+597D)/A/空格/软连字符 */
|
||||
const uint32_t cps[] = { 0x4F60, 0x597D, 'A', ' ', 0x00AD, 0x3002 };
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int adv = 0, bw = 0, bh = 0, left = 0, top = 0;
|
||||
const uint8_t *bmp = NULL;
|
||||
CHECK(rdft_glyph(r, cps[i], &adv, &bmp, &bw, &bh, &left, &top) == 0, "glyph");
|
||||
printf(" cp=U+%04X adv=%d bmp=%dx%d left=%d top=%d\n", cps[i], adv, bw, bh, left, top);
|
||||
if (cps[i] == 'A') CHECK(adv > 5, "A advance>5");
|
||||
if (cps[i] == 0x4F60) CHECK(adv >= 16 && adv <= 22, "CJK adv ~20");
|
||||
}
|
||||
|
||||
/* blend565:把「你」字画进一个 RGB565 缓冲(80×80,白底黑字),校验有像素变黑 */
|
||||
{
|
||||
int W = 80, H = 80;
|
||||
uint16_t *fb = (uint16_t*)malloc((size_t)W * H * 2);
|
||||
for (int i = 0; i < W * H; i++) fb[i] = 0xFFFF; /* 白 */
|
||||
int adv = 0, bw = 0, bh = 0, left = 0, top = 0;
|
||||
const uint8_t *bmp = NULL;
|
||||
rdft_glyph(r, 0x4F60, &adv, &bmp, &bw, &bh, &left, &top);
|
||||
int baseline = 30;
|
||||
rdft_blend565(fb, W * 2, W, H, 10, baseline, bmp, bw, bh, left, top, 0x0000, 0xFFFF);
|
||||
int dark = 0;
|
||||
for (int i = 0; i < W * H; i++) if (fb[i] != 0xFFFF) dark++;
|
||||
CHECK(dark > 10, "blend produced dark pixels");
|
||||
free(fb);
|
||||
}
|
||||
|
||||
/* LRU 缓存上限:请求 600 个不同码点 → used 应 ≤ 512 */
|
||||
{
|
||||
rdft_cache_set_slots(r, 512);
|
||||
for (uint32_t cp = 0x4E00; cp < 0x4E00 + 600; cp++) {
|
||||
int adv = 0, bw = 0, bh = 0, left = 0, top = 0;
|
||||
const uint8_t *bmp = NULL;
|
||||
rdft_glyph(r, cp, &adv, &bmp, &bw, &bh, &left, &top);
|
||||
}
|
||||
int used = rdft_cache_used(r);
|
||||
printf(" lru used=%d slots=%d\n", used, rdft_cache_slots(r));
|
||||
CHECK(used <= 512, "lru used <= 512");
|
||||
CHECK(used >= 1, "lru used >= 1");
|
||||
}
|
||||
|
||||
rdft_free(r);
|
||||
printf("rdft_smoke: %s\n", fails ? "FAIL" : "PASS");
|
||||
return fails ? 1 : 0;
|
||||
}
|
||||
Reference in new issue
Block a user