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

Đang mở
#1,402 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
72/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
linux, rust
Lĩnh vực
backend, desktop

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

现象
  • 触发条件:在预装 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。
Ngôn ngữ chính
Rust
Star
3.7k
Fork
349
Merge trung bình
1 ngày 13 giờ
Pull request đã merge (30 ngày)
98

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của Open-Less/openless

Tất cả issue của Open-Less/openless

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.