git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit9f59fb2436e5003ce332be20d14dd6264ec5c9b3
parent65cda5355d
authorLucas Galante <[email protected]>
date2026-07-03 14:01
Optimize font loading and vertical status bar text alignment/spacing

 src/backend/wgpu_adapter.rs  |  3 +--
 src/backend/window_runner.rs | 26 +++++++++++++++++++++-----
 src/lib.rs                   | 11 +++++++++++
 src/main.rs                  |  2 +-
 src/widget/display/label.rs  | 15 ++++++++++++---
 5 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/src/backend/wgpu_adapter.rs b/src/backend/wgpu_adapter.rs
index 1fda031..260e5b3 100644
--- a/src/backend/wgpu_adapter.rs
+++ b/src/backend/wgpu_adapter.rs
@@ -87,8 +87,7 @@ impl WgpuAdapter {
         surface.configure(&device, &config);
 
         // Initialize text rendering
-        let mut font_system = FontSystem::new();
-        font_system.db_mut().load_fonts_dir("/home/lsgalante/Dropbox/Fonts");
+        let font_system = 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 f01d4ce..d4138ae 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -56,6 +56,7 @@ struct BufferCacheKey {
     text: String,
     size_milli: u32,
     font: Option<String>,
+    is_vertical: bool,
 }
 
 std::thread_local! {
@@ -77,10 +78,12 @@ pub fn get_text_buffer(fs: &mut FontSystem, text: &str, size: f32, font: Option<
 
     let physical_size = font_size * scale;
     let size_key = (physical_size * 1000.0).round() as u32;
+    let is_vertical = crate::IS_VERTICAL.load(std::sync::atomic::Ordering::Relaxed);
     let key = BufferCacheKey {
         text: text.to_string(),
         size_milli: size_key,
         font: family_name.clone(),
+        is_vertical,
     };
 
     let cached = BUFFER_CACHE.with(|cache| {
@@ -91,7 +94,12 @@ pub fn get_text_buffer(fs: &mut FontSystem, text: &str, size: f32, font: Option<
         return buf;
     }
 
-    let metrics = Metrics::new(physical_size, physical_size * 1.4);
+    let line_height = if is_vertical {
+        physical_size * 1.05
+    } else {
+        physical_size * 1.4
+    };
+    let metrics = Metrics::new(physical_size, line_height);
     let mut buf = Buffer::new(fs, metrics);
     let mut attrs = Attrs::new();
     if let Some(ref font_family) = family_name {
@@ -1398,6 +1406,7 @@ pub struct EngineState<A: Application> {
     pub active_popup: Option<ActivePopup>,
     pub current_cursor_icon: Option<CursorIcon>,
     pub qh: QueueHandle<EngineState<A>>,
+    pub just_configured: bool,
 }
 
 impl<A: Application> EngineState<A> {
@@ -1935,6 +1944,7 @@ impl<A: Application> WindowHandler for EngineState<A> {
         self.redraw = true;
         self.frame_callback_pending = false;
         self.first_configure_received = true;
+        self.just_configured = true;
     }
     
     fn request_close(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _window: &XdgWindow) {
@@ -2538,6 +2548,7 @@ pub fn run<A: Application>() {
         active_popup: None,
         current_cursor_icon: None,
         qh: qh.clone(),
+        just_configured: false,
     };
 
     event_queue.roundtrip(&mut engine_state).unwrap();
@@ -2613,10 +2624,15 @@ pub fn run<A: Application>() {
             engine_state.redraw = true;
         }
 
-        if let Some((w, h)) = engine_state.inner.desired_size() {
-            if (engine_state.logical_width - w as f32).abs() > 0.001 || (engine_state.logical_height - h as f32).abs() > 0.001 {
-                engine_state.resize(w as f32, h as f32);
-                engine_state.redraw = true;
+        let just_configured = engine_state.just_configured;
+        engine_state.just_configured = false;
+
+        if !just_configured {
+            if let Some((w, h)) = engine_state.inner.desired_size() {
+                if (engine_state.logical_width - w as f32).abs() > 0.001 || (engine_state.logical_height - h as f32).abs() > 0.001 {
+                    engine_state.resize(w as f32, h as f32);
+                    engine_state.redraw = true;
+                }
             }
         }
 
diff --git a/src/lib.rs b/src/lib.rs
index 87dd7c8..666e0b1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -18,4 +18,15 @@ pub mod colors {
 pub const SHADER: &str = include_str!("shader.wgsl");
 
 pub static IS_VERTICAL: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
+pub static BAR_THICKNESS: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(24);
+
+pub fn create_font_system() -> glyphon::FontSystem {
+    let mut db = glyphon::cosmic_text::fontdb::Database::new();
+    db.load_fonts_dir("/home/lsgalante/Dropbox/Fonts");
+    if std::env::var("CCE_LOAD_SYSTEM_FONTS").is_ok() {
+        db.load_system_fonts();
+    }
+    glyphon::FontSystem::new_with_locale_and_db("en-US".to_string(), db)
+}
+
 
diff --git a/src/main.rs b/src/main.rs
index bb29ec5..c3b4047 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -568,7 +568,7 @@ impl State {
             cache: None,
         });
 
-        let mut font_system = FontSystem::new();
+        let mut font_system = cce_ui::create_font_system();
         let swash_cache = SwashCache::new();
         let cache = Cache::new(&device);
         let viewport = Viewport::new(&device, &cache);
diff --git a/src/widget/display/label.rs b/src/widget/display/label.rs
index 64a6efc..3a9a5ad 100644
--- a/src/widget/display/label.rs
+++ b/src/widget/display/label.rs
@@ -109,11 +109,19 @@ impl StyledLabel {
         if is_vert {
             final_text = text.chars().map(|c| c.to_string()).collect::<Vec<_>>().join("\n");
         }
-        let buffer = crate::backend::window_runner::get_text_buffer(fs, &final_text, size, Some(family));
+        let mut buffer = crate::backend::window_runner::get_text_buffer(fs, &final_text, size, Some(family));
+        if is_vert {
+            let bar_thickness = crate::BAR_THICKNESS.load(std::sync::atomic::Ordering::Relaxed) as f32;
+            buffer.set_size(fs, Some(bar_thickness * scale as f32), None);
+            for line in &mut buffer.lines {
+                line.set_align(Some(glyphon::cosmic_text::Align::Center));
+            }
+            buffer.shape_until_scroll(fs, true);
+        }
         let mut w = buffer.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0) / scale;
         if is_vert {
             let num_lines = buffer.layout_runs().count();
-            w = num_lines as f32 * size * 1.4;
+            w = num_lines as f32 * size * 1.05;
         }
         let g_color = glyphon::Color::rgb(
             (color[0] * 255.0) as u8,
@@ -142,10 +150,11 @@ impl StyledLabel {
 
     pub fn draw(self, text_items: &mut Vec<TextItem>, x: f32, y: f32) -> f32 {
         let w = self.w;
+        let is_vert = crate::IS_VERTICAL.load(std::sync::atomic::Ordering::Relaxed);
         text_items.push(TextItem {
             buffer: self.buffer,
             x,
-            y,
+            y: if is_vert { 0.0 } else { y },
             color: self.g_color,
             bounds: None,
         });