pub(crate) const BRAILLE_OFFSETS: [(usize, usize); 8] = [
(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (3, 0), (3, 1), ];
pub(crate) fn pack_braille_cell(mut dot_at: impl FnMut(usize, usize) -> bool) -> char {
let mut code: u32 = 0x2800;
for (bit, &(row, col)) in BRAILLE_OFFSETS.iter().enumerate() {
if dot_at(row, col) {
code |= 1 << bit;
}
}
char::from_u32(code).unwrap_or(' ')
}
pub(crate) use crate::primitives::minimap::dither_threshold_met;
pub(crate) fn interpolate_dots(grid: &mut [Vec<bool>], x0: usize, y0: usize, x1: usize, y1: usize) {
let dx = (x1 as isize - x0 as isize).abs();
let dy = (y1 as isize - y0 as isize).abs();
let steps = dx.max(dy);
if steps == 0 {
return;
}
for step in 0..=steps {
let t = step as f64 / steps as f64;
let ix = (x0 as f64 + t * (x1 as f64 - x0 as f64)).round() as usize;
let iy = (y0 as f64 + t * (y1 as f64 - y0 as f64)).round() as usize;
if iy < grid.len() && ix < grid[0].len() {
grid[iy][ix] = true;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_dots_off_packs_to_blank_braille() {
assert_eq!(pack_braille_cell(|_, _| false), '\u{2800}');
}
#[test]
fn all_dots_on_packs_to_full_braille_block() {
assert_eq!(pack_braille_cell(|_, _| true), '\u{28FF}');
}
#[test]
fn single_dot_sets_the_documented_bit() {
assert_eq!(pack_braille_cell(|r, c| (r, c) == (0, 0)), '\u{2801}');
assert_eq!(pack_braille_cell(|r, c| (r, c) == (0, 1)), '\u{2808}');
assert_eq!(pack_braille_cell(|r, c| (r, c) == (3, 0)), '\u{2840}');
assert_eq!(pack_braille_cell(|r, c| (r, c) == (3, 1)), '\u{2880}');
}
#[test]
fn zero_coverage_never_meets_the_threshold() {
for row in 0..4 {
for col in 0..4 {
assert!(!dither_threshold_met(0, 6, row, col));
}
}
}
#[test]
fn zero_width_bucket_never_meets_the_threshold() {
assert!(!dither_threshold_met(0, 0, 0, 0));
assert!(!dither_threshold_met(5, 0, 0, 0));
}
#[test]
fn full_coverage_always_meets_the_threshold() {
for row in 0..4 {
for col in 0..4 {
assert!(
dither_threshold_met(6, 6, row, col),
"full coverage must always set the dot at ({row}, {col})"
);
}
}
}
#[test]
fn partial_coverage_sets_only_some_dot_positions() {
let set_count = (0..4)
.flat_map(|row| (0..4).map(move |col| (row, col)))
.filter(|&(row, col)| dither_threshold_met(1, 6, row, col))
.count();
assert!(
set_count > 0 && set_count < 16,
"expected a strict subset of the 16 dot positions to light up, got {set_count}/16"
);
}
#[test]
fn threshold_is_indexed_by_absolute_position_not_just_local_position() {
assert_eq!(
dither_threshold_met(3, 6, 0, 0),
dither_threshold_met(3, 6, 4, 4)
);
}
}