use std::sync::OnceLock;
const APP_ICON_SVG: &[u8] = include_bytes!("../assets/icons/svg/hyprcorrect.svg");
const BRAND_FILL: &str = "#4a86c0";
const TRAY_FILL: &str = "#ffffff";
const TRAY_PIXMAP_SIZE: u32 = 64;
pub fn app_icon_svg_bytes() -> &'static [u8] {
APP_ICON_SVG
}
pub struct TrayPixmap {
pub size: u32,
pub argb: Vec<u8>,
}
pub fn tray_pixmaps(_sizes: &[u32], paused: bool) -> Vec<TrayPixmap> {
let rgba = render_recolored_rgba(TRAY_PIXMAP_SIZE, TRAY_FILL);
let argb = rgba_to_argb_with_alpha(&rgba, paused);
vec![TrayPixmap {
size: TRAY_PIXMAP_SIZE,
argb,
}]
}
fn render_recolored_rgba(size: u32, fill: &str) -> Vec<u8> {
let Ok(text) = std::str::from_utf8(APP_ICON_SVG) else {
return render_app_icon_rgba(size);
};
let recolored = text.replace(BRAND_FILL, fill);
render_svg_bytes_rgba(recolored.as_bytes(), size)
}
fn rgba_to_argb_with_alpha(rgba: &[u8], paused: bool) -> Vec<u8> {
let mut out = Vec::with_capacity(rgba.len());
for chunk in rgba.chunks_exact(4) {
let [r, g, b, a] = [chunk[0], chunk[1], chunk[2], chunk[3]];
let a = if paused { a / 2 } else { a };
out.extend_from_slice(&[a, r, g, b]);
}
out
}
pub fn render_app_icon_rgba(size: u32) -> Vec<u8> {
render_svg_bytes_rgba(APP_ICON_SVG, size)
}
fn render_svg_bytes_rgba(svg: &[u8], size: u32) -> Vec<u8> {
let opts = usvg::Options {
fontdb: fontdb().clone(),
..usvg::Options::default()
};
let Ok(tree) = usvg::Tree::from_data(svg, &opts) else {
return vec![0; (size as usize) * (size as usize) * 4];
};
let mut pixmap = tiny_skia::Pixmap::new(size, size)
.unwrap_or_else(|| tiny_skia::Pixmap::new(1, 1).expect("1x1 pixmap"));
let svg_size = tree.size();
let scale_x = size as f32 / svg_size.width();
let scale_y = size as f32 / svg_size.height();
let scale = scale_x.min(scale_y);
let transform = tiny_skia::Transform::from_scale(scale, scale);
resvg::render(&tree, transform, &mut pixmap.as_mut());
pixmap.take()
}
fn fontdb() -> &'static std::sync::Arc<usvg::fontdb::Database> {
static DB: OnceLock<std::sync::Arc<usvg::fontdb::Database>> = OnceLock::new();
DB.get_or_init(|| {
let mut db = usvg::fontdb::Database::new();
db.load_system_fonts();
std::sync::Arc::new(db)
})
}