fix(files): 目录列表行高按字体行高派生 — 20px 字库下首行标题不再空白(M17)

根因(承接 M12/M15 finding):SDK meow_listview 双行 renderer 把
block = 2*meow_ui_text_height(font_body) + MEOW_LISTV_SUB_GAP(2) 在行内垂直居中
(ty = 行顶 + (item - block)/2),标题只在 ty >= 视口顶时才画。目录行是双行档位,
真机 source_han_serif 20px(ascent 24 + descent 6)行高 30 → block 62,而
browser_page_create 显式 set_item_h(56) → ty = 行顶 - 3:首行(行顶 == 视口顶)
标题被裁剪守卫整条跳过,只剩大小/时间副标题。

修复:
- files_internal.h:APP_ROW_H 降级为行高下限(56);新增 FILES_ROW_SUB_GAP(2,与
  SDK MEOW_LISTV_SUB_GAP 同口径) + files_row_h_for_line_h(line_h)
  = max(56, 2*line_h + 2) + files_row_h()(取当前主题 meow_theme_get()->font_body
  的 meow_ui_text_height)。本地派生,不依赖 M15 新增导出 meow_listview_item_h;
  显式传值在 M15 之前的 SDK(默认 56)与 M15 之后(默认已派生 62)都成立且一致。
- ui/browser.c:browser_page_create 的 set_item_h 改传 files_row_h()
  (行高 30 → 62)。SDK 的 draw/hit/max_scroll 全部按这一个值换算,滚动/命中天然
  同步;页脚几何(r_list 单独扣 APP_FOOTER_H)与行高无关。其它几何/交互不变。

验证(宿主,未碰真机):
- zig-mipsel-cc -Os -static -Wall -Wextra(另用 -Werror 复验)交叉编译 files:0 warning;
- 新宿主 test/test_row_text_fit.c(32 断言,纯头文件派生、不链 SDK):
  字库行高矩阵 14/21/26/27/30 下 block <= item、首行 ty >= 0;行高 30 → 62;
  旧 56 → ty=-3 的 bug 形态哨兵;全 PASS。

影响:meow_ui.a 未改 → 无需重编 SDK;本 App 需重链重部署(热更 files 二进制)。
This commit is contained in:
AskaEth committed 2026-11-05 20:57:13 +08:00
1 parent c2635daf3f
commit e69b8efeeb
4 files changed
+128 -4

No files matched your search

+26 -1
View File
@@ -37,13 +37,38 @@ void picker_cancel(void); /* 取消:发 code=MEOW_ERR
#define APP_W 480
#define APP_H 720
#define APP_TOPBAR_H 56
#define APP_ROW_H 56 /* 列表行高 */
#define APP_ROW_H 56 /* 列表行高下限(旧固定值;实际按字体行高派生,见 files_row_h) */
#define APP_PAD 16
#define APP_ICON_W 26 /* 图标占宽 */
#define APP_OP_W 52 /* 右侧操作钮占宽(触达区) */
#define APP_FOOTER_H 26 /* 底部信息行高(列表/文本内容在其之上滚动) */
#define APP_READ_MAX (256 * 1024) /* 文本预览读取上限 */
/* ---- 列表行高:按字体行高派生(M17,首行标题不显示根因修复)----
* SDK meow_listview 的双行渲染把「标题+副标题」文本块
* block = 2 * meow_ui_text_height(font_body) + MEOW_LISTV_SUB_GAP(2)
* 在行内垂直居中(ty = 行顶 + (item - block) / 2),标题只在 ty >= 视口顶时才画。
* item < block 时 ty = 行顶 - Δ:第一行(行顶 == 视口顶)标题被整条跳过、只剩副标题。
* 真机 source_han_serif 20px(ascent 24 + descent 6)行高 30 → block 62,旧的显式 56 → Δ=3。
* 故行高按当前主题正文行高派生:max(APP_ROW_H, 2*line_h + 2)(行高 30 → 62)。
* 本页行恒为双行档位(browser_src2 填 title + subtitle)→ 用 lines=2 公式。
* 行几何(draw / hit / max_scroll)全由 SDK 按传入的这一个值换算,故滚动与命中天然同步;
* 页脚几何与行高无关(r_list 单独扣 APP_FOOTER_H)。 */
#define FILES_ROW_SUB_GAP 2 /* 与 SDK MEOW_LISTV_SUB_GAP 同口径(标题/副标题行距) */
static inline int files_row_h_for_line_h(int line_h)
{
if (line_h < 1) line_h = 1; /* 字体未就绪 → 退回下限 */
int h = 2 * line_h + FILES_ROW_SUB_GAP;
return (h > APP_ROW_H) ? h : APP_ROW_H;
}
/* 当前主题正文行高下的两行列表行高(页面 create 时取一次;字体档位切换走页面重建)。 */
static inline int files_row_h(void)
{
const meow_theme *th = meow_theme_get();
return files_row_h_for_line_h(th ? meow_ui_text_height(th->font_body) : 0);
}
/* ---- App 级复用矩形/几何 ---- */
typedef struct { int x, y, w, h; } app_rect_t;
#define AR(x,y,w,h) ((app_rect_t){ (x),(y),(w),(h) })