GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
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,
});