use servicepoint::{CharGridMutExt, Grid, GridMut, TILE_SIZE, WindowMut}; use std::io::BufRead; pub type BorderPattern = [bool; TILE_SIZE]; pub const OUTER_BORDER: BorderPattern = [false, false, false, true, true, false, true, false]; pub const INNER_BORDER: BorderPattern = [false, false, false, true, true, false, false, false]; pub fn draw_border_panel<'t, C: GridMut, P: GridMut>( mut chars: WindowMut<'t, char, C>, mut bitmap: WindowMut<'t, bool, P>, label: &'static str, border_pattern: BorderPattern, ) -> (WindowMut<'t, char, C>, WindowMut<'t, bool, P>) { let tile_width = chars.width(); let tile_height = chars.height(); let pixel_width = bitmap.width(); let pixel_height = bitmap.height(); chars .window_mut(2, 0, tile_width - 4, 1) .unwrap() .set_row_str(0, label) .unwrap(); // border top+bottom for tile_x in 1..tile_width - 1 { for inner_x in 0..TILE_SIZE { let x = tile_x * TILE_SIZE + inner_x; let draw_top = tile_x <= 1 || tile_x >= label.chars().count() + 2; for inner_y in 0..TILE_SIZE { let val = border_pattern[inner_y]; if draw_top { bitmap.set(x, inner_y, val); } bitmap.set(x, pixel_height - inner_y - 1, val); } } } // border left + right for tile_y in 1..tile_height - 1 { for inner_y in 0..TILE_SIZE { let y = tile_y * TILE_SIZE + inner_y; for inner_x in 0..TILE_SIZE { let val = border_pattern[inner_x]; bitmap.set(inner_x, y, val); bitmap.set(pixel_width - inner_x - 1, y, val); } } } // edges for pat_index in 0..TILE_SIZE { if !border_pattern[pat_index] { continue; } for extend in 0..=TILE_SIZE - pat_index { bitmap.set(TILE_SIZE - extend, pat_index, true); bitmap.set(pixel_width - 1 - TILE_SIZE + extend, pat_index, true); bitmap.set(pat_index, TILE_SIZE - extend, true); bitmap.set(pat_index, pixel_height - 1 - TILE_SIZE + extend, true); bitmap.set(TILE_SIZE - extend, pixel_height - pat_index - 1, true); bitmap.set( pixel_width - 1 - TILE_SIZE + extend, pixel_height - pat_index - 1, true, ); bitmap.set(pixel_width - pat_index - 1, TILE_SIZE - extend, true); bitmap.set( pixel_width - pat_index - 1, pixel_height - 1 - TILE_SIZE + extend, true, ); } } let (chars, _) = chars.split_horizontal_mut(tile_width - 1).unwrap(); let (_, chars) = chars.split_horizontal_mut(1).unwrap(); let (chars, _) = chars.split_vertical_mut(tile_height - 1).unwrap(); let (_, chars) = chars.split_vertical_mut(1).unwrap(); let (bitmap, _) = bitmap .split_horizontal_mut(pixel_width - TILE_SIZE) .unwrap(); let (_, bitmap) = bitmap.split_horizontal_mut(TILE_SIZE).unwrap(); let (bitmap, _) = bitmap.split_vertical_mut(pixel_height - TILE_SIZE).unwrap(); let (_, bitmap) = bitmap.split_vertical_mut(TILE_SIZE).unwrap(); (chars, bitmap) }