From a8c5c59b22adce9680a3fa1bb5bdc3b8f7805a6e Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 6 Aug 2019 14:04:34 +0200 Subject: [PATCH] Cache all used font glyphs --- src/backlight.rs | 9 +- src/battery.rs | 9 +- src/calendar.rs | 240 ++++++++++++++++++++++--------------------- src/clock.rs | 15 +-- src/draw.rs | 261 ++++++++++++++++++++++++----------------------- src/launcher.rs | 19 ++-- src/main.rs | 1 + src/sound.rs | 8 +- 8 files changed, 284 insertions(+), 278 deletions(-) diff --git a/src/backlight.rs b/src/backlight.rs index 7e5ac42..e60835d 100644 --- a/src/backlight.rs +++ b/src/backlight.rs @@ -1,12 +1,13 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_bar, draw_box, draw_text, ROBOTO_REGULAR}; +use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; use std::fs::OpenOptions; use std::io::{Error, ErrorKind}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; +use std::cell::RefCell; use chrono::{DateTime, Local}; @@ -14,6 +15,7 @@ pub struct Backlight { device_path: PathBuf, cur_brightness: u64, max_brightness: u64, + font: RefCell, dirty: bool, } @@ -85,6 +87,7 @@ impl Backlight { device_path: first_device.path(), cur_brightness: 0, max_brightness: 0, + font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), dirty: true, }; @@ -103,12 +106,10 @@ impl ModuleImpl for Backlight { ) -> Result, Error> { buf.memset(bg); let c = Color::new(1.0, 1.0, 1.0, 1.0); - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &c, - 24.0, "backlight", )?; draw_bar( diff --git a/src/battery.rs b/src/battery.rs index ef5cd54..544a3c6 100644 --- a/src/battery.rs +++ b/src/battery.rs @@ -1,11 +1,12 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_bar, draw_box, draw_text, ROBOTO_REGULAR}; +use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex}; use std::thread; +use std::cell::RefCell; use chrono::{DateTime, Local}; use dbus; @@ -39,6 +40,7 @@ fn get_upower_property( pub struct UpowerBattery { device_path: String, + font: RefCell, inner: Arc>, } @@ -116,6 +118,7 @@ impl UpowerBattery { Ok(UpowerBattery { device_path, + font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), inner: Arc::new(Mutex::new(UpowerBatteryInner { capacity: capacity, state: state, @@ -195,12 +198,10 @@ impl ModuleImpl for UpowerBattery { }; let inner = self.inner.lock().unwrap(); - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &text_color, - 24.0, "battery", )?; draw_bar( diff --git a/src/calendar.rs b/src/calendar.rs index 00561af..6ae9dce 100644 --- a/src/calendar.rs +++ b/src/calendar.rs @@ -1,149 +1,149 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_text, DEJAVUSANS_MONO, ROBOTO_REGULAR}; +use crate::draw::{Font, DEJAVUSANS_MONO, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; +use std::cell::RefCell; + use chrono::{Date, DateTime, Datelike, Local}; pub struct Calendar { cur_date: Date, dirty: bool, offset: f64, + calendar_numeral_cache: RefCell, + month_cache: RefCell, + year_cache: RefCell, + day_cache: RefCell, } -fn draw_month( - buf: &mut Buffer, - background_color: &Color, - orig: &Date, - time: &Date, -) -> Result<(i32, i32, i32, i32), ::std::io::Error> { - let mut time = time.clone(); - let mut y_off = 1; - let mut done = false; +impl Calendar { + fn draw_month( + &self, + buf: &mut Buffer, + background_color: &Color, + orig: &Date, + time: &Date, + ) -> Result<(i32, i32, i32, i32), ::std::io::Error> { + let mut time = time.clone(); + let mut y_off = 1; + let mut done = false; - let month_str = match time.month() { - 1 => "January", - 2 => "February", - 3 => "March", - 4 => "April", - 5 => "May", - 6 => "June", - 7 => "July", - 8 => "August", - 9 => "September", - 10 => "October", - 11 => "November", - 12 => "December", - _ => panic!("impossible value"), - }; - - // - // Draw the of the month - // - draw_text( - &ROBOTO_REGULAR, - &mut buf.subdimensions((0, 0, 304, 72))?, - background_color, - &Color::new(1.0, 1.0, 1.0, 1.0), - 64.0, - month_str, - )?; - - if time.year() != orig.year() { - draw_text( - &ROBOTO_REGULAR, - &mut buf.subdimensions((320, 0, 64, 32))?, - background_color, - &Color::new(0.8, 0.8, 0.8, 1.0), - 24.0, - &format!("{:}", time.year()), - )?; - } - - // - // Draw the week day - // - - for idx in 1..8 { - let wk_chr = match idx { - 1 => "MON", - 2 => "TUE", - 3 => "WED", - 4 => "THU", - 5 => "FRI", - 6 => "SAT", - 7 => "SUN", + let month_str = match time.month() { + 1 => "January", + 2 => "February", + 3 => "March", + 4 => "April", + 5 => "May", + 6 => "June", + 7 => "July", + 8 => "August", + 9 => "September", + 10 => "October", + 11 => "November", + 12 => "December", _ => panic!("impossible value"), }; - draw_text( - &DEJAVUSANS_MONO, - &mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 32, 16))?, + // + // Draw the of the month + // + + self.month_cache.borrow_mut().draw_text( + &mut buf.subdimensions((0, 0, 304, 72))?, background_color, &Color::new(1.0, 1.0, 1.0, 1.0), - 16.0, - &wk_chr, + month_str, )?; - } - - y_off += 1; - - while !done { - let mut x_pos = 0; - - // - // Find the start of this week - // - let mut wkday = time.weekday(); - while wkday != chrono::Weekday::Mon { - x_pos += 1; - wkday = wkday.pred(); + if time.year() != orig.year() { + self.year_cache.borrow_mut().draw_text( + &mut buf.subdimensions((320, 0, 64, 32))?, + background_color, + &Color::new(0.8, 0.8, 0.8, 1.0), + &format!("{:}", time.year()), + )?; } // - // Draw the week number + // Draw the week day // - let wk = time.iso_week(); - draw_text( - &DEJAVUSANS_MONO, - &mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 38, 32))?, - background_color, - &Color::new(0.75, 0.75, 0.75, 1.0), - 32.0, - &format!("{:02}", wk.week()), - )?; - x_pos += 1; - // - // Draw the dates - // - while x_pos < 8 { - let c = if time.day() == orig.day() && time.month() == orig.month() { - Color::new(1.0, 1.0, 1.0, 1.0) - } else { - Color::new(0.5, 0.5, 0.5, 1.0) + for idx in 1..8 { + let wk_chr = match idx { + 1 => "MON", + 2 => "TUE", + 3 => "WED", + 4 => "THU", + 5 => "FRI", + 6 => "SAT", + 7 => "SUN", + _ => panic!("impossible value"), }; - draw_text( - &DEJAVUSANS_MONO, - &mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 38, 32))?, + + self.day_cache.borrow_mut().draw_text( + &mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 32, 16))?, background_color, - &c, - 32.0, - &format!("{:02}", time.day()), + &Color::new(1.0, 1.0, 1.0, 1.0), + &wk_chr, )?; - let t = time.with_day(time.day() + 1); - if t.is_none() { - done = true; - break; - } - time = t.unwrap(); - x_pos += 1; } y_off += 1; - } - Ok(buf.get_signed_bounds()) + while !done { + let mut x_pos = 0; + + // + // Find the start of this week + // + let mut wkday = time.weekday(); + while wkday != chrono::Weekday::Mon { + x_pos += 1; + wkday = wkday.pred(); + } + + // + // Draw the week number + // + let wk = time.iso_week(); + self.calendar_numeral_cache.borrow_mut().draw_text( + &mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 38, 32))?, + background_color, + &Color::new(0.75, 0.75, 0.75, 1.0), + &format!("{:02}", wk.week()), + )?; + x_pos += 1; + + // + // Draw the dates + // + while x_pos < 8 { + let c = if time.day() == orig.day() && time.month() == orig.month() { + Color::new(1.0, 1.0, 1.0, 1.0) + } else { + Color::new(0.5, 0.5, 0.5, 1.0) + }; + + self.calendar_numeral_cache.borrow_mut().draw_text( + &mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 38, 32))?, + background_color, + &c, + &format!("{:02}", time.day()), + )?; + let t = time.with_day(time.day() + 1); + if t.is_none() { + done = true; + break; + } + time = t.unwrap(); + x_pos += 1; + } + + y_off += 1; + } + + Ok(buf.get_signed_bounds()) + } } impl Calendar { @@ -152,6 +152,10 @@ impl Calendar { cur_date: Local::now().date(), dirty: true, offset: 0.0, + calendar_numeral_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 32.0)), + month_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), + year_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 24.0)), + day_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 16.0)), } } } @@ -184,13 +188,13 @@ impl ModuleImpl for Calendar { .with_month((month + 1) as u32) .unwrap(); } - draw_month( + self.draw_month( &mut buf.subdimensions((0, 0, 384, 344))?, background_color, &time, &t.pred().with_day(1).unwrap(), )?; - draw_month( + self.draw_month( &mut buf.subdimensions((448, 0, 384, 344))?, background_color, &time, @@ -201,7 +205,7 @@ impl ModuleImpl for Calendar { } else { t.with_month(t.month() + 1).unwrap() }; - draw_month( + self.draw_month( &mut buf.subdimensions((896, 0, 384, 344))?, background_color, &time, diff --git a/src/clock.rs b/src/clock.rs index 00d0a33..52ecf51 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,8 +1,9 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_text, draw_text_fixed_width, ROBOTO_REGULAR}; +use crate::draw::{Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; +use std::cell::RefCell; use std::sync::mpsc::Sender; use chrono::{DateTime, Datelike, Duration, Local, Timelike}; @@ -10,6 +11,8 @@ use chrono::{DateTime, Datelike, Duration, Local, Timelike}; pub struct Clock { cur_time: DateTime, first_draw: bool, + clock_cache: RefCell, + date_cache: RefCell, } impl Clock { @@ -31,6 +34,8 @@ impl Clock { Clock { cur_time: Local::now(), first_draw: true, + date_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), + clock_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 256.0)), } } } @@ -44,12 +49,10 @@ impl ModuleImpl for Clock { ) -> Result, ::std::io::Error> { buf.memset(bg); - draw_text( - &ROBOTO_REGULAR, + self.date_cache.borrow_mut().draw_text( &mut buf.subdimensions((0, 0, 448, 64))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), - 64.0, &format!( "{:?}, {:02}/{:02}/{:4}", time.weekday(), @@ -59,12 +62,10 @@ impl ModuleImpl for Clock { ), )?; - draw_text_fixed_width( - &ROBOTO_REGULAR, + self.clock_cache.borrow_mut().draw_text_fixed_width( &mut buf.subdimensions((0, 64, 288 * 2 + 64, 256))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), - 256.0, &[120, 120, 64, 120, 120], &format!("{:02}:{:02}", time.hour(), time.minute()), )?; diff --git a/src/draw.rs b/src/draw.rs index b64f243..44969a3 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -1,163 +1,164 @@ use crate::buffer::Buffer; use crate::color::Color; -use rusttype::{point, Font, Scale}; + +use std::collections::HashMap; + +use rusttype::{point, Font as RustFont, Scale}; use lazy_static::lazy_static; pub static DEJAVUSANS_MONO_FONT_DATA: &'static [u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf"); pub static ROBOTO_REGULAR_FONT_DATA: &'static [u8] = include_bytes!("../fonts/Roboto-Regular.ttf"); lazy_static! { - pub static ref DEJAVUSANS_MONO: Font<'static> = Font::from_bytes(DEJAVUSANS_MONO_FONT_DATA as &[u8]).expect("error constructing DejaVuSansMono"); - pub static ref ROBOTO_REGULAR: Font<'static> = Font::from_bytes(ROBOTO_REGULAR_FONT_DATA as &[u8]).expect("error constructing Roboto-Regular"); + pub static ref DEJAVUSANS_MONO: RustFont<'static> = RustFont::from_bytes(DEJAVUSANS_MONO_FONT_DATA as &[u8]).expect("error constructing DejaVuSansMono"); + pub static ref ROBOTO_REGULAR: RustFont<'static> = RustFont::from_bytes(ROBOTO_REGULAR_FONT_DATA as &[u8]).expect("error constructing Roboto-Regular"); } -pub fn draw_text( - font: &Font, - buf: &mut Buffer, - background_color: &Color, - color: &Color, - size: f32, - s: &str, -) -> Result<(u32, u32), ::std::io::Error> { +struct CachedGlyph { + dimensions: (u32, u32), + origin: (i32, i32), + render: Vec, +} - // The font size to use - let scale = Scale::uniform(size); +impl CachedGlyph { + fn new(font: &RustFont, size: f32, ch: char) -> CachedGlyph { + let scale = Scale::uniform(size); + let v_metrics = font.v_metrics(scale); + let glyph = font + .glyph(ch) + .scaled(scale) + .positioned(point(0.0, v_metrics.ascent)); - let v_metrics = font.v_metrics(scale); - let glyphs: Vec<_> = font - .layout(s, scale, point(0.0, v_metrics.ascent)) - .collect(); - - let mut x_max: u32 = 0; - let mut y_max: u32 = 0; - - // Loop through the glyphs in the text, positing each one on a line - for glyph in glyphs { if let Some(bounding_box) = glyph.pixel_bounding_box() { - if bounding_box.max.x > x_max as i32 { - x_max = bounding_box.max.x as u32; - } - if bounding_box.max.y > y_max as i32 { - y_max = bounding_box.max.y as u32; - } - // Draw the glyph into the image per-pixel by using the draw closure + let origin = (bounding_box.min.x, bounding_box.min.y); + + let dimensions = ((bounding_box.max.x - bounding_box.min.x) as u32, (bounding_box.max.y - bounding_box.min.y) as u32); + let mut render = vec![0.0; (dimensions.0 * dimensions.1) as usize]; glyph.draw(|x, y, o| { - let x = x + bounding_box.min.x as u32; - let y = y + bounding_box.min.y as u32; - let o = if o > 1.0 { - 1.0 - } else if o < 0.0 { - 0.0 - } else { - o - }; - let _ = buf.put((x, y), &background_color.blend(color, o)); + let pos = x + (y * dimensions.0); + render[pos as usize] = o; }); + CachedGlyph{ + origin: origin, + dimensions: dimensions, + render: render, + } + } else { + CachedGlyph{ + origin: (0,0), + dimensions: ((size/4.0) as u32, 0), + render: Vec::new(), + } } } - Ok((x_max, y_max)) -} + fn draw(&self, buf: &mut Buffer, pos: (i32, i32), bg: &Color, c: &Color) { + let mut x = 0; + let mut y = 0; + for v in &self.render { + buf.put(((x + pos.0 + self.origin.0) as u32, (y + pos.1 + self.origin.1) as u32), &bg.blend(&c, *v)).unwrap(); -pub fn draw_text_individual_colors( - font: &Font, - buf: &mut Buffer, - background_color: &Color, - color: &[Color], - size: f32, - s: &str, -) -> Result<(u32, u32), ::std::io::Error> { - - // The font size to use - let scale = Scale::uniform(size); - - let v_metrics = font.v_metrics(scale); - - let glyphs: Vec<_> = font - .layout(s, scale, point(0.0, v_metrics.ascent)) - .collect(); - - let mut x_max: u32 = 0; - let mut y_max: u32 = 0; - let mut x_pos: usize = 0; - - // Loop through the glyphs in the text, positing each one on a line - for glyph in glyphs { - if let Some(bounding_box) = glyph.pixel_bounding_box() { - if bounding_box.max.x > x_max as i32 { - x_max = bounding_box.max.x as u32; + if x == self.dimensions.0 as i32 -1 { + y += 1; + x = 0; + } else { + x += 1; } - if bounding_box.max.y > y_max as i32 { - y_max = bounding_box.max.y as u32; - } - // Draw the glyph into the image per-pixel by using the draw closure - glyph.draw(|x, y, o| { - let x = x + bounding_box.min.x as u32; - let y = y + bounding_box.min.y as u32; - let o = if o > 1.0 { - 1.0 - } else if o < 0.0 { - 0.0 - } else { - o - }; - let _ = buf.put((x, y), &background_color.blend(&color[x_pos], o)); - }); } - x_pos += 1; - } - Ok((x_max, y_max)) + } } -pub fn draw_text_fixed_width( - font: &Font, - buf: &mut Buffer, - background_color: &Color, - color: &Color, +pub struct Font { + glyphs: HashMap, + font: &'static RustFont<'static>, size: f32, - distances: &[u32], - s: &str, -) -> Result<(), ::std::io::Error> { +} - // The font size to use - let scale = Scale::uniform(size); - - let v_metrics = font.v_metrics(scale); - - let glyphs: Vec<_> = font - .layout(s, scale, point(0.0, v_metrics.ascent)) - .collect(); - - // Loop through the glyphs in the text, positing each one on a line - let mut x_pos: usize = 0; - let mut x_off: u32 = 0; - for glyph in glyphs { - if let Some(bounding_box) = glyph.pixel_bounding_box() { - let x_dist = distances[x_pos]; - let width = (bounding_box.max.x - bounding_box.min.x) as u32; - let offset = (x_dist - width) / 2; - // Draw the glyph into the image per-pixel by using the draw closure - glyph.draw(|x, y, o| { - let off = x_off + offset + 20; - let x = x + off as u32; - let y = y + bounding_box.min.y as u32; - let o = if o > 1.0 { - 1.0 - } else if o < 0.0 { - 0.0 - } else { - o - }; - let _ = buf.put((x, y), &background_color.blend(color, o)); - }); - x_pos += 1; - x_off += x_dist; +impl Font { + pub fn new(font: &'static RustFont, size: f32) -> Font { + Font{ + glyphs: HashMap::new(), + font: font, + size: size, } } - Ok(()) + pub fn draw_text(&mut self, buf: &mut Buffer, bg: &Color, c: &Color, s: &str) -> Result<(u32, u32), ::std::io::Error> { + let mut x_off = 0; + let mut off = 0; + for ch in s.chars() { + let glyph = match self.glyphs.get(&ch) { + Some(glyph) => glyph, + None => { + let glyph = CachedGlyph::new(self.font, self.size, ch); + self.glyphs.insert(ch, glyph); + self.glyphs.get(&ch).unwrap() + } + }; + if glyph.origin.1 < off { + off = glyph.origin.1 + } + } + for ch in s.chars() { + let glyph = &self.glyphs[&ch]; + glyph.draw(buf, (x_off, -off), bg, c); + x_off += glyph.dimensions.0 as i32 + glyph.origin.0; + } + + Ok((x_off as u32, self.size as u32)) + } + + pub fn draw_text_fixed_width(&mut self, buf: &mut Buffer, bg: &Color, c: &Color, distances: &[u32], s: &str) -> Result<(u32, u32), ::std::io::Error> { + let mut x_off = 0; + let mut off = 0; + for ch in s.chars() { + let glyph = match self.glyphs.get(&ch) { + Some(glyph) => glyph, + None => { + let glyph = CachedGlyph::new(self.font, self.size, ch); + self.glyphs.insert(ch, glyph); + self.glyphs.get(&ch).unwrap() + } + }; + if glyph.origin.1 < off { + off = glyph.origin.1 + } + } + for (idx, ch) in s.chars().enumerate() { + let glyph = &self.glyphs[&ch]; + glyph.draw(buf, (x_off, -off), bg, c); + x_off += distances[idx] as i32; + } + + Ok((x_off as u32, self.size as u32)) + } + + pub fn draw_text_individual_colors(&mut self, buf: &mut Buffer, bg: &Color, color: &[Color], s: &str) -> Result<(u32, u32), ::std::io::Error> { + let mut x_off = 0; + let mut off = 0; + for ch in s.chars() { + let glyph = match self.glyphs.get(&ch) { + Some(glyph) => glyph, + None => { + let glyph = CachedGlyph::new(self.font, self.size, ch); + self.glyphs.insert(ch, glyph); + self.glyphs.get(&ch).unwrap() + } + }; + if glyph.origin.1 < off { + off = glyph.origin.1 + } + } + for (idx, ch) in s.chars().enumerate() { + let glyph = &self.glyphs[&ch]; + glyph.draw(buf, (x_off, -off), bg, &color[idx]); + x_off += glyph.dimensions.0 as i32 + glyph.origin.0; + } + + Ok((x_off as u32, self.size as u32)) + } } pub fn draw_box(buf: &mut Buffer, c: &Color, dim: (u32, u32)) -> Result<(), ::std::io::Error> { diff --git a/src/launcher.rs b/src/launcher.rs index c492e04..94180d6 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -1,10 +1,11 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_text, draw_text_individual_colors, ROBOTO_REGULAR}; +use crate::draw::{Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; use std::cmp::Ordering; use std::io::Read; +use std::cell::RefCell; use atty::Stream; use chrono::{DateTime, Local}; @@ -16,6 +17,7 @@ pub struct Launcher { matches: Vec, cur: String, offset: usize, + font: RefCell, dirty: bool, } @@ -35,6 +37,7 @@ impl Launcher { matches: vec![], cur: "".to_string(), offset: 0, + font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)), dirty: true, }) } else { @@ -55,26 +58,22 @@ impl ModuleImpl for Launcher { ) -> Result, ::std::io::Error> { buf.memset(bg); - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut buf.subdimensions((0, 0, 128, 32))?, bg, &Color::new(0.75, 0.75, 0.75, 1.0), - 32.0, "Run: ", )?; let mut x_off: i32 = 0; let mut width_remaining: i32 = 1280 - 64; if self.matches.len() == 0 && self.cur.len() > 0 { - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut buf .subdimensions((64, 0, width_remaining as u32, 32)) .unwrap(), bg, &Color::new(1.0, 0.5, 0.5, 1.0), - 32.0, &self.cur, )?; } else { @@ -95,14 +94,12 @@ impl ModuleImpl for Launcher { colors.push(Color::new(0.75, 0.75, 0.75, 1.0)); } } - draw_text_individual_colors(&ROBOTO_REGULAR, &mut b, bg, &colors, 32.0, &m)? + self.font.borrow_mut().draw_text_individual_colors(&mut b, bg, &colors, &m)? } else { - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut b, bg, &Color::new(0.5, 0.5, 0.5, 1.0), - 32.0, m, )? }; diff --git a/src/main.rs b/src/main.rs index 8c11d64..baa2463 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; +use std::time::Instant; use nix::poll::{poll, PollFd, PollFlags}; use os_pipe::pipe; diff --git a/src/sound.rs b/src/sound.rs index e1cef37..ca73f5e 100644 --- a/src/sound.rs +++ b/src/sound.rs @@ -1,6 +1,6 @@ use crate::buffer::Buffer; use crate::color::Color; -use crate::draw::{draw_bar, draw_box, draw_text, ROBOTO_REGULAR}; +use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; use std::cell::RefCell; @@ -399,6 +399,7 @@ impl PulseAudioSoundDevice { pub struct PulseAudio { device: Arc>, + font: RefCell, dirty: Arc>, } @@ -407,6 +408,7 @@ impl PulseAudio { let (tx, rx) = channel(); let pa = PulseAudio { device: PulseAudioSoundDevice::new(tx)?, + font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), dirty: Arc::new(Mutex::new(true)), }; let device = pa.device.clone(); @@ -436,12 +438,10 @@ impl ModuleImpl for PulseAudio { } else { Color::new(1.0, 1.0, 1.0, 1.0) }; - draw_text( - &ROBOTO_REGULAR, + self.font.borrow_mut().draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), - 24.0, "volume", )?; draw_bar(&mut buf.subdimensions((128, 0, 432, 24))?, &c, 432, 24, vol)?;