summaryrefslogtreecommitdiff
path: root/src/geom
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-22 15:50:35 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-22 15:50:35 +0100
commit02f114d072ffba72c5b18953f2959eac4dee1612 (patch)
treef3e62020a572f22d98d853649237472c2fd1d407 /src/geom
parent0a974d86ba921af781a6c9d75961b92351a5f28e (diff)
Remove decorum
Diffstat (limited to 'src/geom')
-rw-r--r--src/geom/align.rs4
-rw-r--r--src/geom/angle.rs16
-rw-r--r--src/geom/dir.rs12
-rw-r--r--src/geom/em.rs20
-rw-r--r--src/geom/fr.rs18
-rw-r--r--src/geom/gen.rs2
-rw-r--r--src/geom/length.rs36
-rw-r--r--src/geom/linear.rs6
-rw-r--r--src/geom/mod.rs5
-rw-r--r--src/geom/path.rs2
-rw-r--r--src/geom/point.rs8
-rw-r--r--src/geom/relative.rs18
-rw-r--r--src/geom/scalar.rs152
-rw-r--r--src/geom/sides.rs2
-rw-r--r--src/geom/size.rs12
-rw-r--r--src/geom/spec.rs2
16 files changed, 235 insertions, 80 deletions
diff --git a/src/geom/align.rs b/src/geom/align.rs
index b0cf69db..e99bebea 100644
--- a/src/geom/align.rs
+++ b/src/geom/align.rs
@@ -17,7 +17,7 @@ pub enum Align {
impl Align {
/// The axis this alignment belongs to if it is specific.
- pub fn axis(self) -> Option<SpecAxis> {
+ pub const fn axis(self) -> Option<SpecAxis> {
match self {
Self::Left => Some(SpecAxis::Horizontal),
Self::Top => Some(SpecAxis::Vertical),
@@ -28,7 +28,7 @@ impl Align {
}
/// The inverse alignment.
- pub fn inv(self) -> Self {
+ pub const fn inv(self) -> Self {
match self {
Self::Left => Self::Right,
Self::Top => Self::Bottom,
diff --git a/src/geom/angle.rs b/src/geom/angle.rs
index 929a96fe..af47e51d 100644
--- a/src/geom/angle.rs
+++ b/src/geom/angle.rs
@@ -3,12 +3,12 @@ use super::*;
/// An angle.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
-pub struct Angle(N64);
+pub struct Angle(Scalar);
impl Angle {
/// The zero angle.
- pub fn zero() -> Self {
- Self(N64::from(0.0))
+ pub const fn zero() -> Self {
+ Self(Scalar(0.0))
}
/// Create an angle from a number of radians.
@@ -22,8 +22,8 @@ impl Angle {
}
/// Create an angle from a number of raw units.
- pub fn raw(raw: f64) -> Self {
- Self(N64::from(raw))
+ pub const fn raw(raw: f64) -> Self {
+ Self(Scalar(raw))
}
/// Convert this to a number of radians.
@@ -37,13 +37,13 @@ impl Angle {
}
/// Get the value of this angle in raw units.
- pub fn to_raw(self) -> f64 {
- self.0.into()
+ pub const fn to_raw(self) -> f64 {
+ (self.0).0
}
/// Create an angle from a value in a unit.
pub fn with_unit(val: f64, unit: AngularUnit) -> Self {
- Self(N64::from(val * unit.raw_scale()))
+ Self(Scalar(val * unit.raw_scale()))
}
/// Get the value of this length in unit.
diff --git a/src/geom/dir.rs b/src/geom/dir.rs
index d95c7eb9..8c1d6b9e 100644
--- a/src/geom/dir.rs
+++ b/src/geom/dir.rs
@@ -15,7 +15,7 @@ pub enum Dir {
impl Dir {
/// The side this direction starts at.
- pub fn start(self) -> Side {
+ pub const fn start(self) -> Side {
match self {
Self::LTR => Side::Left,
Self::RTL => Side::Right,
@@ -25,7 +25,7 @@ impl Dir {
}
/// The side this direction ends at.
- pub fn end(self) -> Side {
+ pub const fn end(self) -> Side {
match self {
Self::LTR => Side::Right,
Self::RTL => Side::Left,
@@ -35,7 +35,7 @@ impl Dir {
}
/// The specific axis this direction belongs to.
- pub fn axis(self) -> SpecAxis {
+ pub const fn axis(self) -> SpecAxis {
match self {
Self::LTR | Self::RTL => SpecAxis::Horizontal,
Self::TTB | Self::BTT => SpecAxis::Vertical,
@@ -45,7 +45,7 @@ impl Dir {
/// Whether this direction points into the positive coordinate direction.
///
/// The positive directions are left-to-right and top-to-bottom.
- pub fn is_positive(self) -> bool {
+ pub const fn is_positive(self) -> bool {
match self {
Self::LTR | Self::TTB => true,
Self::RTL | Self::BTT => false,
@@ -56,12 +56,12 @@ impl Dir {
///
/// - `1.0` if the direction is positive.
/// - `-1.0` if the direction is negative.
- pub fn factor(self) -> f64 {
+ pub const fn factor(self) -> f64 {
if self.is_positive() { 1.0 } else { -1.0 }
}
/// The inverse direction.
- pub fn inv(self) -> Self {
+ pub const fn inv(self) -> Self {
match self {
Self::LTR => Self::RTL,
Self::RTL => Self::LTR,
diff --git a/src/geom/em.rs b/src/geom/em.rs
index caddbcdd..05d1d7d5 100644
--- a/src/geom/em.rs
+++ b/src/geom/em.rs
@@ -5,27 +5,27 @@ use super::*;
/// `1em` is the same as the font size.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
-pub struct Em(N64);
+pub struct Em(Scalar);
impl Em {
/// The zero length.
- pub fn zero() -> Self {
- Self(N64::from(0.0))
+ pub const fn zero() -> Self {
+ Self(Scalar(0.0))
}
/// The font size.
- pub fn one() -> Self {
- Self(N64::from(1.0))
+ pub const fn one() -> Self {
+ Self(Scalar(1.0))
}
/// Create an font-relative length.
- pub fn new(em: f64) -> Self {
- Self(N64::from(em))
+ pub const fn new(em: f64) -> Self {
+ Self(Scalar(em))
}
/// Create font units at the given units per em.
pub fn from_units(units: impl Into<f64>, units_per_em: f64) -> Self {
- Self(N64::from(units.into() / units_per_em))
+ Self(Scalar(units.into() / units_per_em))
}
/// Convert to a length at the given font size.
@@ -34,8 +34,8 @@ impl Em {
}
/// The number of em units.
- pub fn get(self) -> f64 {
- self.0.into()
+ pub const fn get(self) -> f64 {
+ (self.0).0
}
/// Whether the length is zero.
diff --git a/src/geom/fr.rs b/src/geom/fr.rs
index 28d53d8f..e7cd276d 100644
--- a/src/geom/fr.rs
+++ b/src/geom/fr.rs
@@ -2,27 +2,27 @@ use super::*;
/// A fractional length.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub struct Fractional(N64);
+pub struct Fractional(Scalar);
impl Fractional {
/// Takes up zero space: `0fr`.
- pub fn zero() -> Self {
- Self(N64::from(0.0))
+ pub const fn zero() -> Self {
+ Self(Scalar(0.0))
}
/// Takes up as much space as all other items with this fractional size: `1fr`.
- pub fn one() -> Self {
- Self(N64::from(1.0))
+ pub const fn one() -> Self {
+ Self(Scalar(1.0))
}
/// Create a new fractional value.
- pub fn new(ratio: f64) -> Self {
- Self(N64::from(ratio))
+ pub const fn new(ratio: f64) -> Self {
+ Self(Scalar(ratio))
}
/// Get the underlying ratio.
- pub fn get(self) -> f64 {
- self.0.into()
+ pub const fn get(self) -> f64 {
+ (self.0).0
}
/// Whether the ratio is zero.
diff --git a/src/geom/gen.rs b/src/geom/gen.rs
index ff8c881a..e770f80d 100644
--- a/src/geom/gen.rs
+++ b/src/geom/gen.rs
@@ -11,7 +11,7 @@ pub struct Gen<T> {
impl<T> Gen<T> {
/// Create a new instance from the two components.
- pub fn new(inline: T, block: T) -> Self {
+ pub const fn new(inline: T, block: T) -> Self {
Self { inline, block }
}
diff --git a/src/geom/length.rs b/src/geom/length.rs
index 68261d5f..210dcce7 100644
--- a/src/geom/length.rs
+++ b/src/geom/length.rs
@@ -4,17 +4,17 @@ use super::*;
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
-pub struct Length(N64);
+pub struct Length(Scalar);
impl Length {
/// The zero length.
- pub fn zero() -> Self {
- Self(N64::from(0.0))
+ pub const fn zero() -> Self {
+ Self(Scalar(0.0))
}
/// The inifinite length.
- pub fn inf() -> Self {
- Self(N64::from(f64::INFINITY))
+ pub const fn inf() -> Self {
+ Self(Scalar(f64::INFINITY))
}
/// Create a length from a number of points.
@@ -38,8 +38,8 @@ impl Length {
}
/// Create a length from a number of raw units.
- pub fn raw(raw: f64) -> Self {
- Self(N64::from(raw))
+ pub const fn raw(raw: f64) -> Self {
+ Self(Scalar(raw))
}
/// Convert this to a number of points.
@@ -63,13 +63,13 @@ impl Length {
}
/// Get the value of this length in raw units.
- pub fn to_raw(self) -> f64 {
- self.0.into()
+ pub const fn to_raw(self) -> f64 {
+ (self.0).0
}
/// Create a length from a value in a unit.
pub fn with_unit(val: f64, unit: LengthUnit) -> Self {
- Self(N64::from(val * unit.raw_scale()))
+ Self(Scalar(val * unit.raw_scale()))
}
/// Get the value of this length in unit.
@@ -79,17 +79,17 @@ impl Length {
/// Whether the length is zero.
pub fn is_zero(self) -> bool {
- self.0 == 0.0
+ self.to_raw() == 0.0
}
/// Whether the length is finite.
pub fn is_finite(self) -> bool {
- self.0.into_inner().is_finite()
+ self.to_raw().is_finite()
}
/// Whether the length is infinite.
pub fn is_infinite(self) -> bool {
- self.0.into_inner().is_infinite()
+ self.to_raw().is_infinite()
}
/// The absolute value of the this length.
@@ -211,14 +211,14 @@ assign_impl!(Length *= f64);
assign_impl!(Length /= f64);
impl Sum for Length {
- fn sum<I: Iterator<Item = Length>>(iter: I) -> Self {
- iter.fold(Length::zero(), Add::add)
+ fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
+ Self(iter.map(|s| s.0).sum())
}
}
-impl<'a> Sum<&'a Length> for Length {
- fn sum<I: Iterator<Item = &'a Length>>(iter: I) -> Self {
- iter.copied().fold(Length::zero(), Add::add)
+impl<'a> Sum<&'a Self> for Length {
+ fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
+ Self(iter.map(|s| s.0).sum())
}
}
diff --git a/src/geom/linear.rs b/src/geom/linear.rs
index 059528e9..4a0def2f 100644
--- a/src/geom/linear.rs
+++ b/src/geom/linear.rs
@@ -11,7 +11,7 @@ pub struct Linear {
impl Linear {
/// The zero linear.
- pub fn zero() -> Self {
+ pub const fn zero() -> Self {
Self {
rel: Relative::zero(),
abs: Length::zero(),
@@ -19,7 +19,7 @@ impl Linear {
}
/// The linear with a relative part of `100%` and no absolute part.
- pub fn one() -> Self {
+ pub const fn one() -> Self {
Self {
rel: Relative::one(),
abs: Length::zero(),
@@ -27,7 +27,7 @@ impl Linear {
}
/// Create a new linear.
- pub fn new(rel: Relative, abs: Length) -> Self {
+ pub const fn new(rel: Relative, abs: Length) -> Self {
Self { rel, abs }
}
diff --git a/src/geom/mod.rs b/src/geom/mod.rs
index ad92813e..c763e8fa 100644
--- a/src/geom/mod.rs
+++ b/src/geom/mod.rs
@@ -14,6 +14,7 @@ mod paint;
mod path;
mod point;
mod relative;
+mod scalar;
mod sides;
mod size;
mod spec;
@@ -30,16 +31,18 @@ pub use paint::*;
pub use path::*;
pub use point::*;
pub use relative::*;
+pub use scalar::*;
pub use sides::*;
pub use size::*;
pub use spec::*;
+use std::cmp::Ordering;
use std::f64::consts::PI;
use std::fmt::{self, Debug, Formatter};
+use std::hash::{Hash, Hasher};
use std::iter::Sum;
use std::ops::*;
-use decorum::N64;
use serde::{Deserialize, Serialize};
/// Generic access to a structure's components.
diff --git a/src/geom/path.rs b/src/geom/path.rs
index 39e75312..20519cb3 100644
--- a/src/geom/path.rs
+++ b/src/geom/path.rs
@@ -16,7 +16,7 @@ pub enum PathElement {
impl Path {
/// Create an empty path.
- pub fn new() -> Self {
+ pub const fn new() -> Self {
Self(vec![])
}
diff --git a/src/geom/point.rs b/src/geom/point.rs
index 8ab043c3..7c11e81b 100644
--- a/src/geom/point.rs
+++ b/src/geom/point.rs
@@ -11,22 +11,22 @@ pub struct Point {
impl Point {
/// The origin point.
- pub fn zero() -> Self {
+ pub const fn zero() -> Self {
Self { x: Length::zero(), y: Length::zero() }
}
/// Create a new point from x and y coordinate.
- pub fn new(x: Length, y: Length) -> Self {
+ pub const fn new(x: Length, y: Length) -> Self {
Self { x, y }
}
/// Create an instance with two equal components.
- pub fn splat(value: Length) -> Self {
+ pub const fn splat(value: Length) -> Self {
Self { x: value, y: value }
}
/// Convert to the generic representation.
- pub fn to_gen(self, block: SpecAxis) -> Gen<Length> {
+ pub const fn to_gen(self, block: SpecAxis) -> Gen<Length> {
match block {
SpecAxis::Horizontal => Gen::new(self.y, self.x),
SpecAxis::Vertical => Gen::new(self.x, self.y),
diff --git a/src/geom/relative.rs b/src/geom/relative.rs
index e46c51de..463c5d46 100644
--- a/src/geom/relative.rs
+++ b/src/geom/relative.rs
@@ -5,27 +5,27 @@ use super::*;
/// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the
/// corresponding [literal](crate::syntax::ast::LitKind::Percent).
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub struct Relative(N64);
+pub struct Relative(Scalar);
impl Relative {
/// A ratio of `0%` represented as `0.0`.
- pub fn zero() -> Self {
- Self(N64::from(0.0))
+ pub const fn zero() -> Self {
+ Self(Scalar(0.0))
}
/// A ratio of `100%` represented as `1.0`.
- pub fn one() -> Self {
- Self(N64::from(1.0))
+ pub const fn one() -> Self {
+ Self(Scalar(1.0))
}
/// Create a new relative value.
- pub fn new(ratio: f64) -> Self {
- Self(N64::from(ratio))
+ pub const fn new(ratio: f64) -> Self {
+ Self(Scalar(ratio))
}
/// Get the underlying ratio.
- pub fn get(self) -> f64 {
- self.0.into()
+ pub const fn get(self) -> f64 {
+ (self.0).0
}
/// Resolve this relative to the given `length`.
diff --git a/src/geom/scalar.rs b/src/geom/scalar.rs
new file mode 100644
index 00000000..6536e23a
--- /dev/null
+++ b/src/geom/scalar.rs
@@ -0,0 +1,152 @@
+use super::*;
+
+/// A 64-bit float that implements `Eq`, `Ord` and `Hash`.
+///
+/// Panics if its `NaN` during any of those operations.
+#[derive(Default, Copy, Clone, Serialize, Deserialize)]
+#[serde(transparent)]
+pub struct Scalar(pub f64);
+
+impl From<f64> for Scalar {
+ fn from(float: f64) -> Self {
+ Self(float)
+ }
+}
+
+impl From<Scalar> for f64 {
+ fn from(scalar: Scalar) -> Self {
+ scalar.0
+ }
+}
+
+impl Debug for Scalar {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+impl Ord for Scalar {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.partial_cmp(&other).expect("float is NaN")
+ }
+}
+
+impl PartialOrd for Scalar {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.0.partial_cmp(&other.0)
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ self.0 < other.0
+ }
+
+ fn le(&self, other: &Self) -> bool {
+ self.0 <= other.0
+ }
+
+ fn gt(&self, other: &Self) -> bool {
+ self.0 > other.0
+ }
+
+ fn ge(&self, other: &Self) -> bool {
+ self.0 >= other.0
+ }
+}
+
+impl Eq for Scalar {}
+
+impl PartialEq for Scalar {
+ fn eq(&self, other: &Self) -> bool {
+ assert!(!self.0.is_nan() && !other.0.is_nan(), "float is NaN");
+ self.0 == other.0
+ }
+}
+
+impl PartialEq<f64> for Scalar {
+ fn eq(&self, other: &f64) -> bool {
+ self == &Self(*other)
+ }
+}
+
+impl Hash for Scalar {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ debug_assert!(!self.0.is_nan(), "float is NaN");
+ self.0.to_bits().hash(state);
+ }
+}
+
+impl Neg for Scalar {
+ type Output = Self;
+
+ fn neg(self) -> Self::Output {
+ Self(-self.0)
+ }
+}
+
+impl<T: Into<Self>> Add<T> for Scalar {
+ type Output = Self;
+
+ fn add(self, rhs: T) -> Self::Output {
+ Self(self.0 + rhs.into().0)
+ }
+}
+
+impl<T: Into<Self>> AddAssign<T> for Scalar {
+ fn add_assign(&mut self, rhs: T) {
+ self.0 += rhs.into().0;
+ }
+}
+
+impl<T: Into<Self>> Sub<T> for Scalar {
+ type Output = Self;
+
+ fn sub(self, rhs: T) -> Self::Output {
+ Self(self.0 - rhs.into().0)
+ }
+}
+
+impl<T: Into<Self>> SubAssign<T> for Scalar {
+ fn sub_assign(&mut self, rhs: T) {
+ self.0 -= rhs.into().0;
+ }
+}
+
+impl<T: Into<Self>> Mul<T> for Scalar {
+ type Output = Self;
+
+ fn mul(self, rhs: T) -> Self::Output {
+ Self(self.0 * rhs.into().0)
+ }
+}
+
+impl<T: Into<Self>> MulAssign<T> for Scalar {
+ fn mul_assign(&mut self, rhs: T) {
+ self.0 *= rhs.into().0;
+ }
+}
+
+impl<T: Into<Self>> Div<T> for Scalar {
+ type Output = Self;
+
+ fn div(self, rhs: T) -> Self::Output {
+ Self(self.0 / rhs.into().0)
+ }
+}
+
+impl<T: Into<Self>> DivAssign<T> for Scalar {
+ fn div_assign(&mut self, rhs: T) {
+ self.0 /= rhs.into().0;
+ }
+}
+
+impl Sum for Scalar {
+ fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
+ Self(iter.map(|s| s.0).sum())
+ }
+}
+
+impl<'a> Sum<&'a Self> for Scalar {
+ fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
+ Self(iter.map(|s| s.0).sum())
+ }
+}
diff --git a/src/geom/sides.rs b/src/geom/sides.rs
index d1fcf9b7..83407ad6 100644
--- a/src/geom/sides.rs
+++ b/src/geom/sides.rs
@@ -15,7 +15,7 @@ pub struct Sides<T> {
impl<T> Sides<T> {
/// Create a new instance from the four components.
- pub fn new(left: T, top: T, right: T, bottom: T) -> Self {
+ pub const fn new(left: T, top: T, right: T, bottom: T) -> Self {
Self { left, top, right, bottom }
}
diff --git a/src/geom/size.rs b/src/geom/size.rs
index 2143c46b..12cb0ad2 100644
--- a/src/geom/size.rs
+++ b/src/geom/size.rs
@@ -11,17 +11,17 @@ pub struct Size {
impl Size {
/// The zero size.
- pub fn zero() -> Self {
+ pub const fn zero() -> Self {
Self { w: Length::zero(), h: Length::zero() }
}
/// Create a new size from width and height.
- pub fn new(w: Length, h: Length) -> Self {
+ pub const fn new(w: Length, h: Length) -> Self {
Self { w, h }
}
/// Create an instance with two equal components.
- pub fn splat(v: Length) -> Self {
+ pub const fn splat(v: Length) -> Self {
Self { w: v, h: v }
}
@@ -41,17 +41,17 @@ impl Size {
}
/// Convert to a point.
- pub fn to_point(self) -> Point {
+ pub const fn to_point(self) -> Point {
Point::new(self.w, self.h)
}
/// Convert to a Spec.
- pub fn to_spec(self) -> Spec<Length> {
+ pub const fn to_spec(self) -> Spec<Length> {
Spec::new(self.w, self.h)
}
/// Convert to the generic representation.
- pub fn to_gen(self, block: SpecAxis) -> Gen<Length> {
+ pub const fn to_gen(self, block: SpecAxis) -> Gen<Length> {
match block {
SpecAxis::Horizontal => Gen::new(self.h, self.w),
SpecAxis::Vertical => Gen::new(self.w, self.h),
diff --git a/src/geom/spec.rs b/src/geom/spec.rs
index 82bedf9e..576c1c89 100644
--- a/src/geom/spec.rs
+++ b/src/geom/spec.rs
@@ -11,7 +11,7 @@ pub struct Spec<T> {
impl<T> Spec<T> {
/// Create a new instance from the two components.
- pub fn new(x: T, y: T) -> Self {
+ pub const fn new(x: T, y: T) -> Self {
Self { x, y }
}