1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
extern crate cairo; use cairo::{Context, ImageSurface, Format}; use crate::pixel::Rgba; use crate::image::Image; use crate::buffer::Buffer; pub fn render_image(width: usize, height: usize, builder: &Fn(Context)) -> Image<Rgba> { let mut surface = ImageSurface::create(Format::ARgb32, width as i32, height as i32).unwrap(); builder(Context::new(&surface)); (&mut surface).into() } pub fn render_buffer( width: usize, height: usize, framerate: usize, builder: &Fn(WrapedContext)) -> Buffer<Rgba> { let surface = ImageSurface::create(Format::ARgb32, width as i32, height as i32).unwrap(); let mut images: Vec<Image<Rgba>> = vec![]; builder(WrapedContext::new(surface, &mut images)); let mut vec = vec![Rgba::default(); width * height * images.len()]; for (i, image) in images.iter().enumerate() { for j in 0..width * height { vec[i * width * height + j] = image.vec[j]; } } Buffer { width: width, height: height, frame_num: images.len(), framerate: framerate, vec: vec } } impl From<&mut ImageSurface> for Image<Rgba> { fn from(surface: &mut ImageSurface) -> Image<Rgba> { let width = surface.get_width() as usize; let height = surface.get_height() as usize; let size = width * height; let mut vec = Vec::with_capacity(size); let data = surface.get_data().unwrap(); for i in 0..size { vec.push(Rgba( data[i * 4 + 2] as f64 / 255.0, data[i * 4 + 1] as f64 / 255.0, data[i * 4 + 0] as f64 / 255.0, data[i * 4 + 3] as f64 / 255.0 )); } Image { width: width, height: height, vec: vec } } } pub struct WrapedContext<'a> { pub context: *mut Context, pub surface: ImageSurface, pub images: &'a mut Vec<Image<Rgba>> } impl<'a> WrapedContext<'a> { pub fn new(surface: ImageSurface, images: &'a mut Vec<Image<Rgba>>) -> Self { WrapedContext { context: Box::into_raw(Box::new(Context::new(&surface))), surface: surface, images: images } } pub fn push(&mut self) { unsafe { drop(Box::from_raw(self.context)) }; self.images.push((&mut self.surface).into()); self.context = Box::into_raw(Box::new(Context::new(&self.surface))); } } impl<'a> Drop for WrapedContext<'a> { fn drop(&mut self) { unsafe { drop(Box::from_raw(self.context)) }; } } impl<'a> core::ops::Deref for WrapedContext<'a> { type Target = Context; fn deref(&self) -> &Context { unsafe { &*self.context } } }