#[cfg(feature = "winit")]
use winit::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize, Pixel};
mod vector;
pub use vector::{DVec2, Quad, Vec2, Vec3};
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Coord(pub i32, pub i32);
impl Coord {
pub const ZERO: Coord = Coord(0, 0);
#[inline]
pub fn uniform(n: i32) -> Self {
Coord(n, n)
}
#[inline]
pub fn min(self, other: Self) -> Self {
Coord(self.0.min(other.0), self.1.min(other.1))
}
#[inline]
pub fn max(self, other: Self) -> Self {
Coord(self.0.max(other.0), self.1.max(other.1))
}
#[inline]
pub fn clamp(self, min: Self, max: Self) -> Self {
self.min(max).max(min)
}
#[inline]
pub fn transpose(self) -> Self {
Coord(self.1, self.0)
}
#[cfg(feature = "winit")]
pub fn from_logical<X: Pixel>(logical: LogicalPosition<X>, dpi_factor: f64) -> Self {
let pos = PhysicalPosition::<i32>::from_logical(logical, dpi_factor);
let pos: (i32, i32) = pos.into();
Coord(pos.0, pos.1)
}
}
impl From<(i32, i32)> for Coord {
#[inline]
fn from(coord: (i32, i32)) -> Coord {
Coord(coord.0, coord.1)
}
}
impl From<Size> for Coord {
#[inline]
fn from(size: Size) -> Coord {
Coord(size.0 as i32, size.1 as i32)
}
}
impl std::ops::Add for Coord {
type Output = Self;
#[inline]
fn add(self, other: Self) -> Self {
Coord(self.0 + other.0, self.1 + other.1)
}
}
impl std::ops::Sub for Coord {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
Coord(self.0 - other.0, self.1 - other.1)
}
}
impl std::ops::Add<Size> for Coord {
type Output = Self;
#[inline]
fn add(self, other: Size) -> Self {
Coord(self.0 + other.0 as i32, self.1 + other.1 as i32)
}
}
#[cfg(feature = "winit")]
impl<X: Pixel> From<PhysicalPosition<X>> for Coord {
#[inline]
fn from(pos: PhysicalPosition<X>) -> Coord {
let pos: (i32, i32) = pos.cast::<i32>().into();
Coord(pos.0, pos.1)
}
}
#[cfg(feature = "winit")]
impl<X: Pixel> From<Coord> for PhysicalPosition<X> {
#[inline]
fn from(coord: Coord) -> PhysicalPosition<X> {
let pos: PhysicalPosition<i32> = (coord.0, coord.1).into();
pos.cast()
}
}
impl std::ops::AddAssign<Coord> for Coord {
#[inline]
fn add_assign(&mut self, rhs: Coord) {
self.0 += rhs.0;
self.1 += rhs.1;
}
}
impl std::ops::AddAssign<Size> for Coord {
#[inline]
fn add_assign(&mut self, rhs: Size) {
self.0 += rhs.0 as i32;
self.1 += rhs.1 as i32;
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Size(pub u32, pub u32);
impl Size {
pub const ZERO: Size = Size(0, 0);
#[inline]
pub const fn uniform(v: u32) -> Self {
Size(v, v)
}
#[inline]
pub fn min(self, other: Self) -> Self {
Size(self.0.min(other.0), self.1.min(other.1))
}
#[inline]
pub fn max(self, other: Self) -> Self {
Size(self.0.max(other.0), self.1.max(other.1))
}
#[inline]
pub fn transpose(self) -> Self {
Size(self.1, self.0)
}
}
impl From<(u32, u32)> for Size {
fn from(size: (u32, u32)) -> Size {
Size(size.0, size.1)
}
}
impl From<Coord> for Size {
fn from(coord: Coord) -> Size {
Size(coord.0 as u32, coord.1 as u32)
}
}
#[cfg(feature = "winit")]
impl<X: Pixel> From<PhysicalSize<X>> for Size {
#[inline]
fn from(size: PhysicalSize<X>) -> Size {
let size: (u32, u32) = size.cast::<u32>().into();
Size(size.0, size.1)
}
}
#[cfg(feature = "winit")]
impl<X: Pixel> From<Size> for PhysicalSize<X> {
#[inline]
fn from(size: Size) -> PhysicalSize<X> {
let pos: PhysicalSize<u32> = (size.0, size.1).into();
pos.cast()
}
}
#[cfg(feature = "winit")]
impl From<Size> for winit::dpi::Size {
#[inline]
fn from(size: Size) -> winit::dpi::Size {
winit::dpi::Size::Physical((size.0, size.1).into())
}
}
impl std::ops::Add for Size {
type Output = Self;
#[inline]
fn add(self, other: Self) -> Self {
Size(self.0 + other.0, self.1 + other.1)
}
}
impl std::ops::Sub for Size {
type Output = Self;
#[inline]
fn sub(self, other: Self) -> Self {
Size(self.0 - other.0, self.1 - other.1)
}
}
impl std::ops::Mul<u32> for Size {
type Output = Self;
#[inline]
fn mul(self, x: u32) -> Self {
Size(self.0 * x, self.1 * x)
}
}
impl std::ops::Mul<f32> for Size {
type Output = Self;
#[inline]
fn mul(self, x: f32) -> Self {
Size((self.0 as f32 * x) as u32, (self.1 as f32 * x) as u32)
}
}
impl std::ops::Div<u32> for Size {
type Output = Self;
#[inline]
fn div(self, x: u32) -> Self {
Size(self.0 / x, self.1 / x)
}
}
impl std::ops::AddAssign for Size {
#[inline]
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
self.1 += rhs.1;
}
}
impl std::ops::SubAssign for Size {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
self.1 -= rhs.1;
}
}
#[derive(Clone, Copy, Default, Debug)]
pub struct Rect {
pub pos: Coord,
pub size: Size,
}
impl Rect {
#[inline]
pub fn new(pos: Coord, size: Size) -> Self {
Rect { pos, size }
}
#[inline]
pub fn pos_end(&self) -> Coord {
self.pos + self.size
}
#[inline]
pub fn contains(&self, c: Coord) -> bool {
c.0 >= self.pos.0
&& c.0 < self.pos.0 + (self.size.0 as i32)
&& c.1 >= self.pos.1
&& c.1 < self.pos.1 + (self.size.1 as i32)
}
#[inline]
pub fn shrink(&self, n: u32) -> Rect {
let pos = self.pos + Coord::uniform(n as i32);
let w = self.size.0.saturating_sub(n + n);
let h = self.size.1.saturating_sub(n + n);
let size = Size(w, h);
Rect { pos, size }
}
}
impl std::ops::Add<Coord> for Rect {
type Output = Self;
#[inline]
fn add(self, offset: Coord) -> Self {
let pos = self.pos + offset;
Rect {
pos,
size: self.size,
}
}
}
impl std::ops::Sub<Coord> for Rect {
type Output = Self;
#[inline]
fn sub(self, offset: Coord) -> Self {
let pos = self.pos - offset;
Rect {
pos,
size: self.size,
}
}
}