diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-10-10 22:19:36 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-10-10 22:19:36 +0200 |
| commit | 92c01da36016e94ff20163806ddcbcf7e33d4031 (patch) | |
| tree | 1a900b3c11edcc93e9153fada3ce92310db5768b /src/geom/linear.rs | |
| parent | 42500d5ed85539c5ab04dd3544beaf802da29be9 (diff) | |
Switch back to custom geometry types, unified with layout primitives 🏞
Diffstat (limited to 'src/geom/linear.rs')
| -rw-r--r-- | src/geom/linear.rs | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/geom/linear.rs b/src/geom/linear.rs new file mode 100644 index 00000000..2567d264 --- /dev/null +++ b/src/geom/linear.rs @@ -0,0 +1,172 @@ +use super::*; + +/// A combined relative and absolute length. +#[derive(Default, Copy, Clone, PartialEq)] +pub struct Linear { + /// The relative part. + pub rel: Relative, + /// The absolute part. + pub abs: Length, +} + +impl Linear { + /// The zero linear. + pub const ZERO: Linear = Linear { rel: Relative::ZERO, abs: Length::ZERO }; + + /// Create a new linear. + pub fn new(rel: Relative, abs: Length) -> Self { + Self { rel, abs } + } + + /// Evaluate the linear length with `one` being `100%` for the relative + /// part. + pub fn eval(self, one: Length) -> Length { + self.rel.eval(one) + self.abs + } + + /// Whether this linear's relative component is zero. + pub fn is_absolute(self) -> bool { + self.rel == Relative::ZERO + } +} + +impl Display for Linear { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{} + {}", self.rel, self.abs) + } +} + +impl Debug for Linear { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl From<Length> for Linear { + fn from(abs: Length) -> Self { + Self { rel: Relative::ZERO, abs } + } +} + +impl From<Relative> for Linear { + fn from(rel: Relative) -> Self { + Self { rel, abs: Length::ZERO } + } +} + +impl Neg for Linear { + type Output = Self; + + fn neg(self) -> Self { + Self { rel: -self.rel, abs: -self.abs } + } +} + +impl Add for Linear { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self { + rel: self.rel + other.rel, + abs: self.abs + other.abs, + } + } +} + +impl Add<Relative> for Length { + type Output = Linear; + + fn add(self, other: Relative) -> Linear { + Linear { rel: other, abs: self } + } +} + +impl Add<Length> for Relative { + type Output = Linear; + + fn add(self, other: Length) -> Linear { + other + self + } +} + +impl Add<Length> for Linear { + type Output = Self; + + fn add(self, other: Length) -> Self { + Self { rel: self.rel, abs: self.abs + other } + } +} + +impl Add<Linear> for Length { + type Output = Linear; + + fn add(self, other: Linear) -> Linear { + other + self + } +} + +impl Add<Relative> for Linear { + type Output = Self; + + fn add(self, other: Relative) -> Self { + Self { rel: self.rel + other, abs: self.abs } + } +} + +impl Add<Linear> for Relative { + type Output = Linear; + + fn add(self, other: Linear) -> Linear { + other + self + } +} + +sub_impl!(Linear - Linear -> Linear); +sub_impl!(Length - Relative -> Linear); +sub_impl!(Relative - Length -> Linear); +sub_impl!(Linear - Length -> Linear); +sub_impl!(Length - Linear -> Linear); +sub_impl!(Linear - Relative -> Linear); +sub_impl!(Relative - Linear -> Linear); + +impl Mul<f64> for Linear { + type Output = Self; + + fn mul(self, other: f64) -> Self { + Self { + rel: self.rel * other, + abs: self.abs * other, + } + } +} + +impl Mul<Linear> for f64 { + type Output = Linear; + + fn mul(self, other: Linear) -> Linear { + Linear { + rel: self * other.rel, + abs: self * other.abs, + } + } +} + +impl Div<f64> for Linear { + type Output = Self; + + fn div(self, other: f64) -> Self { + Self { + rel: self.rel / other, + abs: self.abs / other, + } + } +} + +assign_impl!(Linear += Linear); +assign_impl!(Linear += Length); +assign_impl!(Linear += Relative); +assign_impl!(Linear -= Linear); +assign_impl!(Linear -= Length); +assign_impl!(Linear -= Relative); +assign_impl!(Linear *= f64); +assign_impl!(Linear /= f64); |
