1 use std::time::Instant;
3 const XOFF: usize = 10;
16 pub fn new() -> Self { Self::default() }
17 pub fn reset(&mut self) {
22 pub fn set_duration(&mut self, duration: u64) { self.duration = duration; }
23 pub fn toggle(&mut self) {
29 if self.time.is_none() {
30 self.time = Some(Instant::now());
35 pub fn toggle_perm(&mut self) {
43 pub fn update(&mut self) {
44 if let Some(time) = self.time {
45 if time.elapsed().as_millis() > 3000 {
50 pub fn is_active(&self) -> bool { self.time.is_some() || self.perm }
51 pub fn prepare(&mut self, ts: u64) {
53 if !self.is_active() {
56 let mut time_str = format_time(ts);
57 if self.duration != 0 {
59 time_str += format_time(self.duration).as_str();
62 let mut syms = Vec::with_capacity(time_str.len());
63 for chr in time_str.chars() {
64 let sym_idx = OSD_GLYPHS.iter().position(|el| el.sym == chr).unwrap_or(0);
65 w += OSD_GLYPHS[sym_idx].width;
70 self.text.resize(self.text_stride * 16, 0);
72 for &sym_idx in syms.iter() {
73 let glyph = &OSD_GLYPHS[sym_idx];
74 let mut mask = 1 << (glyph.width - 1);
76 for (dline, (bits, mbits)) in self.text.chunks_exact_mut(w).zip(glyph.bits.iter().zip(glyph.mask.iter())) {
77 let wval = (bits & mask) != 0;
78 let bval = (mbits & mask) != 0;
79 dline[pos] = if wval { 2 } else if bval { 1 } else { 0 };
89 pub fn draw_yuv(&self, buffer: &mut [u8], pitch: usize) {
90 if !self.is_active() || self.text_stride == 0 {
93 for (dline, sline) in buffer.chunks_exact_mut(pitch).skip(YOFF).zip(self.text.chunks_exact(self.text_stride)) {
94 for (dst, &src) in dline.iter_mut().skip(XOFF).zip(sline.iter()) {
103 pub fn draw_rgb(&self, buffer: &mut [u8], pitch: usize) {
104 if !self.is_active() || self.text_stride == 0 {
107 for (dline, sline) in buffer.chunks_exact_mut(pitch).skip(YOFF).zip(self.text.chunks_exact(self.text_stride)) {
108 for (dst, &src) in dline.chunks_exact_mut(3).skip(XOFF).zip(sline.iter()) {
110 2 => dst.copy_from_slice(&[0xFF, 0xFF, 0xFF]),
111 1 => dst.copy_from_slice(&[0x00, 0x00, 0x00]),
119 fn format_time(ms: u64) -> String {
121 let (min, s) = (s / 60, s % 60);
122 let (h, min) = (min / 60, min % 60);
125 format!("0:{:02}", s)
127 format!("{}:{:02}", min, s)
130 format!("{}:{:02}:{:02}", h, min, s)
141 const OSD_GLYPHS: &[Glyph] = &[