From db96ecae94a7c06d04528e8d4461ebca86d2d249 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 30 Mar 2019 16:58:45 +0100 Subject: =?UTF-8?q?Move=20some=20types=20into=20better=20places=20?= =?UTF-8?q?=F0=9F=A7=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine/size.rs | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/engine/size.rs (limited to 'src/engine/size.rs') diff --git a/src/engine/size.rs b/src/engine/size.rs new file mode 100644 index 00000000..a6624c57 --- /dev/null +++ b/src/engine/size.rs @@ -0,0 +1,144 @@ +use std::cmp::Ordering; +use std::fmt::{self, Display, Debug, Formatter}; +use std::iter::Sum; +use std::ops::*; + + +/// A general distance type that can convert between units. +#[derive(Copy, Clone, PartialEq)] +pub struct Size { + /// The size in typographic points (1/72 inches). + points: f32, +} + +impl Size { + /// Create an zeroed size. + #[inline] + pub fn zero() -> Size { Size { points: 0.0 } } + + /// Create a size from a number of points. + #[inline] + pub fn from_points(points: f32) -> Size { Size { points } } + + /// Create a size from a number of inches. + #[inline] + pub fn from_inches(inches: f32) -> Size { Size { points: 72.0 * inches } } + + /// Create a size from a number of millimeters. + #[inline] + pub fn from_mm(mm: f32) -> Size { Size { points: 2.83465 * mm } } + + /// Create a size from a number of centimeters. + #[inline] + pub fn from_cm(cm: f32) -> Size { Size { points: 28.3465 * cm } } + + /// Create a size from a number of points. + #[inline] + pub fn to_points(&self) -> f32 { self.points } + + /// Create a size from a number of inches. + #[inline] + pub fn to_inches(&self) -> f32 { self.points * 0.0138889 } + + /// Create a size from a number of millimeters. + #[inline] + pub fn to_mm(&self) -> f32 { self.points * 0.352778 } + + /// Create a size from a number of centimeters. + #[inline] + pub fn to_cm(&self) -> f32 { self.points * 0.0352778 } +} + +impl Display for Size { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}pt", self.points) + } +} + +impl Debug for Size { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl PartialOrd for Size { + fn partial_cmp(&self, other: &Size) -> Option { + self.points.partial_cmp(&other.points) + } +} + +impl Neg for Size { + type Output = Size; + + fn neg(self) -> Size { + Size { points: -self.points } + } +} + +impl Sum for Size { + fn sum(iter: I) -> Size where I: Iterator { + iter.fold(Size::zero(), Add::add) + } +} + +macro_rules! impl_reflexive { + ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident) => { + impl $trait for Size { + type Output = Size; + + #[inline] + fn $func(self, other: Size) -> Size { + Size { points: $trait::$func(self.points, other.points) } + } + } + + impl $assign_trait for Size { + #[inline] + fn $assign_func(&mut self, other: Size) { + $assign_trait::$assign_func(&mut self.points, other.points); + } + } + }; +} + +macro_rules! impl_num_back { + ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => { + impl $trait<$ty> for Size { + type Output = Size; + + #[inline] + fn $func(self, other: $ty) -> Size { + Size { points: $trait::$func(self.points, other as f32) } + } + } + + impl $assign_trait<$ty> for Size { + #[inline] + fn $assign_func(&mut self, other: $ty) { + $assign_trait::$assign_func(&mut self.points, other as f32); + } + } + }; +} + +macro_rules! impl_num_both { + ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $ty:ty) => { + impl_num_back!($trait, $func, $assign_trait, $assign_func, $ty); + + impl $trait for $ty { + type Output = Size; + + #[inline] + fn $func(self, other: Size) -> Size { + Size { points: $trait::$func(self as f32, other.points) } + } + } + }; +} + +impl_reflexive!(Add, add, AddAssign, add_assign); +impl_reflexive!(Sub, sub, SubAssign, sub_assign); +impl_num_both!(Mul, mul, MulAssign, mul_assign, f32); +impl_num_both!(Mul, mul, MulAssign, mul_assign, i32); +impl_num_back!(Div, div, DivAssign, div_assign, f32); +impl_num_back!(Div, div, DivAssign, div_assign, i32); -- cgit v1.2.3