diff --git a/textium/src/texture.rs b/textium/src/texture.rs index 830e1e7..8271c72 100644 --- a/textium/src/texture.rs +++ b/textium/src/texture.rs @@ -1,16 +1,93 @@ use std::borrow::Cow; +use std::slice::Chunks; use glium::texture::{RawImage2d, Texture2dDataSource}; pub use glium::texture::PixelValue; +/// A CPU RAM-based 2d buffer. +pub trait Buffer2d: Sized { + type Pixel; -pub struct Texture2dData where T: Clone { + fn width(&self) -> usize; + fn height(&self) -> usize; + fn dimensions(&self) -> (usize, usize) {(self.width(), self.height())} + + fn get(&self, x: usize, y: usize) -> Option; + fn set(&mut self, x: usize, y: usize, v: Self::Pixel); + + fn patch(&mut self, x: usize, y: usize, buf: &B) + where B: Buffer2d + { + let (w, h) = buf.dimensions(); + + // TODO: can this be optimized by performing an unsafe memcpy of some sort? + for sy in 0..h { + for sx in 0..w { + match buf.get(sx, sy) { + Some(v) => self.set(x+sx, y+sy, v), + _ => (), + } + } + } + } +} + +pub trait ResizeableBuffer2d: Buffer2d { + fn resize(&mut self, width: usize, height: usize); +} + +pub struct Bitmap { pub data: Vec, - pub width: u32, - pub height: u32, + pub width: usize, + pub height: usize, +} + +impl Bitmap where T: Clone + Default { + pub fn new(w: usize, h: usize) -> Bitmap { + Bitmap { + data: vec![Default::default(); w*h], + width: w, + height: h, + } + } + + pub fn lines(&self) -> Chunks { + self.data.chunks(self.width) + } +} + +impl Buffer2d for Bitmap where T: Clone { + type Pixel = T; + + fn width(&self) -> usize {self.width} + fn height(&self) -> usize {self.height} + + fn get(&self, x: usize, y: usize) -> Option { + self.data.get(x + self.width * y).cloned() + } + + fn set(&mut self, x: usize, y: usize, v: Self::Pixel) { + if let Some(p) = self.data.get_mut(x + self.width * y) { + *p = v; + } + } +} + +impl ResizeableBuffer2d for Bitmap where T: Clone + Default { + fn resize(&mut self, width: usize, height: usize) { + assert!(self.width() <= width && self.height() <= height, + "resizable buffers cannot shrink!"); + + // create new, larger buffer + let mut new: Bitmap = Bitmap::new(width as usize, height as usize); + // copy the existing buffer into it + new.patch(0, 0, self); + // overwrite the current buffer with the new buffer + *self = new; + } } -impl<'a, P> Texture2dDataSource<'a> for &'a Texture2dData

+impl<'a, P> Texture2dDataSource<'a> for &'a Bitmap

where P: Clone + PixelValue { type Data = P; @@ -18,8 +95,8 @@ impl<'a, P> Texture2dDataSource<'a> for &'a Texture2dData

fn into_raw(self) -> RawImage2d<'a, P> { RawImage2d { data: Cow::Borrowed(&self.data), - width: self.width, - height: self.height, + width: self.width as u32, + height: self.height as u32, format:

::get_format(), } }