Files
zed/crates/gpui_wgpu/benches/layout_line.rs
T
Albab Hasan 8ad5baee9b 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
2026-05-15 15:34:18 +00:00

83 lines
2.9 KiB
Rust

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);