extern crate fonterator;
use fonterator::footile;
pub mod icons;
mod gui;
mod window;
pub use crate::gui::Gui;
pub use crate::window::*;
pub use fonterator::{
FontGroup, PathOp,
PathOp::*,
PathOp::{Line, Move, Quad},
};
use footile::PixFmt;
#[derive(Copy, Clone)]
pub struct Size(pub u16, pub u16);
#[derive(Copy, Clone)]
pub struct TexCoord(pub f32, pub f32);
pub struct Image {
plotter: footile::Plotter,
raster: footile::RasterB<footile::Rgba8>,
}
impl Image {
pub fn new(size: Size) -> Self {
let (w, h) = (u32::from(size.0), u32::from(size.1));
Image {
plotter: footile::Plotter::new(w, h),
raster: footile::RasterB::new(w, h),
}
}
pub fn size(&self) -> Size {
Size(self.raster.width() as u16, self.raster.height() as u16)
}
pub unsafe fn clear_ptr(&mut self, pixels: *mut u8) {
let len =
self.raster.width() as usize * self.raster.height() as usize * 4;
self.clear(std::slice::from_raw_parts_mut(pixels, len))
}
pub fn clear(&mut self, pixels: &mut [u8]) {
self.raster.clear(footile::Rgba8::as_slice_mut(pixels));
}
pub unsafe fn fill_ptr<'b, T>(&mut self, color: [u8; 4], path: T, pixels: *mut u8)
where
T: IntoIterator<Item = &'b PathOp>,
{
let len =
self.raster.width() as usize * self.raster.height() as usize * 4;
self.fill(color, path,
std::slice::from_raw_parts_mut(pixels, len)
)
}
pub unsafe fn stroke_ptr<'b, T>(
&mut self,
color: [u8; 4],
path: T,
pixels: *mut u8,
) where
T: IntoIterator<Item = &'b PathOp>,
{
let len =
self.raster.width() as usize * self.raster.height() as usize * 4;
self.stroke(color, path, std::slice::from_raw_parts_mut(pixels, len))
}
pub fn fill<'b, T>(&mut self, color: [u8; 4], path: T, pixels: &mut [u8])
where
T: IntoIterator<Item = &'b PathOp>,
{
let iter = path.into_iter();
let color = footile::Rgba8::new(color[0], color[1], color[2], color[3]);
self.raster.over(
self.plotter.fill(iter, footile::FillRule::NonZero),
color,
footile::Rgba8::as_slice_mut(pixels),
);
}
pub fn stroke<'b, T>(&mut self, color: [u8; 4], path: T, pixels: &mut [u8])
where
T: IntoIterator<Item = &'b PathOp>,
{
let iter = path.into_iter();
let color = footile::Rgba8::new(color[0], color[1], color[2], color[3]);
self.raster.over(
self.plotter.stroke(iter),
color,
footile::Rgba8::as_slice_mut(pixels),
);
}
pub unsafe fn text_ptr(
&mut self,
color: [u8; 4],
xysize: (f32, f32, f32),
font: &FontGroup,
text: &str,
pixels: *mut u8,
) -> (f32, f32) {
let len =
self.raster.width() as usize * self.raster.height() as usize * 4;
self.text(color, xysize, font, text,
std::slice::from_raw_parts_mut(pixels, len)
)
}
pub fn text(
&mut self,
color: [u8; 4],
xysize: (f32, f32, f32),
font: &FontGroup,
text: &str,
pixels: &mut [u8],
) -> (f32, f32) {
let color = footile::Rgba8::new(color[0], color[1], color[2], color[3]);
let mut path = font.render(
text,
(xysize.0, xysize.1),
(xysize.2, xysize.2),
);
self.raster.over(
self.plotter.fill(&mut path, footile::FillRule::NonZero),
color,
footile::Rgba8::as_slice_mut(pixels),
);
let (cx, cy) = path.xy();
(cx, cy)
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
pub fn init_toolbar(window: &mut Window) -> (Shader, Shape) {
let mut gui = window.shader_new(shader!("gui"));
#[rustfmt::skip]
let vertices = [
-1.0, -1.0, 0.0, 1.0,
1.0, -1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 0.0,
-1.0, -1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 0.0,
];
let mut rect = window.shape_new(ShapeBuilder::new(&mut gui).vert(&vertices).face(Transform::new()));
window.instances(&mut rect, &[Transform::new()]);
window.build(&mut gui);
(gui, rect)
}