use crate::compositor::plane::Cell;
pub trait Filter {
fn apply(&self, cell: &mut Cell, x: u16, y: u16, time: f32);
}
pub struct Dim {
pub factor: f32, }
impl Default for Dim {
fn default() -> Self {
Self { factor: 0.5 }
}
}
impl Filter for Dim {
fn apply(&self, cell: &mut Cell, _x: u16, _y: u16, _time: f32) {
let dim = |color: crate::compositor::plane::Color| match color {
crate::compositor::plane::Color::Rgb(r, g, b) => crate::compositor::plane::Color::Rgb(
(r as f32 * self.factor) as u8,
(g as f32 * self.factor) as u8,
(b as f32 * self.factor) as u8,
),
crate::compositor::plane::Color::Ansi(c) => {
if c > 8 {
crate::compositor::plane::Color::Ansi(8)
} else {
color
}
}
crate::compositor::plane::Color::Reset => color,
};
cell.fg = dim(cell.fg);
cell.bg = dim(cell.bg);
}
}
pub struct Invert;
impl Filter for Invert {
fn apply(&self, cell: &mut Cell, _x: u16, _y: u16, _time: f32) {
std::mem::swap(&mut cell.fg, &mut cell.bg);
}
}
pub struct Scanline;
impl Filter for Scanline {
fn apply(&self, cell: &mut Cell, _x: u16, y: u16, _time: f32) {
if y.is_multiple_of(2) {
let dim = |color: crate::compositor::plane::Color| match color {
crate::compositor::plane::Color::Rgb(r, g, b) => {
crate::compositor::plane::Color::Rgb(
(r as f32 * 0.8) as u8,
(g as f32 * 0.8) as u8,
(b as f32 * 0.8) as u16 as u8,
)
}
_ => color,
};
cell.fg = dim(cell.fg);
cell.bg = dim(cell.bg);
}
}
}
pub struct Pulse;
impl Filter for Pulse {
#[allow(clippy::redundant_closure_call)]
fn apply(&self, cell: &mut Cell, _x: u16, _y: u16, time: f32) {
let factor = (time.sin() * 0.2 + 0.8).clamp(0.0, 1.0);
let dim = |color: crate::compositor::plane::Color| match color {
crate::compositor::plane::Color::Rgb(r, g, b) => crate::compositor::plane::Color::Rgb(
(r as f32 * factor) as u8,
(g as f32 * factor) as u8,
(b as f32 * factor) as u8,
),
_ => color,
};
cell.fg = dim(cell.fg);
}
}
pub struct Glitch;
impl Filter for Glitch {
fn apply(&self, cell: &mut Cell, x: u16, y: u16, time: f32) {
let seed = (x as f32 * 12.9898 + y as f32 * 78.233 + time).sin() * 43_758.547;
let rand = seed - seed.floor();
if rand > 0.98 {
cell.char = if rand > 0.99 { '█' } else { '░' };
cell.fg = crate::compositor::plane::Color::Rgb(255, 0, 85); } else if rand > 0.95 {
let shift = (time * 10.0).sin() * 5.0;
if (y as f32 - shift.abs()).abs() < 1.0 {
cell.style.insert(crate::compositor::plane::Styles::REVERSE);
}
}
}
}