rocketsplash-rt 0.2.2

Runtime library for loading and rendering Rocketsplash assets (.rst, .rsf)
Documentation
// <FILE>crates/rocketsplash-rt/src/render/cls_render_buffer.rs</FILE>
// <DESC>Flat render buffer with per-cell styling</DESC>
// <VERS>VERSION: 1.0.0</VERS>
// <WCTX>Runtime library implementation</WCTX>
// <CLOG>Add RenderBuffer and RenderCell primitives</CLOG>

use rocketsplash_formats::Rgb;

use crate::TextStyle;

#[derive(Clone, Debug)]
pub struct RenderBuffer {
    pub width: usize,
    pub height: usize,
    pub cells: Vec<RenderCell>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RenderCell {
    pub ch: char,
    pub fg: Option<Rgb>,
    pub bg: Option<Rgb>,
    pub style: TextStyle,
    pub opacity: u8,
}

impl RenderCell {
    pub fn empty() -> Self {
        Self {
            ch: ' ',
            fg: None,
            bg: None,
            style: TextStyle::empty(),
            opacity: 0,
        }
    }

    pub fn is_empty(&self) -> bool {
        self.ch == ' ' && self.opacity == 0 && self.fg.is_none() && self.bg.is_none()
    }
}

impl RenderBuffer {
    pub fn new(width: usize, height: usize) -> Self {
        let size = width.saturating_mul(height);
        Self {
            width,
            height,
            cells: vec![RenderCell::empty(); size],
        }
    }

    pub fn cell(&self, x: usize, y: usize) -> Option<&RenderCell> {
        self.index(x, y).and_then(|idx| self.cells.get(idx))
    }

    pub fn cell_mut(&mut self, x: usize, y: usize) -> Option<&mut RenderCell> {
        self.index(x, y).and_then(|idx| self.cells.get_mut(idx))
    }

    fn index(&self, x: usize, y: usize) -> Option<usize> {
        if x >= self.width || y >= self.height {
            return None;
        }
        Some(y * self.width + x)
    }
}

// <FILE>crates/rocketsplash-rt/src/render/cls_render_buffer.rs</FILE>
// <VERS>END OF VERSION: 1.0.0</VERS>