Use pre-seeded font caches to avoid mut

This commit is contained in:
Kenny Levinsen
2019-08-06 16:39:17 +02:00
parent c5d7faceba
commit 37fcb7390b
8 changed files with 126 additions and 78 deletions
+5 -4
View File
@@ -3,7 +3,6 @@ use crate::color::Color;
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
use crate::module::{Input, ModuleImpl}; use crate::module::{Input, ModuleImpl};
use std::cell::RefCell;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use std::io::{Read, Write}; use std::io::{Read, Write};
@@ -15,7 +14,7 @@ pub struct Backlight {
device_path: PathBuf, device_path: PathBuf,
cur_brightness: u64, cur_brightness: u64,
max_brightness: u64, max_brightness: u64,
font: RefCell<Font>, font: Font,
dirty: bool, dirty: bool,
} }
@@ -87,10 +86,12 @@ impl Backlight {
device_path: first_device.path(), device_path: first_device.path(),
cur_brightness: 0, cur_brightness: 0,
max_brightness: 0, max_brightness: 0,
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), font: Font::new(&ROBOTO_REGULAR, 24.0),
dirty: true, dirty: true,
}; };
dev.font.add_str_to_cache("backlight");
dev.update()?; dev.update()?;
Ok(dev) Ok(dev)
@@ -106,7 +107,7 @@ impl ModuleImpl for Backlight {
) -> Result<Vec<(i32, i32, i32, i32)>, Error> { ) -> Result<Vec<(i32, i32, i32, i32)>, Error> {
buf.memset(bg); buf.memset(bg);
let c = Color::new(1.0, 1.0, 1.0, 1.0); let c = Color::new(1.0, 1.0, 1.0, 1.0);
self.font.borrow_mut().draw_text( self.font.draw_text(
&mut buf.subdimensions((0, 0, 128, 24))?, &mut buf.subdimensions((0, 0, 128, 24))?,
bg, bg,
&c, &c,
+6 -4
View File
@@ -3,7 +3,6 @@ use crate::color::Color;
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
use crate::module::{Input, ModuleImpl}; use crate::module::{Input, ModuleImpl};
use std::cell::RefCell;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
@@ -40,7 +39,7 @@ fn get_upower_property(
pub struct UpowerBattery { pub struct UpowerBattery {
device_path: String, device_path: String,
font: RefCell<Font>, font: Font,
inner: Arc<Mutex<UpowerBatteryInner>>, inner: Arc<Mutex<UpowerBatteryInner>>,
} }
@@ -116,9 +115,12 @@ impl UpowerBattery {
} }
}; };
let mut font = Font::new(&ROBOTO_REGULAR, 24.0);
font.add_str_to_cache("battery");
Ok(UpowerBattery { Ok(UpowerBattery {
device_path, device_path,
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), font: font,
inner: Arc::new(Mutex::new(UpowerBatteryInner { inner: Arc::new(Mutex::new(UpowerBatteryInner {
capacity: capacity, capacity: capacity,
state: state, state: state,
@@ -204,7 +206,7 @@ impl ModuleImpl for UpowerBattery {
}; };
let inner = self.inner.lock().unwrap(); let inner = self.inner.lock().unwrap();
self.font.borrow_mut().draw_text( self.font.draw_text(
&mut buf.subdimensions((0, 0, 128, 24))?, &mut buf.subdimensions((0, 0, 128, 24))?,
bg, bg,
&text_color, &text_color,
+21 -15
View File
@@ -3,18 +3,16 @@ use crate::color::Color;
use crate::draw::{Font, DEJAVUSANS_MONO, ROBOTO_REGULAR}; use crate::draw::{Font, DEJAVUSANS_MONO, ROBOTO_REGULAR};
use crate::module::{Input, ModuleImpl}; use crate::module::{Input, ModuleImpl};
use std::cell::RefCell;
use chrono::{Date, DateTime, Datelike, Local}; use chrono::{Date, DateTime, Datelike, Local};
pub struct Calendar { pub struct Calendar {
cur_date: Date<Local>, cur_date: Date<Local>,
dirty: bool, dirty: bool,
offset: f64, offset: f64,
calendar_numeral_cache: RefCell<Font>, calendar_cache: Font,
month_cache: RefCell<Font>, month_cache: Font,
year_cache: RefCell<Font>, year_cache: Font,
day_cache: RefCell<Font>, day_cache: Font,
} }
impl Calendar { impl Calendar {
@@ -49,14 +47,14 @@ impl Calendar {
// Draw the of the month // Draw the of the month
// //
self.month_cache.borrow_mut().draw_text( self.month_cache.draw_text(
&mut buf.subdimensions((0, 0, 304, 72))?, &mut buf.subdimensions((0, 0, 304, 72))?,
background_color, background_color,
&Color::new(1.0, 1.0, 1.0, 1.0), &Color::new(1.0, 1.0, 1.0, 1.0),
month_str, month_str,
)?; )?;
if time.year() != orig.year() { if time.year() != orig.year() {
self.year_cache.borrow_mut().draw_text( self.year_cache.draw_text(
&mut buf.subdimensions((320, 0, 64, 32))?, &mut buf.subdimensions((320, 0, 64, 32))?,
background_color, background_color,
&Color::new(0.8, 0.8, 0.8, 1.0), &Color::new(0.8, 0.8, 0.8, 1.0),
@@ -80,7 +78,7 @@ impl Calendar {
_ => panic!("impossible value"), _ => panic!("impossible value"),
}; };
self.day_cache.borrow_mut().draw_text( self.day_cache.draw_text(
&mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 32, 16))?, &mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 32, 16))?,
background_color, background_color,
&Color::new(1.0, 1.0, 1.0, 1.0), &Color::new(1.0, 1.0, 1.0, 1.0),
@@ -106,7 +104,7 @@ impl Calendar {
// Draw the week number // Draw the week number
// //
let wk = time.iso_week(); let wk = time.iso_week();
self.calendar_numeral_cache.borrow_mut().draw_text( self.calendar_cache.draw_text(
&mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 38, 32))?, &mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 38, 32))?,
background_color, background_color,
&Color::new(0.75, 0.75, 0.75, 1.0), &Color::new(0.75, 0.75, 0.75, 1.0),
@@ -124,7 +122,7 @@ impl Calendar {
Color::new(0.5, 0.5, 0.5, 1.0) Color::new(0.5, 0.5, 0.5, 1.0)
}; };
self.calendar_numeral_cache.borrow_mut().draw_text( self.calendar_cache.draw_text(
&mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 38, 32))?, &mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 38, 32))?,
background_color, background_color,
&c, &c,
@@ -148,14 +146,22 @@ impl Calendar {
impl Calendar { impl Calendar {
pub fn new() -> Calendar { pub fn new() -> Calendar {
let mut calendar_cache = Font::new(&DEJAVUSANS_MONO, 32.0);
calendar_cache.add_str_to_cache("0123456789");
let mut month_cache = Font::new(&ROBOTO_REGULAR, 64.0);
month_cache.add_str_to_cache("JanuryFebMchApilJgstSmOoNvD");
let mut year_cache = Font::new(&DEJAVUSANS_MONO, 24.0);
year_cache.add_str_to_cache("-0123456789");
let mut day_cache = Font::new(&DEJAVUSANS_MONO, 16.0);
day_cache.add_str_to_cache("MONTUEWDHFRISA");
Calendar { Calendar {
cur_date: Local::now().date(), cur_date: Local::now().date(),
dirty: true, dirty: true,
offset: 0.0, offset: 0.0,
calendar_numeral_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 32.0)), calendar_cache: calendar_cache,
month_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), month_cache: month_cache,
year_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 24.0)), year_cache: year_cache,
day_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 16.0)), day_cache: day_cache,
} }
} }
} }
+12 -7
View File
@@ -3,7 +3,6 @@ use crate::color::Color;
use crate::draw::{Font, ROBOTO_REGULAR}; use crate::draw::{Font, ROBOTO_REGULAR};
use crate::module::{Input, ModuleImpl}; use crate::module::{Input, ModuleImpl};
use std::cell::RefCell;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use chrono::{DateTime, Datelike, Duration, Local, Timelike}; use chrono::{DateTime, Datelike, Duration, Local, Timelike};
@@ -11,8 +10,8 @@ use chrono::{DateTime, Datelike, Duration, Local, Timelike};
pub struct Clock { pub struct Clock {
cur_time: DateTime<Local>, cur_time: DateTime<Local>,
first_draw: bool, first_draw: bool,
clock_cache: RefCell<Font>, clock_cache: Font,
date_cache: RefCell<Font>, date_cache: Font,
} }
impl Clock { impl Clock {
@@ -31,11 +30,17 @@ impl Clock {
ch.send(true).unwrap(); ch.send(true).unwrap();
}); });
let mut date_cache = Font::new(&ROBOTO_REGULAR, 64.0);
date_cache
.add_str_to_cache("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,/ ");
let mut clock_cache = Font::new(&ROBOTO_REGULAR, 256.0);
clock_cache.add_str_to_cache("0123456789:");
Clock { Clock {
cur_time: Local::now(), cur_time: Local::now(),
first_draw: true, first_draw: true,
date_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), date_cache: date_cache,
clock_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 256.0)), clock_cache: clock_cache,
} }
} }
} }
@@ -49,7 +54,7 @@ impl ModuleImpl for Clock {
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> { ) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg); buf.memset(bg);
self.date_cache.borrow_mut().draw_text( self.date_cache.draw_text(
&mut buf.subdimensions((0, 0, 448, 64))?, &mut buf.subdimensions((0, 0, 448, 64))?,
bg, bg,
&Color::new(1.0, 1.0, 1.0, 1.0), &Color::new(1.0, 1.0, 1.0, 1.0),
@@ -62,7 +67,7 @@ impl ModuleImpl for Clock {
), ),
)?; )?;
self.clock_cache.borrow_mut().draw_text_fixed_width( self.clock_cache.draw_text_fixed_width(
&mut buf.subdimensions((0, 64, 288 * 2 + 64, 256))?, &mut buf.subdimensions((0, 64, 288 * 2 + 64, 256))?,
bg, bg,
&Color::new(1.0, 1.0, 1.0, 1.0), &Color::new(1.0, 1.0, 1.0, 1.0),
+55 -18
View File
@@ -97,8 +97,17 @@ impl Font {
} }
} }
pub fn add_str_to_cache(&mut self, s: &str) {
for ch in s.chars() {
if self.glyphs.get(&ch).is_none() {
let glyph = CachedGlyph::new(self.font, self.size, ch);
self.glyphs.insert(ch, glyph);
}
}
}
pub fn draw_text( pub fn draw_text(
&mut self, &self,
buf: &mut Buffer, buf: &mut Buffer,
bg: &Color, bg: &Color,
c: &Color, c: &Color,
@@ -106,21 +115,23 @@ impl Font {
) -> Result<(u32, u32), ::std::io::Error> { ) -> Result<(u32, u32), ::std::io::Error> {
let mut x_off = 0; let mut x_off = 0;
let mut off = 0; let mut off = 0;
let mut glyphs = Vec::with_capacity(s.len());
for ch in s.chars() { for ch in s.chars() {
let glyph = match self.glyphs.get(&ch) { let glyph = match self.glyphs.get(&ch) {
Some(glyph) => glyph, Some(glyph) => glyph,
None => { None => {
let glyph = CachedGlyph::new(self.font, self.size, ch); return Err(::std::io::Error::new(
self.glyphs.insert(ch, glyph); ::std::io::ErrorKind::Other,
self.glyphs.get(&ch).unwrap() format!("glyph for {:} not in cache", ch),
))
} }
}; };
glyphs.push(glyph);
if glyph.origin.1 < off { if glyph.origin.1 < off {
off = glyph.origin.1 off = glyph.origin.1
} }
} }
for ch in s.chars() { for glyph in glyphs {
let glyph = &self.glyphs[&ch];
glyph.draw(buf, (x_off, -off), bg, c); glyph.draw(buf, (x_off, -off), bg, c);
x_off += glyph.dimensions.0 as i32 + glyph.origin.0; x_off += glyph.dimensions.0 as i32 + glyph.origin.0;
} }
@@ -128,31 +139,44 @@ impl Font {
Ok((x_off as u32, self.size as u32)) Ok((x_off as u32, self.size as u32))
} }
pub fn draw_text_fixed_width( pub fn auto_draw_text(
&mut self, &mut self,
buf: &mut Buffer, buf: &mut Buffer,
bg: &Color, bg: &Color,
c: &Color, c: &Color,
s: &str,
) -> Result<(u32, u32), ::std::io::Error> {
self.add_str_to_cache(s);
self.draw_text(buf, bg, c, s)
}
pub fn draw_text_fixed_width(
&self,
buf: &mut Buffer,
bg: &Color,
c: &Color,
distances: &[u32], distances: &[u32],
s: &str, s: &str,
) -> Result<(u32, u32), ::std::io::Error> { ) -> Result<(u32, u32), ::std::io::Error> {
let mut x_off = 0; let mut x_off = 0;
let mut off = 0; let mut off = 0;
let mut glyphs = Vec::with_capacity(s.len());
for ch in s.chars() { for ch in s.chars() {
let glyph = match self.glyphs.get(&ch) { let glyph = match self.glyphs.get(&ch) {
Some(glyph) => glyph, Some(glyph) => glyph,
None => { None => {
let glyph = CachedGlyph::new(self.font, self.size, ch); return Err(::std::io::Error::new(
self.glyphs.insert(ch, glyph); ::std::io::ErrorKind::Other,
self.glyphs.get(&ch).unwrap() format!("glyph for {:} not in cache", ch),
))
} }
}; };
glyphs.push(glyph);
if glyph.origin.1 < off { if glyph.origin.1 < off {
off = glyph.origin.1 off = glyph.origin.1
} }
} }
for (idx, ch) in s.chars().enumerate() { for (idx, glyph) in glyphs.into_iter().enumerate() {
let glyph = &self.glyphs[&ch];
glyph.draw(buf, (x_off, -off), bg, c); glyph.draw(buf, (x_off, -off), bg, c);
x_off += distances[idx] as i32; x_off += distances[idx] as i32;
} }
@@ -161,7 +185,7 @@ impl Font {
} }
pub fn draw_text_individual_colors( pub fn draw_text_individual_colors(
&mut self, &self,
buf: &mut Buffer, buf: &mut Buffer,
bg: &Color, bg: &Color,
color: &[Color], color: &[Color],
@@ -169,27 +193,40 @@ impl Font {
) -> Result<(u32, u32), ::std::io::Error> { ) -> Result<(u32, u32), ::std::io::Error> {
let mut x_off = 0; let mut x_off = 0;
let mut off = 0; let mut off = 0;
let mut glyphs = Vec::with_capacity(s.len());
for ch in s.chars() { for ch in s.chars() {
let glyph = match self.glyphs.get(&ch) { let glyph = match self.glyphs.get(&ch) {
Some(glyph) => glyph, Some(glyph) => glyph,
None => { None => {
let glyph = CachedGlyph::new(self.font, self.size, ch); return Err(::std::io::Error::new(
self.glyphs.insert(ch, glyph); ::std::io::ErrorKind::Other,
self.glyphs.get(&ch).unwrap() format!("glyph for {:} not in cache", ch),
))
} }
}; };
glyphs.push(glyph);
if glyph.origin.1 < off { if glyph.origin.1 < off {
off = glyph.origin.1 off = glyph.origin.1
} }
} }
for (idx, ch) in s.chars().enumerate() { for (idx, glyph) in glyphs.into_iter().enumerate() {
let glyph = &self.glyphs[&ch];
glyph.draw(buf, (x_off, -off), bg, &color[idx]); glyph.draw(buf, (x_off, -off), bg, &color[idx]);
x_off += glyph.dimensions.0 as i32 + glyph.origin.0; x_off += glyph.dimensions.0 as i32 + glyph.origin.0;
} }
Ok((x_off as u32, self.size as u32)) Ok((x_off as u32, self.size as u32))
} }
pub fn auto_draw_text_individual_colors(
&mut self,
buf: &mut Buffer,
bg: &Color,
color: &[Color],
s: &str,
) -> Result<(u32, u32), ::std::io::Error> {
self.add_str_to_cache(s);
self.draw_text_individual_colors(buf, bg, color, s)
}
} }
pub fn draw_box(buf: &mut Buffer, c: &Color, dim: (u32, u32)) -> Result<(), ::std::io::Error> { pub fn draw_box(buf: &mut Buffer, c: &Color, dim: (u32, u32)) -> Result<(), ::std::io::Error> {
+4 -4
View File
@@ -58,7 +58,7 @@ impl ModuleImpl for Launcher {
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> { ) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg); buf.memset(bg);
self.font.borrow_mut().draw_text( self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((0, 0, 128, 32))?, &mut buf.subdimensions((0, 0, 128, 32))?,
bg, bg,
&Color::new(0.75, 0.75, 0.75, 1.0), &Color::new(0.75, 0.75, 0.75, 1.0),
@@ -68,7 +68,7 @@ impl ModuleImpl for Launcher {
let mut x_off: i32 = 0; let mut x_off: i32 = 0;
let mut width_remaining: i32 = 1280 - 64; let mut width_remaining: i32 = 1280 - 64;
if self.matches.len() == 0 && self.cur.len() > 0 { if self.matches.len() == 0 && self.cur.len() > 0 {
self.font.borrow_mut().draw_text( self.font.borrow_mut().auto_draw_text(
&mut buf &mut buf
.subdimensions((64, 0, width_remaining as u32, 32)) .subdimensions((64, 0, width_remaining as u32, 32))
.unwrap(), .unwrap(),
@@ -96,9 +96,9 @@ impl ModuleImpl for Launcher {
} }
self.font self.font
.borrow_mut() .borrow_mut()
.draw_text_individual_colors(&mut b, bg, &colors, &m)? .auto_draw_text_individual_colors(&mut b, bg, &colors, &m)?
} else { } else {
self.font.borrow_mut().draw_text( self.font.borrow_mut().auto_draw_text(
&mut b, &mut b,
bg, bg,
&Color::new(0.5, 0.5, 0.5, 1.0), &Color::new(0.5, 0.5, 0.5, 1.0),
+18 -23
View File
@@ -10,9 +10,7 @@ use os_pipe::pipe;
use chrono::Local; use chrono::Local;
use smithay_client_toolkit::keyboard::{ use smithay_client_toolkit::keyboard::{keysyms, map_keyboard_auto, Event as KbEvent, KeyState};
keysyms, map_keyboard_auto, Event as KbEvent, KeyState,
};
use smithay_client_toolkit::utils::DoubleMemPool; use smithay_client_toolkit::utils::DoubleMemPool;
use wayland_client::protocol::{wl_compositor, wl_pointer, wl_shm, wl_surface}; use wayland_client::protocol::{wl_compositor, wl_pointer, wl_shm, wl_surface};
@@ -244,29 +242,26 @@ impl App {
// Keyboard processing // Keyboard processing
// //
let kbd_clone = cmd_queue.clone(); let kbd_clone = cmd_queue.clone();
map_keyboard_auto( map_keyboard_auto(&seat, move |event: KbEvent, _| match event {
&seat, KbEvent::Key {
move |event: KbEvent, _| match event { keysym,
KbEvent::Key { utf8,
keysym, state,
utf8, ..
state, } => match state {
.. KeyState::Pressed => match keysym {
} => match state { keysyms::XKB_KEY_Escape => kbd_clone.lock().unwrap().push_back(Cmd::Exit),
KeyState::Pressed => match keysym { v => kbd_clone.lock().unwrap().push_back(Cmd::KeyboardInput {
keysyms::XKB_KEY_Escape => kbd_clone.lock().unwrap().push_back(Cmd::Exit), input: Input::Keypress {
v => kbd_clone.lock().unwrap().push_back(Cmd::KeyboardInput { key: v,
input: Input::Keypress { interpreted: utf8,
key: v, },
interpreted: utf8, }),
},
}),
},
_ => (),
}, },
_ => (), _ => (),
}, },
) _ => (),
})
.expect("Failed to map keyboard"); .expect("Failed to map keyboard");
// //
+5 -3
View File
@@ -399,16 +399,18 @@ impl PulseAudioSoundDevice {
pub struct PulseAudio { pub struct PulseAudio {
device: Arc<Mutex<PulseAudioSoundDevice>>, device: Arc<Mutex<PulseAudioSoundDevice>>,
font: RefCell<Font>, font: Font,
dirty: Arc<Mutex<bool>>, dirty: Arc<Mutex<bool>>,
} }
impl PulseAudio { impl PulseAudio {
pub fn new(listener: Sender<bool>) -> Result<PulseAudio, ::std::io::Error> { pub fn new(listener: Sender<bool>) -> Result<PulseAudio, ::std::io::Error> {
let (tx, rx) = channel(); let (tx, rx) = channel();
let mut font = Font::new(&ROBOTO_REGULAR, 24.0);
font.add_str_to_cache("volume");
let pa = PulseAudio { let pa = PulseAudio {
device: PulseAudioSoundDevice::new(tx)?, device: PulseAudioSoundDevice::new(tx)?,
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), font: font,
dirty: Arc::new(Mutex::new(true)), dirty: Arc::new(Mutex::new(true)),
}; };
let device = pa.device.clone(); let device = pa.device.clone();
@@ -438,7 +440,7 @@ impl ModuleImpl for PulseAudio {
} else { } else {
Color::new(1.0, 1.0, 1.0, 1.0) Color::new(1.0, 1.0, 1.0, 1.0)
}; };
self.font.borrow_mut().draw_text( self.font.draw_text(
&mut buf.subdimensions((0, 0, 128, 24))?, &mut buf.subdimensions((0, 0, 128, 24))?,
bg, bg,
&Color::new(1.0, 1.0, 1.0, 1.0), &Color::new(1.0, 1.0, 1.0, 1.0),