fix(fonts): Termux 上注册 Android 系统 CJK 字体,消除中文方框

glibc 构建跑在 Termux 里时 target_os 仍是 linux,fontdb 只扫 Linux 常规
字体目录,/system/fonts 不在其中,中文实例名与界面文案全渲染成方框。
在字体求值入口按运行时识别 Termux,把 NotoSansCJK 等候选注册进
cosmic-text 的字体库(OnceLock 只加载一次,找不到就静默放过)。
app-iced 直接依赖 unlucky-core 复用平台识别,不再本地复制环境判断。
This commit is contained in:
AskaEth committed 2026-11-06 22:31:11 +08:00
1 parent 898e052c2d
commit 76ddc9b3e9
3 files changed
+39

No files matched your search

+3
View File
@@ -24,6 +24,9 @@ path = "src/lib.rs"
# 令牌唯一真源(M61):颜色/排版/形状/间距/图标几何全部只从这里取。
unlucky-design = { path = "../design", version = "0.2.1" }
# 平台识别(Termux / $PREFIX 路径)唯一真源:字体注册这类平台适配不再各写一份环境判断。
unlucky-core = { path = "../core", version = "0.2.1" }
# M85:UI 框架无关的宿主层(DTO / 状态 reducer / host)。**只登记依赖,本 mission 不接线**——
# 页面用它的时机由后续 iced 页面 mission 决定(接线流程见 crates/presenter/src/lib.rs 的 crate 文档)。
# 与 Slint 版共用同一套 host 与状态语义,这是 D26「重写只换渲染」的落点。
+35
View File
@@ -139,8 +139,43 @@ pub fn resolve() -> Resolved {
resolve_with(None)
}
/// Termux 上把 Android 的系统 CJK 字体注册进 cosmic-text 的字体库。
///
/// 这套 glibc 构建跑在 Termux 里(`target_os = "linux"`),fontdb 只扫 Linux 的常规字体目录,
/// Android 的 `/system/fonts` 不在其中——不注册的话中文实例名与界面文案全是方框。
/// 第一次调用加载一次;找不到任何候选字体时静默放过(由既有回退链兜底)。
fn register_termux_fonts() {
use std::sync::OnceLock;
use unlucky_core::platform::paths::ProcessEnv;
use unlucky_core::platform::termux;
static REGISTERED: OnceLock<()> = OnceLock::new();
REGISTERED.get_or_init(|| {
if !termux::is_termux(&ProcessEnv) {
return;
}
const CANDIDATES: &[&str] = &[
"/system/fonts/NotoSansCJK-Regular.ttc",
"/system/fonts/NotoSansCJKSC-Regular.otf",
"/system/fonts/DroidSansFallback.ttf",
];
let Ok(mut font_system) = iced::advanced::graphics::text::font_system().write() else {
return;
};
let db = font_system.raw().db_mut();
for path in CANDIDATES {
if db.load_font_file(path).is_ok() {
return;
}
}
});
}
/// 同 [`resolve`],但把配置里 `ui.language` 的显式值喂给中文策略(D28 的第一级)。
pub fn resolve_with(setting: Option<&str>) -> Resolved {
register_termux_fonts();
let platform = Platform::current();
let faces = system_faces();