use super::super::layer::Layer;
use crate::layout::Rect;
use crate::render::{Buffer, Cell};
use crate::style::Color;
use super::constants::{BRAILLE_BASE, BRAILLE_DOTS};
pub struct BrailleGrid {
width: usize,
height: usize,
cells: Vec<u8>,
colors: Vec<Option<Color>>,
term_width: usize,
term_height: usize,
}
impl BrailleGrid {
pub fn new(term_width: u16, term_height: u16) -> Self {
let tw = term_width as usize;
let th = term_height as usize;
let cell_count = tw * th;
Self {
width: tw * 2,
height: th * 4,
cells: vec![0; cell_count],
colors: vec![None; cell_count],
term_width: tw,
term_height: th,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn set(&mut self, x: usize, y: usize, color: Color) {
if x >= self.width || y >= self.height {
return;
}
let cell_x = x / 2;
let cell_y = y / 4;
let dot_x = x % 2;
let dot_y = y % 4;
let cell_idx = cell_y * self.term_width + cell_x;
if cell_idx < self.cells.len() {
self.cells[cell_idx] |= BRAILLE_DOTS[dot_x][dot_y];
self.colors[cell_idx] = Some(color);
}
}
pub fn clear(&mut self) {
self.cells.fill(0);
self.colors.fill(None);
}
pub fn get_char(&self, cell_x: usize, cell_y: usize) -> char {
let idx = cell_y * self.term_width + cell_x;
if idx < self.cells.len() {
char::from_u32(BRAILLE_BASE + self.cells[idx] as u32).unwrap_or('⠀')
} else {
'⠀'
}
}
fn get_color(&self, cell_x: usize, cell_y: usize) -> Option<Color> {
let idx = cell_y * self.term_width + cell_x;
if idx < self.colors.len() {
self.colors[idx]
} else {
None
}
}
pub fn render(&self, buffer: &mut Buffer, area: Rect) {
for cy in 0..self.term_height.min(area.height as usize) {
for cx in 0..self.term_width.min(area.width as usize) {
let ch = self.get_char(cx, cy);
if ch != '⠀' {
let mut cell = Cell::new(ch);
cell.fg = self.get_color(cx, cy);
buffer.set(area.x + cx as u16, area.y + cy as u16, cell);
}
}
}
}
pub fn composite_layer(&mut self, layer: &Layer) {
if !layer.is_visible() || layer.opacity() <= 0.0 {
return;
}
let layer_grid = layer.grid();
let max_cells = self.cells.len().min(layer_grid.cells.len());
for idx in 0..max_cells {
let pattern = layer_grid.cells[idx];
if pattern != 0 {
self.cells[idx] |= pattern;
if let Some(color) = layer_grid.colors[idx] {
self.colors[idx] = Some(color);
}
}
}
}
#[doc(hidden)]
pub fn cells(&self) -> &[u8] {
&self.cells
}
#[doc(hidden)]
pub fn colors(&self) -> &[Option<Color>] {
&self.colors
}
}