Files
MeowOS-SDK/tuku/logic/reader/nav.h
T
AskaEth 23c9db73df 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 零警告
2026-11-04 20:58:05 +08:00

71 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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 */