fix: M6.41批 — 启动失败原因透传 + 阅读器左缘返回/阅读页接入view栈 + 后台管理按钮点不动 + 阅读器瘦身(fonts common+页位图释放) + files txt换行

- launcher(453): app_launcher.c g_launch_fail_reason+launch_fail()统一出口(5失败点 fork OOM/exec/no such file/missing dep/execpipe)+main_menu.c launch_fail_toast(缺依赖/CANNOT START: name(reason))+toast256
- launcher(457): bg_page.c bgm_enumerate跳过term_at_ms(杀后当下消失)+不可杀行按钮置灰+row_tap/top_action返回1; subpage.c 消warning
- reader(454): reader_on_swipe LEFT/RIGHT→返回(先关overlay否则page_pop回书架)+app.c书架根LEFT→exit
- reader(458瘦身A+B): app.json fonts full→common(省13MB atlas)+reader.c RD_PAGE_CACHE 3→2+g_anim_old懒分配/anim_done释放+on_enter/on_leave页位图离开释放重建
- reader(459导航): reader_open返回int+shelf点书push ACT_READER(阅读页接入view栈,on_enter/on_leave驱动) — 使454左缘返回+458瘦身B真正生效
- files(455): viewer.c viewer_cp_len+按码位折行(txt中文不冲出右缘)

0warning;宿主测试全过;files二进制已热更
This commit is contained in:
AskaEth committed 2026-09-04 19:43:28 +08:00
1 parent 626a87a30d
commit ddc8d35eb9
11 files changed
+154 -66

No files matched your search

+29 -7
View File
@@ -39,7 +39,27 @@ static int viewer_vp_h(void) { return r_content.h - APP_FOOTER_H; }
/* 屏幕行高(px)。 */
static int viewer_rowh(const meow_theme *th) { return meow_ui_text_height(th->font_body) + 6; }
/* 折行:返回逻辑行 li 折成的屏幕行数;若 intra>=0,把该屏幕行文本写入 out(NUL 结尾)。 */
/* UTF-8 码位字节长(1..4):s[bi] 起、串内有效字节数 lim。
* 首字节非法/续字节非法/序列不完整 → 保守按 1(单字节);保证折行绝不断在多字节码位中间,
* 也保证宽测量(meow_ui_text_width 按码位测)对中文/混合文本正确。 */
static int viewer_cp_len(const unsigned char *s, int bi, int lim)
{
unsigned char c = s[bi];
int n;
if (c < 0x80) return 1;
else if ((c & 0xE0) == 0xC0) n = 2;
else if ((c & 0xF0) == 0xE0) n = 3;
else if ((c & 0xF8) == 0xF0) n = 4;
else return 1;
if (lim - bi < n) return 1;
for (int i = 1; i < n; i++)
if ((s[bi + i] & 0xC0) != 0x80) return 1;
return n;
}
/* 折行:返回逻辑行 li 折成的屏幕行数;若 intra>=0,把该屏幕行文本写入 out(NUL 结尾)。
* 按「UTF-8 码位」逐字累加显示宽度(meow_ui_text_width 按码位测>0),到内容宽 colw 即断行;
* 多字节(CJK)整字不断开。 */
static int viewer_wrap_line(int li, int intra, char *out, int outsz)
{
if (!g_buf || li < 0 || li >= g_nline) return 0;
@@ -49,13 +69,15 @@ static int viewer_wrap_line(int li, int intra, char *out, int outsz)
while (len > 0 && (g_buf[start + len - 1] == '\n' || g_buf[start + len - 1] == '\r')) len--;
int colw = viewer_colw();
int col = 0, row = 0, outlen = 0;
char ch[2]; ch[1] = '\0';
for (int i = 0; i < len; i++) {
ch[0] = g_buf[start + i];
if (ch[0] == '\r') continue;
int w = meow_ui_text_width(ch, 20);
const unsigned char *s = (const unsigned char *)g_buf + start;
for (int bi = 0; bi < len; ) {
int clen = viewer_cp_len(s, bi, len);
if (clen == 1 && s[bi] == '\r') { bi++; continue; }
char cp[5]; cp[clen] = '\0';
memcpy(cp, s + bi, (size_t)clen); bi += clen;
int w = meow_ui_text_width(cp, 20);
if (col + w > colw && col > 0) { row++; col = 0; }
if (row == intra && out && outlen < outsz - 1) out[outlen++] = ch[0];
if (row == intra && out && outlen + clen < outsz) { memcpy(out + outlen, cp, (size_t)clen); outlen += clen; }
col += w;
}
if (out) out[outlen] = '\0';