mod vertex;
use vertex::*;
mod mapping;
mod setup;
mod shaders;
use mapping::*;
pub mod canvas;
pub use canvas::*;
mod text;
mod compute;
mod canvas_glob;
use canvas_glob::*;
pub mod color;
pub mod vector;
pub mod math;
pub mod elements;
use color::*;
use math::{bezier_points, catmull_rom_chain};
pub static mut FPS:f32 = 0f32;
pub static mut HEIGHT:u16 = 0u16;
pub static mut WIDTH:u16 = 0u16;
use vulkano::image::Dimensions;
use png;
use std::fs::File;
pub use winit::VirtualKeyCode as keyCode;
pub use winit::MouseButton;
use winit::ModifiersState;
fn add_to_text(pusher: Stext) {
unsafe {
match &TEXT_VEC {
None => {
TEXT_VEC = Some(vec![pusher]);
}
Some(vec1) => {
let mut vec2 = vec1.clone();
vec2.push(pusher);
TEXT_VEC = Some(vec2);
}
};
}
}
fn add_to_fill(pusher: Vertex) {
unsafe {
match &FILL_VERTECIES {
None => {
FILL_VERTECIES = Some(vec![pusher]);
}
Some(vec1) => {
let mut vec2 = vec1.clone();
vec2.push(pusher);
FILL_VERTECIES = Some(vec2);
}
};
}
}
fn add_to_stroke(pusher: Vertex) {
unsafe {
match &STROKE_VERTECIES {
None => {
STROKE_VERTECIES = Some(vec![pusher]);
}
Some(vec1) => {
let mut vec2 = vec1.clone();
vec2.push(pusher);
STROKE_VERTECIES = Some(vec2);
}
};
}
}
#[allow(non_snake_case)]
pub fn lockKeyEvent(){
unsafe{
CANVAS.key.keep_key = true;
}
}
#[allow(non_snake_case)]
pub fn mouseScrollX()->i64{
unsafe{
CANVAS.mouse_scroll.delta_x()
}
}
#[allow(non_snake_case)]
pub fn mouseScrollY()->i64{
unsafe{
CANVAS.mouse_scroll.delta_y()
}
}
#[allow(non_snake_case)]
pub fn mouseClick()->MouseButton{
unsafe{
match CANVAS.mouse.btn{
Some(btn)=> {return btn;},
None=> {return MouseButton::Other(99);}
}
}
}
#[allow(non_snake_case)]
pub fn mouseX()->u16{
unsafe{
CANVAS.cursor_pos.0
}
}
#[allow(non_snake_case)]
pub fn mouseY()->u16{
unsafe{
CANVAS.cursor_pos.1
}
}
pub fn size(width: u16, height: u16) {
unsafe {
CANVAS.size = (width, height);
}
}
#[allow(non_snake_case)]
pub fn keyPressed()->keyCode{
unsafe{
match CANVAS.key.keycode{
Some(key)=> {return key;},
None=> {return keyCode::Power;}
}
}
}
pub fn get_modifiers()->ModifiersState{
unsafe{
CANVAS.key.get_mod()
}
}
#[allow(non_snake_case)]
pub fn textSize(sz:u8) {
unsafe {
CANVAS.text_size = sz as f32;
}
}
pub fn show<F>(draw_fn: F)
where
F: FnMut() + 'static,
{
unsafe {
CANVAS.show(draw_fn);
}
}
pub fn rect(x: u16, y: u16, width: u16, height: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let t_l = map([x, y], scale);
let b_r = map([x + width, y + height], scale);
let t_r = map([x + width, y], scale);
let b_l = map([x, y + height], scale);
if CANVAS.fill {
let color = CANVAS.fill_color;
add_to_fill(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.stroke {
let color = CANVAS.color;
add_to_stroke(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn square(x: u16, y: u16, width: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let t_l = map([x, y], scale);
let b_r = map([x + width, y + width], scale);
let t_r = map([x + width, y], scale);
let b_l = map([x, y + width], scale);
if CANVAS.fill {
let color = CANVAS.fill_color;
add_to_fill(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.stroke {
let color = CANVAS.color;
add_to_stroke(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_r,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: b_l,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: t_l,
color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn line(x: u16, y: u16, x2: u16, y2: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let srt = map([x, y], scale);
let fin = map([x2, y2], scale);
let color = CANVAS.color;
add_to_stroke(Vertex {
position: srt,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: fin,
color,
tex_coords:[0f32,0f32],
});
}
}
pub fn triangle(x1: u16, y1: u16, x2: u16, y2: u16, x3: u16, y3: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let pt1 = map([x1, y1], scale);
let pt2 = map([x2, y2], scale);
let pt3 = map([x3, y3], scale);
if CANVAS.fill {
let color = CANVAS.fill_color;
add_to_fill(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.stroke {
let color = CANVAS.color;
add_to_stroke(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn quad(x1: u16, y1: u16, x2: u16, y2: u16, x3: u16, y3: u16, x4: u16, y4: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let pt1 = map([x1, y1], scale);
let pt2 = map([x2, y2], scale);
let pt3 = map([x3, y3], scale);
let pt4 = map([x4, y4], scale);
if CANVAS.fill {
let color = CANVAS.fill_color;
add_to_fill(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: pt4,
color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.stroke {
let color = CANVAS.color;
add_to_stroke(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt2,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt3,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt4,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt4,
color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: pt1,
color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn ellipse(x: u16, y: u16, a: u16, b: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
let mut pt_x = x as f32 + a as f32;
let mut pt_y = y as f32;
for an in (0..360).step_by(6) {
let ptx = x as f32 + ((an as f32 / 360.0) * 6.28).cos() * a as f32;
let pty = y as f32 + ((an as f32 / 360.0) * 6.28).sin() * b as f32;
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
pt_x = x as f32 + a as f32 + 0.5;
pt_y = y as f32 + 0.5;
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.fill {
let mut pt_x = x as f32 + a as f32;
let mut pt_y = y as f32;
for an in (0..360).step_by(6) {
let ptx = x as f32 + ((an as f32 / 360.0) * 6.28).cos() * a as f32;
let pty = y as f32 + ((an as f32 / 360.0) * 6.28).sin() * b as f32;
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([x as f32, y as f32], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
pt_x = x as f32 + a as f32 + 0.5;
pt_y = y as f32 + 0.5;
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([x as f32, y as f32], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn circle(x: u16, y: u16, rad: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
let mut pt_x = x as f32 + rad as f32;
let mut pt_y = y as f32;
for a in (0..360).step_by(6) {
let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
pt_x = x as f32 + rad as f32 + 0.5;
pt_y = y as f32 + 0.5;
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
}
if CANVAS.fill {
let mut pt_x = x as f32 + rad as f32;
let mut pt_y = y as f32;
for a in (0..360).step_by(6) {
let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([x as f32, y as f32], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
pt_x = x as f32 + rad as f32 + 0.5;
pt_y = y as f32 + 0.5;
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([x as f32, y as f32], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
}
}
}
pub fn point(x: u16, y: u16) {
unsafe {
let stro = CANVAS.stroke;
let fil = CANVAS.fill;
CANVAS.stroke = false;
CANVAS.fill = true;
circle(x, y, CANVAS.stroke_weight as u16);
CANVAS.stroke = stro;
CANVAS.fill = fil;
}
}
pub fn fill(color: Color) {
let r = color.get_r();
let g = color.get_g();
let b = color.get_b();
let a = color.get_a();
unsafe {
CANVAS.fill = true;
CANVAS.fill_color = mapping::map_colors([r, g, b, a]);
}
}
pub fn stroke(color: Color) {
let r = color.get_r();
let g = color.get_g();
let b = color.get_b();
let a = color.get_a();
unsafe {
CANVAS.stroke = true;
CANVAS.color = mapping::map_colors([r, g, b, a]);
}
}
pub fn background(color: Color) {
let r = color.get_r();
let g = color.get_g();
let b = color.get_b();
let a = color.get_a();
unsafe {
CANVAS.background_color = mapping::map_colors([r, g, b, a]);
}
}
#[allow(non_snake_case)]
pub fn strokeWeight(weight: u8) {
unsafe {
CANVAS.stroke_weight = weight;
}
}
#[allow(non_snake_case)]
pub fn noFill() {
unsafe {
CANVAS.fill = false;
}
}
#[allow(non_snake_case)]
pub fn noStroke() {
unsafe {
CANVAS.stroke = false;
}
}
pub fn arc(x: u16, y: u16, rad: u16, deg: u16) {
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
let mut pt_x = x as f32 + rad as f32;
let mut pt_y = y as f32;
for a in (0..deg + 6).step_by(6) {
let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
add_to_stroke(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
}
if CANVAS.fill {
let mut pt_x = x as f32 + rad as f32;
let mut pt_y = y as f32;
for a in (0..deg + 6).step_by(6) {
let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
add_to_fill(Vertex {
position: map_circ([pt_x, pt_y], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([ptx, pty], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
add_to_fill(Vertex {
position: map_circ([x as f32, y as f32], scale),
color: CANVAS.fill_color,
tex_coords:[0f32,0f32],
});
pt_x = ptx;
pt_y = pty;
}
}
}
}
#[allow(non_snake_case)]
pub fn bezierCurve(ptvec: Vec<[i64; 2]>) {
for i in 0..(ptvec.len() - 3) {
if (i + 1) % 4 == 0 || i == 0 {
bezierCurveVertex(
ptvec[i][0],
ptvec[i][1],
ptvec[i + 1][0],
ptvec[i + 1][1],
ptvec[i + 2][0],
ptvec[i + 2][1],
ptvec[i + 3][0],
ptvec[i + 3][1],
);
}
}
}
pub fn curve(ptvec: Vec<[i64; 2]>) {
for i in 0..(ptvec.len() - 3) {
bezierCurveVertex(
ptvec[i][0],
ptvec[i][1],
ptvec[i + 1][0],
ptvec[i + 1][1],
ptvec[i + 2][0],
ptvec[i + 2][1],
ptvec[i + 3][0],
ptvec[i + 3][1],
);
}
}
#[allow(non_snake_case)]
pub fn curveVertex(x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64, x4: i64, y4: i64) {
let c = catmull_rom_chain(x1, y1, x2, y2, x3, y3, x4, y4);
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
for pt in c.iter() {
add_to_stroke(Vertex {
position: mapf(*pt, scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
}
}
}
#[allow(non_snake_case)]
pub fn bezierCurveVertex(x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64, x4: i64, y4: i64) {
let c = bezier_points(x1, y1, x2, y2, x3, y3, x4, y4);
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let mut ptnxt = c[0];
for pt in c.iter() {
add_to_stroke(Vertex {
position: mapf(ptnxt, scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
add_to_stroke(Vertex {
position: mapf(*pt, scale),
color: CANVAS.color,
tex_coords:[0f32,0f32],
});
ptnxt = *pt;
}
}
}
pub fn text(x:u16,y:u16,text:&'static str){
unsafe{
add_to_text(Stext{
position: [x as f32,y as f32],
color: CANVAS.color,
text: text,
});
}
}
#[derive(Clone)]
pub struct Image{
pub image_data:Vec<u8>,
pub dimensions:Dimensions,
}
#[allow(non_snake_case)]
pub fn img(path:&str)->Image{
let decoder = png::Decoder::new(File::open(path).unwrap());
let (info, mut reader) = decoder.read_info().unwrap();
let mut image_data = Vec::new();
image_data.resize((info.width * info.height * 4) as usize, 0);
reader.next_frame(&mut image_data).unwrap();
let dimensions = Dimensions::Dim2d { width: info.width, height: info.height };
Image{image_data,dimensions}
}
impl Image{
pub fn display(self,x:u16,y:u16){
unsafe {
let scale = [CANVAS.size.0, CANVAS.size.1];
let _imsize = [self.dimensions.width() as u16,self.dimensions.height() as u16];
add_to_fill(Vertex {
position: map([x,y], scale),
color: CANVAS.color,
tex_coords: map([x,y], scale),
});
add_to_fill(Vertex {
position: map([x+(self.dimensions.width() as u16),y], scale),
color: CANVAS.color,
tex_coords: map([x+(self.dimensions.width() as u16),y], scale),
});
add_to_fill(Vertex {
position: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
color: CANVAS.color,
tex_coords: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
});
add_to_fill(Vertex {
position: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
color: CANVAS.color,
tex_coords: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
});
add_to_fill(Vertex {
position: map([x,y], scale),
color: CANVAS.color,
tex_coords: map([x,y], scale),
});
add_to_fill(Vertex {
position: map([x,y+(self.dimensions.height() as u16)], scale),
color: CANVAS.color,
tex_coords: map([x,(y+(self.dimensions.height() as u16))], scale),
});
TEXTURE = Some((self.image_data,self.dimensions));
}
}
}