use crate::backend::cell::SerializableColor;
use crate::backend::CaptureBackend;
const RESET: &str = "\x1b[0m";
pub fn render(backend: &CaptureBackend) -> String {
let width = backend.width();
let height = backend.height();
let mut output = String::new();
for y in 0..height {
if y > 0 {
output.push('\n');
}
let mut last_fg = SerializableColor::Reset;
let mut last_bg = SerializableColor::Reset;
let mut last_modifiers = crate::backend::cell::SerializableModifier::empty();
for x in 0..width {
let Some(cell) = backend.cell(x, y) else {
continue;
};
let need_fg_change = cell.fg != last_fg;
let need_bg_change = cell.bg != last_bg;
let need_mod_change = cell.modifiers != last_modifiers;
if need_fg_change || need_bg_change || need_mod_change {
output.push_str(RESET);
if !cell.modifiers.is_empty() {
output.push_str(&cell.modifiers.to_ansi());
}
if cell.fg != SerializableColor::Reset {
output.push_str(&cell.fg.to_ansi_fg());
}
if cell.bg != SerializableColor::Reset {
output.push_str(&cell.bg.to_ansi_bg());
}
last_fg = cell.fg;
last_bg = cell.bg;
last_modifiers = cell.modifiers;
}
output.push_str(cell.symbol());
}
if last_fg != SerializableColor::Reset
|| last_bg != SerializableColor::Reset
|| !last_modifiers.is_empty()
{
output.push_str(RESET);
}
}
output
}
pub fn render_with_legend(backend: &CaptureBackend) -> String {
let mut output = render(backend);
let width = backend.width();
let height = backend.height();
let mut colors_used: std::collections::HashSet<String> = std::collections::HashSet::new();
for y in 0..height {
for x in 0..width {
let Some(cell) = backend.cell(x, y) else {
continue;
};
if cell.fg != SerializableColor::Reset {
colors_used.insert(format!("FG: {:?}", cell.fg));
}
if cell.bg != SerializableColor::Reset {
colors_used.insert(format!("BG: {:?}", cell.bg));
}
}
}
if !colors_used.is_empty() {
output.push_str("\n\n--- Colors Used ---\n");
for color in colors_used {
output.push_str(&color);
output.push('\n');
}
}
output
}
#[cfg(test)]
mod tests;