mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Remove decorum
This commit is contained in:
parent
0a974d86ba
commit
02f114d072
@ -19,7 +19,6 @@ debug = 0
|
|||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
decorum = { version = "0.3.1", default-features = false, features = ["serialize-serde"] }
|
|
||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
|
image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
@ -17,7 +17,7 @@ pub enum Align {
|
|||||||
|
|
||||||
impl Align {
|
impl Align {
|
||||||
/// The axis this alignment belongs to if it is specific.
|
/// 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 {
|
match self {
|
||||||
Self::Left => Some(SpecAxis::Horizontal),
|
Self::Left => Some(SpecAxis::Horizontal),
|
||||||
Self::Top => Some(SpecAxis::Vertical),
|
Self::Top => Some(SpecAxis::Vertical),
|
||||||
@ -28,7 +28,7 @@ impl Align {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse alignment.
|
/// The inverse alignment.
|
||||||
pub fn inv(self) -> Self {
|
pub const fn inv(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Left => Self::Right,
|
Self::Left => Self::Right,
|
||||||
Self::Top => Self::Bottom,
|
Self::Top => Self::Bottom,
|
||||||
|
@ -3,12 +3,12 @@ use super::*;
|
|||||||
/// An angle.
|
/// An angle.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Angle(N64);
|
pub struct Angle(Scalar);
|
||||||
|
|
||||||
impl Angle {
|
impl Angle {
|
||||||
/// The zero angle.
|
/// The zero angle.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(N64::from(0.0))
|
Self(Scalar(0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an angle from a number of radians.
|
/// Create an angle from a number of radians.
|
||||||
@ -22,8 +22,8 @@ impl Angle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create an angle from a number of raw units.
|
/// Create an angle from a number of raw units.
|
||||||
pub fn raw(raw: f64) -> Self {
|
pub const fn raw(raw: f64) -> Self {
|
||||||
Self(N64::from(raw))
|
Self(Scalar(raw))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this to a number of radians.
|
/// Convert this to a number of radians.
|
||||||
@ -37,13 +37,13 @@ impl Angle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value of this angle in raw units.
|
/// Get the value of this angle in raw units.
|
||||||
pub fn to_raw(self) -> f64 {
|
pub const fn to_raw(self) -> f64 {
|
||||||
self.0.into()
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an angle from a value in a unit.
|
/// Create an angle from a value in a unit.
|
||||||
pub fn with_unit(val: f64, unit: AngularUnit) -> Self {
|
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.
|
/// Get the value of this length in unit.
|
||||||
|
@ -15,7 +15,7 @@ pub enum Dir {
|
|||||||
|
|
||||||
impl Dir {
|
impl Dir {
|
||||||
/// The side this direction starts at.
|
/// The side this direction starts at.
|
||||||
pub fn start(self) -> Side {
|
pub const fn start(self) -> Side {
|
||||||
match self {
|
match self {
|
||||||
Self::LTR => Side::Left,
|
Self::LTR => Side::Left,
|
||||||
Self::RTL => Side::Right,
|
Self::RTL => Side::Right,
|
||||||
@ -25,7 +25,7 @@ impl Dir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The side this direction ends at.
|
/// The side this direction ends at.
|
||||||
pub fn end(self) -> Side {
|
pub const fn end(self) -> Side {
|
||||||
match self {
|
match self {
|
||||||
Self::LTR => Side::Right,
|
Self::LTR => Side::Right,
|
||||||
Self::RTL => Side::Left,
|
Self::RTL => Side::Left,
|
||||||
@ -35,7 +35,7 @@ impl Dir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The specific axis this direction belongs to.
|
/// The specific axis this direction belongs to.
|
||||||
pub fn axis(self) -> SpecAxis {
|
pub const fn axis(self) -> SpecAxis {
|
||||||
match self {
|
match self {
|
||||||
Self::LTR | Self::RTL => SpecAxis::Horizontal,
|
Self::LTR | Self::RTL => SpecAxis::Horizontal,
|
||||||
Self::TTB | Self::BTT => SpecAxis::Vertical,
|
Self::TTB | Self::BTT => SpecAxis::Vertical,
|
||||||
@ -45,7 +45,7 @@ impl Dir {
|
|||||||
/// Whether this direction points into the positive coordinate direction.
|
/// Whether this direction points into the positive coordinate direction.
|
||||||
///
|
///
|
||||||
/// The positive directions are left-to-right and top-to-bottom.
|
/// 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 {
|
match self {
|
||||||
Self::LTR | Self::TTB => true,
|
Self::LTR | Self::TTB => true,
|
||||||
Self::RTL | Self::BTT => false,
|
Self::RTL | Self::BTT => false,
|
||||||
@ -56,12 +56,12 @@ impl Dir {
|
|||||||
///
|
///
|
||||||
/// - `1.0` if the direction is positive.
|
/// - `1.0` if the direction is positive.
|
||||||
/// - `-1.0` if the direction is negative.
|
/// - `-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 }
|
if self.is_positive() { 1.0 } else { -1.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse direction.
|
/// The inverse direction.
|
||||||
pub fn inv(self) -> Self {
|
pub const fn inv(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::LTR => Self::RTL,
|
Self::LTR => Self::RTL,
|
||||||
Self::RTL => Self::LTR,
|
Self::RTL => Self::LTR,
|
||||||
|
@ -5,27 +5,27 @@ use super::*;
|
|||||||
/// `1em` is the same as the font size.
|
/// `1em` is the same as the font size.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Em(N64);
|
pub struct Em(Scalar);
|
||||||
|
|
||||||
impl Em {
|
impl Em {
|
||||||
/// The zero length.
|
/// The zero length.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(N64::from(0.0))
|
Self(Scalar(0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The font size.
|
/// The font size.
|
||||||
pub fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self(N64::from(1.0))
|
Self(Scalar(1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an font-relative length.
|
/// Create an font-relative length.
|
||||||
pub fn new(em: f64) -> Self {
|
pub const fn new(em: f64) -> Self {
|
||||||
Self(N64::from(em))
|
Self(Scalar(em))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create font units at the given units per em.
|
/// Create font units at the given units per em.
|
||||||
pub fn from_units(units: impl Into<f64>, units_per_em: f64) -> Self {
|
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.
|
/// Convert to a length at the given font size.
|
||||||
@ -34,8 +34,8 @@ impl Em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The number of em units.
|
/// The number of em units.
|
||||||
pub fn get(self) -> f64 {
|
pub const fn get(self) -> f64 {
|
||||||
self.0.into()
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the length is zero.
|
/// Whether the length is zero.
|
||||||
|
@ -2,27 +2,27 @@ use super::*;
|
|||||||
|
|
||||||
/// A fractional length.
|
/// A fractional length.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct Fractional(N64);
|
pub struct Fractional(Scalar);
|
||||||
|
|
||||||
impl Fractional {
|
impl Fractional {
|
||||||
/// Takes up zero space: `0fr`.
|
/// Takes up zero space: `0fr`.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(N64::from(0.0))
|
Self(Scalar(0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes up as much space as all other items with this fractional size: `1fr`.
|
/// Takes up as much space as all other items with this fractional size: `1fr`.
|
||||||
pub fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self(N64::from(1.0))
|
Self(Scalar(1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new fractional value.
|
/// Create a new fractional value.
|
||||||
pub fn new(ratio: f64) -> Self {
|
pub const fn new(ratio: f64) -> Self {
|
||||||
Self(N64::from(ratio))
|
Self(Scalar(ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying ratio.
|
/// Get the underlying ratio.
|
||||||
pub fn get(self) -> f64 {
|
pub const fn get(self) -> f64 {
|
||||||
self.0.into()
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the ratio is zero.
|
/// Whether the ratio is zero.
|
||||||
|
@ -11,7 +11,7 @@ pub struct Gen<T> {
|
|||||||
|
|
||||||
impl<T> Gen<T> {
|
impl<T> Gen<T> {
|
||||||
/// Create a new instance from the two components.
|
/// 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 }
|
Self { inline, block }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,17 +4,17 @@ use super::*;
|
|||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Length(N64);
|
pub struct Length(Scalar);
|
||||||
|
|
||||||
impl Length {
|
impl Length {
|
||||||
/// The zero length.
|
/// The zero length.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(N64::from(0.0))
|
Self(Scalar(0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inifinite length.
|
/// The inifinite length.
|
||||||
pub fn inf() -> Self {
|
pub const fn inf() -> Self {
|
||||||
Self(N64::from(f64::INFINITY))
|
Self(Scalar(f64::INFINITY))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of points.
|
/// Create a length from a number of points.
|
||||||
@ -38,8 +38,8 @@ impl Length {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of raw units.
|
/// Create a length from a number of raw units.
|
||||||
pub fn raw(raw: f64) -> Self {
|
pub const fn raw(raw: f64) -> Self {
|
||||||
Self(N64::from(raw))
|
Self(Scalar(raw))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this to a number of points.
|
/// Convert this to a number of points.
|
||||||
@ -63,13 +63,13 @@ impl Length {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value of this length in raw units.
|
/// Get the value of this length in raw units.
|
||||||
pub fn to_raw(self) -> f64 {
|
pub const fn to_raw(self) -> f64 {
|
||||||
self.0.into()
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a value in a unit.
|
/// Create a length from a value in a unit.
|
||||||
pub fn with_unit(val: f64, unit: LengthUnit) -> Self {
|
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.
|
/// Get the value of this length in unit.
|
||||||
@ -79,17 +79,17 @@ impl Length {
|
|||||||
|
|
||||||
/// Whether the length is zero.
|
/// Whether the length is zero.
|
||||||
pub fn is_zero(self) -> bool {
|
pub fn is_zero(self) -> bool {
|
||||||
self.0 == 0.0
|
self.to_raw() == 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the length is finite.
|
/// Whether the length is finite.
|
||||||
pub fn is_finite(self) -> bool {
|
pub fn is_finite(self) -> bool {
|
||||||
self.0.into_inner().is_finite()
|
self.to_raw().is_finite()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the length is infinite.
|
/// Whether the length is infinite.
|
||||||
pub fn is_infinite(self) -> bool {
|
pub fn is_infinite(self) -> bool {
|
||||||
self.0.into_inner().is_infinite()
|
self.to_raw().is_infinite()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The absolute value of the this length.
|
/// The absolute value of the this length.
|
||||||
@ -211,14 +211,14 @@ assign_impl!(Length *= f64);
|
|||||||
assign_impl!(Length /= f64);
|
assign_impl!(Length /= f64);
|
||||||
|
|
||||||
impl Sum for Length {
|
impl Sum for Length {
|
||||||
fn sum<I: Iterator<Item = Length>>(iter: I) -> Self {
|
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
iter.fold(Length::zero(), Add::add)
|
Self(iter.map(|s| s.0).sum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Sum<&'a Length> for Length {
|
impl<'a> Sum<&'a Self> for Length {
|
||||||
fn sum<I: Iterator<Item = &'a Length>>(iter: I) -> Self {
|
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
|
||||||
iter.copied().fold(Length::zero(), Add::add)
|
Self(iter.map(|s| s.0).sum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ pub struct Linear {
|
|||||||
|
|
||||||
impl Linear {
|
impl Linear {
|
||||||
/// The zero linear.
|
/// The zero linear.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rel: Relative::zero(),
|
rel: Relative::zero(),
|
||||||
abs: Length::zero(),
|
abs: Length::zero(),
|
||||||
@ -19,7 +19,7 @@ impl Linear {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The linear with a relative part of `100%` and no absolute part.
|
/// The linear with a relative part of `100%` and no absolute part.
|
||||||
pub fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rel: Relative::one(),
|
rel: Relative::one(),
|
||||||
abs: Length::zero(),
|
abs: Length::zero(),
|
||||||
@ -27,7 +27,7 @@ impl Linear {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 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 }
|
Self { rel, abs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ mod paint;
|
|||||||
mod path;
|
mod path;
|
||||||
mod point;
|
mod point;
|
||||||
mod relative;
|
mod relative;
|
||||||
|
mod scalar;
|
||||||
mod sides;
|
mod sides;
|
||||||
mod size;
|
mod size;
|
||||||
mod spec;
|
mod spec;
|
||||||
@ -30,16 +31,18 @@ pub use paint::*;
|
|||||||
pub use path::*;
|
pub use path::*;
|
||||||
pub use point::*;
|
pub use point::*;
|
||||||
pub use relative::*;
|
pub use relative::*;
|
||||||
|
pub use scalar::*;
|
||||||
pub use sides::*;
|
pub use sides::*;
|
||||||
pub use size::*;
|
pub use size::*;
|
||||||
pub use spec::*;
|
pub use spec::*;
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::iter::Sum;
|
use std::iter::Sum;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
use decorum::N64;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Generic access to a structure's components.
|
/// Generic access to a structure's components.
|
||||||
|
@ -16,7 +16,7 @@ pub enum PathElement {
|
|||||||
|
|
||||||
impl Path {
|
impl Path {
|
||||||
/// Create an empty path.
|
/// Create an empty path.
|
||||||
pub fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self(vec![])
|
Self(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,22 +11,22 @@ pub struct Point {
|
|||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
/// The origin point.
|
/// The origin point.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self { x: Length::zero(), y: Length::zero() }
|
Self { x: Length::zero(), y: Length::zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new point from x and y coordinate.
|
/// 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 }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an instance with two equal components.
|
/// 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 }
|
Self { x: value, y: value }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to the generic representation.
|
/// 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 {
|
match block {
|
||||||
SpecAxis::Horizontal => Gen::new(self.y, self.x),
|
SpecAxis::Horizontal => Gen::new(self.y, self.x),
|
||||||
SpecAxis::Vertical => Gen::new(self.x, self.y),
|
SpecAxis::Vertical => Gen::new(self.x, self.y),
|
||||||
|
@ -5,27 +5,27 @@ use super::*;
|
|||||||
/// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the
|
/// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the
|
||||||
/// corresponding [literal](crate::syntax::ast::LitKind::Percent).
|
/// corresponding [literal](crate::syntax::ast::LitKind::Percent).
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct Relative(N64);
|
pub struct Relative(Scalar);
|
||||||
|
|
||||||
impl Relative {
|
impl Relative {
|
||||||
/// A ratio of `0%` represented as `0.0`.
|
/// A ratio of `0%` represented as `0.0`.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(N64::from(0.0))
|
Self(Scalar(0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A ratio of `100%` represented as `1.0`.
|
/// A ratio of `100%` represented as `1.0`.
|
||||||
pub fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self(N64::from(1.0))
|
Self(Scalar(1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new relative value.
|
/// Create a new relative value.
|
||||||
pub fn new(ratio: f64) -> Self {
|
pub const fn new(ratio: f64) -> Self {
|
||||||
Self(N64::from(ratio))
|
Self(Scalar(ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying ratio.
|
/// Get the underlying ratio.
|
||||||
pub fn get(self) -> f64 {
|
pub const fn get(self) -> f64 {
|
||||||
self.0.into()
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve this relative to the given `length`.
|
/// Resolve this relative to the given `length`.
|
||||||
|
152
src/geom/scalar.rs
Normal file
152
src/geom/scalar.rs
Normal file
@ -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())
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ pub struct Sides<T> {
|
|||||||
|
|
||||||
impl<T> Sides<T> {
|
impl<T> Sides<T> {
|
||||||
/// Create a new instance from the four components.
|
/// 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 }
|
Self { left, top, right, bottom }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,17 +11,17 @@ pub struct Size {
|
|||||||
|
|
||||||
impl Size {
|
impl Size {
|
||||||
/// The zero size.
|
/// The zero size.
|
||||||
pub fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self { w: Length::zero(), h: Length::zero() }
|
Self { w: Length::zero(), h: Length::zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new size from width and height.
|
/// 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 }
|
Self { w, h }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an instance with two equal components.
|
/// 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 }
|
Self { w: v, h: v }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,17 +41,17 @@ impl Size {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to a point.
|
/// Convert to a point.
|
||||||
pub fn to_point(self) -> Point {
|
pub const fn to_point(self) -> Point {
|
||||||
Point::new(self.w, self.h)
|
Point::new(self.w, self.h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to a Spec.
|
/// 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)
|
Spec::new(self.w, self.h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to the generic representation.
|
/// 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 {
|
match block {
|
||||||
SpecAxis::Horizontal => Gen::new(self.h, self.w),
|
SpecAxis::Horizontal => Gen::new(self.h, self.w),
|
||||||
SpecAxis::Vertical => Gen::new(self.w, self.h),
|
SpecAxis::Vertical => Gen::new(self.w, self.h),
|
||||||
|
@ -11,7 +11,7 @@ pub struct Spec<T> {
|
|||||||
|
|
||||||
impl<T> Spec<T> {
|
impl<T> Spec<T> {
|
||||||
/// Create a new instance from the two components.
|
/// 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 }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ use std::cmp::Reverse;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use decorum::N32;
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::{Constrained, Regions};
|
use super::{Constrained, Regions};
|
||||||
use crate::frame::Frame;
|
use crate::frame::Frame;
|
||||||
|
use crate::geom::Scalar;
|
||||||
|
|
||||||
const TEMP_LEN: usize = 5;
|
const TEMP_LEN: usize = 5;
|
||||||
const TEMP_LAST: usize = TEMP_LEN - 1;
|
const TEMP_LAST: usize = TEMP_LEN - 1;
|
||||||
@ -135,28 +135,27 @@ impl LayoutCache {
|
|||||||
.0;
|
.0;
|
||||||
|
|
||||||
for entries in self.frames.values_mut() {
|
for entries in self.frames.values_mut() {
|
||||||
entries.retain(|e| e.cooldown() < threshold);
|
entries.retain(|f| f.cooldown() < threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EvictionPolicy::LeastFrequentlyUsed => {
|
EvictionPolicy::LeastFrequentlyUsed => {
|
||||||
let threshold = self
|
let threshold = self
|
||||||
.entries()
|
.entries()
|
||||||
.map(|f| N32::from(f.hits() as f32 / f.age() as f32))
|
.map(|f| Scalar(f.hits() as f64 / f.age() as f64))
|
||||||
.k_smallest(len - self.max_size)
|
.k_smallest(len - self.max_size)
|
||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.0;
|
||||||
|
|
||||||
for entries in self.frames.values_mut() {
|
for entries in self.frames.values_mut() {
|
||||||
entries.retain(|f| {
|
entries.retain(|f| f.hits() as f64 / f.age() as f64 > threshold);
|
||||||
f.hits() as f32 / f.age() as f32 > threshold.into_inner()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EvictionPolicy::Random => {
|
EvictionPolicy::Random => {
|
||||||
// Fraction of items that should be kept.
|
// Fraction of items that should be kept.
|
||||||
let threshold = self.max_size as f32 / len as f32;
|
let threshold = self.max_size as f64 / len as f64;
|
||||||
for entries in self.frames.values_mut() {
|
for entries in self.frames.values_mut() {
|
||||||
entries.retain(|_| rand::random::<f32>() > threshold);
|
entries.retain(|_| rand::random::<f64>() > threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EvictionPolicy::Patterns => {
|
EvictionPolicy::Patterns => {
|
||||||
@ -170,15 +169,16 @@ impl LayoutCache {
|
|||||||
let threshold = self
|
let threshold = self
|
||||||
.entries()
|
.entries()
|
||||||
.filter(|f| !f.properties().must_keep())
|
.filter(|f| !f.properties().must_keep())
|
||||||
.map(|f| N32::from(f.hits() as f32 / f.age() as f32))
|
.map(|f| Scalar(f.hits() as f64 / f.age() as f64))
|
||||||
.k_smallest((len - kept) - remaining_capacity)
|
.k_smallest((len - kept) - remaining_capacity)
|
||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.0;
|
||||||
|
|
||||||
for (_, entries) in self.frames.iter_mut() {
|
for entries in self.frames.values_mut() {
|
||||||
entries.retain(|f| {
|
entries.retain(|f| {
|
||||||
f.properties().must_keep()
|
f.properties().must_keep()
|
||||||
|| f.hits() as f32 / f.age() as f32 > threshold.into_inner()
|
|| f.hits() as f64 / f.age() as f64 > threshold
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user