From 0dde7ca1d3a8e8c5082533d76084e2aa02bef70e Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Sat, 20 Dec 2025 13:18:15 +0100 Subject: [PATCH] optionally load decoration font at runtime instead of embedding it --- Cargo.lock | 30 ++++++++++++++++++++++++++++++ Cargo.toml | 3 +++ src/server/decoration.rs | 23 ++++++++++++++++++++--- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e502c2a..ec39395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,15 @@ dependencies = [ "syn", ] +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -311,6 +320,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "fontconfig" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b19c4bca8c705ea23bfb3e3403a9e699344d1ee3205b631f03fe4dbf1e52429f" +dependencies = [ + "yeslogic-fontconfig-sys", +] + [[package]] name = "fontdue" version = "0.9.3" @@ -1228,6 +1246,7 @@ dependencies = [ "ab_glyph", "anyhow", "bitflags 2.10.0", + "fontconfig", "fontdue", "hecs", "log", @@ -1248,6 +1267,17 @@ dependencies = [ "xcb-util-cursor", ] +[[package]] +name = "yeslogic-fontconfig-sys" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503a066b4c037c440169d995b869046827dbc71263f6e8f3be6d77d4f3229dbd" +dependencies = [ + "dlib", + "once_cell", + "pkg-config", +] + [[package]] name = "zerocopy" version = "0.8.31" diff --git a/Cargo.toml b/Cargo.toml index 9d28bd1..cff3e4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ pretty_env_logger = "0.5.0" xcb-util-cursor = "0.3.5" smithay-client-toolkit = { version = "0.20.0", default-features = false } +fontconfig = { version = "0.10", optional = true } sd-notify = { version = "0.4.2", optional = true } macros = { version = "0.1.0", path = "macros" } hecs = { version = "0.10.5", features = ["macros"] } @@ -55,6 +56,8 @@ fontdue = "0.9.3" [features] default = [] systemd = ["dep:sd-notify"] +# load decoration font at runtime instead of embedding it into the executable +fontconfig = ["dep:fontconfig"] [dev-dependencies] rustix = { workspace = true, features = ["fs"] } diff --git a/src/server/decoration.rs b/src/server/decoration.rs index f80c886..22eb626 100644 --- a/src/server/decoration.rs +++ b/src/server/decoration.rs @@ -6,6 +6,7 @@ use hecs::{CommandBuffer, Entity, World}; use log::{error, warn}; use smithay_client_toolkit::registry::SimpleGlobal; use smithay_client_toolkit::shm::slot::SlotPool; +use std::borrow::Cow; use std::sync::LazyLock; use tiny_skia::{Color, Paint, PathBuilder, Pixmap, Stroke, Transform}; use tiny_skia::{ColorU8, Rect}; @@ -404,6 +405,25 @@ fn title_pixmap(title: &str, max_width: u32, height: u32, scale: f32) -> Option< Some(pixmap) } +static FONT_DATA: LazyLock> = LazyLock::new(|| { + #[cfg(feature = "fontconfig")] + { + let fc = fontconfig::Fontconfig::new().expect("Failed to initialize fontconfig."); + let font = fc + .find("opensans", None) + .expect("Failed to load Open Sans Regular."); + let data = std::fs::read(font.path).expect("Failed to read font from disk."); + Cow::Owned(data) + } + #[cfg(not(feature = "fontconfig"))] + { + Cow::Borrowed(include_bytes!("../../OpenSans-Regular.ttf")) + } +}); + +static FONT: LazyLock> = + LazyLock::new(|| FontRef::try_from_slice(FONT_DATA.as_ref()).unwrap()); + fn layout_title_glyphs( text: &str, max_width: u32, @@ -412,9 +432,6 @@ fn layout_title_glyphs( ) -> (Vec, PxScaleFont<&FontRef<'_>>) { const TEXT_SIZE: f32 = 10.0; const TEXT_MARGIN: f32 = 11.0; - static FONT: LazyLock> = LazyLock::new(|| { - FontRef::try_from_slice(include_bytes!("../../OpenSans-Regular.ttf")).unwrap() - }); let mut ret = Vec::::new();