[ui] Linux egui 未剥离 fc-match 可变字体集合的高 16 位实例索引导致启动崩溃

未關閉
#1,402 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
3/5
預估耗時
1-2 天
新手友好度
72/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
linux, rust
領域
backend, desktop

研究方向

Start in openless-all/app/linux-egui/src/ui/theme.rs, especially fontconfig_match() and the handling of %{index} before it reaches egui::FontData. Check how the parsed index is used for seen deduplication and the regular_face / medium_face comparison, then look for the linux-egui unit tests. Done means composite indices such as 262146 are normalized consistently and a regression test verifies the font-loading path no longer panics.

由索引模型根據 Issue 內容生成。

描述

现象
  • 触发条件:在预装 Google Noto Sans CJK 可变字体集合(NotoSansCJK-VF.ttc,如 Fedora 44 等现代 Linux 发行版默认配置)的系统上安装并启动 OpenLess-Linux-egui-2.0.2-Beta.4-150-x86_64.rpm(标签 v2.0.2-Beta.4-tauri,上游 beta 提交 c002b56c38d81bcd5044ddb22597a4e78ff2a88d)。
  • 当前表现:主进程拉起 UI 窗口子进程后,UI 子进程在解析 "openless-cjk" 字体时触发 epaint panic(退出码 101),窗口无法打开并导致宿主进程退出。
  • 证据:
    1. 真机运行日志(Fedora 44 KDE Plasma Wayland):
      openless[218836]: [INFO] openless_linux_egui::linux_app::window: [ui-host] spawned UI window process pid=218858 socket=/run/user/1000/openless-ui.sock
      openless[218858]: thread 'main' (218858) panicked at epaint-0.37.0/src/text/family.rs:51:21:
      openless[218858]: Error parsing "openless-cjk" TTF/OTF font file: Invalid index 262146 for font collection
      openless[218836]: [ERROR] openless_linux_egui::linux_app: OpenLess host failed: UI window process failed: exit status: 101
      
    2. 本机 fc-match 实测输出:
      $ fc-match -f "%{file}|%{index}\n" ":lang=zh-cn"
      /usr/share/fonts/google-noto-sans-cjk-vf-fonts/NotoSansCJK-VF.ttc|262146
      
      在 Fontconfig / FreeType 中,针对可变字体集合(Variable Font TTC),FC_INDEX(%{index})采用高 16 位存放命名可变实例索引(Named Instance Index)、低 16 位存放 TTC 字面索引(Face Index):262146 == 0x00040002 == (4 << 16) | 2(即第 4 号可变实例、TTC 内第 2 号字面 Noto Sans CJK SC)。
    3. 源码定位:
      https://github.com/Open-Less/openless/blob/c002b56c38d81bcd5044ddb22597a4e78ff2a88d/openless-all/app/linux-egui/src/ui/theme.rs#L88-L100
      fontconfig_match() 将 %{index} 原样解析为 u32(262146)并直接传入 egui::FontData { index, .. },而 epaint / ab_glyph / ttf-parser 仅接受 TTC 集合内的 16 位字面索引(index & 0xFFFF),传入含高 16 位实例号的复合值会直接越界 panic。
影响
  • 所有默认使用 NotoSansCJK-VF.ttc(或任何其他可变字体集合 .ttc)的 Linux 发行版(如 Fedora 等)用户,启动 OpenLess 时 UI 进程必定 100% 崩溃退出,应用完全无法打开。
建议接受标准
  • openless-all/app/linux-egui/src/ui/theme.rs 在解析 fc-match 返回的 %{index} 时剥离高 16 位可变字体实例索引(例如使用 index & 0xFFFF 提取 TTC face index),不再将 0x00040002(262146)等复合值原样传给 egui::FontData。
  • 对 seen 去重与 regular_face / medium_face 比较逻辑同步使用规范化后的 TTC face index(或明确处理可变字体同一 face index 下的去重语义)。
  • 在 linux-egui 单元测试中增加针对 fc-match 返回复合 FC_INDEX(如 262146 / 0x00040002)的解析与字体加载回归测试,确保不再触发 epaint 越界 panic。
TODO / 不确定项
  • egui 当前不支持可变字体字重轴(源码注释已说明),当 regular_face 与 medium_face 指向同一可变 .ttc 文件的同一 face index(仅高 16 位实例索引不同)时,剥离高 16 位后两者 (path, index) 相同,将按既有设计跳过重复注册 MEDIUM_FACE。
主要語言
Rust
星號
3.7k
分支
349
平均合併
1 天 13 小時
30 天內合併 PR
98

環境準備

這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

Open-Less/openless 的其他 Issue

查看 Open-Less/openless 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。