use crate::{
Result,
backend::{Backend, SurfaceData, instance},
geom::{Transform, Vector},
graphics::{Image, PixelFormat, View},
lifecycle::Window,
};
use std::rc::Rc;
#[derive(Clone, Debug)]
pub struct Surface {
pub(crate) image: Image,
pub(crate) data: Rc<SurfaceData>,
}
impl Surface {
pub fn new(width: u32, height: u32) -> Result<Surface> {
let image = Image::new_null(width, height, PixelFormat::RGBA)?;
let data = unsafe {
Rc::new(instance().create_surface(&image)?)
};
Ok(Surface {
image,
data
})
}
pub fn render_to(&self, window: &mut Window, func: impl FnOnce(&mut Window) -> Result<()>) -> Result<()> {
let backend = unsafe { instance() };
let view = window.view();
let viewport = unsafe {
let view = backend.viewport();
backend.bind_surface(self);
view
};
window.flush()?;
window.set_view(View::new_transformed(self.image.area(), Transform::scale(Vector::new(1, -1))));
func(window)?;
window.set_view(view);
window.flush()?;
unsafe {
backend.unbind_surface(self, &viewport);
}
Ok(())
}
pub fn image(&self) -> &Image {
&self.image
}
}