use std::ops::{Add, AddAssign, Div, Mul, Neg, Rem, Sub, SubAssign};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PixelPoint {
pub x: i64,
pub y: i64,
}
impl PixelPoint {
pub fn new(x: i64, y: i64) -> Self {
Self { x, y }
}
pub fn to_tuple(self) -> (i64, i64) {
(self.x, self.y)
}
}
impl Add for PixelPoint {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
PixelPoint {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl AddAssign for PixelPoint {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl Sub for PixelPoint {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
PixelPoint {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl SubAssign for PixelPoint {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl Neg for PixelPoint {
type Output = Self;
fn neg(self) -> Self::Output {
PixelPoint {
x: -self.x,
y: -self.y,
}
}
}
impl Mul<i64> for PixelPoint {
type Output = Self;
fn mul(self, rhs: i64) -> Self::Output {
PixelPoint {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl Div<i64> for PixelPoint {
type Output = Self;
fn div(self, rhs: i64) -> Self::Output {
PixelPoint {
x: self.x / rhs,
y: self.y / rhs,
}
}
}
impl Rem<i64> for PixelPoint {
type Output = Self;
fn rem(self, rhs: i64) -> Self::Output {
PixelPoint {
x: self.x % rhs,
y: self.y % rhs,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct PixelRect {
top_left: PixelPoint,
bottom_right: PixelPoint,
}
impl PixelRect {
pub fn new(top_left: PixelPoint, bottom_right: PixelPoint) -> Self {
assert!(top_left.x <= bottom_right.x);
assert!(top_left.y <= bottom_right.y);
Self {
top_left,
bottom_right,
}
}
pub fn top_left(self) -> PixelPoint {
self.top_left
}
pub fn bottom_right(self) -> PixelPoint {
self.bottom_right
}
pub fn left_x(self) -> i64 {
self.top_left.x
}
pub fn right_x(self) -> i64 {
self.bottom_right.x
}
pub fn middle_x(self) -> i64 {
self.left_x().midpoint(self.right_x())
}
pub fn top_y(self) -> i64 {
self.top_left.y
}
#[allow(dead_code)]
pub fn bottom_y(self) -> i64 {
self.bottom_right.y
}
pub fn middle_y(self) -> i64 {
self.top_y() + self.height() as i64 / 2
}
pub fn width(self) -> u64 {
(self.bottom_right.x - self.top_left.x) as u64
}
pub fn height(self) -> u64 {
(self.bottom_right.y - self.top_left.y) as u64
}
pub fn without_half_margin(self, half_margin_x: u64, half_margin_y: u64) -> Self {
let half_margin_point = PixelPoint {
x: half_margin_x as i64,
y: half_margin_y as i64,
};
let top_left = self.top_left + half_margin_point;
let mut bottom_right = self.bottom_right - half_margin_point;
if bottom_right.x < top_left.x {
bottom_right.x = top_left.x;
}
if bottom_right.y < top_left.y {
bottom_right.y = top_left.y;
}
Self::new(top_left, bottom_right)
}
}