GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat(engine): Application::load_system_fonts — system fonts in the render FontSystem
The engine's render FontSystem (WgpuAdapter) is bundled-fonts-only, so
text asking for a family that exists only among installed system fonts
is silently invisible — buffers shaped app-side against a system-fonts
FontSystem carry fontdb face IDs the engine's database doesn't have (the
cce-colors Phase 6e bug, and cce-fonts' entire reason to exist). The new
hook lets an app opt the render FontSystem into system fonts (additive —
bundled fonts still load first, keeping face IDs aligned with
create_font_system databases); consulted once at GPU init.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016MjP3pGQEDLkJbV5WEmYBe
src/backend/wgpu_adapter.rs | 11 +++++++++--
src/backend/window_runner.rs | 16 +++++++++++++++-
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/backend/wgpu_adapter.rs b/src/backend/wgpu_adapter.rs
index 260e5b3..b8c2b8b 100644
--- a/src/backend/wgpu_adapter.rs
+++ b/src/backend/wgpu_adapter.rs
@@ -21,6 +21,7 @@ impl WgpuAdapter {
surface_ptr: *mut std::ffi::c_void,
width: u32,
height: u32,
+ load_system_fonts: bool,
) -> Self {
let wayland_handle = Box::leak(Box::new(WaylandSurfaceHandle {
display_ptr,
@@ -86,8 +87,14 @@ impl WgpuAdapter {
surface.configure(&device, &config);
- // Initialize text rendering
- let font_system = crate::create_font_system();
+ // Initialize text rendering. The render FontSystem is bundled-fonts-only unless the
+ // app opts into system fonts (Application::load_system_fonts — the font picker must
+ // shape and rasterize every installed family).
+ let font_system = if load_system_fonts {
+ crate::create_font_system_with_system_fonts()
+ } else {
+ crate::create_font_system()
+ };
let swash_cache = SwashCache::new();
let cache = Cache::new(&device);
let mut text_atlas = TextAtlas::new(&device, &queue, &cache, config.format);
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 189c48b..cfb2ce6 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -1634,6 +1634,19 @@ pub trait Application: Sized + 'static {
fn display_list_text(&self) -> bool {
false
}
+
+ /// Opt into system fonts in the ENGINE's render `FontSystem` (the one that shapes
+ /// display-list text and rasterizes every glyph at prepare time). Default `false`: the
+ /// render FontSystem loads only the bundled CCE fonts, and text asking for a family that
+ /// exists only among installed system fonts is silently invisible — buffers shaped
+ /// app-side against a system-fonts `FontSystem` carry fontdb face IDs the engine's
+ /// database doesn't have (the cce-colors Phase 6e bug). An app whose UI must render
+ /// arbitrary installed families (the font picker) returns `true`; its own `FontSystem`,
+ /// if it keeps one for measurement, should be `create_font_system_with_system_fonts()`
+ /// so both databases load identically. Consulted once, at GPU init.
+ fn load_system_fonts(&self) -> bool {
+ false
+ }
}
pub struct PressedKey {
@@ -1722,7 +1735,8 @@ impl<A: Application> EngineState<A> {
let display_ptr = conn.backend().display_id().as_ptr() as *mut std::ffi::c_void;
let surface_ptr = surface.id().as_ptr() as *mut std::ffi::c_void;
- let adapter = WgpuAdapter::new(display_ptr, surface_ptr, pw, ph).await;
+ let load_system_fonts = self.inner.as_ref().map_or(false, |a| a.load_system_fonts());
+ let adapter = WgpuAdapter::new(display_ptr, surface_ptr, pw, ph, load_system_fonts).await;
let shader = adapter.device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Shader"),