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:
1 parent
c2635daf3f
commit
e69b8efeeb
4 files changed
+128
-4
No files matched your search
@@ -0,0 +1,86 @@
|
||||
/* test/test_row_text_fit.c — 宿主回归(M17):目录列表行高必须容纳双行文本块。
|
||||
*
|
||||
* 背景(真机根因,承接 M12/M15):SDK meow_listview 的双行渲染把
|
||||
* block = 2 * meow_ui_text_height(font_body) + 2 (标题行 + 2px 行距 + 副标题行)
|
||||
* 在行内垂直居中:ty = 行顶 + (item - block) / 2;且标题只在 `ty >= 视口顶` 时才画(越界钳制)。
|
||||
* 行高 item < block 时 ty < 行顶 → **第一行(行顶 == 视口顶)标题被整条跳过**、副标题仍在。
|
||||
* 真机字库实测(source_han_serif 20px:ascent 24 + descent 6 → 行高 30)block = 62,旧的
|
||||
* 显式 set_item_h(56) → ty = 行顶 - 3(本 App 目录列表首行名称空白)。
|
||||
*
|
||||
* 本测试只验 app 侧行高派生(files_row_h_for_line_h,纯整数、不链 SDK):
|
||||
* 行高 = max(APP_ROW_H, 2*行高 + FILES_ROW_SUB_GAP) → block ≤ item,首行标题不被钳掉。
|
||||
*
|
||||
* 编译/运行(宿主 gcc,只需 SDK 头,不需要 meow_ui.a):
|
||||
* cd patch_v2/files_app
|
||||
* gcc -O2 -Wall -Wextra -I. -I../sdk test/test_row_text_fit.c -o "$TMPDIR/test_row_text_fit" \
|
||||
* && "$TMPDIR/test_row_text_fit"
|
||||
*
|
||||
* 断言矩阵 = 真机已装字库 20px 面实测行高:source_han_serif 30(当前生效)、
|
||||
* misans/default 27、google_sans/meslo 26、source_han_sans 21;14 = 宿主 5x7 回退。
|
||||
* ① block ≤ item(否则居中偏移为负)
|
||||
* ② 首行 ty ≥ 0 → 绝对 ty_abs ≥ 视口顶(标题不被裁剪守卫跳过)
|
||||
* ③ 副标题底边 ty + block ≤ item(两行都不越行)
|
||||
* ④ item ≥ APP_ROW_H 下限(小字库/字体未就绪不缩回固定小值)
|
||||
* ⑤ 旧固定 56 在行高 30 下 ty < 0(bug 形态复现,防止再写死 56)
|
||||
*/
|
||||
#include "../files_internal.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int g_checks, g_fail;
|
||||
|
||||
static void chk(int cond, int line_h, const char *what)
|
||||
{
|
||||
g_checks++;
|
||||
if (!cond) {
|
||||
g_fail++;
|
||||
printf(" FAIL lh=%d: %s\n", line_h, what);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static const int lh_all[] = { 14, 21, 26, 27, 30 };
|
||||
const int n = (int)(sizeof lh_all / sizeof lh_all[0]);
|
||||
const int list_y = 120; /* 任意列表顶(只验相对几何) */
|
||||
|
||||
for (int k = 0; k < n; k++) {
|
||||
int lh = lh_all[k];
|
||||
int item = files_row_h_for_line_h(lh);
|
||||
int block = 2 * lh + FILES_ROW_SUB_GAP;
|
||||
int ty = (item - block) / 2; /* SDK 双行文本块居中偏移 */
|
||||
|
||||
printf("lh=%2d item=%3d block=%3d ty=%d\n", lh, item, block, ty);
|
||||
|
||||
chk(block <= item, lh, "文本块必须 <= 行高(否则首行标题被视口顶裁剪)");
|
||||
chk(ty >= 0, lh, "首行标题 y 不得高于行顶/视口顶");
|
||||
chk(ty + block <= item, lh, "副标题底边仍在行内");
|
||||
chk(item >= APP_ROW_H, lh, "行高不得小于 APP_ROW_H 下限");
|
||||
|
||||
/* 首行(scroll=0 → 行顶 == 视口顶)的绝对坐标 */
|
||||
chk(list_y + ty >= list_y, lh, "首行标题绝对 y 不得被视口顶裁掉");
|
||||
}
|
||||
|
||||
/* 行高随字体行高单调不减 */
|
||||
chk(files_row_h_for_line_h(30) >= files_row_h_for_line_h(26), 30, "行高随字体行高单调不减");
|
||||
|
||||
/* 真机当前生效字库(source_han_serif 20px,行高 30):block 62 → item 62 */
|
||||
chk(files_row_h_for_line_h(30) == 62, 30, "行高 30 → 派生行高 62");
|
||||
chk(2 * 30 + FILES_ROW_SUB_GAP <= files_row_h_for_line_h(30), 30, "派生行高容纳 62px 文本块");
|
||||
|
||||
/* 下限:小字库 / 字体未就绪(line_h=0)仍不缩回固定小值 */
|
||||
chk(files_row_h_for_line_h(14) == APP_ROW_H, 14, "小字库退回 APP_ROW_H 下限");
|
||||
chk(files_row_h_for_line_h(0) == APP_ROW_H, 0, "字体未就绪(行高 0)退回下限");
|
||||
|
||||
/* 回归哨兵:旧固定行高 56 + 当前默认字体(行高 30)就是 bug 形态 */
|
||||
{
|
||||
const int lh = 30;
|
||||
int block = 2 * lh + FILES_ROW_SUB_GAP; /* 62 */
|
||||
int ty_legacy = (APP_ROW_H - block) / 2; /* -3 */
|
||||
chk(ty_legacy < 0, lh, "旧行高 56 + 行高 30 → ty<0(首行标题被跳过,bug 复现)");
|
||||
chk(files_row_h_for_line_h(lh) > APP_ROW_H, lh, "默认字体下行高必须大于旧值 56");
|
||||
}
|
||||
|
||||
printf("%s: %d checks, %d fail (font line-height matrix: %d)\n",
|
||||
g_fail ? "FAIL" : "PASS", g_checks, g_fail, n);
|
||||
return g_fail ? 1 : 0;
|
||||
}
|
||||
Reference in new issue
Block a user