Use structs with Drawable trait instead of methods on shm_pool
This commit is contained in:
39
src/graphics/circle.rs
Normal file
39
src/graphics/circle.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
use crate::wayland::shm::ShmPool;
|
||||||
|
use super::drawable::{Drawable, color_blend};
|
||||||
|
|
||||||
|
// x and y are center of circle
|
||||||
|
pub struct Circle {
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
radius: usize,
|
||||||
|
color: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Circle {
|
||||||
|
pub fn new(x: usize, y: usize, radius: usize, color: u32) -> Self {
|
||||||
|
Circle { x, y, radius, color }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawable for Circle {
|
||||||
|
fn draw(&self, shm_pool: &mut ShmPool) {
|
||||||
|
for l_row in 1..self.radius {
|
||||||
|
let inner_diff = (((self.radius-1).pow(2) - l_row.pow(2)) as f64).sqrt();
|
||||||
|
let outer_diff = ((self.radius.pow(2) - l_row.pow(2)) as f64).sqrt();
|
||||||
|
let row: Vec<u32> = vec![self.color; 2*(inner_diff.floor() as usize)];
|
||||||
|
shm_pool.write(&row, (self.y-l_row)*shm_pool.width + self.x - inner_diff.floor() as usize);
|
||||||
|
shm_pool.write(&row, (self.y+l_row-1)*shm_pool.width + self.x - inner_diff.floor() as usize);
|
||||||
|
for l_col in (inner_diff.floor() as usize+1)..(outer_diff.ceil() as usize) {
|
||||||
|
let distance = ((l_row.pow(2) + l_col.pow(2)) as f64).sqrt();
|
||||||
|
let offset = (self.y-l_row)*shm_pool.width + self.x - l_col;
|
||||||
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
|
let offset = (self.y-l_row)*shm_pool.width + self.x + l_col-1;
|
||||||
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
|
let offset = (self.y+l_row-1)*shm_pool.width + self.x - l_col;
|
||||||
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
|
let offset = (self.y+l_row-1)*shm_pool.width + self.x + l_col-1;
|
||||||
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/graphics/drawable.rs
Normal file
31
src/graphics/drawable.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use crate::wayland::shm::ShmPool;
|
||||||
|
|
||||||
|
pub fn color_blend(col1: u32, col2: u32, diff: f64) -> u32 {
|
||||||
|
// TODO: Account for alpha channel
|
||||||
|
let r1 = (col1 & 0x00ff0000) >> 16;
|
||||||
|
let g1 = (col1 & 0x0000ff00) >> 8;
|
||||||
|
let b1 = col1 & 0x000000ff;
|
||||||
|
let r2 = (col2 & 0x00ff0000) >> 16;
|
||||||
|
let g2 = (col2 & 0x0000ff00) >> 8;
|
||||||
|
let b2 = col2 & 0x000000ff;
|
||||||
|
let r3 = if r1 < r2 {
|
||||||
|
r1 + ((r2 - r1) as f64 * diff) as u32
|
||||||
|
} else {
|
||||||
|
r1 - ((r1 - r2) as f64 * diff) as u32
|
||||||
|
};
|
||||||
|
let g3 = if g1 < g2 {
|
||||||
|
g1 + ((g2 - g1) as f64 * diff) as u32
|
||||||
|
} else {
|
||||||
|
g1 - ((g1 - g2) as f64 * diff) as u32
|
||||||
|
};
|
||||||
|
let b3 = if b1 < b2 {
|
||||||
|
b1 + ((b2 - b1) as f64 * diff) as u32
|
||||||
|
} else {
|
||||||
|
b1 - ((b1 - b2) as f64 * diff) as u32
|
||||||
|
};
|
||||||
|
return 0xff000000 + (r3 << 16) + (g3 << 8) + b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Drawable {
|
||||||
|
fn draw(&self, shm_pool: &mut ShmPool);
|
||||||
|
}
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
|
|
||||||
|
pub mod drawable;
|
||||||
pub mod rectangle;
|
pub mod rectangle;
|
||||||
|
pub mod circle;
|
||||||
|
|||||||
@@ -1,94 +1,45 @@
|
|||||||
use std::usize;
|
|
||||||
|
|
||||||
use crate::wayland::shm::ShmPool;
|
use crate::wayland::shm::ShmPool;
|
||||||
|
use super::drawable::{Drawable, color_blend};
|
||||||
|
|
||||||
fn color_blend(col1: u32, col2: u32, diff: f64) -> u32 {
|
|
||||||
// TODO: Account for alpha channel
|
|
||||||
let r1 = (col1 & 0x00ff0000) >> 16;
|
|
||||||
let g1 = (col1 & 0x0000ff00) >> 8;
|
|
||||||
let b1 = col1 & 0x000000ff;
|
|
||||||
let r2 = (col2 & 0x00ff0000) >> 16;
|
|
||||||
let g2 = (col2 & 0x0000ff00) >> 8;
|
|
||||||
let b2 = col2 & 0x000000ff;
|
|
||||||
let r3 = if r1 < r2 {
|
|
||||||
r1 + ((r2 - r1) as f64 * diff) as u32
|
|
||||||
} else {
|
|
||||||
r1 - ((r1 - r2) as f64 * diff) as u32
|
|
||||||
};
|
|
||||||
let g3 = if g1 < g2 {
|
|
||||||
g1 + ((g2 - g1) as f64 * diff) as u32
|
|
||||||
} else {
|
|
||||||
g1 - ((g1 - g2) as f64 * diff) as u32
|
|
||||||
};
|
|
||||||
let b3 = if b1 < b2 {
|
|
||||||
b1 + ((b2 - b1) as f64 * diff) as u32
|
|
||||||
} else {
|
|
||||||
b1 - ((b1 - b2) as f64 * diff) as u32
|
|
||||||
};
|
|
||||||
return 0xff000000 + (r3 << 16) + (g3 << 8) + b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// l_row means local row and g_row means global row
|
|
||||||
impl ShmPool {
|
|
||||||
|
|
||||||
// x and y are topleft corner of rect
|
|
||||||
pub fn rectangle(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) {
|
|
||||||
for g_row in y..y+h {
|
|
||||||
self.write(&vec![color; w], g_row*self.width+x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// x and y and topleft corner of rect
|
// x and y and topleft corner of rect
|
||||||
pub fn rounded_rectangle(
|
pub struct Rectangle {
|
||||||
&mut self,
|
|
||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
w: usize,
|
width: usize,
|
||||||
h: usize,
|
height: usize,
|
||||||
radius: usize,
|
radius: usize,
|
||||||
color: u32
|
color: u32,
|
||||||
) {
|
|
||||||
for l_row in 1..radius {
|
|
||||||
let inner_diff = (((radius-1).pow(2) - l_row.pow(2)) as f64).sqrt();
|
|
||||||
let outer_diff = ((radius.pow(2) - l_row.pow(2)) as f64).sqrt();
|
|
||||||
self.write(&vec![color; w - (2*(radius - inner_diff.floor() as usize-1))], (y+radius-l_row)*self.width + x + radius - inner_diff.floor() as usize-1);
|
|
||||||
self.write(&vec![color; w - (2*(radius - inner_diff.floor() as usize-1))], (y+h-radius+l_row)*self.width + x + radius - inner_diff.floor() as usize-1);
|
|
||||||
for l_col in inner_diff.floor() as usize+1..outer_diff.ceil() as usize {
|
|
||||||
let distance = ((l_row.pow(2) + l_col.pow(2)) as f64).sqrt();
|
|
||||||
let offset = (y+radius-l_row)*self.width + x + radius - l_col - 1;
|
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
|
||||||
let offset = (y+radius-l_row)*self.width + x + w - radius + l_col;
|
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
|
||||||
let offset = (y+h-radius+l_row)*self.width + x + radius - l_col - 1;
|
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
|
||||||
let offset = (y+h-radius+l_row)*self.width + x + w - radius + l_col;
|
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for g_row in y+radius..y+h-radius+1 {
|
impl Rectangle {
|
||||||
self.write(&vec![color; w], g_row*self.width+x);
|
pub fn new(x: usize, y: usize, width: usize, height: usize, radius: usize, color: u32) -> Self {
|
||||||
|
Rectangle {x, y, width, height, radius, color}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// x and y are center of circle
|
impl Drawable for Rectangle {
|
||||||
pub fn circle(&mut self, x: usize, y: usize, radius: usize, color: u32) {
|
fn draw(&self, shm_pool: &mut ShmPool) {
|
||||||
for l_row in 1..radius {
|
for g_row in self.y+self.radius..self.y+self.height-self.radius+1 {
|
||||||
let inner_diff = (((radius-1).pow(2) - l_row.pow(2)) as f64).sqrt();
|
shm_pool.write(&vec![self.color; self.width], g_row*shm_pool.width+self.x);
|
||||||
let outer_diff = ((radius.pow(2) - l_row.pow(2)) as f64).sqrt();
|
}
|
||||||
let row: Vec<u32> = vec![color; 2*(inner_diff.floor() as usize)];
|
for l_row in 1..self.radius {
|
||||||
self.write(&row, (y-l_row)*self.width + x - inner_diff.floor() as usize);
|
let inner_diff = (((self.radius-1).pow(2) - l_row.pow(2)) as f64).sqrt();
|
||||||
self.write(&row, (y+l_row-1)*self.width + x - inner_diff.floor() as usize);
|
let outer_diff = ((self.radius.pow(2) - l_row.pow(2)) as f64).sqrt();
|
||||||
for l_col in (inner_diff.floor() as usize+1)..(outer_diff.ceil() as usize) {
|
shm_pool.write(&vec![self.color; self.width - (2*(self.radius - inner_diff.floor() as usize-1))], (self.y+self.radius-l_row)*shm_pool.width + self.x + self.radius - inner_diff.floor() as usize-1);
|
||||||
|
shm_pool.write(&vec![self.color; self.width - (2*(self.radius - inner_diff.floor() as usize-1))], (self.y+self.height-self.radius+l_row)*shm_pool.width + self.x + self.radius - inner_diff.floor() as usize-1);
|
||||||
|
for l_col in inner_diff.floor() as usize+1..outer_diff.ceil() as usize {
|
||||||
let distance = ((l_row.pow(2) + l_col.pow(2)) as f64).sqrt();
|
let distance = ((l_row.pow(2) + l_col.pow(2)) as f64).sqrt();
|
||||||
let offset = (y-l_row)*self.width + x - l_col;
|
let offset = (self.y+self.radius-l_row)*shm_pool.width + self.x + self.radius - l_col - 1;
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
let offset = (y-l_row)*self.width + x + l_col-1;
|
let offset = (self.y+self.radius-l_row)*shm_pool.width + self.x + self.width - self.radius + l_col;
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
let offset = (y+l_row-1)*self.width + x - l_col;
|
let offset = (self.y+self.height-self.radius+l_row)*shm_pool.width + self.x + self.radius - l_col - 1;
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
let offset = (y+l_row-1)*self.width + x + l_col-1;
|
let offset = (self.y+self.height-self.radius+l_row)*shm_pool.width + self.x + self.width - self.radius + l_col;
|
||||||
self.write_pixel(color_blend(color, self.read_pixel(offset), distance.fract()), offset as isize);
|
shm_pool.write_pixel(color_blend(self.color, shm_pool.read_pixel(offset), distance.fract()), offset as isize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use std::{error::Error, io::Write, os::unix::net::SocketAncillary, sync::atomic::Ordering, u8};
|
use std::{error::Error, io::Write, os::unix::net::SocketAncillary, sync::atomic::Ordering, u8};
|
||||||
|
use crate::graphics::drawable::Drawable;
|
||||||
use crate::wayland::{shm, surface::UnsetErr, vec_utils::WlMessage, wl_client::WlClient};
|
use crate::wayland::{shm, surface::UnsetErr, vec_utils::WlMessage, wl_client::WlClient};
|
||||||
|
use crate::graphics::{rectangle::Rectangle, circle::Circle};
|
||||||
|
|
||||||
const STRIDE: usize = 4;
|
const STRIDE: usize = 4;
|
||||||
|
|
||||||
@@ -15,9 +17,10 @@ impl WlClient {
|
|||||||
self.shmpool_id.store(current_id, Ordering::Relaxed);
|
self.shmpool_id.store(current_id, Ordering::Relaxed);
|
||||||
|
|
||||||
shm_pool.write(&vec![0xffff0000; width * height], 0);
|
shm_pool.write(&vec![0xffff0000; width * height], 0);
|
||||||
shm_pool.rectangle(50, 50, 50, 50, 0xff00ff00);
|
let rect = Rectangle::new(100, 100, 200, 50, 25, 0xffffff);
|
||||||
shm_pool.circle(300, 300, 200, 0xff0000ff);
|
rect.draw(&mut shm_pool);
|
||||||
shm_pool.rounded_rectangle(450, 400, 60, 40, 16, 0xffffff00);
|
let circle = Circle::new(250, 150, 20, 0xff00ffff);
|
||||||
|
circle.draw(&mut shm_pool);
|
||||||
|
|
||||||
let object = self.shm_id.load(Ordering::Relaxed);
|
let object = self.shm_id.load(Ordering::Relaxed);
|
||||||
if object == 0 {
|
if object == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user