├── .github
└── workflows
│ └── rust.yml
├── .gitignore
├── .gitlab-ci.yml
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── examples
├── button
│ ├── .main.rs.swo
│ ├── .main.rs.swp
│ └── main.rs
├── canvas_struct
│ └── main.rs
├── count1
│ └── main.rs
├── curve1
│ ├── .main.rs.swp
│ └── main.rs
├── gravity
│ └── main.rs
├── image
│ └── main.rs
├── key_event
│ └── main.rs
├── key_event_glob
│ └── main.rs
├── snake
│ └── main.rs
└── wave
│ └── main.rs
└── src
├── .math.rs.swp
├── .vector.rs.swp
├── canvas.rs
├── canvas_glob.rs
├── color.rs
├── compute.rs
├── elements.rs
├── fonts.rs
├── fonts
├── Apache License.txt
├── DejaVuSans.ttf
├── GreatVibes-Regular.otf
├── OpenSans-Bold.ttf
├── OpenSans-BoldItalic.ttf
├── OpenSans-ExtraBold.ttf
├── OpenSans-ExtraBoldItalic.ttf
├── OpenSans-Italic.ttf
├── OpenSans-Light.ttf
├── OpenSans-LightItalic.ttf
├── OpenSans-Regular.ttf
├── OpenSans-Semibold.ttf
├── OpenSans-SemiboldItalic.ttf
├── Roboto-Black.ttf
├── Roboto-BlackItalic.ttf
├── Roboto-Bold.ttf
├── Roboto-BoldItalic.ttf
├── Roboto-Italic.ttf
├── Roboto-Light.ttf
├── Roboto-LightItalic.ttf
├── Roboto-Medium.ttf
├── Roboto-MediumItalic.ttf
├── Roboto-Regular.ttf
├── Roboto-Thin.ttf
├── Roboto-ThinItalic.ttf
├── RobotoCondensed-Bold.ttf
├── RobotoCondensed-BoldItalic.ttf
├── RobotoCondensed-Italic.ttf
├── RobotoCondensed-Light.ttf
├── RobotoCondensed-LightItalic.ttf
├── RobotoCondensed-Regular.ttf
├── matches.txt
├── names.txt
└── scrpt1.py
├── lib.rs
├── mapping.rs
├── math.rs
├── page.rs
├── setup.rs
├── shaders.rs
├── text.rs
├── vector.rs
└── vertex.rs
/.github/workflows/rust.yml:
--------------------------------------------------------------------------------
1 | name: Rust
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v1
12 | - name: Build
13 | run: cargo build --verbose
14 | - name: Run tests
15 | run: cargo test --verbose
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | **/*.rs.bk
3 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: 'rust:latest'
2 |
3 | stages:
4 | - test
5 | - doc
6 | - build
7 |
8 | variables:
9 | CARGO_HOME: $CI_PROJECT_DIR/cargo
10 | APT_CACHE_DIR: $CI_PROJECT_DIR/apt
11 |
12 | before_script:
13 | - apt-get update -yq
14 | - apt-get install --yes cmake
15 | #- apt install libvulkan1 mesa-vulkan-drivers vulkan-utils
16 | #- apt-get install -o dir::cache::archives="$APT_CACHE_DIR" -y {{ DEPENDENCIES }}
17 |
18 | test:
19 | stage: test
20 | script:
21 | - rustc --version
22 | - cargo --version
23 | #- cargo test
24 | - cargo build --release
25 |
26 | pages:
27 | stage: doc
28 | script:
29 | - cargo doc --no-deps
30 | - mv target/doc public
31 | - echo '' > public/index.html
32 | artifacts:
33 | paths:
34 | - public
35 | only:
36 | - master
37 |
38 | cache:
39 | paths:
40 | - apt/
41 | - cargo/
42 | - target/
43 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "metropolis"
3 | version = "0.9.1"
4 | authors = ["guy "]
5 | edition = "2018"
6 | description = "A high level easy to use graphics renderer"
7 | repository = "http://github.com/GuyL99/metropolis"
8 | readme = "README.md"
9 | categories = ["games","graphics","gui"]
10 | keywords = ["cli", "api","gui","gamedev","graphics"]
11 | license = "MIT"
12 | documentation = "https://docs.rs/metropolis/0.9.1/metropolis"
13 | gitlab = { repository = "https://gitlab.com/GuyL99/graphics-renderer", branch = "master" }
14 |
15 |
16 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
17 |
18 | [dependencies]
19 | vulkano = "0.16.0"
20 | vulkano-shaders = "0.16.0"
21 | vulkano-win = "0.16.0"
22 | winit = "0.19.5"
23 | rusttype = { version = "0.7", features = ["gpu_cache"] }
24 | png = "0.15"
25 |
26 | [profile.dev]
27 | opt-level = 0
28 |
29 | [profile.release]
30 | opt-level = 3
31 |
32 |
33 | [lib]
34 | name = "metropolis"
35 |
36 | path = "src/lib.rs"
37 |
38 | doctest = true
39 |
40 | doc = true
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Guy Levinger
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Metropolis
2 |  [](https://opensource.org/licenses/MIT) 
3 | ## What is it and what is it for?
4 |
5 | Metropolis is an easy to use high level graphics renderer written in rust, utilizing [vulkano](https://crates.io/crates/vulkano) and [winit](https://crates.io/crates/winit),
6 | I still have some work to do on it and I am currently still developing it and would love community input.
7 | Later I hope to develop a game engine using it but first I'll finish the renderer.
8 | ## How to install it?
9 |
10 | ### you can use cargo(the preferable and much easier and safe way):
11 | ```console
12 | :~$ cargo install metropolis
13 | ```
14 | ### then install the vulkan required dependencies:
15 | ### if you have linux debian/ubuntu:
16 | ```console
17 | :~$ apt install libvulkan1 mesa-vulkan-drivers vulkan-utils
18 | ```
19 | ### if you have fedora:
20 | ```console
21 | # dnf install vulkan vulkan-info
22 | ```
23 | ### if you have arch linux:
24 | ```console
25 | # pacman -S vulkan-radeon lib32-vulkan-radeon
26 | ```
27 | ### if you have mac:
28 | ```console
29 | :~$ xcode-select --install
30 | :~$ brew install cmake
31 | ```
32 | ### for windows just install ninja.
33 |
34 | ## Usage
35 |
36 | Add the following to your Cargo.toml:
37 | ```rust
38 | [dependencies]
39 | metropolis = "0.9.1"
40 | ```
41 | First use import the crate:
42 | ```rust
43 | extern crate metro;
44 | use metropolis::*;
45 | use metropolis::color::*;
46 | //if you want some math functions use math as well
47 | use metropolis::math::*;
48 | ```
49 |
50 | Then you use the funcion size that creates a canvas(I wwould suggest to save height and width as variables so you can use them later
51 | ```rust
52 | fn main(){
53 | let height = 600;
54 | let width = 800;
55 | size(width,height);
56 | ```
57 | Next comes the setup(here I declare the varibles I will be using insode the looped function):
58 | ```rust
59 | let mut spd = 0;
60 | let mut acc = 1;
61 | let mut posy = 0;
62 | background(grayscale(220));
63 | ```
64 | Next comes the draw function, this function gets looped over so what's in it should be decided accordingly
65 | ```rust
66 | let draw =move || {
67 | spd+=1;
68 | if posy+50< height{
69 | posy+=spd;
70 | }
71 | fill(rgb(255,0.1.3));
72 | ellipse(400,posy,200,100);
73 | };
74 | ```
75 | Finally use the show() function to run the whole thing:
76 | ```rust
77 | show(draw);
78 | }
79 | ```
80 | If you noticed - this program displays gravity working on an ellipse
81 |
82 | ## release notes:
83 | ### a patch version to fix the text module laggines:
84 | now the text module functions ok and on par with the rest of the crates FPS, the text can be between size 1 and 128.
85 | ### former versions release notes:
86 | #### 0.8.1
87 | I finally fixed the image module and now it could be used to place a png image wherever you want in the page in the same size as it was(the resize is on you...)
88 | #### 0.8.0
89 | I improved the text fps by a bit, added a Vector struct that allowes for some linear algebra related calculations, added from trait,display trait, and debug trait to color. changed image functions: now only takes png images, and displays the whole image, I still have problems with it that I'm fixing.changed the curve to work with bezier by default(beacuse of problems with te catmull rom chain)
90 | #### 0.7.0
91 | added the possiblity to use keyboard events see the examples:key_event and key_event_glob. I added mouse position getters and mouse scroll delta getters.
92 | #### 0.6.0
93 | you can now use a public mutithreading safe canvas struct, the matching example is called canvas_struct
94 | #### 0.5.1
95 | fixed a bug that caused the text vertecies to not be cleared at he end of each iteration of the draw function
96 | #### 0.5.0
97 | some of the math functions were deprecated due to community feedback:sin,cos,tan,abs
98 | I added an image module that allows you to load an image and display it(see the example for more details)
99 | #### 0.4.1
100 | fixed the text module slowdown for the non-text using canvases
101 | added FPS unsafe static
102 | added WIDTH/HEIGHT unsafe statics
103 | #### 0.4.0
104 | 1 - added a text module - uses text() and textSize()
105 | 2 - added abs() and absf() functions to math
106 | #### 0.3.3
107 | 1 - changed map to recieve generic variable
108 | 2 - added quad and square functions
109 | #### 0.3.2
110 | ported to vulkano 0.16, fixed the problem with the unclosing window!
111 | #### 0.3.1:
112 | there is a bezier curve, 2 function - one for vertex(4 x's and y's) and one for a chain(should have amout of values of 4+3*i such as 4,7,10,13...)
113 | #### 0.3.0:
114 | 1 - there is a mapping function called map
115 | 2 - there is a factorial function called factorial
116 | 3 - there is a function called linspace that create evenly spaced floats between two numbers
117 | 4 - there are curves - using the catmull rom chain algorithm there is are functions to create a curves: curve, curveVertex, catmull_rom_chain
118 |
119 | ### If you want to checkout the crate further that you should take a look in the [examples](https://github.com/GuyL99/metropolis/tree/master/examples) folder.
120 | ## Currently being developed:
121 | 1)dynamic line width.
122 | 2)page elements and multicanvas module
123 | 3)making the static mut into a lazy_static(in development).
124 | 4)3D.
125 | 5)HTML type file parsing into elements.
126 | 6)anithyng else from community feedback!
127 |
128 | # License
129 | This crate is primarily distributed under the terms of the MIT license
130 | See [LICENSE-MIT](https://github.com/GuyL99/metropolis/blob/master/LICENSE) for details.
131 |
--------------------------------------------------------------------------------
/examples/button/.main.rs.swo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/examples/button/.main.rs.swo
--------------------------------------------------------------------------------
/examples/button/.main.rs.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/examples/button/.main.rs.swp
--------------------------------------------------------------------------------
/examples/button/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::canvas::*;
2 | use metropolis::color::*;
3 | use metropolis::elements::*;
4 | use metropolis::fonts::*;
5 | fn main(){
6 | let mut canv = Canvas::new(800,600);
7 | canv.background(Color::from(20));
8 | let mut btn1 = button(610,410,"btn1");//.style(Styles::RoundEdges);
9 | let mut clicked = false;
10 | let mut hovered = false;
11 | let draw = move |mut canvas:Canvas|->Canvas{
12 | canvas.font(Fonts::RobotoBlackItalic);
13 | canvas.text_color(rgb(255,0,0));
14 | //canvas.font(Fonts::DejaVuSans);
15 | if btn1.onHover(&canvas){
16 | if !clicked{
17 | btn1.color(rgb(255,100,00));
18 | }else{
19 | hovered = true;
20 | btn1.color(rgba(255,0,100,127));
21 | }
22 | }else{
23 | if btn1.onClick(&canvas){
24 | clicked = true;
25 | btn1.color(rgb(255,0,100));
26 | }else if !clicked{
27 | btn1.color(grayscale(255));
28 | }
29 | }
30 | if btn1.get_color()==rgba(255,0,100,127)&&!hovered{
31 | btn1.color(rgb(255,0,100));
32 | }
33 | //println!("{}",btn1.get_color());
34 | canvas.attach(btn1);
35 | //println!("{:?}",btn1.get_size());
36 | hovered = false;
37 | //println!("{:?}",canvas.fps);
38 | canvas
39 | };
40 | canv.show(draw);
41 | }
42 |
--------------------------------------------------------------------------------
/examples/canvas_struct/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::vector::*;
3 | use metropolis::canvas::Canvas;
4 | fn main(){
5 | let height = 600;
6 | let width = 800;
7 | //size(width, height);
8 | let mut canv:Canvas= Canvas::new(width,height);
9 | let mut vec1 = Vector{vec:vec![1,2,3,4,6,8,9,10]};
10 | vec1+=1;
11 | println!("{:?}",vec1);
12 | canv.background(grayscale(100));
13 | let draw = |mut canvas:Canvas|->Canvas {
14 | let curve_vec: Vec<[i64; 2]> = vec![
15 | [0, 400],
16 | [30, 370],
17 | [50, 300],
18 | [75, 257],
19 | [80, 240],
20 | [150, 150],
21 | [250, 050],
22 | ];
23 | canvas.bezierCurve(curve_vec);
24 | canvas
25 | };
26 | //canv = draw();
27 | canv.show(draw);
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/examples/count1/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::*;
3 | fn main() {
4 | size(800,600);
5 | background(grayscale(100));
6 | let mut count = 0;
7 | let mut frames = 0;
8 | let mut str_from_count = "0";
9 | let mut state =1;
10 | textSize(45);
11 | let draw = move||{
12 | unsafe{
13 | println!("{}",FPS);
14 | }
15 | frames += 1;
16 |
17 | match count{
18 | 0=>{str_from_count = "00";},
19 | 1=>{str_from_count = "10";},
20 | 2=>{str_from_count = "02";},
21 | 3=>{str_from_count = "3";},
22 | 4=>{str_from_count = "4";},
23 | 5=>{str_from_count = "5";},
24 | 6=>{str_from_count = "6";},
25 | 7=>{str_from_count = "7";},
26 | 8=>{str_from_count = "8";},
27 | 9=>{str_from_count = "9";},
28 | _=>{},
29 | }
30 | text(300,300,str_from_count);
31 | if frames % 15 == 0{
32 | count += state;
33 | }
34 | if count == 9||count==0 {
35 | state *= -1
36 | }
37 | };
38 | show(draw);
39 | }
40 |
--------------------------------------------------------------------------------
/examples/curve1/.main.rs.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/examples/curve1/.main.rs.swp
--------------------------------------------------------------------------------
/examples/curve1/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::*;
3 | use metropolis::math::*;
4 | fn main() {
5 | let height = 600;
6 | let width = 800;
7 | size(width, height);
8 | background(grayscale(100));
9 | strokeWeight(8);
10 | let draw = move || {
11 | /*let curve_vec: Vec<[i64; 2]> = vec![
12 | [0, 400],
13 | [30, 370],
14 | [50, 300],
15 | [75, 257],
16 | [80, 240],
17 | [150, 150],
18 | [250, 050],
19 | ];*/
20 | //let curve_vec:Vec<[i64;2]> = vec![[400,0],[370,4],[300,50],[257,75],[80,240],[150,150]];
21 | //bezierCurve(curve_vec);
22 | //let arr1 = bezier_points(1,5,2,4,3,4,4,1);
23 | let arr1 = catmull_rom_chain(1,5,2,5,3,5,4,4);
24 | for pt in arr1.iter(){
25 | println!("val for x {} is: {}",pt[0],pt[1]);
26 | }
27 | };
28 | show(draw);
29 | }
30 |
--------------------------------------------------------------------------------
/examples/gravity/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::*;
3 | fn main() {
4 | let height = 900;
5 | let width = 1200;
6 | size(width, height);
7 | let mut spd = 0;
8 | let mut posy = 0;
9 | background(grayscale(100));
10 | let draw = move || {
11 | spd += 1;
12 | if posy + 50 < height {
13 | posy += spd;
14 | }
15 | unsafe{
16 | println!("{}",FPS);
17 | }
18 | fill(rgb(255, 0, 100));
19 | //fill(0,0,00);
20 | //circle(400,posy,50);
21 | ellipse(400, posy, 200, 100);
22 | //arc(500,500,100,180);
23 | //line(800,800,posy,posy);
24 | };
25 | show(draw);
26 | }
27 |
--------------------------------------------------------------------------------
/examples/image/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::canvas::*;
3 | fn main() {
4 | let mut canv = Canvas::new(800,600);
5 | //canv.background(grayscale(100));
6 | let mut posy = 0;
7 | let mut cnt = 0;
8 | let mut r = 100;
9 | let mut g = 100;
10 | let mut b = 100;
11 | //let image = img("/home/guyl/Desktop/saitama.png");
12 | let image = img("/home/guyl/Desktop/rust.png");//.dimensions(500,500);
13 | let draw = move |mut canvas:Canvas|->Canvas{
14 | canvas.display(image.clone(),canvas.mouseX(),canvas.mouseY());
15 | //canvas.textSize(128);
16 | //canvas.text(100,100,"ttsstttadsas");
17 | //canvas.text(500,500,"tttttadsas");
18 | /*println!("{}",Color::from((r,g,b)));
19 | canvas.background(rgb(r,g,b));
20 | if cnt%50 == 0{
21 | posy+=100;
22 | }
23 | cnt+=1;
24 | if r == 255{
25 | r=0;
26 | g=0;
27 | b=0;
28 | }
29 | if g == 255{
30 | r+=1;
31 | g=0;
32 | b=0;
33 | }
34 | if b == 255{
35 | g+=1;
36 | b=0;
37 | }
38 | b+=1;
39 | canvas.fill(Color::from((0,0,0)));
40 | canvas.rect(0,0,20,20);
41 | canvas.fill(Color::from((100,160,200)));
42 | canvas.rect(30,30,20,20);*/
43 | println!("{}",canvas.fps);
44 | canvas
45 | };
46 | canv.show(draw);
47 | }
48 |
--------------------------------------------------------------------------------
/examples/key_event/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::canvas::*;
2 | use metropolis::color::*;
3 | fn main(){
4 | let mut canv = Canvas::new(800,600);
5 | canv.background(grayscale(100));
6 | canv.textSize(45);
7 | let draw = |mut canvas:Canvas|->Canvas{
8 | let mut str_from_count = "0";
9 | match canvas.keyPressed(){
10 | keyCode::Key0=>{str_from_count = "0";},
11 | keyCode::Key1=>{str_from_count = "1";},
12 | keyCode::Key2=>{str_from_count = "2";},
13 | keyCode::Key3=>{str_from_count = "3";},
14 | keyCode::Key4=>{str_from_count = "4";},
15 | keyCode::Key5=>{str_from_count = "5";},
16 | keyCode::Key6=>{str_from_count = "6";},
17 | keyCode::Key7=>{str_from_count = "7";},
18 | keyCode::Key8=>{str_from_count = "8";},
19 | keyCode::Key9=>{str_from_count = "9";},
20 | _=>{},
21 |
22 | }
23 | canvas.lockKeyEvent();
24 | //println!("{:?}",canvas.mouseX());
25 | canvas.text(300,300,str_from_count);
26 | canvas
27 | };
28 | canv.show(draw);
29 | }
30 |
--------------------------------------------------------------------------------
/examples/key_event_glob/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::*;
3 | fn main() {
4 | size(800,600);
5 | background(grayscale(100));
6 | textSize(45);
7 | let draw = move||{
8 | let mut str_from_count = "0";
9 | match keyPressed(){
10 | keyCode::Key0=>{str_from_count = "0";},
11 | keyCode::Key1=>{str_from_count = "1";},
12 | keyCode::Key2=>{str_from_count = "2";},
13 | keyCode::Key3=>{str_from_count = "3";},
14 | keyCode::Key4=>{str_from_count = "4";},
15 | keyCode::Key5=>{str_from_count = "5";},
16 | keyCode::Key6=>{str_from_count = "6";},
17 | keyCode::Key7=>{str_from_count = "7";},
18 | keyCode::Key8=>{str_from_count = "8";},
19 | keyCode::Key9=>{str_from_count = "9";},
20 | _=>{},
21 | }
22 | lockKeyEvent();
23 | text(300,300,str_from_count);
24 | };
25 | show(draw);
26 | }
27 |
--------------------------------------------------------------------------------
/examples/snake/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::canvas::*;
2 | use metropolis::color::*;
3 | fn main(){
4 | let mut canv = Canvas::new(800,600);
5 | canv.background(grayscale(100));
6 | let mut posx = 0;
7 | let mut posy = 0;
8 | let draw = move |mut canvas:Canvas|->Canvas{
9 | match canvas.keyPressed(){
10 | keyCode::W=>{posy-=10;},
11 | keyCode::A=>{posx-=10;},
12 | keyCode::S=>{posy+=10;},
13 | keyCode::D=>{posx+=10;},
14 | _=>{},
15 | }
16 | if canvas.mouseClick() == MouseButton::Left{
17 | canvas.fill(rgb(255,0,100));
18 | canvas.ellipse(200,200,100,150);
19 | }
20 | //println!("{:?}",canvas.mouseX());
21 | println!("{:?}",canvas.fps);
22 | canvas.fill(rgb(0,255,100));
23 | canvas.rect(posx,posy,20,20);
24 | canvas
25 | };
26 | canv.show(draw);
27 | }
28 |
--------------------------------------------------------------------------------
/examples/wave/main.rs:
--------------------------------------------------------------------------------
1 | use metropolis::color::*;
2 | use metropolis::math::*;
3 | use metropolis::*;
4 | fn main() {
5 | size(800,600);
6 | background(grayscale(100));
7 | let mut count = 0;
8 | let draw = move || {
9 | for i in 0..80{
10 | for j in 0..60{
11 | fill(grayscale(255));
12 | rect(i as u16*10u16,j as u16*10u16,10,10);
13 | }
14 | }
15 | count+=1;
16 | if count ==100{
17 | count =0;
18 | }
19 | };
20 | show(draw);
21 | }
22 |
--------------------------------------------------------------------------------
/src/.math.rs.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/.math.rs.swp
--------------------------------------------------------------------------------
/src/.vector.rs.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/.vector.rs.swp
--------------------------------------------------------------------------------
/src/canvas_glob.rs:
--------------------------------------------------------------------------------
1 | use crate::setup::*;
2 | use crate::vertex::*;
3 | use crate::fonts::*;
4 | use std::sync::Arc;
5 | use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
6 | use vulkano::command_buffer::{AutoCommandBufferBuilder,AutoCommandBuffer};
7 | use vulkano::swapchain;
8 | use vulkano::swapchain::{AcquireError, SwapchainCreationError};
9 | use vulkano::sync;
10 | use vulkano::sync::{FlushError, GpuFuture};
11 | use winit::{ElementState,KeyboardInput,Event, WindowEvent,VirtualKeyCode,ModifiersState};
12 | use winit::dpi::LogicalPosition;
13 | use winit::MouseScrollDelta;
14 | use crate::text::{DrawText, DrawTextTrait};
15 | use crate::{FPS,HEIGHT,WIDTH};
16 | use std::time::{Duration, Instant};
17 | use vulkano::image::{ImmutableImage, Dimensions};
18 | use vulkano::sampler::{Sampler, SamplerAddressMode, Filter, MipmapMode};
19 | use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
20 | use winit::MouseButton;
21 | use vulkano::format::Format;
22 | #[derive(Copy,Clone,PartialEq)]
23 | pub struct Key{
24 | pub keycode:Option,
25 | pub moder:ModifiersState,
26 | pub keep_key: bool,
27 | }
28 | impl Key{
29 | pub fn get_mod(self)->ModifiersState{
30 | self.moder
31 | }
32 | }
33 | #[derive(Copy,Clone,PartialEq)]
34 | pub struct MouseScroll{
35 | pub delta:(i64,i64),
36 | pub moder:ModifiersState,
37 | }
38 | impl MouseScroll{
39 | pub fn delta_x(self)->i64{
40 | self.delta.0
41 | }
42 | pub fn delta_y(self)->i64{
43 | self.delta.1//.PixelDelta.y as i64
44 | }
45 | }
46 | #[derive(Copy,Clone,PartialEq)]
47 | pub struct Mouse{
48 | pub btn:Option,
49 | pub moder:ModifiersState,
50 | }
51 | #[derive(Copy, Clone, PartialEq)]
52 | pub struct CanvasGlob {
53 | pub size: (u16, u16),
54 | pub stroke: bool,
55 | pub color: [f32; 4],
56 | pub stroke_weight: u8,
57 | pub fill: bool,
58 | pub fill_color: [f32; 4],
59 | pub background_color: [f32; 4],
60 | pub fps: f32,
61 | pub resizeable: bool,
62 | pub text_size: f32,
63 | pub key:Key,
64 | pub cursor_pos:(u16,u16),
65 | pub mouse:Mouse,
66 | pub mouse_scroll:MouseScroll,
67 | pub font:Fonts,
68 | }
69 | impl CanvasGlob{
70 | pub fn show(&mut self, mut draw_fn:F)
71 | where F :FnMut()+ 'static,
72 | {
73 | let set;
74 | let mut previous_frame_end;
75 | let (mut env, mut events_loop) = init(self.size.0, self.size.1);
76 | unsafe{
77 | draw_fn();
78 | match &TEXTURE{
79 | Some((vec1,dim1))=>{
80 | let vec_tex = vec1.to_vec();
81 | let dimensions = *dim1;
82 | let (texture, tex_future) = {
83 | ImmutableImage::from_iter(
84 | vec_tex.iter().cloned(),
85 | dimensions,
86 | Format::R8G8B8A8Srgb,
87 | env.queue.clone()
88 | ).unwrap()
89 | };
90 | let sampler = Sampler::new(env.device.clone(), Filter::Linear, Filter::Linear,
91 | MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
92 | SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
93 | set = Some(Arc::new(PersistentDescriptorSet::start(env.tex_pipeline.clone(),0)
94 | .add_sampled_image(texture.clone(), sampler.clone()).unwrap()
95 | .build().unwrap()));
96 | previous_frame_end = Box::new(tex_future) as Box;
97 | },
98 | None =>{
99 | set =None;
100 | previous_frame_end =Box::new(env.previous_frame_end.unwrap());
101 | }
102 | }
103 | }
104 | let mut text = DrawText::new(env.device.clone(), env.queue.clone(), env.swapchain.clone(), &env.images,self.font);
105 | let mut counter1 = 0;
106 | let start = Instant::now();
107 | let mut end;
108 | let mut recreate_swapchain = env.recreate_swapchain;
109 |
110 | loop {
111 | let mut done = false;
112 | previous_frame_end.cleanup_finished();
113 | events_loop.poll_events(|ev| match ev {
114 | Event::WindowEvent {
115 | event: WindowEvent::CloseRequested,
116 | ..
117 | } => done = true,
118 | Event::WindowEvent {
119 | event: WindowEvent::Resized(_),
120 | ..
121 | } => recreate_swapchain = true,
122 | Event::WindowEvent{event,..}=>
123 | match event{
124 | WindowEvent::KeyboardInput{
125 | input:KeyboardInput{
126 | state: ElementState::Pressed,
127 | virtual_keycode: Some(key),
128 | modifiers,
129 | ..
130 | },
131 | ..
132 | } => {
133 | if key == VirtualKeyCode::W && modifiers.ctrl{
134 | done = true;
135 | }
136 | self.key = Key{keycode:Some(key),moder:modifiers,keep_key:false};
137 | },
138 | WindowEvent::CursorMoved{
139 | position:LogicalPosition{x:posx,y:posy},
140 | ..
141 | }=>{self.cursor_pos = (posx as u16,posy as u16);},
142 | WindowEvent::MouseInput{
143 | state: ElementState::Pressed,
144 | button: button1,
145 | modifiers,
146 | ..
147 | } => {
148 | self.mouse = Mouse{btn:Some(button1),moder:modifiers};
149 | },
150 | WindowEvent::MouseWheel{
151 | delta: MouseScrollDelta::PixelDelta(pos),
152 | modifiers,
153 | ..
154 | } => {
155 | self.mouse_scroll = MouseScroll{delta:(pos.x as i64,pos.y as i64),moder:modifiers};
156 | },
157 | _=>{},
158 | }
159 | _ => (),
160 | });
161 | if done {
162 | return;
163 | }
164 | unsafe {
165 | env.dynamic_state.line_width = Some(CANVAS.stroke_weight as f32);
166 | match &STROKE_VERTECIES {
167 | Some(vec1) => STROKE_VERTECIES = Some(vec1.to_vec()),
168 | None => {
169 | let vec2 = vec![];
170 | STROKE_VERTECIES = Some(vec2);
171 | }
172 | };
173 | match &FILL_VERTECIES {
174 | Some(vec1) => FILL_VERTECIES = Some(vec1.to_vec()),
175 | None => {
176 | let vec2 = vec![];
177 | FILL_VERTECIES = Some(vec2);
178 | }
179 | };
180 | let stroke_vertex_buffer = CpuAccessibleBuffer::from_iter(
181 | env.device.clone(),
182 | BufferUsage::all(),
183 | STROKE_VERTECIES.clone().unwrap().iter().cloned(),
184 | )
185 | .unwrap();
186 | let fill_vertex_buffer = CpuAccessibleBuffer::from_iter(
187 | env.device.clone(),
188 | BufferUsage::all(),
189 | FILL_VERTECIES.clone().unwrap().iter().cloned(),
190 | )
191 | .unwrap();
192 | let window = env.surface.window();
193 | if recreate_swapchain {
194 | let dimensions = {
195 | let dimensions: (u32, u32) = window
196 | .get_inner_size()
197 | .unwrap()
198 | .to_physical(window.get_hidpi_factor())
199 | .into();
200 | [dimensions.0, dimensions.1]
201 | };
202 | let (new_swapchain, new_images) =
203 | match env.swapchain.recreate_with_dimension(dimensions) {
204 | Ok(r) => r,
205 | Err(SwapchainCreationError::UnsupportedDimensions) => continue,
206 | Err(err) => panic!("{:?}", err),
207 | };
208 | env.swapchain = new_swapchain;
209 | env.framebuffers = window_size_dependent_setup(
210 | &new_images,
211 | env.render_pass.clone(),
212 | &mut env.dynamic_state,
213 | );
214 | text = DrawText::new(env.device.clone(), env.queue.clone(), env.swapchain.clone(), &new_images,self.font);
215 | recreate_swapchain = false;
216 | }
217 | let (image_num, acquire_future) =
218 | match swapchain::acquire_next_image(env.swapchain.clone(), None) {
219 | Ok(r) => r,
220 | Err(AcquireError::OutOfDate) => {
221 | recreate_swapchain = true;
222 | continue;
223 | }
224 | Err(err) => panic!("{:?}", err),
225 | };
226 | let clear_values = vec![self.background_color.into()];
227 | let command_buffer:AutoCommandBuffer;
228 | match &TEXT_VEC {
229 | Some(vec1) => {if vec1.len()>0{
230 | for txt in vec1{
231 | text.queue_text(txt.position[0],txt.position[0], CANVAS.text_size, txt.color,txt.text);
232 | }
233 | match set.clone(){
234 | Some(set)=>{
235 | command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(
236 | env.device.clone(),
237 | env.queue.family(),
238 | )
239 | .unwrap()
240 | .begin_render_pass(env.framebuffers[image_num].clone(), false, clear_values)
241 | .unwrap()
242 | .draw(
243 | env.tex_pipeline.clone(),
244 | &env.dynamic_state,
245 | vec![fill_vertex_buffer.clone()],
246 | set.clone(),
247 | (),
248 | )
249 | .unwrap()
250 | .draw(
251 | env.stroke_pipeline.clone(),
252 | &env.dynamic_state,
253 | vec![stroke_vertex_buffer.clone()],
254 | (),
255 | (),
256 | )
257 | .unwrap()
258 | .end_render_pass()
259 | .unwrap()
260 | .draw_text(&mut text, image_num)
261 | .build()
262 | .unwrap();
263 | },
264 | None=>{
265 | command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(
266 | env.device.clone(),
267 | env.queue.family(),
268 | )
269 | .unwrap()
270 | .begin_render_pass(env.framebuffers[image_num].clone(), false, clear_values)
271 | .unwrap()
272 | .draw(
273 | env.fill_pipeline.clone(),
274 | &env.dynamic_state,
275 | vec![fill_vertex_buffer.clone()],
276 | (),
277 | (),
278 | )
279 | .unwrap()
280 | .draw(
281 | env.stroke_pipeline.clone(),
282 | &env.dynamic_state,
283 | vec![stroke_vertex_buffer.clone()],
284 | (),
285 | (),
286 | )
287 | .unwrap()
288 | .end_render_pass()
289 | .unwrap()
290 | .draw_text(&mut text, image_num)
291 | .build()
292 | .unwrap();
293 | }
294 | }
295 | }else{
296 | match set.clone(){
297 | Some(set)=>{
298 | command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(
299 | env.device.clone(),
300 | env.queue.family(),
301 | )
302 | .unwrap()
303 | .begin_render_pass(env.framebuffers[image_num].clone(), false, clear_values)
304 | .unwrap()
305 | .draw(
306 | env.tex_pipeline.clone(),
307 | &env.dynamic_state,
308 | vec![fill_vertex_buffer.clone()],
309 | set.clone(),
310 | (),
311 | )
312 | .unwrap()
313 | .draw(
314 | env.stroke_pipeline.clone(),
315 | &env.dynamic_state,
316 | vec![stroke_vertex_buffer.clone()],
317 | (),
318 | (),
319 | )
320 | .unwrap()
321 | .end_render_pass()
322 | .unwrap()
323 | .build()
324 | .unwrap();
325 | },
326 |
327 | None =>{
328 | command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(
329 | env.device.clone(),
330 | env.queue.family(),
331 | )
332 | .unwrap()
333 | .begin_render_pass(env.framebuffers[image_num].clone(), false, clear_values)
334 | .unwrap()
335 | .draw(
336 | env.fill_pipeline.clone(),
337 | &env.dynamic_state,
338 | vec![fill_vertex_buffer.clone()],
339 | (),
340 | (),
341 | )
342 | .unwrap()
343 | .draw(
344 | env.stroke_pipeline.clone(),
345 | &env.dynamic_state,
346 | vec![stroke_vertex_buffer.clone()],
347 | (),
348 | (),
349 | )
350 | .unwrap()
351 | .end_render_pass()
352 | .unwrap()
353 | .build()
354 | .unwrap();
355 | }
356 | }
357 | }
358 | },
359 | None => {
360 | let vec2 = vec![];
361 | TEXT_VEC = Some(vec2);
362 | command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(
363 | env.device.clone(),
364 | env.queue.family(),
365 | )
366 | .unwrap()
367 | .build()
368 | .unwrap();
369 | }
370 | };
371 | //let prev =/* env.*/ (&mut *previous_frame_end).take();
372 | let future = previous_frame_end
373 | .join(acquire_future)
374 | .then_execute(env.queue.clone(), command_buffer)
375 | .unwrap()
376 | .then_swapchain_present(env.queue.clone(), env.swapchain.clone(), image_num)
377 | .then_signal_fence_and_flush();
378 | match future {
379 | Ok(future) => {
380 | future.wait(None).unwrap();
381 | previous_frame_end = Box::new(future) as Box<_>;
382 | }
383 | Err(FlushError::OutOfDate) => {
384 | recreate_swapchain = true;
385 | previous_frame_end =
386 | Box::new(sync::now(env.device.clone())) as Box<_>;
387 | }
388 | Err(e) => {
389 | println!("{:?}", e);
390 | previous_frame_end =
391 | Box::new(sync::now(env.device.clone())) as Box<_>;
392 | }
393 | }
394 | end = Instant::now();
395 | if (end-start)>Duration::new(1,0){
396 | CANVAS.fps = counter1 as f32/(end-start).as_secs() as f32;
397 | FPS = CANVAS.fps;
398 | }
399 | HEIGHT = CANVAS.size.1;
400 | WIDTH = CANVAS.size.0;
401 | }
402 | zero_out();
403 | draw_fn();
404 | if self.key.keep_key == false{
405 | self.key.keycode = Some(VirtualKeyCode::Power);
406 | }
407 | self.mouse.btn = Some(MouseButton::Other(99));
408 | counter1+=1;
409 | }
410 | //});
411 | }
412 | }
413 | pub fn zero_out() {
414 | unsafe {
415 | match &STROKE_VERTECIES {
416 | None => {}
417 | Some(_vec1) => {
418 | let vec2 = vec![];
419 | STROKE_VERTECIES = Some(vec2);
420 | }
421 | };
422 | match &FILL_VERTECIES {
423 | None => {}
424 | Some(_vec1) => {
425 | let vec2 = vec![];
426 | FILL_VERTECIES = Some(vec2);
427 | }
428 | };
429 | match &TEXT_VEC {
430 | None => {}
431 | Some(_vec1) => {
432 | let vec2 = vec![];
433 | TEXT_VEC = Some(vec2);
434 | }
435 | };
436 | }
437 | }
438 | pub static mut CANVAS: CanvasGlob = CanvasGlob {
439 | size: (0, 0),
440 | stroke: true,
441 | color: [0.0, 0.0, 0.0, 1.0],
442 | stroke_weight: 8,
443 | fill: false,
444 | fill_color: [1.0, 1.0, 1.0, 1.0],
445 | background_color: [1.0, 1.0, 1.0, 1.0],
446 | fps: 30.0,
447 | resizeable: false,
448 | text_size: 18.0,
449 | key:Key{keycode:None,moder:ModifiersState{shift:false,ctrl:false,alt:false,logo:false},keep_key:false},
450 | cursor_pos:(0,0),
451 | mouse:Mouse{btn:None,moder:ModifiersState{shift:false,ctrl:false,alt:false,logo:false},},
452 | mouse_scroll:MouseScroll{delta:(0,0),moder:ModifiersState{shift:false,ctrl:false,alt:false,logo:false},},
453 | font:Fonts::DejaVuSans,
454 |
455 | };
456 | pub static mut FILL_VERTECIES: Option> = None;
457 | pub static mut STROKE_VERTECIES: Option> = None;
458 | pub static mut TEXT_VEC: Option> = None;
459 | pub static mut TEXTURE:Option<(Vec,Dimensions)> = None;
460 |
--------------------------------------------------------------------------------
/src/color.rs:
--------------------------------------------------------------------------------
1 | use std::ops::Add;
2 | use std::ops::Sub;
3 | use std::fmt;
4 | ///a struct used for the coloring in this create
5 | #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
6 | pub struct Color {
7 | r: u8,
8 | g: u8,
9 | b: u8,
10 | a: u8,
11 | }
12 | impl Color {
13 | pub fn get_g(self) -> u8 {
14 | self.g
15 | }
16 | pub fn get_r(self) -> u8 {
17 | self.r
18 | }
19 | pub fn get_b(self) -> u8 {
20 | self.b
21 | }
22 | pub fn get_a(self) -> u8 {
23 | self.a
24 | }
25 | }
26 | ///retrun Color sruct from rgb values
27 | pub fn rgb(r: u8, g: u8, b: u8) -> Color {
28 | Color { r, g, b, a: 255 }
29 | }
30 | ///retrun Color sruct from rgba values
31 | pub fn rgba(r: u8, g: u8, b: u8, a: u8) -> Color {
32 | Color { r, g, b, a }
33 | }
34 | ///retrun Color sruct from grayscale values - need fixing
35 | pub fn grayscale(gr: u8) -> Color {
36 | Color {
37 | r: gr,
38 | g: gr, //(gr as f32 *0.59) as u8,
39 | b: gr, //(gr as f32 *0.11) as u8,
40 | a: 255,
41 | }
42 | }
43 | impl fmt::Display for Color{
44 | fn fmt(&self,f: &mut fmt::Formatter<'_>)->fmt::Result{
45 | write!(f, "({},{},{},{})", self.r, self.g,self.b,self.a)
46 | }
47 | }
48 | impl fmt::Debug for Color{
49 | fn fmt(&self,f: &mut fmt::Formatter<'_>)->fmt::Result{
50 | write!(f, "({},{},{},{})", self.r, self.g,self.b,self.a)
51 | }
52 | }
53 | impl From<(u8,u8,u8)> for Color{
54 | fn from(vals:(u8,u8,u8))->Self{
55 | Color{r:vals.0,g:vals.1,b:vals.2,a:255}
56 | }
57 | }
58 | impl From<(u8,u8,u8,u8)> for Color{
59 | fn from(vals:(u8,u8,u8,u8))->Self{
60 | Color{r:vals.0,g:vals.1,b:vals.2,a:vals.3}
61 | }
62 | }
63 | impl From for Color{
64 | fn from(vals:u8)->Self{
65 | Color{r:vals,g:vals,b:vals,a:255}
66 | }
67 | }
68 | impl Add for Color{
69 | type Output = Self;
70 | fn add(self,adder:u8)->Self{
71 | Color{r:self.get_r()+adder,g:self.get_g()+adder,b:self.get_b()+adder,a:self.get_a()}
72 | }
73 | }
74 | impl Sub for Color{
75 | type Output = Self;
76 | fn sub(self,adder:u8)->Self{
77 | let mut r:i16 = self.get_r() as i16 -adder as i16;
78 | let mut g:i16 = self.get_g() as i16 -adder as i16;
79 | let mut b:i16 = self.get_b() as i16 -adder as i16;
80 | if r<0{
81 | r=0;
82 | }
83 | if g<0{
84 | g=0;
85 | }
86 | if b<0{
87 | b=0;
88 | }
89 | Color{r:r as u8,g: g as u8,b: b as u8,a:self.get_a()}
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/compute.rs:
--------------------------------------------------------------------------------
1 | use crate::shaders::*;
2 | use std::sync::Arc;
3 | use vulkano::buffer::BufferUsage;
4 | use vulkano::buffer::CpuAccessibleBuffer;
5 | use vulkano::command_buffer::AutoCommandBufferBuilder;
6 | use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
7 | use vulkano::device::Device;
8 | use vulkano::device::DeviceExtensions;
9 | use vulkano::device::Features;
10 | use vulkano::instance::Instance;
11 | use vulkano::instance::InstanceExtensions;
12 | use vulkano::instance::PhysicalDevice;
13 | use vulkano::pipeline::ComputePipeline;
14 | use vulkano::sync;
15 | use vulkano::sync::GpuFuture;
16 | #[allow(non_camel_case_types)]
17 | #[allow(dead_code)]
18 | pub enum ops {
19 | Sub,
20 | Add,
21 | Mult,
22 | Div,
23 | FloatAdd,
24 | FloatSub,
25 | FloatDiv,
26 | FloatMult,
27 | AddVecs,
28 | SubVecs,
29 | FloatAddVecs,
30 | FloatSubVecs,
31 | FloatDivVecs,
32 | FloatMultVecs,
33 | }
34 | pub fn compute_ops(arr1: [T; 100], scalar1: T, op: ops) -> [T; 100]
35 | where
36 | T: Copy + Clone + Sync + Send,
37 | {
38 | let instance =
39 | Instance::new(None, &InstanceExtensions::none(), None).expect("failed to create instance");
40 |
41 | let physical = PhysicalDevice::enumerate(&instance)
42 | .next()
43 | .expect("no device available");
44 |
45 | let queue_family = physical
46 | .queue_families()
47 | .find(|&q| q.supports_compute())
48 | .expect("couldn't find a compute queue family");
49 | let (device, mut queues) = {
50 | Device::new(
51 | physical,
52 | &Features::none(),
53 | &DeviceExtensions::none(),
54 | [(queue_family, 0.5)].iter().cloned(),
55 | )
56 | .expect("failed to create device")
57 | };
58 | let queue = queues.next().unwrap();
59 | match op {
60 | ops::Sub => {
61 | let shader =
62 | cs_sub::Shader::load(device.clone()).expect("failed to create shader module");
63 | let compute_pipeline = Arc::new(
64 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
65 | .expect("failed to create compute pipeline"),
66 | );
67 | let data_buffer =
68 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
69 | .expect("failed to create buffer");
70 | let data_buffer2 =
71 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
72 | .expect("failed to create buffer");
73 | let set = Arc::new(
74 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
75 | .add_buffer(data_buffer.clone())
76 | .unwrap()
77 | .add_buffer(data_buffer2.clone())
78 | .unwrap()
79 | .build()
80 | .unwrap(),
81 | );
82 | let command_buffer =
83 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
84 | .unwrap()
85 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
86 | .unwrap()
87 | .build()
88 | .unwrap();
89 | let _future = sync::now(device.clone())
90 | .then_execute(queue.clone(), command_buffer)
91 | .unwrap()
92 | .then_signal_fence_and_flush()
93 | .unwrap()
94 | .wait(None)
95 | .unwrap();
96 | let arr2 = data_buffer.read().unwrap();
97 | return *arr2;
98 | }
99 | ops::Add => {
100 | let shader =
101 | cs_add::Shader::load(device.clone()).expect("failed to create shader module");
102 | let compute_pipeline = Arc::new(
103 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
104 | .expect("failed to create compute pipeline"),
105 | );
106 | let data_buffer =
107 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
108 | .expect("failed to create buffer");
109 | let data_buffer2 =
110 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
111 | .expect("failed to create buffer");
112 | let set = Arc::new(
113 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
114 | .add_buffer(data_buffer.clone())
115 | .unwrap()
116 | .add_buffer(data_buffer2.clone())
117 | .unwrap()
118 | .build()
119 | .unwrap(),
120 | );
121 | let command_buffer =
122 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
123 | .unwrap()
124 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
125 | .unwrap()
126 | .build()
127 | .unwrap();
128 | let _future = sync::now(device.clone())
129 | .then_execute(queue.clone(), command_buffer)
130 | .unwrap()
131 | .then_signal_fence_and_flush()
132 | .unwrap()
133 | .wait(None)
134 | .unwrap();
135 | let arr2 = data_buffer.read().unwrap();
136 | return *arr2;
137 | }
138 | ops::Div => {
139 | let shader =
140 | cs_div::Shader::load(device.clone()).expect("failed to create shader module");
141 | let compute_pipeline = Arc::new(
142 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
143 | .expect("failed to create compute pipeline"),
144 | );
145 | let data_buffer =
146 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
147 | .expect("failed to create buffer");
148 | let data_buffer2 =
149 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
150 | .expect("failed to create buffer");
151 | let set = Arc::new(
152 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
153 | .add_buffer(data_buffer.clone())
154 | .unwrap()
155 | .add_buffer(data_buffer2.clone())
156 | .unwrap()
157 | .build()
158 | .unwrap(),
159 | );
160 | let command_buffer =
161 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
162 | .unwrap()
163 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
164 | .unwrap()
165 | .build()
166 | .unwrap();
167 | let _future = sync::now(device.clone())
168 | .then_execute(queue.clone(), command_buffer)
169 | .unwrap()
170 | .then_signal_fence_and_flush()
171 | .unwrap()
172 | .wait(None)
173 | .unwrap();
174 | let arr2 = data_buffer.read().unwrap();
175 | return *arr2;
176 | }
177 | ops::Mult => {
178 | let shader =
179 | cs_mult::Shader::load(device.clone()).expect("failed to create shader module");
180 | let compute_pipeline = Arc::new(
181 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
182 | .expect("failed to create compute pipeline"),
183 | );
184 | let data_buffer =
185 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
186 | .expect("failed to create buffer");
187 | let data_buffer2 =
188 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
189 | .expect("failed to create buffer");
190 | let set = Arc::new(
191 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
192 | .add_buffer(data_buffer.clone())
193 | .unwrap()
194 | .add_buffer(data_buffer2.clone())
195 | .unwrap()
196 | .build()
197 | .unwrap(),
198 | );
199 | let command_buffer =
200 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
201 | .unwrap()
202 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
203 | .unwrap()
204 | .build()
205 | .unwrap();
206 | let _future = sync::now(device.clone())
207 | .then_execute(queue.clone(), command_buffer)
208 | .unwrap()
209 | .then_signal_fence_and_flush()
210 | .unwrap()
211 | .wait(None)
212 | .unwrap();
213 | let arr2 = data_buffer.read().unwrap();
214 | return *arr2;
215 | }
216 | ops::FloatAdd => {
217 | let shader =
218 | cs_float_add::Shader::load(device.clone()).expect("failed to create shader module");
219 | let compute_pipeline = Arc::new(
220 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
221 | .expect("failed to create compute pipeline"),
222 | );
223 | let data_buffer =
224 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
225 | .expect("failed to create buffer");
226 | let data_buffer2 =
227 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
228 | .expect("failed to create buffer");
229 | let set = Arc::new(
230 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
231 | .add_buffer(data_buffer.clone())
232 | .unwrap()
233 | .add_buffer(data_buffer2.clone())
234 | .unwrap()
235 | .build()
236 | .unwrap(),
237 | );
238 | let command_buffer =
239 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
240 | .unwrap()
241 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
242 | .unwrap()
243 | .build()
244 | .unwrap();
245 | let _future = sync::now(device.clone())
246 | .then_execute(queue.clone(), command_buffer)
247 | .unwrap()
248 | .then_signal_fence_and_flush()
249 | .unwrap()
250 | .wait(None)
251 | .unwrap();
252 | let arr2 = data_buffer.read().unwrap();
253 | return *arr2;
254 | }
255 | ops::FloatSub => {
256 | let shader =
257 | cs_float_sub::Shader::load(device.clone()).expect("failed to create shader module");
258 | let compute_pipeline = Arc::new(
259 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
260 | .expect("failed to create compute pipeline"),
261 | );
262 | let data_buffer =
263 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
264 | .expect("failed to create buffer");
265 | let data_buffer2 =
266 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
267 | .expect("failed to create buffer");
268 | let set = Arc::new(
269 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
270 | .add_buffer(data_buffer.clone())
271 | .unwrap()
272 | .add_buffer(data_buffer2.clone())
273 | .unwrap()
274 | .build()
275 | .unwrap(),
276 | );
277 | let command_buffer =
278 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
279 | .unwrap()
280 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
281 | .unwrap()
282 | .build()
283 | .unwrap();
284 | let _future = sync::now(device.clone())
285 | .then_execute(queue.clone(), command_buffer)
286 | .unwrap()
287 | .then_signal_fence_and_flush()
288 | .unwrap()
289 | .wait(None)
290 | .unwrap();
291 | let arr2 = data_buffer.read().unwrap();
292 | return *arr2;
293 | }
294 | ops::FloatDiv => {
295 | let shader =
296 | cs_float_div::Shader::load(device.clone()).expect("failed to create shader module");
297 | let compute_pipeline = Arc::new(
298 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
299 | .expect("failed to create compute pipeline"),
300 | );
301 | let data_buffer =
302 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
303 | .expect("failed to create buffer");
304 | let data_buffer2 =
305 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
306 | .expect("failed to create buffer");
307 | let set = Arc::new(
308 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
309 | .add_buffer(data_buffer.clone())
310 | .unwrap()
311 | .add_buffer(data_buffer2.clone())
312 | .unwrap()
313 | .build()
314 | .unwrap(),
315 | );
316 | let command_buffer =
317 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
318 | .unwrap()
319 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
320 | .unwrap()
321 | .build()
322 | .unwrap();
323 | let _future = sync::now(device.clone())
324 | .then_execute(queue.clone(), command_buffer)
325 | .unwrap()
326 | .then_signal_fence_and_flush()
327 | .unwrap()
328 | .wait(None)
329 | .unwrap();
330 | let arr2 = data_buffer.read().unwrap();
331 | return *arr2;
332 | }
333 | ops::FloatMult => {
334 | let shader = cs_float_mult::Shader::load(device.clone())
335 | .expect("failed to create shader module");
336 | let compute_pipeline = Arc::new(
337 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
338 | .expect("failed to create compute pipeline"),
339 | );
340 | let data_buffer =
341 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
342 | .expect("failed to create buffer");
343 | let data_buffer2 =
344 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), scalar1)
345 | .expect("failed to create buffer");
346 | let set = Arc::new(
347 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
348 | .add_buffer(data_buffer.clone())
349 | .unwrap()
350 | .add_buffer(data_buffer2.clone())
351 | .unwrap()
352 | .build()
353 | .unwrap(),
354 | );
355 | let command_buffer =
356 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
357 | .unwrap()
358 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
359 | .unwrap()
360 | .build()
361 | .unwrap();
362 | let _future = sync::now(device.clone())
363 | .then_execute(queue.clone(), command_buffer)
364 | .unwrap()
365 | .then_signal_fence_and_flush()
366 | .unwrap()
367 | .wait(None)
368 | .unwrap();
369 | let arr2 = data_buffer.read().unwrap();
370 | return *arr2;
371 | }
372 | _ => {
373 | return arr1;
374 | }
375 | }
376 | }
377 | pub fn compute_ops2(arr1: [T; 100], arr2: [T; 100], op: ops) -> [T; 100]
378 | where
379 | T: Copy + Clone + Sync + Send,
380 | {
381 | let instance =
382 | Instance::new(None, &InstanceExtensions::none(), None).expect("failed to create instance");
383 |
384 | let physical = PhysicalDevice::enumerate(&instance)
385 | .next()
386 | .expect("no device available");
387 |
388 | let queue_family = physical
389 | .queue_families()
390 | .find(|&q| q.supports_compute())
391 | .expect("couldn't find a compute queue family");
392 |
393 | let (device, mut queues) = {
394 | Device::new(
395 | physical,
396 | &Features::none(),
397 | &DeviceExtensions::none(),
398 | [(queue_family, 0.5)].iter().cloned(),
399 | )
400 | .expect("failed to create device")
401 | };
402 | let queue = queues.next().unwrap();
403 | match op {
404 | ops::FloatSubVecs => {
405 | let shader = cs_float_sub_vec::Shader::load(device.clone())
406 | .expect("failed to create shader module");
407 | let compute_pipeline = Arc::new(
408 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
409 | .expect("failed to create compute pipeline"),
410 | );
411 | let data_buffer =
412 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
413 | .expect("failed to create buffer");
414 | let data_buffer2 =
415 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr2)
416 | .expect("failed to create buffer");
417 | let set = Arc::new(
418 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
419 | .add_buffer(data_buffer.clone())
420 | .unwrap()
421 | .add_buffer(data_buffer2.clone())
422 | .unwrap()
423 | .build()
424 | .unwrap(),
425 | );
426 | let command_buffer =
427 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
428 | .unwrap()
429 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
430 | .unwrap()
431 | .build()
432 | .unwrap();
433 | let _future = sync::now(device.clone())
434 | .then_execute(queue.clone(), command_buffer)
435 | .unwrap()
436 | .then_signal_fence_and_flush()
437 | .unwrap()
438 | .wait(None)
439 | .unwrap();
440 | let arr3 = data_buffer.read().unwrap();
441 | return *arr3;
442 | }
443 | ops::AddVecs => {
444 | let shader =
445 | cs_add_vec::Shader::load(device.clone()).expect("failed to create shader module");
446 | let compute_pipeline = Arc::new(
447 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
448 | .expect("failed to create compute pipeline"),
449 | );
450 | let data_buffer =
451 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
452 | .expect("failed to create buffer");
453 | let data_buffer2 =
454 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr2)
455 | .expect("failed to create buffer");
456 | let set = Arc::new(
457 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
458 | .add_buffer(data_buffer.clone())
459 | .unwrap()
460 | .add_buffer(data_buffer2.clone())
461 | .unwrap()
462 | .build()
463 | .unwrap(),
464 | );
465 | let command_buffer =
466 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
467 | .unwrap()
468 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
469 | .unwrap()
470 | .build()
471 | .unwrap();
472 | let _future = sync::now(device.clone())
473 | .then_execute(queue.clone(), command_buffer)
474 | .unwrap()
475 | .then_signal_fence_and_flush()
476 | .unwrap()
477 | .wait(None)
478 | .unwrap();
479 | let arr3 = data_buffer.read().unwrap();
480 | return *arr3;
481 | }
482 | ops::SubVecs => {
483 | let shader =
484 | cs_sub_vec::Shader::load(device.clone()).expect("failed to create shader module");
485 | let compute_pipeline = Arc::new(
486 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
487 | .expect("failed to create compute pipeline"),
488 | );
489 | let data_buffer =
490 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
491 | .expect("failed to create buffer");
492 | let data_buffer2 =
493 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr2)
494 | .expect("failed to create buffer");
495 | let set = Arc::new(
496 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
497 | .add_buffer(data_buffer.clone())
498 | .unwrap()
499 | .add_buffer(data_buffer2.clone())
500 | .unwrap()
501 | .build()
502 | .unwrap(),
503 | );
504 | let command_buffer =
505 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
506 | .unwrap()
507 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
508 | .unwrap()
509 | .build()
510 | .unwrap();
511 | let _future = sync::now(device.clone())
512 | .then_execute(queue.clone(), command_buffer)
513 | .unwrap()
514 | .then_signal_fence_and_flush()
515 | .unwrap()
516 | .wait(None)
517 | .unwrap();
518 | let arr3 = data_buffer.read().unwrap();
519 | return *arr3;
520 | }
521 | ops::FloatDivVecs => {
522 | let shader = cs_float_div_vec::Shader::load(device.clone())
523 | .expect("failed to create shader module");
524 | let compute_pipeline = Arc::new(
525 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
526 | .expect("failed to create compute pipeline"),
527 | );
528 | let data_buffer =
529 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
530 | .expect("failed to create buffer");
531 | let data_buffer2 =
532 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr2)
533 | .expect("failed to create buffer");
534 | let set = Arc::new(
535 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
536 | .add_buffer(data_buffer.clone())
537 | .unwrap()
538 | .add_buffer(data_buffer2.clone())
539 | .unwrap()
540 | .build()
541 | .unwrap(),
542 | );
543 | let command_buffer =
544 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
545 | .unwrap()
546 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
547 | .unwrap()
548 | .build()
549 | .unwrap();
550 | let _future = sync::now(device.clone())
551 | .then_execute(queue.clone(), command_buffer)
552 | .unwrap()
553 | .then_signal_fence_and_flush()
554 | .unwrap()
555 | .wait(None)
556 | .unwrap();
557 | let arr3 = data_buffer.read().unwrap();
558 | return *arr3;
559 | }
560 | ops::FloatMultVecs => {
561 | let shader = cs_float_mult_vec::Shader::load(device.clone())
562 | .expect("failed to create shader module");
563 | let compute_pipeline = Arc::new(
564 | ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
565 | .expect("failed to create compute pipeline"),
566 | );
567 | let data_buffer =
568 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr1)
569 | .expect("failed to create buffer");
570 | let data_buffer2 =
571 | CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), arr2)
572 | .expect("failed to create buffer");
573 | let set = Arc::new(
574 | PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
575 | .add_buffer(data_buffer.clone())
576 | .unwrap()
577 | .add_buffer(data_buffer2.clone())
578 | .unwrap()
579 | .build()
580 | .unwrap(),
581 | );
582 | let command_buffer =
583 | AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
584 | .unwrap()
585 | .dispatch([100, 1, 1], compute_pipeline.clone(), set.clone(), ())
586 | .unwrap()
587 | .build()
588 | .unwrap();
589 | let _future = sync::now(device.clone())
590 | .then_execute(queue.clone(), command_buffer)
591 | .unwrap()
592 | .then_signal_fence_and_flush()
593 | .unwrap()
594 | .wait(None)
595 | .unwrap();
596 | let arr3 = data_buffer.read().unwrap();
597 | return *arr3;
598 | }
599 | _ => {
600 | return arr1;
601 | }
602 | }
603 | }
604 |
--------------------------------------------------------------------------------
/src/elements.rs:
--------------------------------------------------------------------------------
1 | use crate::color::*;
2 | use crate::canvas::*;
3 | pub trait PageElement {
4 | fn draw(self,canvas:&mut Canvas);
5 | #[allow(non_snake_case)]
6 | fn onClick(self,canvas:&Canvas)->bool;
7 | #[allow(non_snake_case)]
8 | fn onHover(self,canvas:&Canvas)->bool;
9 | }
10 | #[derive(Copy,Clone)]
11 | pub enum Styles{
12 | Normal,
13 | RoundEdges,
14 | Triangular,
15 | Elliptic,
16 | }
17 | #[derive(Clone,Copy)]
18 | pub struct Button{
19 | color:Color,
20 | x:u16,
21 | y:u16,
22 | width:u16,
23 | height:u16,
24 | border_width:u8,
25 | style:Styles,
26 | text:&'static str,
27 | }
28 | impl PageElement for Button {
29 | fn draw(self,canvas:&mut Canvas){
30 | canvas.textSize(12);
31 | canvas.text(self.x+self.border_width as u16+6,self.y+self.border_width as u16+(self.height/2)+1,self.text);
32 | match self.style{
33 | Styles::Normal=>{
34 | /*canvas.fill(self.color-20);
35 | canvas.rect(self.x,self.y,self.width,self.height);*/
36 | canvas.fill(self.color);
37 | canvas.rect(self.x+self.border_width as u16,self.y+self.border_width as u16,self.width-(self.border_width*2) as u16,self.height-(self.border_width*2) as u16);
38 | },
39 | Styles::RoundEdges=>{
40 | canvas.line(self.x+2,self.y,self.x+self.width-4,self.y);
41 | canvas.bezierCurveVertex((self.x+self.width-4) as i64,self.y as i64,(self.x+self.width-2) as i64,(self.y+2) as i64,(self.x+self.width-4) as i64,self.y as i64,(self.x+self.width-2) as i64,(self.y+2) as i64);
42 | canvas.line(self.x+self.width-2,self.y+2,self.x+self.width-2,self.y+self.height-4);
43 | canvas.bezierCurveVertex((self.x+self.width-2) as i64,(self.y+self.height-4) as i64,(self.x+self.width-4) as i64,(self.y+self.height-2) as i64,(self.x+self.width-2) as i64,(self.y+self.height-4) as i64,(self.x+self.width-4) as i64,(self.y+self.height-2) as i64);
44 | canvas.line(self.x+self.width-4,self.y+self.height-2,self.x+2,self.y+self.height-2);
45 | canvas.bezierCurveVertex((self.x+2) as i64,(self.y+self.height-2) as i64,(self.x) as i64,(self.y+self.height-4) as i64,(self.x+2) as i64,(self.y+self.height-2) as i64,(self.x) as i64,(self.y+self.height-4) as i64);
46 | canvas.line(self.x,self.y+self.height-4,self.x,self.y+2);
47 | canvas.bezierCurveVertex((self.x) as i64,(self.y+2) as i64,(self.x+2) as i64,self.y as i64,(self.x) as i64,(self.y+2) as i64,(self.x+2) as i64,self.y as i64);
48 | },
49 | _=>{},
50 | }
51 | }
52 | #[allow(non_snake_case)]
53 | fn onClick(self,canvas:&Canvas)->bool{
54 | if canvas.mouseClick()==MouseButton::Left && (canvas.mouseX()>self.x && canvas.mouseX()self.y && canvas.mouseY()bool{
61 | if canvas.mouseClick()!=MouseButton::Left && (canvas.mouseX()>self.x && canvas.mouseX()self.y && canvas.mouseY()Button{
69 | Button{color:Color::from(190), x,y,width:40,height:20,border_width:2,style:Styles::Normal,text,}
70 | }
71 | pub fn location(&mut self,x:u16,y:u16)->Self{
72 | self.x = x;
73 | self.y = y;
74 | *self
75 | }
76 | pub fn get_location(self)->(u16,u16){
77 | (self.x,self.y)
78 | }
79 | pub fn get_x(self)->u16{
80 | self.x
81 | }
82 | pub fn get_y(self)->u16{
83 | self.y
84 | }
85 | pub fn color(&mut self,color:Color)->Self{
86 | self.color = color;
87 | *self
88 | }
89 | pub fn size(&mut self,width:u16,height:u16)->Self{
90 | self.width = width;
91 | self.height= height;
92 | *self
93 | }
94 | pub fn get_size(self)->(u16,u16){
95 | (self.width,self.height)
96 | }
97 | pub fn get_width(self)->u16{
98 | self.width
99 | }
100 | pub fn get_height(self)->u16{
101 | self.height
102 | }
103 | pub fn width(&mut self,width:u16)->Self{
104 | self.width = width;
105 | *self
106 | }
107 | pub fn height(&mut self,height:u16)->Self{
108 | self.height = height;
109 | *self
110 | }
111 |
112 | pub fn border_width(&mut self,width:u8)->Self{
113 | self.border_width = width;
114 | *self
115 | }
116 | pub fn get_border_width(self)->u8{
117 | self.border_width
118 | }
119 | pub fn button_text(&mut self,text:&'static str)->Self{
120 | self.text = text;
121 | *self
122 | }
123 | pub fn get_color(self)->Color{
124 | self.color
125 | }
126 | pub fn style(&mut self,style:Styles)->Self{
127 | self.style = style;
128 | *self
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/fonts.rs:
--------------------------------------------------------------------------------
1 | #[derive(Debug, Clone, Copy, PartialEq)]
2 | pub enum Fonts{
3 | RobotoBlack,
4 | OpenSansBold,
5 | RobotoMedium,
6 | OpenSansExtraBold,
7 | RobotoCondensedItalic,
8 | OpenSansExtraBoldItalic,
9 | RobotoThinItalic,
10 | RobotoThin,
11 | DejaVuSans,
12 | RobotoBold,
13 | OpenSansRegular,
14 | OpenSansSemibold,
15 | OpenSansLight,
16 | RobotoRegular,
17 | RobotoCondensedRegular,
18 | RobotoCondensedBold,
19 | RobotoCondensedLightItalic,
20 | OpenSansItalic,
21 | OpenSansBoldItalic,
22 | OpenSansSemiboldItalic,
23 | RobotoItalic,
24 | OpenSansLightItalic,
25 | RobotoCondensedBoldItalic,
26 | RobotoMediumItalic,
27 | RobotoBoldItalic,
28 | RobotoCondensedLight,
29 | RobotoLight,
30 | RobotoLightItalic,
31 | RobotoBlackItalic,
32 | }
33 | impl Fonts{
34 | pub fn get_ttf(self)->&'static [u8]{
35 | match self{
36 | Fonts::RobotoBlack=>{ let ttf1 = include_bytes!( "fonts/Roboto-Black.ttf");
37 | return ttf1;},
38 | Fonts::OpenSansBold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Bold.ttf");
39 | return ttf1;},
40 | Fonts::RobotoMedium=>{ let ttf1 = include_bytes!( "fonts/Roboto-Medium.ttf");
41 | return ttf1;},
42 | Fonts::OpenSansExtraBold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-ExtraBold.ttf");
43 | return ttf1;},
44 | Fonts::RobotoCondensedItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Italic.ttf");
45 | return ttf1;},
46 | Fonts::OpenSansExtraBoldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-ExtraBoldItalic.ttf");
47 | return ttf1;},
48 | Fonts::RobotoThinItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-ThinItalic.ttf");
49 | return ttf1;},
50 | Fonts::RobotoThin=>{ let ttf1 = include_bytes!( "fonts/Roboto-Thin.ttf");
51 | return ttf1;},
52 | Fonts::DejaVuSans=>{ let ttf1 = include_bytes!( "fonts/DejaVuSans.ttf");
53 | return ttf1;},
54 | Fonts::RobotoBold=>{ let ttf1 = include_bytes!( "fonts/Roboto-Bold.ttf");
55 | return ttf1;},
56 | Fonts::OpenSansRegular=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Regular.ttf");
57 | return ttf1;},
58 | Fonts::OpenSansSemibold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Semibold.ttf");
59 | return ttf1;},
60 | Fonts::OpenSansLight=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Light.ttf");
61 | return ttf1;},
62 | Fonts::RobotoRegular=>{ let ttf1 = include_bytes!( "fonts/Roboto-Regular.ttf");
63 | return ttf1;},
64 | Fonts::RobotoCondensedRegular=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Regular.ttf");
65 | return ttf1;},
66 | Fonts::RobotoCondensedBold=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Bold.ttf");
67 | return ttf1;},
68 | Fonts::RobotoCondensedLightItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-LightItalic.ttf");
69 | return ttf1;},
70 | Fonts::OpenSansItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Italic.ttf");
71 | return ttf1;},
72 | Fonts::OpenSansBoldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-BoldItalic.ttf");
73 | return ttf1;},
74 | Fonts::OpenSansSemiboldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-SemiboldItalic.ttf");
75 | return ttf1;},
76 | Fonts::RobotoItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-Italic.ttf");
77 | return ttf1;},
78 | Fonts::OpenSansLightItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-LightItalic.ttf");
79 | return ttf1;},
80 | Fonts::RobotoCondensedBoldItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-BoldItalic.ttf");
81 | return ttf1;},
82 | Fonts::RobotoMediumItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-MediumItalic.ttf");
83 | return ttf1;},
84 | Fonts::RobotoBoldItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-BoldItalic.ttf");
85 | return ttf1;},
86 | Fonts::RobotoCondensedLight=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Light.ttf");
87 | return ttf1;},
88 | Fonts::RobotoLight=>{ let ttf1 = include_bytes!( "fonts/Roboto-Light.ttf");
89 | return ttf1;},
90 | Fonts::RobotoLightItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-LightItalic.ttf");
91 | return ttf1;},
92 | Fonts::RobotoBlackItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-BlackItalic.ttf");
93 | return ttf1;},
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/fonts/Apache License.txt:
--------------------------------------------------------------------------------
1 | Font data copyright Google 2012
2 |
3 | Apache License
4 | Version 2.0, January 2004
5 | http://www.apache.org/licenses/
6 |
7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8 |
9 | 1. Definitions.
10 |
11 | "License" shall mean the terms and conditions for use, reproduction,
12 | and distribution as defined by Sections 1 through 9 of this document.
13 |
14 | "Licensor" shall mean the copyright owner or entity authorized by
15 | the copyright owner that is granting the License.
16 |
17 | "Legal Entity" shall mean the union of the acting entity and all
18 | other entities that control, are controlled by, or are under common
19 | control with that entity. For the purposes of this definition,
20 | "control" means (i) the power, direct or indirect, to cause the
21 | direction or management of such entity, whether by contract or
22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
23 | outstanding shares, or (iii) beneficial ownership of such entity.
24 |
25 | "You" (or "Your") shall mean an individual or Legal Entity
26 | exercising permissions granted by this License.
27 |
28 | "Source" form shall mean the preferred form for making modifications,
29 | including but not limited to software source code, documentation
30 | source, and configuration files.
31 |
32 | "Object" form shall mean any form resulting from mechanical
33 | transformation or translation of a Source form, including but
34 | not limited to compiled object code, generated documentation,
35 | and conversions to other media types.
36 |
37 | "Work" shall mean the work of authorship, whether in Source or
38 | Object form, made available under the License, as indicated by a
39 | copyright notice that is included in or attached to the work
40 | (an example is provided in the Appendix below).
41 |
42 | "Derivative Works" shall mean any work, whether in Source or Object
43 | form, that is based on (or derived from) the Work and for which the
44 | editorial revisions, annotations, elaborations, or other modifications
45 | represent, as a whole, an original work of authorship. For the purposes
46 | of this License, Derivative Works shall not include works that remain
47 | separable from, or merely link (or bind by name) to the interfaces of,
48 | the Work and Derivative Works thereof.
49 |
50 | "Contribution" shall mean any work of authorship, including
51 | the original version of the Work and any modifications or additions
52 | to that Work or Derivative Works thereof, that is intentionally
53 | submitted to Licensor for inclusion in the Work by the copyright owner
54 | or by an individual or Legal Entity authorized to submit on behalf of
55 | the copyright owner. For the purposes of this definition, "submitted"
56 | means any form of electronic, verbal, or written communication sent
57 | to the Licensor or its representatives, including but not limited to
58 | communication on electronic mailing lists, source code control systems,
59 | and issue tracking systems that are managed by, or on behalf of, the
60 | Licensor for the purpose of discussing and improving the Work, but
61 | excluding communication that is conspicuously marked or otherwise
62 | designated in writing by the copyright owner as "Not a Contribution."
63 |
64 | "Contributor" shall mean Licensor and any individual or Legal Entity
65 | on behalf of whom a Contribution has been received by Licensor and
66 | subsequently incorporated within the Work.
67 |
68 | 2. Grant of Copyright License. Subject to the terms and conditions of
69 | this License, each Contributor hereby grants to You a perpetual,
70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71 | copyright license to reproduce, prepare Derivative Works of,
72 | publicly display, publicly perform, sublicense, and distribute the
73 | Work and such Derivative Works in Source or Object form.
74 |
75 | 3. Grant of Patent License. Subject to the terms and conditions of
76 | this License, each Contributor hereby grants to You a perpetual,
77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78 | (except as stated in this section) patent license to make, have made,
79 | use, offer to sell, sell, import, and otherwise transfer the Work,
80 | where such license applies only to those patent claims licensable
81 | by such Contributor that are necessarily infringed by their
82 | Contribution(s) alone or by combination of their Contribution(s)
83 | with the Work to which such Contribution(s) was submitted. If You
84 | institute patent litigation against any entity (including a
85 | cross-claim or counterclaim in a lawsuit) alleging that the Work
86 | or a Contribution incorporated within the Work constitutes direct
87 | or contributory patent infringement, then any patent licenses
88 | granted to You under this License for that Work shall terminate
89 | as of the date such litigation is filed.
90 |
91 | 4. Redistribution. You may reproduce and distribute copies of the
92 | Work or Derivative Works thereof in any medium, with or without
93 | modifications, and in Source or Object form, provided that You
94 | meet the following conditions:
95 |
96 | (a) You must give any other recipients of the Work or
97 | Derivative Works a copy of this License; and
98 |
99 | (b) You must cause any modified files to carry prominent notices
100 | stating that You changed the files; and
101 |
102 | (c) You must retain, in the Source form of any Derivative Works
103 | that You distribute, all copyright, patent, trademark, and
104 | attribution notices from the Source form of the Work,
105 | excluding those notices that do not pertain to any part of
106 | the Derivative Works; and
107 |
108 | (d) If the Work includes a "NOTICE" text file as part of its
109 | distribution, then any Derivative Works that You distribute must
110 | include a readable copy of the attribution notices contained
111 | within such NOTICE file, excluding those notices that do not
112 | pertain to any part of the Derivative Works, in at least one
113 | of the following places: within a NOTICE text file distributed
114 | as part of the Derivative Works; within the Source form or
115 | documentation, if provided along with the Derivative Works; or,
116 | within a display generated by the Derivative Works, if and
117 | wherever such third-party notices normally appear. The contents
118 | of the NOTICE file are for informational purposes only and
119 | do not modify the License. You may add Your own attribution
120 | notices within Derivative Works that You distribute, alongside
121 | or as an addendum to the NOTICE text from the Work, provided
122 | that such additional attribution notices cannot be construed
123 | as modifying the License.
124 |
125 | You may add Your own copyright statement to Your modifications and
126 | may provide additional or different license terms and conditions
127 | for use, reproduction, or distribution of Your modifications, or
128 | for any such Derivative Works as a whole, provided Your use,
129 | reproduction, and distribution of the Work otherwise complies with
130 | the conditions stated in this License.
131 |
132 | 5. Submission of Contributions. Unless You explicitly state otherwise,
133 | any Contribution intentionally submitted for inclusion in the Work
134 | by You to the Licensor shall be under the terms and conditions of
135 | this License, without any additional terms or conditions.
136 | Notwithstanding the above, nothing herein shall supersede or modify
137 | the terms of any separate license agreement you may have executed
138 | with Licensor regarding such Contributions.
139 |
140 | 6. Trademarks. This License does not grant permission to use the trade
141 | names, trademarks, service marks, or product names of the Licensor,
142 | except as required for reasonable and customary use in describing the
143 | origin of the Work and reproducing the content of the NOTICE file.
144 |
145 | 7. Disclaimer of Warranty. Unless required by applicable law or
146 | agreed to in writing, Licensor provides the Work (and each
147 | Contributor provides its Contributions) on an "AS IS" BASIS,
148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149 | implied, including, without limitation, any warranties or conditions
150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151 | PARTICULAR PURPOSE. You are solely responsible for determining the
152 | appropriateness of using or redistributing the Work and assume any
153 | risks associated with Your exercise of permissions under this License.
154 |
155 | 8. Limitation of Liability. In no event and under no legal theory,
156 | whether in tort (including negligence), contract, or otherwise,
157 | unless required by applicable law (such as deliberate and grossly
158 | negligent acts) or agreed to in writing, shall any Contributor be
159 | liable to You for damages, including any direct, indirect, special,
160 | incidental, or consequential damages of any character arising as a
161 | result of this License or out of the use or inability to use the
162 | Work (including but not limited to damages for loss of goodwill,
163 | work stoppage, computer failure or malfunction, or any and all
164 | other commercial damages or losses), even if such Contributor
165 | has been advised of the possibility of such damages.
166 |
167 | 9. Accepting Warranty or Additional Liability. While redistributing
168 | the Work or Derivative Works thereof, You may choose to offer,
169 | and charge a fee for, acceptance of support, warranty, indemnity,
170 | or other liability obligations and/or rights consistent with this
171 | License. However, in accepting such obligations, You may act only
172 | on Your own behalf and on Your sole responsibility, not on behalf
173 | of any other Contributor, and only if You agree to indemnify,
174 | defend, and hold each Contributor harmless for any liability
175 | incurred by, or claims asserted against, such Contributor by reason
176 | of your accepting any such warranty or additional liability.
177 |
178 | END OF TERMS AND CONDITIONS
179 |
180 | APPENDIX: How to apply the Apache License to your work.
181 |
182 | To apply the Apache License to your work, attach the following
183 | boilerplate notice, with the fields enclosed by brackets "[]"
184 | replaced with your own identifying information. (Don't include
185 | the brackets!) The text should be enclosed in the appropriate
186 | comment syntax for the file format. We also recommend that a
187 | file or class name and description of purpose be included on the
188 | same "printed page" as the copyright notice for easier
189 | identification within third-party archives.
190 |
191 | Copyright [yyyy] [name of copyright owner]
192 |
193 | Licensed under the Apache License, Version 2.0 (the "License");
194 | you may not use this file except in compliance with the License.
195 | You may obtain a copy of the License at
196 |
197 | http://www.apache.org/licenses/LICENSE-2.0
198 |
199 | Unless required by applicable law or agreed to in writing, software
200 | distributed under the License is distributed on an "AS IS" BASIS,
201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202 | See the License for the specific language governing permissions and
203 | limitations under the License.
--------------------------------------------------------------------------------
/src/fonts/DejaVuSans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/DejaVuSans.ttf
--------------------------------------------------------------------------------
/src/fonts/GreatVibes-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/GreatVibes-Regular.otf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-Bold.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-BoldItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-ExtraBold.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-Italic.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-Light.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-LightItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/src/fonts/OpenSans-SemiboldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/OpenSans-SemiboldItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Black.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-BlackItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-BoldItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Italic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Light.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-LightItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-MediumItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/src/fonts/Roboto-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/Roboto-ThinItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-Bold.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-BoldItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-Italic.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-Light.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-LightItalic.ttf
--------------------------------------------------------------------------------
/src/fonts/RobotoCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GuyL99/metropolis/1eac53f089b4cc30a8e6620f63cc21ea5e95f1b7/src/fonts/RobotoCondensed-Regular.ttf
--------------------------------------------------------------------------------
/src/fonts/matches.txt:
--------------------------------------------------------------------------------
1 | match self{
2 | Fonts::RobotoBlack=>{ let ttf1 = include_bytes!( "fonts/Roboto-Black.ttf");
3 | return ttf1;},
4 | Fonts::OpenSansBold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Bold.ttf");
5 | return ttf1;},
6 | Fonts::RobotoMedium=>{ let ttf1 = include_bytes!( "fonts/Roboto-Medium.ttf");
7 | return ttf1;},
8 | Fonts::OpenSansExtraBold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-ExtraBold.ttf");
9 | return ttf1;},
10 | Fonts::RobotoCondensedItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Italic.ttf");
11 | return ttf1;},
12 | Fonts::OpenSansExtraBoldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-ExtraBoldItalic.ttf");
13 | return ttf1;},
14 | Fonts::RobotoThinItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-ThinItalic.ttf");
15 | return ttf1;},
16 | Fonts::RobotoThin=>{ let ttf1 = include_bytes!( "fonts/Roboto-Thin.ttf");
17 | return ttf1;},
18 | Fonts::DejaVuSans=>{ let ttf1 = include_bytes!( "fonts/DejaVuSans.ttf");
19 | return ttf1;},
20 | Fonts::RobotoBold=>{ let ttf1 = include_bytes!( "fonts/Roboto-Bold.ttf");
21 | return ttf1;},
22 | Fonts::OpenSansRegular=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Regular.ttf");
23 | return ttf1;},
24 | Fonts::OpenSansSemibold=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Semibold.ttf");
25 | return ttf1;},
26 | Fonts::OpenSansLight=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Light.ttf");
27 | return ttf1;},
28 | Fonts::RobotoRegular=>{ let ttf1 = include_bytes!( "fonts/Roboto-Regular.ttf");
29 | return ttf1;},
30 | Fonts::RobotoCondensedRegular=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Regular.ttf");
31 | return ttf1;},
32 | Fonts::RobotoCondensedBold=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Bold.ttf");
33 | return ttf1;},
34 | Fonts::RobotoCondensedLightItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-LightItalic.ttf");
35 | return ttf1;},
36 | Fonts::OpenSansItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-Italic.ttf");
37 | return ttf1;},
38 | Fonts::OpenSansBoldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-BoldItalic.ttf");
39 | return ttf1;},
40 | Fonts::OpenSansSemiboldItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-SemiboldItalic.ttf");
41 | return ttf1;},
42 | Fonts::RobotoItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-Italic.ttf");
43 | return ttf1;},
44 | Fonts::OpenSansLightItalic=>{ let ttf1 = include_bytes!( "fonts/OpenSans-LightItalic.ttf");
45 | return ttf1;},
46 | Fonts::RobotoCondensedBoldItalic=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-BoldItalic.ttf");
47 | return ttf1;},
48 | Fonts::RobotoMediumItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-MediumItalic.ttf");
49 | return ttf1;},
50 | Fonts::RobotoBoldItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-BoldItalic.ttf");
51 | return ttf1;},
52 | Fonts::RobotoCondensedLight=>{ let ttf1 = include_bytes!( "fonts/RobotoCondensed-Light.ttf");
53 | return ttf1;},
54 | Fonts::RobotoLight=>{ let ttf1 = include_bytes!( "fonts/Roboto-Light.ttf");
55 | return ttf1;},
56 | Fonts::RobotoLightItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-LightItalic.ttf");
57 | return ttf1;},
58 | Fonts::RobotoBlackItalic=>{ let ttf1 = include_bytes!( "fonts/Roboto-BlackItalic.ttf");
59 | return ttf1;},
60 | }
--------------------------------------------------------------------------------
/src/fonts/names.txt:
--------------------------------------------------------------------------------
1 | RobotoBlack,
2 | OpenSansBold,
3 | RobotoMedium,
4 | OpenSansExtraBold,
5 | RobotoCondensedItalic,
6 | OpenSansExtraBoldItalic,
7 | RobotoThinItalic,
8 | RobotoThin,
9 | DejaVuSans,
10 | RobotoBold,
11 | OpenSansRegular,
12 | OpenSansSemibold,
13 | OpenSansLight,
14 | RobotoRegular,
15 | RobotoCondensedRegular,
16 | RobotoCondensedBold,
17 | RobotoCondensedLightItalic,
18 | OpenSansItalic,
19 | OpenSansBoldItalic,
20 | OpenSansSemiboldItalic,
21 | RobotoItalic,
22 | OpenSansLightItalic,
23 | RobotoCondensedBoldItalic,
24 | RobotoMediumItalic,
25 | RobotoBoldItalic,
26 | RobotoCondensedLight,
27 | RobotoLight,
28 | RobotoLightItalic,
29 | RobotoBlackItalic,
30 |
--------------------------------------------------------------------------------
/src/fonts/scrpt1.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | with open("matches.txt","a") as f:
4 | f.write("match self{\n")
5 | for font in os.listdir():
6 | with open("matches.txt","a") as ff:
7 | font1 = font.split('.')
8 | #print(font)
9 | if font1[1]=='ttf':
10 | font2 = font1[0]
11 | '''ff.write("\t\t\t")
12 | ff.write(font1[0].replace('-',''))
13 | ff.write(",\n")'''
14 | ff.write("\tFonts::")
15 | ff.write(font2.replace('-',''))
16 | ff.write("=>{ let ttf1 = include_bytes!( \"fonts/")
17 | ff.write(font1[0])
18 | ff.write(".ttf\");\n")
19 | ff.write("\treturn ttf1;},")
20 | ff.write("\n")
21 | with open("matches.txt","a") as fff:
22 | fff.write("}")
23 |
24 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | //!this crate is a high level easy to use graphics renderer inspired by processing in java and p5 in
2 | //!javascript. Working with it utilizes high level function like arc,line,rect and such that are
3 | //!you to make sveral canvases and display them as you wish. 3D is also coming and is currently
4 | //!under development(for now it's just 2D functions).
5 | //!the way to use the library is to use the size function to create a canvas with a fixed
6 | //!size(width,height), afterwards, you create some setup variable and setup the background for the
7 | //!animation/game/test/simulation you want to run, then you create a closure and save it to a variable,
8 | //!and finally send it to the show function(designed to loop over the draw function).
9 | //!like this (grvaity example):
10 | //!```
11 | //!use metropolis::*;
12 | //!use metropolis::color::*;
13 | //!fn main() {
14 | //! //here I set up the background, height, width,spd,and the position on y
15 | //! let height = 900;
16 | //! let width = 1200;
17 | //! size(width,height);
18 | //! let mut spd = 0;
19 | //! let mut posy = 0;
20 | //! background(grayscale(100));
21 | //! let draw =move || {
22 | //! //inside the draw function I create the accelaration to simulate gravity
23 | //! spd+=1;
24 | //! if posy+50< height{
25 | //! posy+=spd;
26 | //! }
27 | //! // and those are the library functions fill-which makes the filled color be pinkish
28 | //! // and circle which draws a circle with a center in 400(in x) and posy(changing y), with a
29 | //! //radius of 100.
30 | //! fill(rgb(255,0,100));
31 | //! circle(400,posy,100);
32 | //! };
33 | //! //finally I send the draw function into show like that(should be used without the commenting,
34 | //! //it's commented because it loopes over with no timeout
35 | //! //show(draw);
36 | //!}
37 | //!```
38 | //!or you can do something similar only with a safe canvas struct(take your pick for your use case:
39 | //!the public canvas struct(there is actually an inner one for the static functions). it is
40 | //!```
41 | //!use metropolis::color::*;
42 | //!use metropolis::canvas::Canvas;
43 | //!fn main(){
44 | //! let height = 600;
45 | //! let width = 800;
46 | //! //size(width, height);
47 | //! let mut canv:Canvas= Canvas::new(width,height);
48 | //! canv.background(grayscale(100));
49 | //! let draw = |mut canvas:Canvas|->Canvas {
50 | //! let curve_vec: Vec<[i64; 2]> = vec![
51 | //! [0, 400],
52 | //! [30, 370],
53 | //! [50, 300],
54 | //! [75, 257],
55 | //! [80, 240],
56 | //! [150, 150],
57 | //! [250, 050],
58 | //! ];
59 | //! canvas.bezierCurve(curve_vec);
60 | //! canvas
61 | //! };
62 | //! canv.show(draw);
63 | //!}
64 | //!```
65 | //!as you may see the draw loop is designed a bit different.
66 | mod vertex;
67 | use vertex::*;
68 | mod mapping;
69 | mod setup;
70 | mod shaders;
71 | use mapping::*;
72 | ///the canvas mod contains the canvas and image structs used to create multiple and multithreading
73 | ///safe canvases
74 | pub mod canvas;
75 | pub use canvas::*;
76 | mod text;
77 | mod compute;
78 | mod canvas_glob;
79 | use canvas_glob::*;
80 | ///a module used for coloring in this crate, will be adding more functions and easier set in the
81 | ///future.
82 | pub mod color;
83 | //pub mod page;
84 | ///a module to provide some mathematical help functions from the crate.
85 | ///Will be much expanded upon in the near future.
86 | pub mod vector;
87 | pub mod math;
88 | pub mod elements;
89 | pub mod fonts;
90 | use color::*;
91 | use math::{bezier_points, catmull_rom_chain};
92 | pub static mut FPS:f32 = 0f32;
93 | pub static mut HEIGHT:u16 = 0u16;
94 | pub static mut WIDTH:u16 = 0u16;
95 | use vulkano::image::Dimensions;
96 | use png;
97 | use std::fs::File;
98 | pub use winit::VirtualKeyCode as keyCode;
99 | pub use winit::MouseButton;
100 | use winit::ModifiersState;
101 | fn add_to_text(pusher: Stext) {
102 | unsafe {
103 | match &TEXT_VEC {
104 | None => {
105 | TEXT_VEC = Some(vec![pusher]);
106 | }
107 | Some(vec1) => {
108 | let mut vec2 = vec1.clone();
109 | vec2.push(pusher);
110 | TEXT_VEC = Some(vec2);
111 | }
112 | };
113 | }
114 | }
115 | fn add_to_fill(pusher: Vertex) {
116 | unsafe {
117 | match &FILL_VERTECIES {
118 | None => {
119 | FILL_VERTECIES = Some(vec![pusher]);
120 | }
121 | Some(vec1) => {
122 | let mut vec2 = vec1.clone();
123 | vec2.push(pusher);
124 | FILL_VERTECIES = Some(vec2);
125 | }
126 | };
127 | }
128 | }
129 | fn add_to_stroke(pusher: Vertex) {
130 | unsafe {
131 | match &STROKE_VERTECIES {
132 | None => {
133 | STROKE_VERTECIES = Some(vec![pusher]);
134 | }
135 | Some(vec1) => {
136 | let mut vec2 = vec1.clone();
137 | vec2.push(pusher);
138 | STROKE_VERTECIES = Some(vec2);
139 | }
140 | };
141 | }
142 | }
143 | ///keeps the key pressed in the key event until a new key is pressed
144 | #[allow(non_snake_case)]
145 | pub fn lockKeyEvent(){
146 | unsafe{
147 | CANVAS.key.keep_key = true;
148 | }
149 | }
150 | ///returns the x scroll delta of the mouse
151 | #[allow(non_snake_case)]
152 | pub fn mouseScrollX()->i64{
153 | unsafe{
154 | CANVAS.mouse_scroll.delta_x()
155 | }
156 | }
157 | ///returns the y scroll delta of the mouse
158 | #[allow(non_snake_case)]
159 | pub fn mouseScrollY()->i64{
160 | unsafe{
161 | CANVAS.mouse_scroll.delta_y()
162 | }
163 | }
164 | ///returns the current key that is pressed on the mouse.
165 | #[allow(non_snake_case)]
166 | pub fn mouseClick()->MouseButton{
167 | unsafe{
168 | match CANVAS.mouse.btn{
169 | Some(btn)=> {return btn;},
170 | None=> {return MouseButton::Other(99);}
171 | }
172 | }
173 | }
174 | ///returns the x position of the mouse
175 | #[allow(non_snake_case)]
176 | pub fn mouseX()->u16{
177 | unsafe{
178 | CANVAS.cursor_pos.0
179 | }
180 | }
181 | ///returns the y position of the mouse
182 | #[allow(non_snake_case)]
183 | pub fn mouseY()->u16{
184 | unsafe{
185 | CANVAS.cursor_pos.1
186 | }
187 | }
188 | ///creates the canvas with the width and height sent to this function
189 | pub fn size(width: u16, height: u16) {
190 | unsafe {
191 | CANVAS.size = (width, height);
192 | }
193 | }
194 | ///returns the current key that is pressed.
195 | #[allow(non_snake_case)]
196 | pub fn keyPressed()->keyCode{
197 | unsafe{
198 | match CANVAS.key.keycode{
199 | Some(key)=> {return key;},
200 | None=> {return keyCode::Power;}
201 | }
202 | }
203 | }
204 | ///returns the current state of the modifiers
205 | pub fn get_modifiers()->ModifiersState{
206 | unsafe{
207 | CANVAS.key.get_mod()
208 | }
209 | }
210 | ///recieves f32 ext size and sets the canvases text_size to that size
211 | #[allow(non_snake_case)]
212 | pub fn textSize(sz:u8) {
213 | unsafe {
214 | CANVAS.text_size = sz as f32;
215 | }
216 | }
217 | ///this is the function used to run the animation
218 | pub fn show(draw_fn: F)
219 | where
220 | F: FnMut() + 'static,
221 | {
222 | unsafe {
223 | CANVAS.show(draw_fn);
224 | }
225 | }
226 | ///recieves the x and y of the top spot and then the width and height of the rectangle you want
227 | ///built.
228 | pub fn rect(x: u16, y: u16, width: u16, height: u16) {
229 | unsafe {
230 | let scale = [CANVAS.size.0, CANVAS.size.1];
231 | let t_l = map([x, y], scale);
232 | let b_r = map([x + width, y + height], scale);
233 | let t_r = map([x + width, y], scale);
234 | let b_l = map([x, y + height], scale);
235 | if CANVAS.fill {
236 | let color = CANVAS.fill_color;
237 | add_to_fill(Vertex {
238 | position: b_r,
239 | color,
240 | tex_coords:[0f32,0f32],
241 | });
242 | add_to_fill(Vertex {
243 | position: t_r,
244 | color,
245 | tex_coords:[0f32,0f32],
246 | });
247 | add_to_fill(Vertex {
248 | position: t_l,
249 | color,
250 | tex_coords:[0f32,0f32],
251 | });
252 | add_to_fill(Vertex {
253 | position: t_l,
254 | color,
255 | tex_coords:[0f32,0f32],
256 | });
257 | add_to_fill(Vertex {
258 | position: b_l,
259 | color,
260 | tex_coords:[0f32,0f32],
261 | });
262 | add_to_fill(Vertex {
263 | position: b_r,
264 | color,
265 | tex_coords:[0f32,0f32],
266 | });
267 | }
268 | if CANVAS.stroke {
269 | let color = CANVAS.color;
270 | add_to_stroke(Vertex {
271 | position: t_l,
272 | color,
273 | tex_coords:[0f32,0f32],
274 | });
275 | add_to_stroke(Vertex {
276 | position: t_r,
277 | color,
278 | tex_coords:[0f32,0f32],
279 | });
280 | add_to_stroke(Vertex {
281 | position: t_r,
282 | color,
283 | tex_coords:[0f32,0f32],
284 | });
285 | add_to_stroke(Vertex {
286 | position: b_r,
287 | color,
288 | tex_coords:[0f32,0f32],
289 | });
290 | add_to_stroke(Vertex {
291 | position: b_r,
292 | color,
293 | tex_coords:[0f32,0f32],
294 | });
295 | add_to_stroke(Vertex {
296 | position: b_l,
297 | color,
298 | tex_coords:[0f32,0f32],
299 | });
300 | add_to_stroke(Vertex {
301 | position: b_l,
302 | color,
303 | tex_coords:[0f32,0f32],
304 | });
305 | add_to_stroke(Vertex {
306 | position: t_l,
307 | color,
308 | tex_coords:[0f32,0f32],
309 | });
310 | }
311 | }
312 | }
313 | ///recieves the x and y of the top spot and then the width of the sqaure you want built.
314 | pub fn square(x: u16, y: u16, width: u16) {
315 | unsafe {
316 | let scale = [CANVAS.size.0, CANVAS.size.1];
317 | let t_l = map([x, y], scale);
318 | let b_r = map([x + width, y + width], scale);
319 | let t_r = map([x + width, y], scale);
320 | let b_l = map([x, y + width], scale);
321 | if CANVAS.fill {
322 | let color = CANVAS.fill_color;
323 | add_to_fill(Vertex {
324 | position: b_r,
325 | color,
326 | tex_coords:[0f32,0f32],
327 | });
328 | add_to_fill(Vertex {
329 | position: t_r,
330 | color,
331 | tex_coords:[0f32,0f32],
332 | });
333 | add_to_fill(Vertex {
334 | position: t_l,
335 | color,
336 | tex_coords:[0f32,0f32],
337 | });
338 | add_to_fill(Vertex {
339 | position: t_l,
340 | color,
341 | tex_coords:[0f32,0f32],
342 | });
343 | add_to_fill(Vertex {
344 | position: b_l,
345 | color,
346 | tex_coords:[0f32,0f32],
347 | });
348 | add_to_fill(Vertex {
349 | position: b_r,
350 | color,
351 | tex_coords:[0f32,0f32],
352 | });
353 | }
354 | if CANVAS.stroke {
355 | let color = CANVAS.color;
356 | add_to_stroke(Vertex {
357 | position: t_l,
358 | color,
359 | tex_coords:[0f32,0f32],
360 | });
361 | add_to_stroke(Vertex {
362 | position: t_r,
363 | color,
364 | tex_coords:[0f32,0f32],
365 | });
366 | add_to_stroke(Vertex {
367 | position: t_r,
368 | color,
369 | tex_coords:[0f32,0f32],
370 | });
371 | add_to_stroke(Vertex {
372 | position: b_r,
373 | color,
374 | tex_coords:[0f32,0f32],
375 | });
376 | add_to_stroke(Vertex {
377 | position: b_l,
378 | color,
379 | tex_coords:[0f32,0f32],
380 | });
381 | add_to_stroke(Vertex {
382 | position: b_l,
383 | color,
384 | tex_coords:[0f32,0f32],
385 | });
386 | add_to_stroke(Vertex {
387 | position: t_l,
388 | color,
389 | tex_coords:[0f32,0f32],
390 | });
391 | }
392 | }
393 | }
394 | ///recieves the x and y of the top point and then the x and the y of the bottom point and creates a
395 | ///line between them.
396 | pub fn line(x: u16, y: u16, x2: u16, y2: u16) {
397 | unsafe {
398 | let scale = [CANVAS.size.0, CANVAS.size.1];
399 | let srt = map([x, y], scale);
400 | let fin = map([x2, y2], scale);
401 | let color = CANVAS.color;
402 | add_to_stroke(Vertex {
403 | position: srt,
404 | color,
405 | tex_coords:[0f32,0f32],
406 | });
407 | add_to_stroke(Vertex {
408 | position: fin,
409 | color,
410 | tex_coords:[0f32,0f32],
411 | });
412 | }
413 | }
414 | ///recieves the x and y of the 3 points of the triangle and creates it based on them
415 | pub fn triangle(x1: u16, y1: u16, x2: u16, y2: u16, x3: u16, y3: u16) {
416 | unsafe {
417 | let scale = [CANVAS.size.0, CANVAS.size.1];
418 | let pt1 = map([x1, y1], scale);
419 | let pt2 = map([x2, y2], scale);
420 | let pt3 = map([x3, y3], scale);
421 | if CANVAS.fill {
422 | let color = CANVAS.fill_color;
423 | add_to_fill(Vertex {
424 | position: pt1,
425 | color,
426 | tex_coords:[0f32,0f32],
427 | });
428 | add_to_fill(Vertex {
429 | position: pt2,
430 | color,
431 | tex_coords:[0f32,0f32],
432 | });
433 | add_to_fill(Vertex {
434 | position: pt3,
435 | color,
436 | tex_coords:[0f32,0f32],
437 | });
438 | }
439 | if CANVAS.stroke {
440 | let color = CANVAS.color;
441 | add_to_stroke(Vertex {
442 | position: pt1,
443 | color,
444 | tex_coords:[0f32,0f32],
445 | });
446 | add_to_stroke(Vertex {
447 | position: pt2,
448 | color,
449 | tex_coords:[0f32,0f32],
450 | });
451 | add_to_stroke(Vertex {
452 | position: pt2,
453 | color,
454 | tex_coords:[0f32,0f32],
455 | });
456 | add_to_stroke(Vertex {
457 | position: pt3,
458 | color,
459 | tex_coords:[0f32,0f32],
460 | });
461 | add_to_stroke(Vertex {
462 | position: pt3,
463 | color,
464 | tex_coords:[0f32,0f32],
465 | });
466 | add_to_stroke(Vertex {
467 | position: pt1,
468 | color,
469 | tex_coords:[0f32,0f32],
470 | });
471 | }
472 | }
473 | }
474 | ///recieves the x and y of the 4 points of the quad and creates it based on them
475 | pub fn quad(x1: u16, y1: u16, x2: u16, y2: u16, x3: u16, y3: u16, x4: u16, y4: u16) {
476 | unsafe {
477 | let scale = [CANVAS.size.0, CANVAS.size.1];
478 | let pt1 = map([x1, y1], scale);
479 | let pt2 = map([x2, y2], scale);
480 | let pt3 = map([x3, y3], scale);
481 | let pt4 = map([x4, y4], scale);
482 | if CANVAS.fill {
483 | let color = CANVAS.fill_color;
484 | add_to_fill(Vertex {
485 | position: pt1,
486 | color,
487 | tex_coords:[0f32,0f32],
488 | });
489 | add_to_fill(Vertex {
490 | position: pt2,
491 | color,
492 | tex_coords:[0f32,0f32],
493 | });
494 | add_to_fill(Vertex {
495 | position: pt3,
496 | color,
497 | tex_coords:[0f32,0f32],
498 | });
499 | add_to_fill(Vertex {
500 | position: pt4,
501 | color,
502 | tex_coords:[0f32,0f32],
503 | });
504 | }
505 | if CANVAS.stroke {
506 | let color = CANVAS.color;
507 | add_to_stroke(Vertex {
508 | position: pt1,
509 | color,
510 | tex_coords:[0f32,0f32],
511 | });
512 | add_to_stroke(Vertex {
513 | position: pt2,
514 | color,
515 | tex_coords:[0f32,0f32],
516 | });
517 | add_to_stroke(Vertex {
518 | position: pt2,
519 | color,
520 | tex_coords:[0f32,0f32],
521 | });
522 | add_to_stroke(Vertex {
523 | position: pt3,
524 | color,
525 | tex_coords:[0f32,0f32],
526 | });
527 | add_to_stroke(Vertex {
528 | position: pt3,
529 | color,
530 | tex_coords:[0f32,0f32],
531 | });
532 | add_to_stroke(Vertex {
533 | position: pt4,
534 | color,
535 | tex_coords:[0f32,0f32],
536 | });
537 | add_to_stroke(Vertex {
538 | position: pt4,
539 | color,
540 | tex_coords:[0f32,0f32],
541 | });
542 | add_to_stroke(Vertex {
543 | position: pt1,
544 | color,
545 | tex_coords:[0f32,0f32],
546 | });
547 | }
548 | }
549 | }
550 | ///recieves the x and the y of the center of the ellipse and the width and height of the ellipse
551 | ///and creates it accordingly
552 | pub fn ellipse(x: u16, y: u16, a: u16, b: u16) {
553 | unsafe {
554 | let scale = [CANVAS.size.0, CANVAS.size.1];
555 | if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
556 | let mut pt_x = x as f32 + a as f32;
557 | let mut pt_y = y as f32;
558 | for an in (0..360).step_by(6) {
559 | let ptx = x as f32 + ((an as f32 / 360.0) * 6.28).cos() * a as f32;
560 | let pty = y as f32 + ((an as f32 / 360.0) * 6.28).sin() * b as f32;
561 | add_to_stroke(Vertex {
562 | position: map_circ([pt_x, pt_y], scale),
563 | color: CANVAS.color,
564 | tex_coords:[0f32,0f32],
565 | });
566 | add_to_stroke(Vertex {
567 | position: map_circ([ptx, pty], scale),
568 | color: CANVAS.color,
569 | tex_coords:[0f32,0f32],
570 | });
571 | pt_x = ptx;
572 | pt_y = pty;
573 | }
574 | add_to_stroke(Vertex {
575 | position: map_circ([pt_x, pt_y], scale),
576 | color: CANVAS.color,
577 | tex_coords:[0f32,0f32],
578 | });
579 | pt_x = x as f32 + a as f32 + 0.5;
580 | pt_y = y as f32 + 0.5;
581 | add_to_stroke(Vertex {
582 | position: map_circ([pt_x, pt_y], scale),
583 | color: CANVAS.color,
584 | tex_coords:[0f32,0f32],
585 | });
586 | }
587 | if CANVAS.fill {
588 | let mut pt_x = x as f32 + a as f32;
589 | let mut pt_y = y as f32;
590 | for an in (0..360).step_by(6) {
591 | let ptx = x as f32 + ((an as f32 / 360.0) * 6.28).cos() * a as f32;
592 | let pty = y as f32 + ((an as f32 / 360.0) * 6.28).sin() * b as f32;
593 | add_to_fill(Vertex {
594 | position: map_circ([pt_x, pt_y], scale),
595 | color: CANVAS.fill_color,
596 | tex_coords:[0f32,0f32],
597 | });
598 | add_to_fill(Vertex {
599 | position: map_circ([ptx, pty], scale),
600 | color: CANVAS.fill_color,
601 | tex_coords:[0f32,0f32],
602 | });
603 | add_to_fill(Vertex {
604 | position: map_circ([x as f32, y as f32], scale),
605 | color: CANVAS.fill_color,
606 | tex_coords:[0f32,0f32],
607 | });
608 | pt_x = ptx;
609 | pt_y = pty;
610 | }
611 | add_to_fill(Vertex {
612 | position: map_circ([pt_x, pt_y], scale),
613 | color: CANVAS.fill_color,
614 | tex_coords:[0f32,0f32],
615 | });
616 | pt_x = x as f32 + a as f32 + 0.5;
617 | pt_y = y as f32 + 0.5;
618 | add_to_fill(Vertex {
619 | position: map_circ([pt_x, pt_y], scale),
620 | color: CANVAS.fill_color,
621 | tex_coords:[0f32,0f32],
622 | });
623 | add_to_fill(Vertex {
624 | position: map_circ([x as f32, y as f32], scale),
625 | color: CANVAS.fill_color,
626 | tex_coords:[0f32,0f32],
627 | });
628 | }
629 | }
630 | }
631 | ///recieves the x and y of the center of the circle and the radius and builds it with them.
632 | pub fn circle(x: u16, y: u16, rad: u16) {
633 | unsafe {
634 | let scale = [CANVAS.size.0, CANVAS.size.1];
635 | if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
636 | let mut pt_x = x as f32 + rad as f32;
637 | let mut pt_y = y as f32;
638 | for a in (0..360).step_by(6) {
639 | let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
640 | let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
641 | add_to_stroke(Vertex {
642 | position: map_circ([pt_x, pt_y], scale),
643 | color: CANVAS.color,
644 | tex_coords:[0f32,0f32],
645 | });
646 | add_to_stroke(Vertex {
647 | position: map_circ([ptx, pty], scale),
648 | color: CANVAS.color,
649 | tex_coords:[0f32,0f32],
650 | });
651 | pt_x = ptx;
652 | pt_y = pty;
653 | }
654 | add_to_stroke(Vertex {
655 | position: map_circ([pt_x, pt_y], scale),
656 | color: CANVAS.color,
657 | tex_coords:[0f32,0f32],
658 | });
659 | pt_x = x as f32 + rad as f32 + 0.5;
660 | pt_y = y as f32 + 0.5;
661 | add_to_stroke(Vertex {
662 | position: map_circ([pt_x, pt_y], scale),
663 | color: CANVAS.color,
664 | tex_coords:[0f32,0f32],
665 | });
666 | }
667 | if CANVAS.fill {
668 | let mut pt_x = x as f32 + rad as f32;
669 | let mut pt_y = y as f32;
670 | for a in (0..360).step_by(6) {
671 | let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
672 | let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
673 | add_to_fill(Vertex {
674 | position: map_circ([pt_x, pt_y], scale),
675 | color: CANVAS.fill_color,
676 | tex_coords:[0f32,0f32],
677 | });
678 | add_to_fill(Vertex {
679 | position: map_circ([ptx, pty], scale),
680 | color: CANVAS.fill_color,
681 | tex_coords:[0f32,0f32],
682 | });
683 | add_to_fill(Vertex {
684 | position: map_circ([x as f32, y as f32], scale),
685 | color: CANVAS.fill_color,
686 | tex_coords:[0f32,0f32],
687 | });
688 | pt_x = ptx;
689 | pt_y = pty;
690 | }
691 | add_to_fill(Vertex {
692 | position: map_circ([pt_x, pt_y], scale),
693 | color: CANVAS.fill_color,
694 | tex_coords:[0f32,0f32],
695 | });
696 | pt_x = x as f32 + rad as f32 + 0.5;
697 | pt_y = y as f32 + 0.5;
698 | add_to_fill(Vertex {
699 | position: map_circ([pt_x, pt_y], scale),
700 | color: CANVAS.fill_color,
701 | tex_coords:[0f32,0f32],
702 | });
703 | add_to_fill(Vertex {
704 | position: map_circ([x as f32, y as f32], scale),
705 | color: CANVAS.fill_color,
706 | tex_coords:[0f32,0f32],
707 | });
708 | }
709 | }
710 | }
711 | ///recieves the x and the y and makes a small circle in the spot(size depends on strokeWeight).
712 | pub fn point(x: u16, y: u16) {
713 | unsafe {
714 | let stro = CANVAS.stroke;
715 | let fil = CANVAS.fill;
716 | CANVAS.stroke = false;
717 | CANVAS.fill = true;
718 | circle(x, y, CANVAS.stroke_weight as u16);
719 | CANVAS.stroke = stro;
720 | CANVAS.fill = fil;
721 | }
722 | }
723 | ///enables fill and receives the color of the fill(the struct color) and sets the fill color to be
724 | ///the color.
725 | pub fn fill(color: Color) {
726 | let r = color.get_r();
727 | let g = color.get_g();
728 | let b = color.get_b();
729 | let a = color.get_a();
730 | unsafe {
731 | CANVAS.fill = true;
732 | CANVAS.fill_color = mapping::map_colors([r, g, b, a]);
733 | }
734 | }
735 | ///enables stroke and receives the color of the stroke(the struct color) and sets the stroke color to be
736 | ///the color.
737 | pub fn stroke(color: Color) {
738 | let r = color.get_r();
739 | let g = color.get_g();
740 | let b = color.get_b();
741 | let a = color.get_a();
742 | unsafe {
743 | CANVAS.stroke = true;
744 | CANVAS.color = mapping::map_colors([r, g, b, a]);
745 | }
746 | }
747 | ///sets the background color(using the color struct).
748 | pub fn background(color: Color) {
749 | let r = color.get_r();
750 | let g = color.get_g();
751 | let b = color.get_b();
752 | let a = color.get_a();
753 | unsafe {
754 | CANVAS.background_color = mapping::map_colors([r, g, b, a]);
755 | }
756 | }
757 | ///sets the stroke weight(the width of lines and points
758 | #[allow(non_snake_case)]
759 | pub fn strokeWeight(weight: u8) {
760 | unsafe {
761 | CANVAS.stroke_weight = weight;
762 | }
763 | }
764 | ///disables fill on the canvas.
765 | #[allow(non_snake_case)]
766 | pub fn noFill() {
767 | unsafe {
768 | CANVAS.fill = false;
769 | }
770 | }
771 | ///disables stroke on the canvas.
772 | #[allow(non_snake_case)]
773 | pub fn noStroke() {
774 | unsafe {
775 | CANVAS.stroke = false;
776 | }
777 | }
778 | ///create an arc from a circle, recieves the center of the circle and the radius and the degrees
779 | ///covered by the arc (360 degree arc is a full circle).
780 | pub fn arc(x: u16, y: u16, rad: u16, deg: u16) {
781 | unsafe {
782 | let scale = [CANVAS.size.0, CANVAS.size.1];
783 | if CANVAS.stroke && !(CANVAS.fill && CANVAS.color == CANVAS.fill_color) {
784 | let mut pt_x = x as f32 + rad as f32;
785 | let mut pt_y = y as f32;
786 | for a in (0..deg + 6).step_by(6) {
787 | let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
788 | let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
789 | add_to_stroke(Vertex {
790 | position: map_circ([pt_x, pt_y], scale),
791 | color: CANVAS.color,
792 | tex_coords:[0f32,0f32],
793 | });
794 | add_to_stroke(Vertex {
795 | position: map_circ([ptx, pty], scale),
796 | color: CANVAS.color,
797 | tex_coords:[0f32,0f32],
798 | });
799 | pt_x = ptx;
800 | pt_y = pty;
801 | }
802 | }
803 | if CANVAS.fill {
804 | let mut pt_x = x as f32 + rad as f32;
805 | let mut pt_y = y as f32;
806 | for a in (0..deg + 6).step_by(6) {
807 | let ptx = x as f32 + ((a as f32 / 360.0) * 6.28).cos() * rad as f32;
808 | let pty = y as f32 + ((a as f32 / 360.0) * 6.28).sin() * rad as f32;
809 | add_to_fill(Vertex {
810 | position: map_circ([pt_x, pt_y], scale),
811 | color: CANVAS.fill_color,
812 | tex_coords:[0f32,0f32],
813 | });
814 | add_to_fill(Vertex {
815 | position: map_circ([ptx, pty], scale),
816 | color: CANVAS.fill_color,
817 | tex_coords:[0f32,0f32],
818 | });
819 | add_to_fill(Vertex {
820 | position: map_circ([x as f32, y as f32], scale),
821 | color: CANVAS.fill_color,
822 | tex_coords:[0f32,0f32],
823 | });
824 | pt_x = ptx;
825 | pt_y = pty;
826 | }
827 | }
828 | }
829 | }
830 | ///loopes over the array and uses curveVertex to create a bezier curve
831 | #[allow(non_snake_case)]
832 | pub fn bezierCurve(ptvec: Vec<[i64; 2]>) {
833 | for i in 0..(ptvec.len() - 3) {
834 | if (i + 1) % 4 == 0 || i == 0 {
835 | bezierCurveVertex(
836 | ptvec[i][0],
837 | ptvec[i][1],
838 | ptvec[i + 1][0],
839 | ptvec[i + 1][1],
840 | ptvec[i + 2][0],
841 | ptvec[i + 2][1],
842 | ptvec[i + 3][0],
843 | ptvec[i + 3][1],
844 | );
845 | }
846 | }
847 | }
848 | ///loopes over the array and uses curveVertex to create a catmull rom chain curve
849 | pub fn curve(ptvec: Vec<[i64; 2]>) {
850 | for i in 0..(ptvec.len() - 3) {
851 | bezierCurveVertex(
852 | ptvec[i][0],
853 | ptvec[i][1],
854 | ptvec[i + 1][0],
855 | ptvec[i + 1][1],
856 | ptvec[i + 2][0],
857 | ptvec[i + 2][1],
858 | ptvec[i + 3][0],
859 | ptvec[i + 3][1],
860 | );
861 | }
862 | }
863 | ///uses the catmull rom chain algorithm in order to create a curve
864 | #[allow(non_snake_case)]
865 | pub fn curveVertex(x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64, x4: i64, y4: i64) {
866 | let c = catmull_rom_chain(x1, y1, x2, y2, x3, y3, x4, y4);
867 | unsafe {
868 | let scale = [CANVAS.size.0, CANVAS.size.1];
869 | for pt in c.iter() {
870 | add_to_stroke(Vertex {
871 | position: mapf(*pt, scale),
872 | color: CANVAS.color,
873 | tex_coords:[0f32,0f32],
874 | });
875 | }
876 | }
877 | }
878 | ///uses the cubic bezier curve algorithm in order to create a curve
879 | #[allow(non_snake_case)]
880 | pub fn bezierCurveVertex(x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64, x4: i64, y4: i64) {
881 | let c = bezier_points(x1, y1, x2, y2, x3, y3, x4, y4);
882 | unsafe {
883 | let scale = [CANVAS.size.0, CANVAS.size.1];
884 | let mut ptnxt = c[0];
885 | for pt in c.iter() {
886 | add_to_stroke(Vertex {
887 | position: mapf(ptnxt, scale),
888 | color: CANVAS.color,
889 | tex_coords:[0f32,0f32],
890 | });
891 | add_to_stroke(Vertex {
892 | position: mapf(*pt, scale),
893 | color: CANVAS.color,
894 | tex_coords:[0f32,0f32],
895 | });
896 | ptnxt = *pt;
897 | }
898 | }
899 | }
900 | ///drawes a text of a certain color and locaion on the canvas
901 | pub fn text(x:u16,y:u16,text:&'static str){
902 | unsafe{
903 | add_to_text(Stext{
904 | position: [x as f32,y as f32],
905 | color: CANVAS.color,
906 | text: text,
907 | });
908 | }
909 | }
910 | ///This struct is meant for loading and saving the image once and not every frame
911 | #[derive(Clone)]
912 | pub struct Image{
913 | pub image_data:Vec,
914 | pub dimensions:Dimensions,
915 | }
916 | ///takes a path to the image and loads it into an Image struct
917 | ///should strictly be used outside the draw loop!
918 | #[allow(non_snake_case)]
919 | pub fn img(path:&str)->Image{
920 | let decoder = png::Decoder::new(File::open(path).unwrap());
921 | let (info, mut reader) = decoder.read_info().unwrap();
922 | let mut image_data = Vec::new();
923 | image_data.resize((info.width * info.height * 4) as usize, 0);
924 | reader.next_frame(&mut image_data).unwrap();
925 | let dimensions = Dimensions::Dim2d { width: info.width, height: info.height };
926 | Image{image_data,dimensions}
927 | }
928 | impl Image{
929 | ///this function shoould be used inside the draw loop, because it does not load an image, it
930 | ///simply displays a loaded image
931 | pub fn display(self,x:u16,y:u16){
932 | unsafe {
933 | let scale = [CANVAS.size.0, CANVAS.size.1];
934 | let _imsize = [self.dimensions.width() as u16,self.dimensions.height() as u16];
935 | add_to_fill(Vertex {
936 | position: map([x,y], scale),
937 | color: CANVAS.color,
938 | //tex_coords: map_tex(map([x,y], scale),imsize),
939 | tex_coords: map([x,y], scale),
940 | });
941 | add_to_fill(Vertex {
942 | position: map([x+(self.dimensions.width() as u16),y], scale),
943 | color: CANVAS.color,
944 | //tex_coords: map_tex(map([x+(self.dimensions.width() as u16),y], scale),imsize),
945 | tex_coords: map([x+(self.dimensions.width() as u16),y], scale),
946 | });
947 | add_to_fill(Vertex {
948 | position: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
949 | color: CANVAS.color,
950 | //tex_coords: map_tex(map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),imsize),
951 | tex_coords: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
952 | });
953 | add_to_fill(Vertex {
954 | position: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
955 | color: CANVAS.color,
956 | //tex_coords: map_tex(map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),imsize),
957 | tex_coords: map([x+(self.dimensions.width() as u16),y+(self.dimensions.height() as u16)], scale),
958 | });
959 | add_to_fill(Vertex {
960 | position: map([x,y], scale),
961 | color: CANVAS.color,
962 | //tex_coords: map_tex(map([x,y], scale),imsize),
963 | tex_coords: map([x,y], scale),
964 | });
965 | add_to_fill(Vertex {
966 | position: map([x,y+(self.dimensions.height() as u16)], scale),
967 | color: CANVAS.color,
968 | //tex_coords: map_tex(map([x,(y+(self.dimensions.height() as u16))], scale),imsize),
969 | tex_coords: map([x,(y+(self.dimensions.height() as u16))], scale),
970 | });
971 | //println!("pos:{:?}\ntex:{:?}",FILL_VERTECIES.clone().unwrap()[0].position,FILL_VERTECIES.clone().unwrap()[0].tex_coords);
972 | TEXTURE = Some((self.image_data,self.dimensions));
973 | }
974 | }
975 | }
976 |
--------------------------------------------------------------------------------
/src/mapping.rs:
--------------------------------------------------------------------------------
1 | pub fn map(point: [u16; 2], scale: [u16; 2]) -> [f32; 2] {
2 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Copy+Clone+PartialEq{
3 | let new_point: [f32; 2] = [
4 | (point[0] as f32 / scale[0] as f32),
5 | (point[1] as f32 / scale[1] as f32),
6 | ];
7 | [(new_point[0] * 2.0) - 1.0, (new_point[1] * 2.0) - 1.0]
8 | }
9 | pub fn map_colors(color: [u8; 4]) -> [f32; 4] {
10 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Copy+Clone+PartialEq{
11 | [
12 | color[0] as f32 / 255.0,
13 | color[1] as f32 / 255.0,
14 | color[2] as f32 / 255.0,
15 | color[3] as f32 / 255.0,
16 | ]
17 | }
18 | pub fn map_circ(point: [f32; 2], scale: [u16; 2]) -> [f32; 2] {
19 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Copy+Clone+PartialEq{
20 | let new_point: [f32; 2] = [(point[0] / scale[0] as f32), (point[1] / scale[1] as f32)];
21 | [(new_point[0] * 2.0) - 1.0, (new_point[1] * 2.0) - 1.0]
22 | }
23 | pub fn mapf(point: [f64; 2], scale: [u16; 2]) -> [f32; 2] {
24 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Copy+Clone+PartialEq{
25 | let new_point: [f32; 2] = [
26 | (point[0] as f32 / scale[0] as f32),
27 | (point[1] as f32 / scale[1] as f32),
28 | ];
29 | [(new_point[0] * 2.0) - 1.0, (new_point[1] * 2.0) - 1.0]
30 | }
31 | /*#[allow(dead_code)]
32 | pub fn map_tex(point: [f32; 2], scale: [u16; 2]) -> [f32; 2] {
33 | let new_point: [f32; 2] = [
34 | (point[0]/ scale[0] as f32),
35 | (point[1]/ scale[1] as f32),
36 | ];
37 | new_point
38 | }*/
39 | pub fn map_tex(point: [f32; 2], scale: [u16; 2]) -> [f32; 2] {
40 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Copy+Clone+PartialEq{
41 | let new_point: [f32; 2] = [
42 | (point[0]/ scale[0] as f32),
43 | (point[1]/ scale[1] as f32),
44 | ];
45 | [(new_point[0]), (new_point[1])]
46 | }
47 |
--------------------------------------------------------------------------------
/src/math.rs:
--------------------------------------------------------------------------------
1 | use crate::compute::*;
2 | use crate::vector::*;
3 | use std::ops::Add;
4 | use std::ops::Div;
5 | use std::ops::Mul;
6 | use std::ops::Sub;
7 | ///converts degrees to radians
8 | ///
9 | ///```
10 | ///use metropolis::math::*;
11 | ///assert_eq!(rad(90.0),PI/2.0);
12 | ///```
13 | pub fn rad(x: f32) -> f32 {
14 | (x / 180.0) * PI
15 | }
16 | ///converts radians to degrees
17 | ///
18 | ///```
19 | ///use metropolis::math::*;
20 | ///assert_eq!(deg(PI),180.0);
21 | ///```
22 | pub fn deg(x: f32) -> f32 {
23 | x * 180.0 / PI
24 | }
25 | /*
26 | ///uses Taylor's series to determine sinus at the x, for now accepts f32, in the future also u/i
27 | pub fn sin(x: f32) -> f32 {
28 | #[allow(illegal_floating_point_literal_pattern)]
29 | match x {
30 | 90.0 => {
31 | return 1.0;
32 | }
33 | 0.0 => {
34 | return 0.0;
35 | }
36 | 30.0 => {
37 | return 0.5;
38 | }
39 | _ => {
40 | let ang = rad(x % 360.0);
41 | return ang - ang.powf(3.0) / 6.0 + ang.powf(5.0) / 120.0 - ang.powf(7.0) / 5040.0;
42 | }
43 | };
44 | }
45 | /*pub fn cos(x:T) -> f32
46 | where T:Add+Sub+Div+Mul+Sub+Mul+Copy+Div+Copy+Add+Copy+Sub+Sub+Div+Copy+Clone+PartialEq+Ord{
47 | //where T:Add+Sub+Div+Mul+Sub+Add+Div+Mul+Mul+Copy+Div+Copy+Add+Copy+Sub+Sub+Div+Copy+Clone+PartialEq+PartialOrd{
48 | //where T:numerous{*/
49 | ///uses sin(90-alpha) in order to calculate cosine
50 | pub fn cos(x: f32) -> f32 {
51 | if x <= 90.0 {
52 | return sin(90.0 - x);
53 | } else if x <= 18.0 {
54 | return -1.0 * sin(180.0 - x);
55 | } else if x <= 270.0 {
56 | return sin(270.0 - x);
57 | } else {
58 | return -1.0 * sin(360.0 - x);
59 | }
60 | }
61 | ///uses sin(x)/cos(x) in order to calculate tan(x)
62 | pub fn tan(x: f32) -> f32 {
63 | sin(x) / cos(x)
64 | }*/
65 | ///calculates the factorial of a number
66 | ///
67 | ///```
68 | ///use metropolis::math::*;
69 | ///assert_eq!(factorial(6),720);
70 | ///```
71 | pub fn factorial(n: u64) -> u64 {
72 | real_factorial(n, 1)
73 | }
74 | fn real_factorial(n: u64, mut accume: u64) -> u64 {
75 | if n == 1 {
76 | return accume;
77 | }
78 | accume *= n;
79 | real_factorial(n - 1, accume)
80 | }
81 | /*///returns the absolute value of the number i number
82 | ///
83 | ///```
84 | ///use metropolis::math::*;
85 | ///assert_eq!(abs(-1),1);
86 | ///```
87 | pub fn abs(x: T) -> T
88 | where
89 | T: Copy + Clone + Add + Sub + Div + Mul+ Mul + PartialOrd+PartialEq,
90 | {
91 | if x<(x*-1){
92 | return x*-1;
93 | }
94 | x
95 | }
96 | ///returns the absolute value of the number f number
97 | ///
98 | ///```
99 | ///use metropolis::math::*;
100 | ///assert_eq!(absf(-1.5),1.5);
101 | ///```
102 | pub fn absf(x: T) -> T
103 | where
104 | T: Copy + Clone + Add + Sub + Div + Mul+ Mul + PartialOrd+PartialEq,
105 | {
106 | if x<(x*-1.0){
107 | return x*-1.0;
108 | }
109 | x
110 | }*/
111 | ///converts from one range to another
112 | ///
113 | ///```
114 | ///use metropolis::math::*;
115 | ///assert_eq!(map(1.0,0.0,2.0,0.0,1.0),0.5);
116 | ///```
117 | pub fn map(x: T, a1: T, a2: T, b1: T, b2: T) -> f64
118 | where
119 | T: Copy + Clone + Add + Sub + Div + Mul + Sub + Add,
120 | {
121 | b1 + ((x - a1) / (a2 - a1) * (b2 - b1))
122 | }
123 | #[allow(clippy::approx_constant)]
124 | pub const PI: f32 = 3.14159265359;
125 | pub const TWO_PI: f32 = PI * 2.0;
126 | ///create evenly spaced points inside the space between two points:
127 | ///```
128 | ///use metropolis::math::*;
129 | ///assert_eq!(linspace(0.0,1.0,4),vec![0.0,0.25,0.5,0.75,1.0]);
130 | ///```
131 | pub fn linspace(start: f64, finish: f64, n: u64) -> Vec {
132 | let mut vec1 = vec![];
133 | for i in 0..(n + 1) {
134 | vec1.push(((finish - start) / n as f64) * i as f64 + start);
135 | }
136 | vec1
137 | }
138 | ///takes 8 values(4 x's and 4 y's ad constructs a 100 points array of a catmull rom chain curve
139 | ///from them using he algorithm.
140 | pub fn catmull_rom_chain(
141 | x1: i64,
142 | y1: i64,
143 | x2: i64,
144 | y2: i64,
145 | x3: i64,
146 | y3: i64,
147 | x4: i64,
148 | y4: i64,
149 | ) -> [[f64; 2]; 100] {
150 | let t0 = 0f64;
151 | let t1 = (((x2 - x1).pow(2) + (y2 - y1).pow(2)) as f64).sqrt().sqrt() + t0 as f64;
152 | let t2 = (((x3 - x2).pow(2) + (y3 - y2).pow(2)) as f64).sqrt().sqrt() + t1 as f64;
153 | let t3 = (((x4 - x3).pow(2) + (y4 - y3).pow(2)) as f64).sqrt().sqrt() + t2 as f64;
154 | let t = linspace_in(t1, t2);
155 | let tt = Vector{vec:linspace_in(t1, t2).to_vec()};
156 | let ttt = [((tt.clone()*-1.0+t1)/(t1+t0)*(x1 as f64))+((tt.clone()-t0)/(t1-t0)*(x2 as f64)),(tt.clone()*-1.0+t1)/(t1+t0)*(y1 as f64)+((tt.clone()-t0)/(t1-t0)*(y2 as f64))];
157 | let ttt2 = [((tt.clone()*-1.0+t2)/(t2+t1)*(x2 as f64))+((tt.clone()-t1)/(t2-t1)*(x3 as f64)),(tt.clone()*-1.0+t2)/(t2+t1)*(y2 as f64)+((tt.clone()-t1)/(t2-t1)*(y3 as f64))];
158 | let ttt3 = [((tt.clone()*-1.0+t3)/(t3+t2)*(x3 as f64))+((tt.clone()-t2)/(t3-t2)*(x4 as f64)),(tt.clone()*-1.0+t3)/(t3+t2)*(y3 as f64)+((tt.clone()-t2)/(t3-t2)*(y4 as f64))];
159 | println!("{:?}",ttt);
160 | let a11 = [
161 | compute_ops(
162 | compute_ops(
163 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t1, ops::FloatAdd),
164 | t1 - t0,
165 | ops::FloatDiv,
166 | ),
167 | x1 as f64,
168 | ops::FloatMult,
169 | ),
170 | compute_ops(
171 | compute_ops(
172 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t1, ops::FloatAdd),
173 | t1 - t0,
174 | ops::FloatDiv,
175 | ),
176 | y1 as f64,
177 | ops::FloatMult,
178 | ),
179 | ];
180 | let a12 = [
181 | compute_ops(
182 | compute_ops(compute_ops(t, t0, ops::FloatSub), t1 - t0, ops::FloatDiv),
183 | x2 as f64,
184 | ops::FloatMult,
185 | ),
186 | compute_ops(
187 | compute_ops(compute_ops(t, t0, ops::FloatAdd), t1 - t0, ops::FloatDiv),
188 | y2 as f64,
189 | ops::FloatMult,
190 | ),
191 | ];
192 | let a1 = [
193 | compute_ops2(a11[0], a12[0], ops::FloatAddVecs),
194 | compute_ops2(a11[1], a12[1], ops::FloatAddVecs),
195 | ];
196 | let a21 = [
197 | compute_ops(
198 | compute_ops(
199 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t2, ops::FloatAdd),
200 | t2 - t1,
201 | ops::FloatDiv,
202 | ),
203 | x2 as f64,
204 | ops::FloatMult,
205 | ),
206 | compute_ops(
207 | compute_ops(
208 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t2, ops::FloatAdd),
209 | t2 - t1,
210 | ops::FloatDiv,
211 | ),
212 | y2 as f64,
213 | ops::FloatMult,
214 | ),
215 | ];
216 | let a22 = [
217 | compute_ops(
218 | compute_ops(compute_ops(t, t1, ops::FloatSub), t2 - t1, ops::FloatDiv),
219 | x3 as f64,
220 | ops::FloatMult,
221 | ),
222 | compute_ops(
223 | compute_ops(compute_ops(t, t1, ops::FloatAdd), t2 - t1, ops::FloatDiv),
224 | y3 as f64,
225 | ops::FloatMult,
226 | ),
227 | ];
228 | let a2 = [
229 | compute_ops2(a21[0], a22[0], ops::FloatAddVecs),
230 | compute_ops2(a21[1], a22[1], ops::FloatAddVecs),
231 | ];
232 | let a31 = [
233 | compute_ops(
234 | compute_ops(
235 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t3, ops::FloatAdd),
236 | t3 - t2,
237 | ops::FloatDiv,
238 | ),
239 | x3 as f64,
240 | ops::FloatMult,
241 | ),
242 | compute_ops(
243 | compute_ops(
244 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t3, ops::FloatAdd),
245 | t3 - t2,
246 | ops::FloatDiv,
247 | ),
248 | y3 as f64,
249 | ops::FloatMult,
250 | ),
251 | ];
252 | let a32 = [
253 | compute_ops(
254 | compute_ops(compute_ops(t, t2, ops::FloatSub), t3 - t2, ops::FloatDiv),
255 | x4 as f64,
256 | ops::FloatMult,
257 | ),
258 | compute_ops(
259 | compute_ops(compute_ops(t, t2, ops::FloatAdd), t3 - t2, ops::FloatDiv),
260 | y4 as f64,
261 | ops::FloatMult,
262 | ),
263 | ];
264 | let a3 = [
265 | compute_ops2(a31[0], a32[0], ops::FloatAddVecs),
266 | compute_ops2(a31[1], a32[1], ops::FloatAddVecs),
267 | ];
268 | let b11 = [
269 | compute_ops2(
270 | compute_ops(
271 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t2, ops::FloatAdd),
272 | t2 - t0,
273 | ops::FloatDiv,
274 | ),
275 | a1[0],
276 | ops::FloatMultVecs,
277 | ),
278 | compute_ops2(
279 | compute_ops(
280 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t2, ops::FloatAdd),
281 | t2 - t0,
282 | ops::FloatDiv,
283 | ),
284 | a1[1],
285 | ops::FloatMultVecs,
286 | ),
287 | ];
288 | let b12 = [
289 | compute_ops2(
290 | compute_ops(compute_ops(t, t0, ops::FloatSub), t2 - t0, ops::FloatDiv),
291 | a2[0],
292 | ops::FloatMultVecs,
293 | ),
294 | compute_ops2(
295 | compute_ops(compute_ops(t, t2, ops::FloatAdd), t2 - t0, ops::FloatDiv),
296 | a2[1],
297 | ops::FloatMultVecs,
298 | ),
299 | ];
300 | let b1 = [
301 | compute_ops2(b11[0], b12[0], ops::FloatAddVecs),
302 | compute_ops2(b11[1], b12[1], ops::FloatAddVecs),
303 | ];
304 | let b21 = [
305 | compute_ops2(
306 | compute_ops(
307 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t3, ops::FloatAdd),
308 | t3 - t1,
309 | ops::FloatDiv,
310 | ),
311 | a2[0],
312 | ops::FloatMultVecs,
313 | ),
314 | compute_ops2(
315 | compute_ops(
316 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t3, ops::FloatAdd),
317 | t3 - t1,
318 | ops::FloatDiv,
319 | ),
320 | a2[1],
321 | ops::FloatMultVecs,
322 | ),
323 | ];
324 | let b22 = [
325 | compute_ops2(
326 | compute_ops(compute_ops(t, t1, ops::FloatSub), t3 - t1, ops::FloatDiv),
327 | a3[0],
328 | ops::FloatMultVecs,
329 | ),
330 | compute_ops2(
331 | compute_ops(compute_ops(t, t1, ops::FloatAdd), t3 - t1, ops::FloatDiv),
332 | a3[1],
333 | ops::FloatMultVecs,
334 | ),
335 | ];
336 | let b2 = [
337 | compute_ops2(b21[0], b22[0], ops::FloatAddVecs),
338 | compute_ops2(b21[1], b22[1], ops::FloatAddVecs),
339 | ];
340 |
341 | let c11 = [
342 | compute_ops2(
343 | compute_ops(
344 | compute_ops(compute_ops(t, -1.0, ops::FloatMult), t2, ops::FloatAdd),
345 | t2 - t1,
346 | ops::FloatDiv,
347 | ),
348 | b1[0],
349 | ops::FloatMultVecs,
350 | ),
351 | compute_ops2(
352 | compute_ops(
353 | compute_ops(compute_ops(t, -1f64, ops::FloatMult), t2, ops::FloatAdd),
354 | t2 - t1,
355 | ops::FloatDiv,
356 | ),
357 | b1[1],
358 | ops::FloatMultVecs,
359 | ),
360 | ];
361 | let c12 = [
362 | compute_ops2(
363 | compute_ops(compute_ops(t, t1, ops::FloatSub), t2 - t1, ops::FloatDiv),
364 | b2[0],
365 | ops::FloatMultVecs,
366 | ),
367 | compute_ops2(
368 | compute_ops(compute_ops(t, t1, ops::FloatAdd), t2 - t1, ops::FloatDiv),
369 | b2[1],
370 | ops::FloatMultVecs,
371 | ),
372 | ];
373 | let c1 = [
374 | compute_ops2(c11[0], c12[0], ops::FloatAddVecs),
375 | compute_ops2(c11[1], c12[1], ops::FloatAddVecs),
376 | ];
377 | let mut c: [[f64; 2]; 100] = [[0f64; 2]; 100];
378 | for i in 0..99 {
379 | c[i] = [c1[0][i], c1[1][i]];
380 | }
381 | c
382 | }
383 | fn linspace_in(start: f64, finish: f64) -> [f64; 100] {
384 | let mut arr1: [f64; 100] = [0.0; 100];
385 | for i in 0..(99) {
386 | arr1[i] = ((finish - start) / 100 as f64) * i as f64 + start;
387 | }
388 | arr1
389 | }
390 | pub fn bezier_points(
391 | x1: i64,
392 | y1: i64,
393 | x2: i64,
394 | y2: i64,
395 | x3: i64,
396 | y3: i64,
397 | x4: i64,
398 | y4: i64,
399 | ) -> [[f64; 2]; 101] {
400 | let mut t: f64;
401 | let mut b: [f64; 2];
402 | let mut arr_b = [[0f64; 2]; 101];
403 | for i in 0..101 {
404 | t = i as f64 / 100.0;
405 | b = [
406 | ((1.0 - t).powf(3.0) * x1 as f64)
407 | + (3.0 * (1.0 - t).powf(2.0) * t) * x2 as f64
408 | + (3.0 * (1.0 - t) * t.powf(2.0)) * x3 as f64
409 | + (t.powf(3.0)) * x4 as f64,
410 | ((1.0 - t).powf(3.0) * y1 as f64)
411 | + (3.0 * (1.0 - t).powf(2.0) * t) * y2 as f64
412 | + (3.0 * (1.0 - t) * t.powf(2.0)) * y3 as f64
413 | + (t.powf(3.0)) * y4 as f64,
414 | ];
415 | arr_b[i] = b;
416 | }
417 | arr_b
418 | }
419 |
--------------------------------------------------------------------------------
/src/page.rs:
--------------------------------------------------------------------------------
1 | use crate::elements::PageElements;
2 | use crate::canvas::Canvas;
3 | use crate::mapping;
4 | use vulkano::image::Dimensions;
5 | //use winit::MouseScrollDelta;
6 | use winit::{ModifiersState/*,KeyboardInput,ElementState,Event, WindowEvent*/,VirtualKeyCode};
7 | pub use winit::MouseButton;
8 | use crate::color::Color;
9 | #[derive(Copy,Clone,PartialEq)]
10 | struct MouseScroll{
11 | pub delta:(i64,i64),
12 | pub moder:ModifiersState,
13 | }
14 | impl MouseScroll{
15 | pub fn new()->MouseScroll{
16 | let moder = ModifiersState{shift:false,ctrl:false,alt:false,logo:false};
17 | let delta = (0,0);
18 | MouseScroll{delta,moder}
19 | }
20 | pub fn delta_x(self)->i64{
21 | self.delta.0
22 | }
23 | pub fn delta_y(self)->i64{
24 | self.delta.1//.PixelDelta.y as i64
25 | }
26 | }
27 | #[derive(Copy,Clone,PartialEq)]
28 | struct Mouse{
29 | pub btn:Option,
30 | pub moder:ModifiersState,
31 | }
32 | impl Mouse{
33 | pub fn new()->Mouse{
34 | let moder = ModifiersState{shift:false,ctrl:false,alt:false,logo:false};
35 | let btn = None;
36 | Mouse{btn,moder}
37 | }
38 | }
39 | #[derive(Copy,Clone,PartialEq)]
40 | struct Key{
41 | pub keycode:Option,
42 | pub moder:ModifiersState,
43 | pub keep_key: bool,
44 | }
45 | impl Key{
46 | pub fn new()->Key{
47 | let moder = ModifiersState{shift:false,ctrl:false,alt:false,logo:false};
48 | let keycode = None;
49 | Key{keycode,moder,keep_key:false}
50 | }
51 | pub fn get_mod(self)->ModifiersState{
52 | self.moder
53 | }
54 | }
55 | #[derive(Clone)]
56 | struct Page{
57 | size: (u16, u16),
58 | background: [f32; 4],
59 | texture:Option<(Vec,Dimensions)>,
60 | elements:Vec,
61 | canvases:Vec