/* test/turn_repro.c — 复现「翻页跳页」(R3.2 分段流式)。 * 模拟真机序列:open → (可选 set_enc 到 UTF-16LE) → 跳页/翻页 → 渲染校验(非空/seg 边界正确)。 * 跑于 qemu-mipsel(静态)。 * 用法:qemu-mipsel ./test/turn_repro_mipsel [enc] [turns] */ #include "book.h" #include #include #include static int render_buf(uint16_t *buf, int W, int H, rd_book *b, int page, uint16_t bg, uint16_t fg) { for (int i = 0; i < W * H; i++) buf[i] = bg; int rc = rd_book_render(b, page, buf, W * 2, bg, fg); if (rc != 0) return -100 + rc; int ink = 0; for (int i = 0; i < W * H; i++) if (buf[i] != bg) ink++; return ink; } int main(int argc, char **argv) { const char *font = (argc > 1) ? argv[1] : "/home/Aska/Project/R3ProII/font/src/MiSans-Regular.otf"; const char *book = (argc > 2) ? argv[2] : "/tmp/rdsample/tongyi.txt"; const char *pref = (argc > 3) ? argv[3] : "/tmp/rdsample/repro"; int force_enc = (argc > 4) ? atoi(argv[4]) : 0; int turns = (argc > 5) ? atoi(argv[5]) : 200; char segbase[420], idxdir[420]; snprintf(segbase, sizeof segbase, "%s/segbase", pref); snprintf(idxdir, sizeof idxdir, "%s/index", pref); rd_book_set_seg_base(segbase); rd_book_set_index_dir(idxdir); int fs = 16, ls = 135, pw = 480, ph = 724, mx = 16, my = 20, top = 62; uint16_t *buf = (uint16_t *)malloc((size_t)pw * ph * 2); rd_book *b = NULL; int rc = rd_book_open(&b, book, font, fs, ls, pw, ph, mx, my, top); printf("open rc=%d enc=%s\n", rc, rc == 0 ? rd_book_encname(b) : "-"); if (rc != 0) return 1; if (force_enc) { printf("set_enc(%d)->rc=%d\n", force_enc, rd_book_set_enc(b, (rd_enc_t)force_enc)); } int np = rd_book_pages(b); printf("npages=%d\n", np); /* ① 翻页序列:跨段边界观察 cur 跳变 */ rd_book_set_page(b, 2); int prev = rd_book_current(b), jumps = 0; for (int i = 0; i < turns; i++) { int nxt = rd_book_turn(b, 1); int d = nxt - prev; if (d != 1) { printf(" JUMP turn#%d %d->%d d=%d npages=%d\n", i, prev, nxt, d, rd_book_pages(b)); if (d > 1) jumps++; } prev = nxt; if (rd_book_pages(b) < 1) break; } printf("turn jumps>1=%d\n", jumps); /* ② 渲染首页/第3页/中间页 校验非空 */ int targets[3] = { 0, 2, np > 3 ? np / 2 : 0 }; for (int t = 0; t < 3; t++) { if (targets[t] >= rd_book_pages(b)) continue; int ink = render_buf(buf, pw, ph, b, targets[t], 0xFFFF, 0x0000); printf("render page %d -> %s (ink=%d)\n", targets[t], ink < 0 ? "ERR" : (ink > 50 ? "OK" : "BLANK"), ink); } /* ③ set_page 到远页(触发按需补段),渲染校验 + 观察是否落到目标 */ int far = 316; int got = rd_book_set_page(b, far); printf("set_page(%d) -> cur=%d npages=%d\n", far, got, rd_book_pages(b)); int ink = render_buf(buf, pw, ph, b, got, 0xFFFF, 0x0000); printf("render page %d -> %s (ink=%d)\n", got, ink < 0 ? "ERR" : (ink > 50 ? "OK" : "BLANK"), ink); /* ④ 跳到更远(超过当前 npages,强制补段到 seg 20) */ int far2 = 4000; int got2 = rd_book_set_page(b, far2); printf("set_page(%d) -> cur=%d npages=%d\n", far2, got2, rd_book_pages(b)); ink = render_buf(buf, pw, ph, b, got2, 0xFFFF, 0x0000); printf("render page %d -> %s (ink=%d)\n", got2, ink < 0 ? "ERR" : (ink > 50 ? "OK" : "BLANK"), ink); free(buf); rd_book_close(b); printf("done\n"); return 0; }