pub mod raster_floating;
pub mod raster_fixed;
pub mod vector;
pub enum Op {
Over,
Src,
}
pub struct Rasterizer {
buf: SimdVec,
use_fpm: bool,
size: [usize; 2],
first: [f32; 2],
pen: [f32; 2],
pub draw_op: Op,
}
#[repr(align(16))]
#[derive(Clone)]
struct SimdAlign([f32; 4]);
pub struct SimdVec {
v: Vec<SimdAlign>
}
impl SimdVec {
fn new(len: usize) -> Self {
let len = len / 4 + ((len % 4) != 0) as usize;
Self { v: vec![SimdAlign([0.0; 4]); len] }
}
fn recycle(&mut self, len: usize) {
self.v.clear();
let len = len / 4 + ((len % 4) != 0) as usize;
self.v.resize(len, SimdAlign([0.0; 4]))
}
fn as_slice_f32(&self) -> &[f32] {
unsafe {
let data = self.v.as_ptr() as *const f32;
let len = self.v.len() * 4;
std::slice::from_raw_parts(data, len)
}
}
fn as_slice_u32(&self) -> &[u32] {
unsafe {
let data = self.v.as_ptr() as *const u32;
let len = self.v.len() * 4;
std::slice::from_raw_parts(data, len)
}
}
fn as_f32(&mut self) -> &mut [f32] {
unsafe { self.u_f32() }
}
fn as_u32(&mut self) -> &mut [u32] {
unsafe { self.u_u32() }
}
unsafe fn u_f32<'a>(&mut self) -> &'a mut [f32] {
unsafe {
let data = self.v.as_mut_ptr() as *mut f32;
let len = self.v.len() * 4;
std::slice::from_raw_parts_mut(data, len)
}
}
unsafe fn u_u32<'a>(&mut self) -> &'a mut [u32] {
unsafe {
let data = self.v.as_mut_ptr() as *mut u32;
let len = self.v.len() * 4;
std::slice::from_raw_parts_mut(data, len)
}
}
}
#[inline(always)]
fn lerp(t: f32, px: f32, py: f32, qx: f32, qy: f32) -> (f32, f32) {
(px + t * (qx - px), py + t * (qy - py))
}
#[inline(always)]
fn clamp(i: i32, width: i32) -> usize {
if i < 0 {
return 0
}
if i < width {
return i as usize
}
width as usize
}
#[inline(always)]
fn dev_squared(ax: f32, ay: f32, bx: f32, by: f32, cx: f32, cy: f32) -> f32{
let devx = ax - 2.0*bx + cx;
let devy = ay - 2.0*by + cy;
devx*devx + devy*devy
}
enum PorterDuff {
A,
B,
AoverB,
BoverA,
AinB,
BinA,
AoutB,
BoutA,
AatopB,
BatopA,
AxorB,
Clear,
}
enum PD {
Src,
Over,
In,
Out,
Atop,
Xor,
}