use retroglyph_core::grid::Grid;
#[must_use]
pub fn join_h(grids: &[Grid]) -> Grid {
if grids.is_empty() {
return Grid::new(1, 0);
}
let width = grids
.iter()
.fold(0u16, |acc, g| acc.saturating_add(g.width()));
let height = grids.iter().map(Grid::height).max().unwrap_or(0);
let mut out = Grid::new(width, height);
let mut x_offset = 0u16;
for g in grids {
out.blit(0, g, g.size().to_rect(), x_offset, 0);
x_offset = x_offset.saturating_add(g.width());
}
out
}
#[must_use]
pub fn join_v(grids: &[Grid]) -> Grid {
if grids.is_empty() {
return Grid::new(1, 0);
}
let width = grids.iter().map(Grid::width).max().unwrap_or(0);
let height = grids
.iter()
.fold(0u16, |acc, g| acc.saturating_add(g.height()));
let mut out = Grid::new(width, height);
let mut y_offset = 0u16;
for g in grids {
out.blit(0, g, g.size().to_rect(), 0, y_offset);
y_offset = y_offset.saturating_add(g.height());
}
out
}
#[cfg(test)]
mod tests {
use retroglyph_core::color::Style;
use retroglyph_core::grid::Pos;
use retroglyph_core::tile::Tile;
use super::*;
#[test]
fn join_h_concatenates_and_pads_shorter_grids() {
let mut a = Grid::new(2, 3);
a.put_tile(0, (0, 0), Tile::new('a', Style::default()));
let mut b = Grid::new(2, 1);
b.put_tile(0, (0, 0), Tile::new('b', Style::default()));
let joined = join_h(&[a, b]);
assert_eq!((joined.width(), joined.height()), (4, 3));
assert_eq!(joined[Pos::new(0, 0)].glyph(), 'a');
assert_eq!(joined[Pos::new(2, 0)].glyph(), 'b');
assert_eq!(joined[Pos::new(2, 1)].glyph(), ' ');
}
#[test]
fn join_v_stacks_and_pads_narrower_grids() {
let mut a = Grid::new(3, 1);
a.put_tile(0, (0, 0), Tile::new('a', Style::default()));
let mut b = Grid::new(1, 1);
b.put_tile(0, (0, 0), Tile::new('b', Style::default()));
let joined = join_v(&[a, b]);
assert_eq!((joined.width(), joined.height()), (3, 2));
assert_eq!(joined[Pos::new(0, 0)].glyph(), 'a');
assert_eq!(joined[Pos::new(0, 1)].glyph(), 'b');
assert_eq!(joined[Pos::new(1, 1)].glyph(), ' ');
}
#[test]
fn join_empty_slice_is_essentially_empty() {
let joined = join_h(&[]);
assert_eq!((joined.width(), joined.height()), (1, 0));
let joined = join_v(&[]);
assert_eq!((joined.width(), joined.height()), (1, 0));
}
#[test]
fn join_only_copies_layer_zero() {
let mut a = Grid::new(1, 1);
a.put_tile(0, (0, 0), Tile::new('a', Style::default())); a.put_tile(1, (0, 0), Tile::new('z', Style::default()));
let joined = join_h(&[a]);
assert_eq!(joined[Pos::new(0, 0)].glyph(), 'a');
assert_eq!(joined.tile(1, (0, 0)), None); }
}