diff --git a/Cargo.lock b/Cargo.lock index 8728054..7f65aba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5003,6 +5003,7 @@ dependencies = [ "image", "log", "unlucky-cli", + "unlucky-core", "unlucky-design", "unlucky-i18n", "unlucky-presenter", diff --git a/crates/app-iced/Cargo.toml b/crates/app-iced/Cargo.toml index e3cf139..468ab48 100644 --- a/crates/app-iced/Cargo.toml +++ b/crates/app-iced/Cargo.toml @@ -24,6 +24,9 @@ path = "src/lib.rs" # 令牌唯一真源(M61):颜色/排版/形状/间距/图标几何全部只从这里取。 unlucky-design = { path = "../design", version = "0.2.2" } +# 平台识别(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「重写只换渲染」的落点。 diff --git a/crates/app-iced/src/fonts.rs b/crates/app-iced/src/fonts.rs index 74c5b5e..8690f05 100644 --- a/crates/app-iced/src/fonts.rs +++ b/crates/app-iced/src/fonts.rs @@ -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();