organicomplex 0.7.0

Interactive complex-valued cellular automaton on 2D and 3D grids in search of that stuff - emergence, open-endedness, organicity etc.
use sdl2::pixels::Color;

use crate::{
    base::{
        ARGB,
        RGB
    },
    fontset::Font
};

use super::{
    image::Image,
    System
};


impl System {
    pub fn make_text_image(font: &Font, text: impl ToString, wrap: i32, color: RGB) -> Result<Image, String> {
        let text = text.to_string();

        let surface = if wrap > 0 {
            font.sdl_font.render(&text).blended_wrapped(Color::RGB(color.r, color.g, color.b), wrap as u32)
        } else {
            font.sdl_font.render(&text).blended(Color::RGB(color.r, color.g, color.b))
        };
        match surface {
            Ok(surface) => {
                match surface.without_lock() {
                    Some(raw) => {
                        let (width, height, pitch) = (surface.width() as usize, surface.height() as usize, surface.pitch() as usize);
                        // Is pitch always = width * 4? - NO in Windows (at least)
                        let mut buf: Vec<u8> = Vec::new();
                        let mut offs: usize = 0;
                        for _ in 0..height {
                            buf.extend_from_slice(&raw[offs..(offs + (width << 2))]);
                            offs += pitch;
                        }
                        Ok(Image::make(width as i32, height as i32, buf))
                    },
                    None => Err(format!("sdl surface requires locking"))
                }
            },
            Err(e) => Err(e.to_string())
        }
    }

    pub fn draw_text_image(&mut self, txt_img: &Image, shade: u8, margin: i32, x: i32, y: i32) {
        let _ = self.draw_rect(x, y, x + txt_img.width() - 1 + (margin << 1), y + txt_img.height() - 1 + (margin << 1), ARGB{a: shade, r: 0, g: 0, b: 0}, true);
        self.draw_image(txt_img, x + margin, y + margin);
    }

    /// Slow to do it every frame.
    /// Prepare image with make_text_image() once and draw it with draw_text_image() every frame...
    pub fn draw_text(&mut self, font: &Font, text: impl ToString, wrap: i32, color: RGB, shade: u8, margin: i32, x: i32, y: i32) {
        let text = text.to_string();

        if let Ok(txt_img) = Self::make_text_image(font, text, wrap, color) {
            self.draw_text_image(&txt_img, shade, margin, x, y)
        }
    }
}