//! A theme in message words, as the display hands it to a window //! (`types::display::window::THEME`). Its name stays behind. use crate::{Rgba, Theme}; pub const WORDS: usize = types::display::window::THEME_WORDS; fn colours(t: &Theme) -> [Rgba; 12] { [ t.background, t.surface, t.surface_raised, t.accent, t.on_accent, t.text_primary, t.text_secondary, t.destructive, t.on_destructive, t.focus, t.orbs[0], t.orbs[1], ] } pub fn encode(t: &Theme) -> [usize; WORDS] { let c = colours(t); let mut w = [0usize; WORDS]; for i in 0..6 { w[i] = c[2 * i].to_rgb() as usize | (c[2 * i + 1].to_rgb() as usize) << 32; } w[6] = t.corner_radius as usize | (t.spacing_base as usize) << 8 | (t.blur_radius as usize) << 16 | (t.panel_opacity as usize) << 24 | (t.highlight as usize) << 32 | (t.duration_fast as usize) << 40; w[7] = t.duration_normal as usize | (t.spring_stiffness as usize) << 16 | (t.spring_damping as usize & 0xff) << 32 | (t.orbs[2].to_rgb() as usize & 0xff_ffff) << 40; w } pub fn decode(w: [usize; WORDS]) -> Theme { let c = |i: usize| Rgba::rgb((w[i / 2] >> (32 * (i % 2))) as u32 & 0xff_ffff); let byte = |word: usize, at: u32| (w[word] >> at) as u8; let half = |word: usize, at: u32| (w[word] >> at) as u16; Theme { name: [0; crate::NAME_BYTES], name_len: 0, background: c(0), surface: c(1), surface_raised: c(2), accent: c(3), on_accent: c(4), text_primary: c(5), text_secondary: c(6), destructive: c(7), on_destructive: c(8), focus: c(9), orbs: [c(10), c(11), Rgba::rgb((w[7] >> 40) as u32 & 0xff_ffff)], corner_radius: byte(6, 0) as f32, spacing_base: byte(6, 8) as f32, blur_radius: byte(6, 16), panel_opacity: byte(6, 24), highlight: byte(6, 32), duration_fast: half(6, 40), duration_normal: half(7, 0), spring_stiffness: half(7, 16), // At most 200 (see `parse`): a byte. spring_damping: byte(7, 32) as u16, } }