mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
gpui_wgpu: Respect buffer_font_fallbacks setting (#54878)
wires user configured `FontFallbacks` into the cosmic text path. the chain is resolved at font load time and stored on each `LoadedFont`. `layout_line` splits each `FontRun` into spans by codepoint coverage and emits one `Attrs` per slot so cosmic text shapes each span with the correct face. inheriting codepoints (marks, zwj, zwnj, variation selectors) stick to the current span so emoji zwj sequences and combining marks are not torn across faces. Closes #17254 Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] Performance impact has been considered and is acceptable - [x] Tests cover the new/changed behavior - [] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - added support for `buffer_font_fallbacks` on linux
This commit is contained in:
parent
3eeda10ede
commit
1c16e13a2b
4 changed files with 1154 additions and 654 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -7930,6 +7930,7 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"collections",
|
||||
"cosmic-text",
|
||||
"criterion",
|
||||
"etagere",
|
||||
"gpui",
|
||||
"gpui_util",
|
||||
|
|
@ -7942,6 +7943,7 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"smallvec",
|
||||
"swash",
|
||||
"unicode-segmentation",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ profiling.workspace = true
|
|||
raw-window-handle = "0.6"
|
||||
smallvec.workspace = true
|
||||
swash = "0.2.6"
|
||||
unicode-segmentation.workspace = true
|
||||
gpui_util.workspace = true
|
||||
wgpu.workspace = true
|
||||
|
||||
|
|
@ -43,4 +44,11 @@ pollster.workspace = true
|
|||
wasm-bindgen.workspace = true
|
||||
wasm-bindgen-futures = "0.4"
|
||||
web-sys = { version = "0.3", features = ["HtmlCanvasElement"] }
|
||||
js-sys = "0.3"
|
||||
js-sys = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion.workspace = true
|
||||
|
||||
[[bench]]
|
||||
name = "layout_line"
|
||||
harness = false
|
||||
82
crates/gpui_wgpu/benches/layout_line.rs
Normal file
82
crates/gpui_wgpu/benches/layout_line.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use gpui::{FontFallbacks, FontRun, PlatformTextSystem, font, px};
|
||||
use gpui_wgpu::CosmicTextSystem;
|
||||
use std::borrow::Cow;
|
||||
|
||||
const LILEX: &[u8] = include_bytes!("../../../assets/fonts/lilex/Lilex-Regular.ttf");
|
||||
const IBM_PLEX: &[u8] =
|
||||
include_bytes!("../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Regular.ttf");
|
||||
|
||||
// ~4 000 chars of typical ASCII code text.
|
||||
fn code_text() -> String {
|
||||
concat!(
|
||||
" fn compute_run_spans(\n",
|
||||
" text: &str,\n",
|
||||
" run_offset: usize,\n",
|
||||
" run_len: usize,\n",
|
||||
" primary: FontId,\n",
|
||||
" fallback_chain: &[(FontId, SharedString)],\n",
|
||||
" covers: &impl Fn(FontId, char) -> bool,\n",
|
||||
" ) -> SmallVec<[RunSpan; 4]> {\n",
|
||||
" let mut spans = SmallVec::new();\n",
|
||||
" let run_end = run_offset + run_len;\n",
|
||||
" if run_end <= run_offset { return spans; }\n",
|
||||
" let run_text = &text[run_offset..run_end];\n",
|
||||
" let mut span_start = run_offset;\n",
|
||||
" let mut span_slot: Option<usize> = None;\n",
|
||||
" for (ch_idx, ch) in run_text.char_indices() {\n",
|
||||
" let abs = run_offset + ch_idx;\n",
|
||||
" let next = pick_covering_slot(ch, span_slot, primary, fallback_chain, covers);\n",
|
||||
" if next == span_slot { continue; }\n",
|
||||
" if abs > span_start {\n",
|
||||
" spans.push(RunSpan { start: span_start, end: abs, slot: span_slot });\n",
|
||||
" }\n",
|
||||
" span_start = abs;\n",
|
||||
" span_slot = next;\n",
|
||||
" }\n",
|
||||
" spans\n",
|
||||
" }\n",
|
||||
)
|
||||
.repeat(8) // ~3 800 chars
|
||||
}
|
||||
|
||||
fn bench_layout_line(c: &mut Criterion) {
|
||||
let system = CosmicTextSystem::new_without_system_fonts("Lilex");
|
||||
system
|
||||
.add_fonts(vec![Cow::Borrowed(LILEX), Cow::Borrowed(IBM_PLEX)])
|
||||
.unwrap();
|
||||
|
||||
let font_id_no_fallback = system.font_id(&font("Lilex")).unwrap();
|
||||
|
||||
let font_id_with_fallback = {
|
||||
let mut f = font("Lilex");
|
||||
f.fallbacks = Some(FontFallbacks::from_fonts(vec!["IBM Plex Sans".to_string()]));
|
||||
system.font_id(&f).unwrap()
|
||||
};
|
||||
|
||||
let text = code_text();
|
||||
|
||||
let runs_no_fallback = vec![FontRun {
|
||||
len: text.len(),
|
||||
font_id: font_id_no_fallback,
|
||||
}];
|
||||
let runs_with_fallback = vec![FontRun {
|
||||
len: text.len(),
|
||||
font_id: font_id_with_fallback,
|
||||
}];
|
||||
|
||||
let mut group = c.benchmark_group("layout_line");
|
||||
|
||||
group.bench_function("no_fallback", |b| {
|
||||
b.iter(|| system.layout_line(&text, px(14.0), &runs_no_fallback))
|
||||
});
|
||||
|
||||
group.bench_function("with_fallback_ascii", |b| {
|
||||
b.iter(|| system.layout_line(&text, px(14.0), &runs_with_fallback))
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_layout_line);
|
||||
criterion_main!(benches);
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue