feat(tuku): 阅读器左右翻页核心——页源契约/预解码窗口/跟手翻页/方向感知 tap
- 页源契约(logic/reader):count/meta/open/close + 目录册(文件夹即书)为第一个实现; meta 由纯 C 图片头探测(PNG IHDR/JPEG SOF/BMP)提供原始尺寸,条漫可先排版再取图, zip 册(M9/M11)只需另写 mr_book_ops,两种消费方式零改动复用 - 翻页引擎:pthread 后台解码窗口=当前±1 页(目录册 downscale 到屏幕长边),翻页只 blit 缓存页图 + meow_anim 150ms 滑动吸附;未命中立即切页显示加载态、不在翻页路径解码; 只 flush 内容区;decode/flip 首帧/翻页完成/进出内存全部 meow_log 打点 - 阅读页 UI:fit 三档(适宽/适高/原始,TopAppBar 动作循环,标题显示页码 x/y)+ 双击以点击点为锚放大(临时缓冲超上限自动降倍率)+ 单指拖拽/滑动步进平移; tap 三分区方向感知(RTL 默认:左=下一页,LTR 反之),中区切 chrome; 左缘返回交给 app.c、屏底热区交给 SDK 回桌面,两者都不拦截 - 跟手:app.c 仅补 2 处极小路由(ACT_READER 的 down/move),reader 自行算位移; 屏底 28px/左缘 24px 不进拖动,竖向主导放弃横滑 - 内存纪律:驻留 ≤3 张 downscale 页图;放大时窗口收缩到当前页;on_leave 停解码线程、 释放全部页图/册索引/TopAppBar,并记录 VmRSS/MemAvailable 前后对比 - 测试/构建:新增 test_reader_core(契约边界/空册/越界/重复 open-close/首末页/头探测/ 方向语义/fit/平移夹取,108 项);run_tests.sh 与 build_tuku.sh 源列表接线; 宿主 46+108 全 PASS,交叉构建静态 MIPS32r2 ELF、-Wall -Wextra 零警告
This commit is contained in:
1 parent
28b67a7b8d
commit
23c9db73df
10 files changed
+2088
-69
No files matched your search
@@ -0,0 +1,70 @@
|
||||
/* logic/reader/nav.h — 阅读导航纯逻辑(方向语义 / tap 分区 / fit / 平移 clamp)。
|
||||
*
|
||||
* 纯 C、无 SDK 依赖:reader.c 与宿主测试共用同一实现(logic/reader/nav.c)。
|
||||
*
|
||||
* 方向语义(mr_reader_get_direction,默认 RTL):
|
||||
* - LTR(左→右读):页码沿屏幕向右递增;屏左 1/3 = 上一页,屏右 1/3 = 下一页;
|
||||
* 手指向右拖露出左边那页 = 上一页。
|
||||
* - RTL(日漫,默认):页码沿屏幕向左递增;屏左 1/3 = **下一页**,屏右 1/3 = 上一页;
|
||||
* 手指向右拖露出左边那页 = 下一页。
|
||||
* 图像本身不做镜像(RTL 只影响翻页语义)。
|
||||
*/
|
||||
#ifndef MR_READER_NAV_H
|
||||
#define MR_READER_NAV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ---- fit 三档 ---- */
|
||||
#define MR_FIT_WIDTH 0 /* 适宽:撑满屏宽 */
|
||||
#define MR_FIT_HEIGHT 1 /* 适高:撑满屏高 */
|
||||
#define MR_FIT_ORIGINAL 2 /* 原始:1:1 像素 */
|
||||
#define MR_FIT_COUNT 3
|
||||
|
||||
/* ---- tap 分区(按屏幕横向三分) ---- */
|
||||
#define MR_ZONE_LEFT 0
|
||||
#define MR_ZONE_MIDDLE 1
|
||||
#define MR_ZONE_RIGHT 2
|
||||
|
||||
/* 屏宽三分:左/中/右。view_w<=0 返回 MIDDLE。 */
|
||||
int mr_nav_tap_zone(int x, int view_w);
|
||||
|
||||
/* tap 分区的页增量:+1=下一页 / -1=上一页 / 0=chrome 显隐(中区)。 */
|
||||
int mr_nav_tap_delta(int rtl, int zone);
|
||||
|
||||
/* 中部横向拖动的页增量。dx>0 = 手指向右(露出屏幕左侧那页)。
|
||||
* 首/末页不在这里判断——调用方用 mr_nav_clamp_page 落到实际目标页。 */
|
||||
int mr_nav_swipe_delta(int rtl, int dx);
|
||||
|
||||
/* 页下标 clamp;count<=0 返回 -1。 */
|
||||
int mr_nav_clamp_page(int page, int count);
|
||||
|
||||
/* 翻页提交阈值:视口宽的 1/4,夹在 [60,160] px。 */
|
||||
int mr_nav_commit_dist(int view_w);
|
||||
|
||||
/* 松手位移是否达到翻页阈值。 */
|
||||
int mr_nav_commit(int dx, int view_w);
|
||||
|
||||
/* fit 目标尺寸(未含 zoom)。0=成功;参数非法 -1。 */
|
||||
int mr_nav_fit_size(int fit, int src_w, int src_h, int vw, int vh, int *out_w, int *out_h);
|
||||
|
||||
/* 按百分比放大(zoom_pct=100 原样;200=2×)。0=成功。 */
|
||||
int mr_nav_zoom_size(int w, int h, int zoom_pct, int *out_w, int *out_h);
|
||||
|
||||
/* 平移半幅:内容比视口每侧多出的像素(>=0)。内容不溢出该轴 → 0(该轴不可平移)。 */
|
||||
void mr_nav_pan_limit(int content_w, int content_h, int vw, int vh, int *lim_x, int *lim_y);
|
||||
|
||||
/* 把平移量夹到 ±半幅。 */
|
||||
void mr_nav_pan_clamp(int content_w, int content_h, int vw, int vh, int *pan_x, int *pan_y);
|
||||
|
||||
/* 翻页动画的进场起点(px):下一页在 RTL 从左侧进、LTR 从右侧进。delta=0 返回 0。 */
|
||||
int mr_nav_slide_from(int rtl, int delta, int view_w);
|
||||
|
||||
/* fit 档循环:适宽 → 适高 → 原始 → 适宽。 */
|
||||
int mr_nav_fit_next(int fit);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MR_READER_NAV_H */
|
||||
Reference in new issue
Block a user