rocketsplash-rt 0.2.2

Runtime library for loading and rendering Rocketsplash assets (.rst, .rsf)
Documentation
// <FILE>crates/rocketsplash-rt/src/render/fnc_apply_shadow.rs</FILE>
// <DESC>Apply drop shadow to render buffer</DESC>
// <VERS>VERSION: 1.0.1</VERS>
// <WCTX>Runtime library implementation</WCTX>
// <CLOG>Respect opacity-only shadowing for transparent glyphs</CLOG>

use rocketsplash_formats::Rgb;

use crate::RenderBuffer;

pub fn apply_shadow(buffer: &mut RenderBuffer, dx: i8, dy: i8, color: Rgb) {
    if dx == 0 && dy == 0 {
        return;
    }

    let width = buffer.width as i64;
    let height = buffer.height as i64;
    let mut shadows = Vec::new();

    for y in 0..buffer.height {
        for x in 0..buffer.width {
            let idx = y * buffer.width + x;
            let cell = buffer.cells[idx];
            if cell.opacity == 0 {
                continue;
            }
            let target_x = x as i64 + dx as i64;
            let target_y = y as i64 + dy as i64;
            if target_x < 0 || target_y < 0 || target_x >= width || target_y >= height {
                continue;
            }
            let target_idx = target_y as usize * buffer.width + target_x as usize;
            if !buffer.cells[target_idx].is_empty() {
                continue;
            }
            let alpha = cell.opacity as f32 / 255.0;
            let shadow_color = scale_color(color, alpha);

            shadows.push((target_idx, cell.ch, Some(shadow_color), cell.opacity));
        }
    }

    for (target_idx, ch, fg, opacity) in shadows {
        if buffer.cells[target_idx].is_empty() {
            let shadow_cell = &mut buffer.cells[target_idx];
            shadow_cell.ch = ch;
            shadow_cell.fg = fg;
            shadow_cell.opacity = opacity;
        }
    }
}

fn scale_color(color: Rgb, alpha: f32) -> Rgb {
    let clamp_alpha = alpha.clamp(0.0, 1.0);
    Rgb {
        r: (color.r as f32 * clamp_alpha).round() as u8,
        g: (color.g as f32 * clamp_alpha).round() as u8,
        b: (color.b as f32 * clamp_alpha).round() as u8,
    }
}

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