use color::Rgba8; use kiln_core::glyph::Glyph; use ratatui::layout::Rect; use ratatui::prelude::Color; use ratatui::style::Style; use ratatui::text::Span; /// Converts a core [`Rgba8`] color into a ratatui truecolor [`Color`]. /// /// The alpha channel is dropped — terminals have no per-cell alpha. Truecolor /// requires terminal support; terminals limited to 256 colors approximate it. pub fn rgba8_to_color(c: Rgba8) -> Color { Color::Rgb(c.r, c.g, c.b) } /// The character this terminal front-end draws for `glyph`. /// /// A glyph carries its character directly, so this is almost the identity — the /// one case that needs handling is the transparent sentinel `'\0'`, which means /// "draw nothing". By the time a glyph reaches a renderer, `Board::glyph_at` has /// already exhausted its precedence chain, so there is nothing underneath left to /// reveal and the cell is simply blank. Writing the NUL through to the terminal /// buffer would emit an unprintable character instead. /// /// How a sentinel looks on screen is a front-end decision, which is why this /// lives here rather than in kiln-core. pub fn glyph_char(glyph: Glyph) -> char { if glyph.is_visible() { glyph.tile } else { ' ' } } /// Converts a [`Glyph`] to a single-character styled [`Span`], applying fg and bg. pub fn glyph_to_span(glyph: Glyph) -> Span<'static> { let style = Style::default() .fg(rgba8_to_color(glyph.fg)) .bg(rgba8_to_color(glyph.bg)); Span::styled(glyph_char(glyph).to_string(), style) } /// Returns true if two `Rect`s share at least one cell. pub fn rects_overlap(a: Rect, b: Rect) -> bool { a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height }