/* test/book_smoke.c — os.meow.reader 书桥全链路 qemu-mipsel 冒烟。 * 开一本 TXT(UTF-8,含章节)→ 探测编码 → 建段+页索引 → FreeType 渲染首页(校验非底像素)→ * 翻页/锚定 → 改字号重排回锚 → 再渲染;全程不碰 SDK(book.c 只依赖 core+engine)。 * 跑于 qemu-mipsel(静态)。用法:qemu-mipsel ./test/book_smoke_mipsel */ #include "book.h" #include #include #include 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) static void write_txt(const char *path) { FILE *f = fopen(path, "wb"); fprintf(f, "第一章 测试编码与排版\n"); for (int i = 0; i < 60; i++) { fprintf(f, "第%d段:这是一段用于验证流式排版与 FreeType 渲染的中文正文内容。" "它包含汉字、标点,以及一些 English words 混合排版。" "断行、避头尾与分页行为都要正确。\n", i + 1); } fprintf(f, "\nChapter two: the quick brown fox jumps over the lazy dog.\n"); fclose(f); } int main(int argc, char **argv) { const char *font = (argc > 1) ? argv[1] : "/home/Aska/Project/R3ProII/font/src/MiSans-Regular.otf"; const char *txt = "/tmp/rdbook_smoke.txt"; write_txt(txt); rd_book *b = NULL; int rc = rd_book_open(&b, txt, font, 20, 130, 480, 720, 16, 20, 62); CHECK(rc == 0, "rd_book_open"); if (rc != 0) { printf("open rc=%d\n", rc); return 1; } int np = rd_book_pages(b); printf(" pages=%d basename=%s enc=%s\n", np, rd_book_basename(b), rd_book_encname(b)); CHECK(np > 0, "pages>0"); /* 渲染首页:校验有非背景像素 */ int W = 480, H = 720; uint16_t *buf = (uint16_t *)malloc((size_t)W * H * 2); uint16_t bg = 0xFFFF, fg = 0x0000; rc = rd_book_render(b, 0, buf, W * 2, bg, fg); CHECK(rc == 0, "render page0"); int inked = 0; for (int i = 0; i < W * H; i++) if (buf[i] != bg) inked++; printf(" page0 inked=%d px\n", inked); CHECK(inked > 100, "page0 has ink"); /* 锚定当前页 */ int seg = -1; int32_t ch = -1; rd_book_anchor(b, &seg, &ch); CHECK(seg >= 0 && ch >= 0, "anchor valid"); /* 翻页 */ int cur = rd_book_current(b); int np_total = rd_book_pages(b); int nxt = rd_book_turn(b, 1); CHECK(np_total > 1 || nxt == 0, "pages>1 or single-page clamps"); if (np_total > 1) CHECK(nxt == cur + 1, "turn fwd +1"); /* 回退 */ rd_book_turn(b, -1); CHECK(rd_book_current(b) == cur, "turn back to cur"); /* 改字号(20→24) 重排回锚到含 (seg,ch) 的页 */ int np2 = rd_book_jump_to_anchor(b, seg, ch, 24, 130); CHECK(np2 >= 0 && np2 < rd_book_pages(b), "reflow lands in range"); int seg2 = -1; int32_t ch2 = -1; rd_book_anchor(b, &seg2, &ch2); CHECK(seg2 == seg, "reflow keeps segment"); /* 重排后渲染 */ rc = rd_book_render(b, rd_book_current(b), buf, W * 2, bg, fg); CHECK(rc == 0, "render after reflow"); /* 行距调整再排 */ int np3 = rd_book_set_size(b, 20, 150); CHECK(np3 >= 0 && np3 < rd_book_pages(b), "set_size reflow ok"); free(buf); rd_book_close(b); printf("book_smoke: %s\n", fails ? "FAIL" : "PASS"); return fails ? 1 : 0; }