mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Rename length-related types
`Fractional` => `Fraction` `Relative` => `Ratio` `Linear` => `Relative`
This commit is contained in:
parent
eb22eed31b
commit
1192132dc0
@ -456,7 +456,7 @@ impl<'a> Builder<'a> {
|
|||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
{
|
{
|
||||||
par.push_front(ParChild::Spacing(Spacing::Linear(indent)))
|
par.push_front(ParChild::Spacing(Spacing::Relative(indent)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = ParNode(par).pack();
|
let node = ParNode(par).pack();
|
||||||
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
|||||||
use super::{Barrier, StyleChain};
|
use super::{Barrier, StyleChain};
|
||||||
use crate::diag::TypResult;
|
use crate::diag::TypResult;
|
||||||
use crate::frame::{Element, Frame, Geometry, Shape, Stroke};
|
use crate::frame::{Element, Frame, Geometry, Shape, Stroke};
|
||||||
use crate::geom::{Align, Length, Linear, Paint, Point, Sides, Size, Spec, Transform};
|
use crate::geom::{Align, Length, Paint, Point, Relative, Sides, Size, Spec, Transform};
|
||||||
use crate::library::graphics::MoveNode;
|
use crate::library::graphics::MoveNode;
|
||||||
use crate::library::layout::{AlignNode, PadNode};
|
use crate::library::layout::{AlignNode, PadNode};
|
||||||
use crate::util::Prehashed;
|
use crate::util::Prehashed;
|
||||||
@ -161,7 +161,7 @@ impl LayoutNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Force a size for this node.
|
/// Force a size for this node.
|
||||||
pub fn sized(self, sizing: Spec<Option<Linear>>) -> Self {
|
pub fn sized(self, sizing: Spec<Option<Relative>>) -> Self {
|
||||||
if sizing.any(Option::is_some) {
|
if sizing.any(Option::is_some) {
|
||||||
SizedNode { sizing, child: self }.pack()
|
SizedNode { sizing, child: self }.pack()
|
||||||
} else {
|
} else {
|
||||||
@ -189,7 +189,7 @@ impl LayoutNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pad this node at the sides.
|
/// Pad this node at the sides.
|
||||||
pub fn padded(self, padding: Sides<Linear>) -> Self {
|
pub fn padded(self, padding: Sides<Relative>) -> Self {
|
||||||
if !padding.left.is_zero()
|
if !padding.left.is_zero()
|
||||||
|| !padding.top.is_zero()
|
|| !padding.top.is_zero()
|
||||||
|| !padding.right.is_zero()
|
|| !padding.right.is_zero()
|
||||||
@ -292,7 +292,7 @@ impl Layout for EmptyNode {
|
|||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
struct SizedNode {
|
struct SizedNode {
|
||||||
/// How to size the node horizontally and vertically.
|
/// How to size the node horizontally and vertically.
|
||||||
sizing: Spec<Option<Linear>>,
|
sizing: Spec<Option<Relative>>,
|
||||||
/// The node to be sized.
|
/// The node to be sized.
|
||||||
child: LayoutNode,
|
child: LayoutNode,
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ impl Layout for SizedNode {
|
|||||||
.unwrap_or(regions.first);
|
.unwrap_or(regions.first);
|
||||||
|
|
||||||
// Select the appropriate base and expansion for the child depending
|
// Select the appropriate base and expansion for the child depending
|
||||||
// on whether it is automatically or linearly sized.
|
// on whether it is automatically or relatively sized.
|
||||||
let is_auto = self.sizing.map_is_none();
|
let is_auto = self.sizing.map_is_none();
|
||||||
let base = is_auto.select(regions.base, size);
|
let base = is_auto.select(regions.base, size);
|
||||||
let expand = regions.expand | !is_auto;
|
let expand = regions.expand | !is_auto;
|
||||||
|
@ -41,7 +41,7 @@ use parking_lot::{MappedRwLockWriteGuard, RwLockWriteGuard};
|
|||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use crate::diag::{At, StrResult, Trace, Tracepoint, TypResult};
|
use crate::diag::{At, StrResult, Trace, Tracepoint, TypResult};
|
||||||
use crate::geom::{Angle, Fractional, Length, Relative};
|
use crate::geom::{Angle, Fraction, Length, Ratio};
|
||||||
use crate::library;
|
use crate::library;
|
||||||
use crate::syntax::ast::*;
|
use crate::syntax::ast::*;
|
||||||
use crate::syntax::{Span, Spanned};
|
use crate::syntax::{Span, Spanned};
|
||||||
@ -245,8 +245,8 @@ impl Eval for Lit {
|
|||||||
LitKind::Float(v) => Value::Float(v),
|
LitKind::Float(v) => Value::Float(v),
|
||||||
LitKind::Length(v, unit) => Value::Length(Length::with_unit(v, unit)),
|
LitKind::Length(v, unit) => Value::Length(Length::with_unit(v, unit)),
|
||||||
LitKind::Angle(v, unit) => Value::Angle(Angle::with_unit(v, unit)),
|
LitKind::Angle(v, unit) => Value::Angle(Angle::with_unit(v, unit)),
|
||||||
LitKind::Percent(v) => Value::Relative(Relative::new(v / 100.0)),
|
LitKind::Percent(v) => Value::Ratio(Ratio::new(v / 100.0)),
|
||||||
LitKind::Fractional(v) => Value::Fractional(Fractional::new(v)),
|
LitKind::Fractional(v) => Value::Fraction(Fraction::new(v)),
|
||||||
LitKind::Str(ref v) => Value::Str(v.clone()),
|
LitKind::Str(ref v) => Value::Str(v.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
102
src/eval/ops.rs
102
src/eval/ops.rs
@ -34,9 +34,9 @@ pub fn pos(value: Value) -> StrResult<Value> {
|
|||||||
Float(v) => Float(v),
|
Float(v) => Float(v),
|
||||||
Length(v) => Length(v),
|
Length(v) => Length(v),
|
||||||
Angle(v) => Angle(v),
|
Angle(v) => Angle(v),
|
||||||
|
Ratio(v) => Ratio(v),
|
||||||
Relative(v) => Relative(v),
|
Relative(v) => Relative(v),
|
||||||
Linear(v) => Linear(v),
|
Fraction(v) => Fraction(v),
|
||||||
Fractional(v) => Fractional(v),
|
|
||||||
v => mismatch!("cannot apply '+' to {}", v),
|
v => mismatch!("cannot apply '+' to {}", v),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -48,9 +48,9 @@ pub fn neg(value: Value) -> StrResult<Value> {
|
|||||||
Float(v) => Float(-v),
|
Float(v) => Float(-v),
|
||||||
Length(v) => Length(-v),
|
Length(v) => Length(-v),
|
||||||
Angle(v) => Angle(-v),
|
Angle(v) => Angle(-v),
|
||||||
|
Ratio(v) => Ratio(-v),
|
||||||
Relative(v) => Relative(-v),
|
Relative(v) => Relative(-v),
|
||||||
Linear(v) => Linear(-v),
|
Fraction(v) => Fraction(-v),
|
||||||
Fractional(v) => Fractional(-v),
|
|
||||||
v => mismatch!("cannot apply '-' to {}", v),
|
v => mismatch!("cannot apply '-' to {}", v),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -66,18 +66,18 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
|
|||||||
(Angle(a), Angle(b)) => Angle(a + b),
|
(Angle(a), Angle(b)) => Angle(a + b),
|
||||||
|
|
||||||
(Length(a), Length(b)) => Length(a + b),
|
(Length(a), Length(b)) => Length(a + b),
|
||||||
(Length(a), Relative(b)) => Linear(a + b),
|
(Length(a), Ratio(b)) => Relative(a + b),
|
||||||
(Length(a), Linear(b)) => Linear(a + b),
|
(Length(a), Relative(b)) => Relative(a + b),
|
||||||
|
|
||||||
(Relative(a), Length(b)) => Linear(a + b),
|
(Ratio(a), Length(b)) => Relative(a + b),
|
||||||
|
(Ratio(a), Ratio(b)) => Ratio(a + b),
|
||||||
|
(Ratio(a), Relative(b)) => Relative(a + b),
|
||||||
|
|
||||||
|
(Relative(a), Length(b)) => Relative(a + b),
|
||||||
|
(Relative(a), Ratio(b)) => Relative(a + b),
|
||||||
(Relative(a), Relative(b)) => Relative(a + b),
|
(Relative(a), Relative(b)) => Relative(a + b),
|
||||||
(Relative(a), Linear(b)) => Linear(a + b),
|
|
||||||
|
|
||||||
(Linear(a), Length(b)) => Linear(a + b),
|
(Fraction(a), Fraction(b)) => Fraction(a + b),
|
||||||
(Linear(a), Relative(b)) => Linear(a + b),
|
|
||||||
(Linear(a), Linear(b)) => Linear(a + b),
|
|
||||||
|
|
||||||
(Fractional(a), Fractional(b)) => Fractional(a + b),
|
|
||||||
|
|
||||||
(Str(a), Str(b)) => Str(a + b),
|
(Str(a), Str(b)) => Str(a + b),
|
||||||
|
|
||||||
@ -123,18 +123,18 @@ pub fn sub(lhs: Value, rhs: Value) -> StrResult<Value> {
|
|||||||
(Angle(a), Angle(b)) => Angle(a - b),
|
(Angle(a), Angle(b)) => Angle(a - b),
|
||||||
|
|
||||||
(Length(a), Length(b)) => Length(a - b),
|
(Length(a), Length(b)) => Length(a - b),
|
||||||
(Length(a), Relative(b)) => Linear(a - b),
|
(Length(a), Ratio(b)) => Relative(a - b),
|
||||||
(Length(a), Linear(b)) => Linear(a - b),
|
(Length(a), Relative(b)) => Relative(a - b),
|
||||||
|
|
||||||
(Relative(a), Length(b)) => Linear(a - b),
|
(Ratio(a), Length(b)) => Relative(a - b),
|
||||||
|
(Ratio(a), Ratio(b)) => Ratio(a - b),
|
||||||
|
(Ratio(a), Relative(b)) => Relative(a - b),
|
||||||
|
|
||||||
|
(Relative(a), Length(b)) => Relative(a - b),
|
||||||
|
(Relative(a), Ratio(b)) => Relative(a - b),
|
||||||
(Relative(a), Relative(b)) => Relative(a - b),
|
(Relative(a), Relative(b)) => Relative(a - b),
|
||||||
(Relative(a), Linear(b)) => Linear(a - b),
|
|
||||||
|
|
||||||
(Linear(a), Length(b)) => Linear(a - b),
|
(Fraction(a), Fraction(b)) => Fraction(a - b),
|
||||||
(Linear(a), Relative(b)) => Linear(a - b),
|
|
||||||
(Linear(a), Linear(b)) => Linear(a - b),
|
|
||||||
|
|
||||||
(Fractional(a), Fractional(b)) => Fractional(a - b),
|
|
||||||
|
|
||||||
(a, b) => mismatch!("cannot subtract {1} from {0}", a, b),
|
(a, b) => mismatch!("cannot subtract {1} from {0}", a, b),
|
||||||
})
|
})
|
||||||
@ -158,20 +158,20 @@ pub fn mul(lhs: Value, rhs: Value) -> StrResult<Value> {
|
|||||||
(Int(a), Angle(b)) => Angle(a as f64 * b),
|
(Int(a), Angle(b)) => Angle(a as f64 * b),
|
||||||
(Float(a), Angle(b)) => Angle(a * b),
|
(Float(a), Angle(b)) => Angle(a * b),
|
||||||
|
|
||||||
|
(Ratio(a), Int(b)) => Ratio(a * b as f64),
|
||||||
|
(Ratio(a), Float(b)) => Ratio(a * b),
|
||||||
|
(Float(a), Ratio(b)) => Ratio(a * b),
|
||||||
|
(Int(a), Ratio(b)) => Ratio(a as f64 * b),
|
||||||
|
|
||||||
(Relative(a), Int(b)) => Relative(a * b as f64),
|
(Relative(a), Int(b)) => Relative(a * b as f64),
|
||||||
(Relative(a), Float(b)) => Relative(a * b),
|
(Relative(a), Float(b)) => Relative(a * b),
|
||||||
(Float(a), Relative(b)) => Relative(a * b),
|
|
||||||
(Int(a), Relative(b)) => Relative(a as f64 * b),
|
(Int(a), Relative(b)) => Relative(a as f64 * b),
|
||||||
|
(Float(a), Relative(b)) => Relative(a * b),
|
||||||
|
|
||||||
(Linear(a), Int(b)) => Linear(a * b as f64),
|
(Float(a), Fraction(b)) => Fraction(a * b),
|
||||||
(Linear(a), Float(b)) => Linear(a * b),
|
(Fraction(a), Int(b)) => Fraction(a * b as f64),
|
||||||
(Int(a), Linear(b)) => Linear(a as f64 * b),
|
(Fraction(a), Float(b)) => Fraction(a * b),
|
||||||
(Float(a), Linear(b)) => Linear(a * b),
|
(Int(a), Fraction(b)) => Fraction(a as f64 * b),
|
||||||
|
|
||||||
(Float(a), Fractional(b)) => Fractional(a * b),
|
|
||||||
(Fractional(a), Int(b)) => Fractional(a * b as f64),
|
|
||||||
(Fractional(a), Float(b)) => Fractional(a * b),
|
|
||||||
(Int(a), Fractional(b)) => Fractional(a as f64 * b),
|
|
||||||
|
|
||||||
(Str(a), Int(b)) => Str(StrExt::repeat(&a, b)?),
|
(Str(a), Int(b)) => Str(StrExt::repeat(&a, b)?),
|
||||||
(Int(a), Str(b)) => Str(StrExt::repeat(&b, a)?),
|
(Int(a), Str(b)) => Str(StrExt::repeat(&b, a)?),
|
||||||
@ -200,16 +200,16 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
|
|||||||
(Angle(a), Float(b)) => Angle(a / b),
|
(Angle(a), Float(b)) => Angle(a / b),
|
||||||
(Angle(a), Angle(b)) => Float(a / b),
|
(Angle(a), Angle(b)) => Float(a / b),
|
||||||
|
|
||||||
|
(Ratio(a), Int(b)) => Ratio(a / b as f64),
|
||||||
|
(Ratio(a), Float(b)) => Ratio(a / b),
|
||||||
|
(Ratio(a), Ratio(b)) => Float(a / b),
|
||||||
|
|
||||||
(Relative(a), Int(b)) => Relative(a / b as f64),
|
(Relative(a), Int(b)) => Relative(a / b as f64),
|
||||||
(Relative(a), Float(b)) => Relative(a / b),
|
(Relative(a), Float(b)) => Relative(a / b),
|
||||||
(Relative(a), Relative(b)) => Float(a / b),
|
|
||||||
|
|
||||||
(Linear(a), Int(b)) => Linear(a / b as f64),
|
(Fraction(a), Int(b)) => Fraction(a / b as f64),
|
||||||
(Linear(a), Float(b)) => Linear(a / b),
|
(Fraction(a), Float(b)) => Fraction(a / b),
|
||||||
|
(Fraction(a), Fraction(b)) => Float(a / b),
|
||||||
(Fractional(a), Int(b)) => Fractional(a / b as f64),
|
|
||||||
(Fractional(a), Float(b)) => Fractional(a / b),
|
|
||||||
(Fractional(a), Fractional(b)) => Float(a / b),
|
|
||||||
|
|
||||||
(a, b) => mismatch!("cannot divide {} by {}", a, b),
|
(a, b) => mismatch!("cannot divide {} by {}", a, b),
|
||||||
})
|
})
|
||||||
@ -278,9 +278,9 @@ pub fn equal(lhs: &Value, rhs: &Value) -> bool {
|
|||||||
(Float(a), Float(b)) => a == b,
|
(Float(a), Float(b)) => a == b,
|
||||||
(Length(a), Length(b)) => a == b,
|
(Length(a), Length(b)) => a == b,
|
||||||
(Angle(a), Angle(b)) => a == b,
|
(Angle(a), Angle(b)) => a == b,
|
||||||
|
(Ratio(a), Ratio(b)) => a == b,
|
||||||
(Relative(a), Relative(b)) => a == b,
|
(Relative(a), Relative(b)) => a == b,
|
||||||
(Linear(a), Linear(b)) => a == b,
|
(Fraction(a), Fraction(b)) => a == b,
|
||||||
(Fractional(a), Fractional(b)) => a == b,
|
|
||||||
(Color(a), Color(b)) => a == b,
|
(Color(a), Color(b)) => a == b,
|
||||||
(Str(a), Str(b)) => a == b,
|
(Str(a), Str(b)) => a == b,
|
||||||
(Content(a), Content(b)) => a == b,
|
(Content(a), Content(b)) => a == b,
|
||||||
@ -292,10 +292,10 @@ pub fn equal(lhs: &Value, rhs: &Value) -> bool {
|
|||||||
// Some technically different things should compare equal.
|
// Some technically different things should compare equal.
|
||||||
(&Int(a), &Float(b)) => a as f64 == b,
|
(&Int(a), &Float(b)) => a as f64 == b,
|
||||||
(&Float(a), &Int(b)) => a == b as f64,
|
(&Float(a), &Int(b)) => a == b as f64,
|
||||||
(&Length(a), &Linear(b)) => a == b.abs && b.rel.is_zero(),
|
(&Length(a), &Relative(b)) => a == b.abs && b.rel.is_zero(),
|
||||||
(&Relative(a), &Linear(b)) => a == b.rel && b.abs.is_zero(),
|
(&Ratio(a), &Relative(b)) => a == b.rel && b.abs.is_zero(),
|
||||||
(&Linear(a), &Length(b)) => a.abs == b && a.rel.is_zero(),
|
(&Relative(a), &Length(b)) => a.abs == b && a.rel.is_zero(),
|
||||||
(&Linear(a), &Relative(b)) => a.rel == b && a.abs.is_zero(),
|
(&Relative(a), &Ratio(b)) => a.rel == b && a.abs.is_zero(),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -309,17 +309,17 @@ pub fn compare(lhs: &Value, rhs: &Value) -> Option<Ordering> {
|
|||||||
(Float(a), Float(b)) => a.partial_cmp(b),
|
(Float(a), Float(b)) => a.partial_cmp(b),
|
||||||
(Angle(a), Angle(b)) => a.partial_cmp(b),
|
(Angle(a), Angle(b)) => a.partial_cmp(b),
|
||||||
(Length(a), Length(b)) => a.partial_cmp(b),
|
(Length(a), Length(b)) => a.partial_cmp(b),
|
||||||
(Relative(a), Relative(b)) => a.partial_cmp(b),
|
(Ratio(a), Ratio(b)) => a.partial_cmp(b),
|
||||||
(Fractional(a), Fractional(b)) => a.partial_cmp(b),
|
(Fraction(a), Fraction(b)) => a.partial_cmp(b),
|
||||||
(Str(a), Str(b)) => a.partial_cmp(b),
|
(Str(a), Str(b)) => a.partial_cmp(b),
|
||||||
|
|
||||||
// Some technically different things should be comparable.
|
// Some technically different things should be comparable.
|
||||||
(&Int(a), &Float(b)) => (a as f64).partial_cmp(&b),
|
(&Int(a), &Float(b)) => (a as f64).partial_cmp(&b),
|
||||||
(&Float(a), &Int(b)) => a.partial_cmp(&(b as f64)),
|
(&Float(a), &Int(b)) => a.partial_cmp(&(b as f64)),
|
||||||
(&Length(a), &Linear(b)) if b.rel.is_zero() => a.partial_cmp(&b.abs),
|
(&Length(a), &Relative(b)) if b.rel.is_zero() => a.partial_cmp(&b.abs),
|
||||||
(&Relative(a), &Linear(b)) if b.abs.is_zero() => a.partial_cmp(&b.rel),
|
(&Ratio(a), &Relative(b)) if b.abs.is_zero() => a.partial_cmp(&b.rel),
|
||||||
(&Linear(a), &Length(b)) if a.rel.is_zero() => a.abs.partial_cmp(&b),
|
(&Relative(a), &Length(b)) if a.rel.is_zero() => a.abs.partial_cmp(&b),
|
||||||
(&Linear(a), &Relative(b)) if a.abs.is_zero() => a.rel.partial_cmp(&b),
|
(&Relative(a), &Ratio(b)) if a.abs.is_zero() => a.rel.partial_cmp(&b),
|
||||||
|
|
||||||
_ => Option::None,
|
_ => Option::None,
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ pub trait Key<'a>: 'static {
|
|||||||
/// from a style chain. For example, this is [`bool`] for the
|
/// from a style chain. For example, this is [`bool`] for the
|
||||||
/// [`STRONG`](TextNode::STRONG) property. For non-copy, non-folding
|
/// [`STRONG`](TextNode::STRONG) property. For non-copy, non-folding
|
||||||
/// properties this is a reference type.
|
/// properties this is a reference type.
|
||||||
type Output: 'a;
|
type Output;
|
||||||
|
|
||||||
/// The name of the property, used for debug printing.
|
/// The name of the property, used for debug printing.
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
@ -6,7 +6,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use super::{ops, Args, Array, Content, Context, Dict, Func, Layout, StrExt};
|
use super::{ops, Args, Array, Content, Context, Dict, Func, Layout, StrExt};
|
||||||
use crate::diag::{with_alternative, At, StrResult, TypResult};
|
use crate::diag::{with_alternative, At, StrResult, TypResult};
|
||||||
use crate::geom::{Angle, Color, Fractional, Length, Linear, Relative, RgbaColor};
|
use crate::geom::{Angle, Color, Fraction, Length, Ratio, Relative, RgbaColor};
|
||||||
use crate::library::text::RawNode;
|
use crate::library::text::RawNode;
|
||||||
use crate::syntax::{Span, Spanned};
|
use crate::syntax::{Span, Spanned};
|
||||||
use crate::util::EcoString;
|
use crate::util::EcoString;
|
||||||
@ -28,12 +28,12 @@ pub enum Value {
|
|||||||
Length(Length),
|
Length(Length),
|
||||||
/// An angle: `1.5rad`, `90deg`.
|
/// An angle: `1.5rad`, `90deg`.
|
||||||
Angle(Angle),
|
Angle(Angle),
|
||||||
/// A relative value: `50%`.
|
/// A ratio: `50%`.
|
||||||
|
Ratio(Ratio),
|
||||||
|
/// A relative length, combination of a ratio and a length: `20% + 5cm`.
|
||||||
Relative(Relative),
|
Relative(Relative),
|
||||||
/// A combination of an absolute length and a relative value: `20% + 5cm`.
|
/// A fraction: `1fr`.
|
||||||
Linear(Linear),
|
Fraction(Fraction),
|
||||||
/// A fractional value: `1fr`.
|
|
||||||
Fractional(Fractional),
|
|
||||||
/// A color value: `#f79143ff`.
|
/// A color value: `#f79143ff`.
|
||||||
Color(Color),
|
Color(Color),
|
||||||
/// A string: `"string"`.
|
/// A string: `"string"`.
|
||||||
@ -79,9 +79,9 @@ impl Value {
|
|||||||
Self::Float(_) => f64::TYPE_NAME,
|
Self::Float(_) => f64::TYPE_NAME,
|
||||||
Self::Length(_) => Length::TYPE_NAME,
|
Self::Length(_) => Length::TYPE_NAME,
|
||||||
Self::Angle(_) => Angle::TYPE_NAME,
|
Self::Angle(_) => Angle::TYPE_NAME,
|
||||||
|
Self::Ratio(_) => Ratio::TYPE_NAME,
|
||||||
Self::Relative(_) => Relative::TYPE_NAME,
|
Self::Relative(_) => Relative::TYPE_NAME,
|
||||||
Self::Linear(_) => Linear::TYPE_NAME,
|
Self::Fraction(_) => Fraction::TYPE_NAME,
|
||||||
Self::Fractional(_) => Fractional::TYPE_NAME,
|
|
||||||
Self::Color(_) => Color::TYPE_NAME,
|
Self::Color(_) => Color::TYPE_NAME,
|
||||||
Self::Str(_) => EcoString::TYPE_NAME,
|
Self::Str(_) => EcoString::TYPE_NAME,
|
||||||
Self::Content(_) => Content::TYPE_NAME,
|
Self::Content(_) => Content::TYPE_NAME,
|
||||||
@ -255,9 +255,9 @@ impl Debug for Value {
|
|||||||
Self::Float(v) => Debug::fmt(v, f),
|
Self::Float(v) => Debug::fmt(v, f),
|
||||||
Self::Length(v) => Debug::fmt(v, f),
|
Self::Length(v) => Debug::fmt(v, f),
|
||||||
Self::Angle(v) => Debug::fmt(v, f),
|
Self::Angle(v) => Debug::fmt(v, f),
|
||||||
|
Self::Ratio(v) => Debug::fmt(v, f),
|
||||||
Self::Relative(v) => Debug::fmt(v, f),
|
Self::Relative(v) => Debug::fmt(v, f),
|
||||||
Self::Linear(v) => Debug::fmt(v, f),
|
Self::Fraction(v) => Debug::fmt(v, f),
|
||||||
Self::Fractional(v) => Debug::fmt(v, f),
|
|
||||||
Self::Color(v) => Debug::fmt(v, f),
|
Self::Color(v) => Debug::fmt(v, f),
|
||||||
Self::Str(v) => Debug::fmt(v, f),
|
Self::Str(v) => Debug::fmt(v, f),
|
||||||
Self::Content(_) => f.pad("<content>"),
|
Self::Content(_) => f.pad("<content>"),
|
||||||
@ -293,9 +293,9 @@ impl Hash for Value {
|
|||||||
Self::Float(v) => v.to_bits().hash(state),
|
Self::Float(v) => v.to_bits().hash(state),
|
||||||
Self::Length(v) => v.hash(state),
|
Self::Length(v) => v.hash(state),
|
||||||
Self::Angle(v) => v.hash(state),
|
Self::Angle(v) => v.hash(state),
|
||||||
|
Self::Ratio(v) => v.hash(state),
|
||||||
Self::Relative(v) => v.hash(state),
|
Self::Relative(v) => v.hash(state),
|
||||||
Self::Linear(v) => v.hash(state),
|
Self::Fraction(v) => v.hash(state),
|
||||||
Self::Fractional(v) => v.hash(state),
|
|
||||||
Self::Color(v) => v.hash(state),
|
Self::Color(v) => v.hash(state),
|
||||||
Self::Str(v) => v.hash(state),
|
Self::Str(v) => v.hash(state),
|
||||||
Self::Content(v) => v.hash(state),
|
Self::Content(v) => v.hash(state),
|
||||||
@ -548,9 +548,9 @@ primitive! { i64: "integer", Int }
|
|||||||
primitive! { f64: "float", Float, Int(v) => v as f64 }
|
primitive! { f64: "float", Float, Int(v) => v as f64 }
|
||||||
primitive! { Length: "length", Length }
|
primitive! { Length: "length", Length }
|
||||||
primitive! { Angle: "angle", Angle }
|
primitive! { Angle: "angle", Angle }
|
||||||
primitive! { Relative: "relative", Relative }
|
primitive! { Ratio: "ratio", Ratio }
|
||||||
primitive! { Linear: "relative length", Linear, Length(v) => v.into(), Relative(v) => v.into() }
|
primitive! { Relative: "relative length", Relative, Length(v) => v.into(), Ratio(v) => v.into() }
|
||||||
primitive! { Fractional: "fractional length", Fractional }
|
primitive! { Fraction: "fraction", Fraction }
|
||||||
primitive! { Color: "color", Color }
|
primitive! { Color: "color", Color }
|
||||||
primitive! { EcoString: "string", Str }
|
primitive! { EcoString: "string", Str }
|
||||||
primitive! { Content: "content", Content, None => Content::new() }
|
primitive! { Content: "content", Content, None => Content::new() }
|
||||||
@ -673,9 +673,9 @@ mod tests {
|
|||||||
test(3.14, "3.14");
|
test(3.14, "3.14");
|
||||||
test(Length::pt(5.5), "5.5pt");
|
test(Length::pt(5.5), "5.5pt");
|
||||||
test(Angle::deg(90.0), "90deg");
|
test(Angle::deg(90.0), "90deg");
|
||||||
test(Relative::one() / 2.0, "50%");
|
test(Ratio::one() / 2.0, "50%");
|
||||||
test(Relative::new(0.3) + Length::cm(2.0), "30% + 56.69pt");
|
test(Ratio::new(0.3) + Length::cm(2.0), "30% + 56.69pt");
|
||||||
test(Fractional::one() * 7.55, "7.55fr");
|
test(Fraction::one() * 7.55, "7.55fr");
|
||||||
test(Color::Rgba(RgbaColor::new(1, 1, 1, 0xff)), "#010101");
|
test(Color::Rgba(RgbaColor::new(1, 1, 1, 0xff)), "#010101");
|
||||||
|
|
||||||
// Collections.
|
// Collections.
|
||||||
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use ttf_parser::{name_id, GlyphId, PlatformId, Tag};
|
use ttf_parser::{name_id, GlyphId, PlatformId, Tag};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use crate::geom::{Em, Length, Linear};
|
use crate::geom::{Em, Length, Relative};
|
||||||
use crate::loading::{FileHash, Loader};
|
use crate::loading::{FileHash, Loader};
|
||||||
use crate::util::decode_mac_roman;
|
use crate::util::decode_mac_roman;
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ impl FaceMetrics {
|
|||||||
VerticalFontMetric::XHeight => self.x_height.resolve(size),
|
VerticalFontMetric::XHeight => self.x_height.resolve(size),
|
||||||
VerticalFontMetric::Baseline => Length::zero(),
|
VerticalFontMetric::Baseline => Length::zero(),
|
||||||
VerticalFontMetric::Descender => self.descender.resolve(size),
|
VerticalFontMetric::Descender => self.descender.resolve(size),
|
||||||
VerticalFontMetric::Linear(v) => v.resolve(size),
|
VerticalFontMetric::Relative(v) => v.resolve(size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,7 +415,7 @@ pub enum VerticalFontMetric {
|
|||||||
Descender,
|
Descender,
|
||||||
/// An font-size dependent distance from the baseline (positive goes up, negative
|
/// An font-size dependent distance from the baseline (positive goes up, negative
|
||||||
/// down).
|
/// down).
|
||||||
Linear(Linear),
|
Relative(Relative),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Properties of a single font face.
|
/// Properties of a single font face.
|
||||||
|
@ -17,7 +17,7 @@ impl Em {
|
|||||||
Self(Scalar(1.0))
|
Self(Scalar(1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an font-relative length.
|
/// Create a font-relative length.
|
||||||
pub const fn new(em: f64) -> Self {
|
pub const fn new(em: f64) -> Self {
|
||||||
Self(Scalar(em))
|
Self(Scalar(em))
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// A fractional length.
|
/// A fraction of remaining space.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct Fractional(Scalar);
|
pub struct Fraction(Scalar);
|
||||||
|
|
||||||
impl Fractional {
|
impl Fraction {
|
||||||
/// Takes up zero space: `0fr`.
|
/// Takes up zero space: `0fr`.
|
||||||
pub const fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(Scalar(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 fraction: `1fr`.
|
||||||
pub const fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self(Scalar(1.0))
|
Self(Scalar(1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new fractional value.
|
/// Create a new fraction.
|
||||||
pub const fn new(ratio: f64) -> Self {
|
pub const fn new(ratio: f64) -> Self {
|
||||||
Self(Scalar(ratio))
|
Self(Scalar(ratio))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying ratio.
|
/// Get the underlying number.
|
||||||
pub const fn get(self) -> f64 {
|
pub const fn get(self) -> f64 {
|
||||||
(self.0).0
|
(self.0).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the ratio is zero.
|
/// Whether the fraction is zero.
|
||||||
pub fn is_zero(self) -> bool {
|
pub fn is_zero(self) -> bool {
|
||||||
self.0 == 0.0
|
self.0 == 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The absolute value of the this fractional.
|
/// The absolute value of the this fraction.
|
||||||
pub fn abs(self) -> Self {
|
pub fn abs(self) -> Self {
|
||||||
Self::new(self.get().abs())
|
Self::new(self.get().abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve this fractionals share in the remaining space.
|
/// Resolve this fraction's share in the remaining space.
|
||||||
pub fn resolve(self, total: Self, remaining: Length) -> Length {
|
pub fn resolve(self, total: Self, remaining: Length) -> Length {
|
||||||
let ratio = self / total;
|
let ratio = self / total;
|
||||||
if ratio.is_finite() && remaining.is_finite() {
|
if ratio.is_finite() && remaining.is_finite() {
|
||||||
@ -46,13 +46,13 @@ impl Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Fractional {
|
impl Debug for Fraction {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{}fr", round_2(self.get()))
|
write!(f, "{}fr", round_2(self.get()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Neg for Fractional {
|
impl Neg for Fraction {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn neg(self) -> Self {
|
fn neg(self) -> Self {
|
||||||
@ -60,7 +60,7 @@ impl Neg for Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for Fractional {
|
impl Add for Fraction {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, other: Self) -> Self {
|
fn add(self, other: Self) -> Self {
|
||||||
@ -68,9 +68,9 @@ impl Add for Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub_impl!(Fractional - Fractional -> Fractional);
|
sub_impl!(Fraction - Fraction -> Fraction);
|
||||||
|
|
||||||
impl Mul<f64> for Fractional {
|
impl Mul<f64> for Fraction {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn mul(self, other: f64) -> Self {
|
fn mul(self, other: f64) -> Self {
|
||||||
@ -78,15 +78,15 @@ impl Mul<f64> for Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<Fractional> for f64 {
|
impl Mul<Fraction> for f64 {
|
||||||
type Output = Fractional;
|
type Output = Fraction;
|
||||||
|
|
||||||
fn mul(self, other: Fractional) -> Fractional {
|
fn mul(self, other: Fraction) -> Fraction {
|
||||||
other * self
|
other * self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<f64> for Fractional {
|
impl Div<f64> for Fraction {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, other: f64) -> Self {
|
fn div(self, other: f64) -> Self {
|
||||||
@ -94,7 +94,7 @@ impl Div<f64> for Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div for Fractional {
|
impl Div for Fraction {
|
||||||
type Output = f64;
|
type Output = f64;
|
||||||
|
|
||||||
fn div(self, other: Self) -> f64 {
|
fn div(self, other: Self) -> f64 {
|
||||||
@ -102,7 +102,7 @@ impl Div for Fractional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assign_impl!(Fractional += Fractional);
|
assign_impl!(Fraction += Fraction);
|
||||||
assign_impl!(Fractional -= Fractional);
|
assign_impl!(Fraction -= Fraction);
|
||||||
assign_impl!(Fractional *= f64);
|
assign_impl!(Fraction *= f64);
|
||||||
assign_impl!(Fractional /= f64);
|
assign_impl!(Fraction /= f64);
|
@ -1,190 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
|
|
||||||
/// A combined relative and absolute length.
|
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
|
||||||
pub struct Linear {
|
|
||||||
/// The relative part.
|
|
||||||
pub rel: Relative,
|
|
||||||
/// The absolute part.
|
|
||||||
pub abs: Length,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Linear {
|
|
||||||
/// The zero linear.
|
|
||||||
pub const fn zero() -> Self {
|
|
||||||
Self {
|
|
||||||
rel: Relative::zero(),
|
|
||||||
abs: Length::zero(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The linear with a relative part of `100%` and no absolute part.
|
|
||||||
pub const fn one() -> Self {
|
|
||||||
Self {
|
|
||||||
rel: Relative::one(),
|
|
||||||
abs: Length::zero(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new linear.
|
|
||||||
pub const fn new(rel: Relative, abs: Length) -> Self {
|
|
||||||
Self { rel, abs }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolve this linear's relative component to the given `length`.
|
|
||||||
pub fn resolve(self, length: Length) -> Length {
|
|
||||||
self.rel.resolve(length) + self.abs
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compose with another linear.
|
|
||||||
///
|
|
||||||
/// The resulting linear is (self ∘ inner)(x) = self(inner(x)).
|
|
||||||
pub fn compose(self, inner: Self) -> Self {
|
|
||||||
Self {
|
|
||||||
rel: self.rel * inner.rel,
|
|
||||||
abs: self.rel.resolve(inner.abs) + self.abs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether both parts are zero.
|
|
||||||
pub fn is_zero(self) -> bool {
|
|
||||||
self.rel.is_zero() && self.abs.is_zero()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether there is a linear component.
|
|
||||||
pub fn is_relative(self) -> bool {
|
|
||||||
!self.rel.is_zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Linear {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{:?} + {:?}", self.rel, self.abs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
other * self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
@ -6,13 +6,13 @@ mod align;
|
|||||||
mod angle;
|
mod angle;
|
||||||
mod dir;
|
mod dir;
|
||||||
mod em;
|
mod em;
|
||||||
mod fr;
|
mod fraction;
|
||||||
mod gen;
|
mod gen;
|
||||||
mod length;
|
mod length;
|
||||||
mod linear;
|
|
||||||
mod paint;
|
mod paint;
|
||||||
mod path;
|
mod path;
|
||||||
mod point;
|
mod point;
|
||||||
|
mod ratio;
|
||||||
mod relative;
|
mod relative;
|
||||||
mod scalar;
|
mod scalar;
|
||||||
mod sides;
|
mod sides;
|
||||||
@ -23,13 +23,13 @@ pub use align::*;
|
|||||||
pub use angle::*;
|
pub use angle::*;
|
||||||
pub use dir::*;
|
pub use dir::*;
|
||||||
pub use em::*;
|
pub use em::*;
|
||||||
pub use fr::*;
|
pub use fraction::*;
|
||||||
pub use gen::*;
|
pub use gen::*;
|
||||||
pub use length::*;
|
pub use length::*;
|
||||||
pub use linear::*;
|
|
||||||
pub use paint::*;
|
pub use paint::*;
|
||||||
pub use path::*;
|
pub use path::*;
|
||||||
pub use point::*;
|
pub use point::*;
|
||||||
|
pub use ratio::*;
|
||||||
pub use relative::*;
|
pub use relative::*;
|
||||||
pub use scalar::*;
|
pub use scalar::*;
|
||||||
pub use sides::*;
|
pub use sides::*;
|
||||||
|
125
src/geom/ratio.rs
Normal file
125
src/geom/ratio.rs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// A ratio of a whole.
|
||||||
|
///
|
||||||
|
/// _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 Ratio(Scalar);
|
||||||
|
|
||||||
|
impl Ratio {
|
||||||
|
/// A ratio of `0%` represented as `0.0`.
|
||||||
|
pub const fn zero() -> Self {
|
||||||
|
Self(Scalar(0.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A ratio of `100%` represented as `1.0`.
|
||||||
|
pub const fn one() -> Self {
|
||||||
|
Self(Scalar(1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new ratio from a value, whre `1.0` means `100%`.
|
||||||
|
pub const fn new(ratio: f64) -> Self {
|
||||||
|
Self(Scalar(ratio))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the underlying ratio.
|
||||||
|
pub const fn get(self) -> f64 {
|
||||||
|
(self.0).0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolve this relative to the given `length`.
|
||||||
|
pub fn resolve(self, length: Length) -> Length {
|
||||||
|
// We don't want NaNs.
|
||||||
|
if length.is_infinite() {
|
||||||
|
Length::zero()
|
||||||
|
} else {
|
||||||
|
self.get() * length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether the ratio is zero.
|
||||||
|
pub fn is_zero(self) -> bool {
|
||||||
|
self.0 == 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether the ratio is one.
|
||||||
|
pub fn is_one(self) -> bool {
|
||||||
|
self.0 == 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The absolute value of the this ratio.
|
||||||
|
pub fn abs(self) -> Self {
|
||||||
|
Self::new(self.get().abs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Ratio {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}%", round_2(100.0 * self.get()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Neg for Ratio {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self {
|
||||||
|
Self(-self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Ratio {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Self) -> Self {
|
||||||
|
Self(self.0 + other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_impl!(Ratio - Ratio -> Ratio);
|
||||||
|
|
||||||
|
impl Mul for Ratio {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, other: Self) -> Self {
|
||||||
|
Self(self.0 * other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f64> for Ratio {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, other: f64) -> Self {
|
||||||
|
Self(self.0 * other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<Ratio> for f64 {
|
||||||
|
type Output = Ratio;
|
||||||
|
|
||||||
|
fn mul(self, other: Ratio) -> Ratio {
|
||||||
|
other * self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<f64> for Ratio {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn div(self, other: f64) -> Self {
|
||||||
|
Self(self.0 / other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div for Ratio {
|
||||||
|
type Output = f64;
|
||||||
|
|
||||||
|
fn div(self, other: Self) -> f64 {
|
||||||
|
self.get() / other.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_impl!(Ratio += Ratio);
|
||||||
|
assign_impl!(Ratio -= Ratio);
|
||||||
|
assign_impl!(Ratio *= Ratio);
|
||||||
|
assign_impl!(Ratio *= f64);
|
||||||
|
assign_impl!(Ratio /= f64);
|
@ -1,62 +1,61 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// A relative length.
|
/// A relative length.
|
||||||
///
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
/// _Note_: `50%` is represented as `0.5` here, but stored as `50.0` in the
|
pub struct Relative {
|
||||||
/// corresponding [literal](crate::syntax::ast::LitKind::Percent).
|
/// The relative part.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
pub rel: Ratio,
|
||||||
pub struct Relative(Scalar);
|
/// The absolute part.
|
||||||
|
pub abs: Length,
|
||||||
|
}
|
||||||
|
|
||||||
impl Relative {
|
impl Relative {
|
||||||
/// A ratio of `0%` represented as `0.0`.
|
/// The zero relative length.
|
||||||
pub const fn zero() -> Self {
|
pub const fn zero() -> Self {
|
||||||
Self(Scalar(0.0))
|
Self { rel: Ratio::zero(), abs: Length::zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A ratio of `100%` represented as `1.0`.
|
/// A relative length with a ratio of `100%` and no absolute part.
|
||||||
pub const fn one() -> Self {
|
pub const fn one() -> Self {
|
||||||
Self(Scalar(1.0))
|
Self { rel: Ratio::one(), abs: Length::zero() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new relative value.
|
/// Create a new relative length from its parts.
|
||||||
pub const fn new(ratio: f64) -> Self {
|
pub const fn new(rel: Ratio, abs: Length) -> Self {
|
||||||
Self(Scalar(ratio))
|
Self { rel, abs }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying ratio.
|
/// Resolve this length relative to the given `length`.
|
||||||
pub const fn get(self) -> f64 {
|
|
||||||
(self.0).0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolve this relative to the given `length`.
|
|
||||||
pub fn resolve(self, length: Length) -> Length {
|
pub fn resolve(self, length: Length) -> Length {
|
||||||
// We don't want NaNs.
|
self.rel.resolve(length) + self.abs
|
||||||
if length.is_infinite() {
|
|
||||||
Length::zero()
|
|
||||||
} else {
|
|
||||||
self.get() * length
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the ratio is zero.
|
/// Whether both parts are zero.
|
||||||
pub fn is_zero(self) -> bool {
|
pub fn is_zero(self) -> bool {
|
||||||
self.0 == 0.0
|
self.rel.is_zero() && self.abs.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the ratio is one.
|
/// Whether there is a relative part.
|
||||||
pub fn is_one(self) -> bool {
|
pub fn is_relative(self) -> bool {
|
||||||
self.0 == 1.0
|
!self.rel.is_zero()
|
||||||
}
|
|
||||||
|
|
||||||
/// The absolute value of the this relative.
|
|
||||||
pub fn abs(self) -> Self {
|
|
||||||
Self::new(self.get().abs())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Relative {
|
impl Debug for Relative {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{}%", round_2(100.0 * self.get()))
|
write!(f, "{:?} + {:?}", self.rel, self.abs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Length> for Relative {
|
||||||
|
fn from(abs: Length) -> Self {
|
||||||
|
Self { rel: Ratio::zero(), abs }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Ratio> for Relative {
|
||||||
|
fn from(rel: Ratio) -> Self {
|
||||||
|
Self { rel, abs: Length::zero() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +63,7 @@ impl Neg for Relative {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn neg(self) -> Self {
|
fn neg(self) -> Self {
|
||||||
Self(-self.0)
|
Self { rel: -self.rel, abs: -self.abs }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,25 +71,77 @@ impl Add for Relative {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, other: Self) -> Self {
|
fn add(self, other: Self) -> Self {
|
||||||
Self(self.0 + other.0)
|
Self {
|
||||||
|
rel: self.rel + other.rel,
|
||||||
|
abs: self.abs + other.abs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Ratio> for Length {
|
||||||
|
type Output = Relative;
|
||||||
|
|
||||||
|
fn add(self, other: Ratio) -> Relative {
|
||||||
|
Relative { rel: other, abs: self }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Length> for Ratio {
|
||||||
|
type Output = Relative;
|
||||||
|
|
||||||
|
fn add(self, other: Length) -> Relative {
|
||||||
|
other + self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Length> for Relative {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Length) -> Self {
|
||||||
|
Self { rel: self.rel, abs: self.abs + other }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Relative> for Length {
|
||||||
|
type Output = Relative;
|
||||||
|
|
||||||
|
fn add(self, other: Relative) -> Relative {
|
||||||
|
other + self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Ratio> for Relative {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Ratio) -> Self {
|
||||||
|
Self { rel: self.rel + other, abs: self.abs }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<Relative> for Ratio {
|
||||||
|
type Output = Relative;
|
||||||
|
|
||||||
|
fn add(self, other: Relative) -> Relative {
|
||||||
|
other + self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub_impl!(Relative - Relative -> Relative);
|
sub_impl!(Relative - Relative -> Relative);
|
||||||
|
sub_impl!(Length - Ratio -> Relative);
|
||||||
impl Mul for Relative {
|
sub_impl!(Ratio - Length -> Relative);
|
||||||
type Output = Self;
|
sub_impl!(Relative - Length -> Relative);
|
||||||
|
sub_impl!(Length - Relative -> Relative);
|
||||||
fn mul(self, other: Self) -> Self {
|
sub_impl!(Relative - Ratio -> Relative);
|
||||||
Self(self.0 * other.0)
|
sub_impl!(Ratio - Relative -> Relative);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mul<f64> for Relative {
|
impl Mul<f64> for Relative {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn mul(self, other: f64) -> Self {
|
fn mul(self, other: f64) -> Self {
|
||||||
Self(self.0 * other)
|
Self {
|
||||||
|
rel: self.rel * other,
|
||||||
|
abs: self.abs * other,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,20 +157,18 @@ impl Div<f64> for Relative {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, other: f64) -> Self {
|
fn div(self, other: f64) -> Self {
|
||||||
Self(self.0 / other)
|
Self {
|
||||||
}
|
rel: self.rel / other,
|
||||||
}
|
abs: self.abs / other,
|
||||||
|
}
|
||||||
impl Div for Relative {
|
|
||||||
type Output = f64;
|
|
||||||
|
|
||||||
fn div(self, other: Self) -> f64 {
|
|
||||||
self.get() / other.get()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assign_impl!(Relative += Relative);
|
assign_impl!(Relative += Relative);
|
||||||
|
assign_impl!(Relative += Length);
|
||||||
|
assign_impl!(Relative += Ratio);
|
||||||
assign_impl!(Relative -= Relative);
|
assign_impl!(Relative -= Relative);
|
||||||
assign_impl!(Relative *= Relative);
|
assign_impl!(Relative -= Length);
|
||||||
|
assign_impl!(Relative -= Ratio);
|
||||||
assign_impl!(Relative *= f64);
|
assign_impl!(Relative *= f64);
|
||||||
assign_impl!(Relative /= f64);
|
assign_impl!(Relative /= f64);
|
||||||
|
@ -43,8 +43,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sides<Linear> {
|
impl Sides<Relative> {
|
||||||
/// Resolve the linear sides relative to the given `size`.
|
/// Resolve the sides relative to the given `size`.
|
||||||
pub fn resolve(self, size: Size) -> Sides<Length> {
|
pub fn resolve(self, size: Size) -> Sides<Length> {
|
||||||
Sides {
|
Sides {
|
||||||
left: self.left.resolve(size.x),
|
left: self.left.resolve(size.x),
|
||||||
|
@ -3,10 +3,10 @@ use super::*;
|
|||||||
/// A scale-skew-translate transformation.
|
/// A scale-skew-translate transformation.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
pub sx: Relative,
|
pub sx: Ratio,
|
||||||
pub ky: Relative,
|
pub ky: Ratio,
|
||||||
pub kx: Relative,
|
pub kx: Ratio,
|
||||||
pub sy: Relative,
|
pub sy: Ratio,
|
||||||
pub tx: Length,
|
pub tx: Length,
|
||||||
pub ty: Length,
|
pub ty: Length,
|
||||||
}
|
}
|
||||||
@ -15,10 +15,10 @@ impl Transform {
|
|||||||
/// The identity transformation.
|
/// The identity transformation.
|
||||||
pub const fn identity() -> Self {
|
pub const fn identity() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sx: Relative::one(),
|
sx: Ratio::one(),
|
||||||
ky: Relative::zero(),
|
ky: Ratio::zero(),
|
||||||
kx: Relative::zero(),
|
kx: Ratio::zero(),
|
||||||
sy: Relative::one(),
|
sy: Ratio::one(),
|
||||||
tx: Length::zero(),
|
tx: Length::zero(),
|
||||||
ty: Length::zero(),
|
ty: Length::zero(),
|
||||||
}
|
}
|
||||||
@ -30,14 +30,14 @@ impl Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A scaling transform.
|
/// A scaling transform.
|
||||||
pub const fn scale(sx: Relative, sy: Relative) -> Self {
|
pub const fn scale(sx: Ratio, sy: Ratio) -> Self {
|
||||||
Self { sx, sy, ..Self::identity() }
|
Self { sx, sy, ..Self::identity() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A rotation transform.
|
/// A rotation transform.
|
||||||
pub fn rotation(angle: Angle) -> Self {
|
pub fn rotation(angle: Angle) -> Self {
|
||||||
let cos = Relative::new(angle.cos());
|
let cos = Ratio::new(angle.cos());
|
||||||
let sin = Relative::new(angle.sin());
|
let sin = Ratio::new(angle.sin());
|
||||||
Self {
|
Self {
|
||||||
sx: cos,
|
sx: cos,
|
||||||
ky: sin,
|
ky: sin,
|
||||||
|
@ -3,24 +3,24 @@ use crate::library::prelude::*;
|
|||||||
/// Display a line without affecting the layout.
|
/// Display a line without affecting the layout.
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
pub struct LineNode {
|
pub struct LineNode {
|
||||||
origin: Spec<Linear>,
|
origin: Spec<Relative>,
|
||||||
delta: Spec<Linear>,
|
delta: Spec<Relative>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node]
|
#[node]
|
||||||
impl LineNode {
|
impl LineNode {
|
||||||
/// How the stroke the line.
|
/// How to stroke the line.
|
||||||
pub const STROKE: Paint = Color::BLACK.into();
|
pub const STROKE: Paint = Color::BLACK.into();
|
||||||
/// The line's thickness.
|
/// The line's thickness.
|
||||||
pub const THICKNESS: Length = Length::pt(1.0);
|
pub const THICKNESS: Length = Length::pt(1.0);
|
||||||
|
|
||||||
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
let origin = args.named::<Spec<Linear>>("origin")?.unwrap_or_default();
|
let origin = args.named::<Spec<Relative>>("origin")?.unwrap_or_default();
|
||||||
let delta = match args.named::<Spec<Linear>>("to")? {
|
let delta = match args.named::<Spec<Relative>>("to")? {
|
||||||
Some(to) => to.zip(origin).map(|(to, from)| to - from),
|
Some(to) => to.zip(origin).map(|(to, from)| to - from),
|
||||||
None => {
|
None => {
|
||||||
let length =
|
let length =
|
||||||
args.named::<Linear>("length")?.unwrap_or(Length::cm(1.0).into());
|
args.named::<Relative>("length")?.unwrap_or(Length::cm(1.0).into());
|
||||||
let angle = args.named::<Angle>("angle")?.unwrap_or_default();
|
let angle = args.named::<Angle>("angle")?.unwrap_or_default();
|
||||||
|
|
||||||
let x = angle.cos() * length;
|
let x = angle.cos() * length;
|
||||||
@ -48,9 +48,9 @@ impl Layout for LineNode {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let resolved_origin =
|
let resolved_origin =
|
||||||
self.origin.zip(regions.base).map(|(l, b)| Linear::resolve(l, b));
|
self.origin.zip(regions.base).map(|(l, b)| Relative::resolve(l, b));
|
||||||
let resolved_delta =
|
let resolved_delta =
|
||||||
self.delta.zip(regions.base).map(|(l, b)| Linear::resolve(l, b));
|
self.delta.zip(regions.base).map(|(l, b)| Relative::resolve(l, b));
|
||||||
|
|
||||||
let geometry = Geometry::Line(resolved_delta.to_point());
|
let geometry = Geometry::Line(resolved_delta.to_point());
|
||||||
let shape = Shape { geometry, fill: None, stroke };
|
let shape = Shape { geometry, fill: None, stroke };
|
||||||
|
@ -23,17 +23,17 @@ pub type EllipseNode = ShapeNode<ELLIPSE>;
|
|||||||
impl<const S: ShapeKind> ShapeNode<S> {
|
impl<const S: ShapeKind> ShapeNode<S> {
|
||||||
/// How to fill the shape.
|
/// How to fill the shape.
|
||||||
pub const FILL: Option<Paint> = None;
|
pub const FILL: Option<Paint> = None;
|
||||||
/// How the stroke the shape.
|
/// How to stroke the shape.
|
||||||
pub const STROKE: Smart<Option<Paint>> = Smart::Auto;
|
pub const STROKE: Smart<Option<Paint>> = Smart::Auto;
|
||||||
/// The stroke's thickness.
|
/// The stroke's thickness.
|
||||||
pub const THICKNESS: Length = Length::pt(1.0);
|
pub const THICKNESS: Length = Length::pt(1.0);
|
||||||
/// How much to pad the shape's content.
|
/// How much to pad the shape's content.
|
||||||
pub const PADDING: Linear = Linear::zero();
|
pub const PADDING: Relative = Relative::zero();
|
||||||
|
|
||||||
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
let size = match S {
|
let size = match S {
|
||||||
SQUARE => args.named::<Length>("size")?.map(Linear::from),
|
SQUARE => args.named::<Length>("size")?.map(Relative::from),
|
||||||
CIRCLE => args.named::<Length>("radius")?.map(|r| 2.0 * Linear::from(r)),
|
CIRCLE => args.named::<Length>("radius")?.map(|r| 2.0 * Relative::from(r)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
|
|||||||
if let Some(child) = &self.0 {
|
if let Some(child) = &self.0 {
|
||||||
let mut padding = styles.get(Self::PADDING);
|
let mut padding = styles.get(Self::PADDING);
|
||||||
if is_round(S) {
|
if is_round(S) {
|
||||||
padding.rel += Relative::new(0.5 - SQRT_2 / 4.0);
|
padding.rel += Ratio::new(0.5 - SQRT_2 / 4.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad the child.
|
// Pad the child.
|
||||||
|
@ -37,8 +37,8 @@ impl<const T: TransformKind> TransformNode<T> {
|
|||||||
}
|
}
|
||||||
SCALE | _ => {
|
SCALE | _ => {
|
||||||
let all = args.find()?;
|
let all = args.find()?;
|
||||||
let sx = args.named("x")?.or(all).unwrap_or(Relative::one());
|
let sx = args.named("x")?.or(all).unwrap_or(Ratio::one());
|
||||||
let sy = args.named("y")?.or(all).unwrap_or(Relative::one());
|
let sy = args.named("y")?.or(all).unwrap_or(Ratio::one());
|
||||||
Transform::scale(sx, sy)
|
Transform::scale(sx, sy)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@ pub struct ColumnsNode {
|
|||||||
#[node]
|
#[node]
|
||||||
impl ColumnsNode {
|
impl ColumnsNode {
|
||||||
/// The size of the gutter space between each column.
|
/// The size of the gutter space between each column.
|
||||||
pub const GUTTER: Linear = Relative::new(0.04).into();
|
pub const GUTTER: Relative = Ratio::new(0.04).into();
|
||||||
|
|
||||||
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
Ok(Content::block(Self {
|
Ok(Content::block(Self {
|
||||||
|
@ -100,8 +100,8 @@ pub struct FlowLayouter {
|
|||||||
full: Size,
|
full: Size,
|
||||||
/// The size used by the frames for the current region.
|
/// The size used by the frames for the current region.
|
||||||
used: Size,
|
used: Size,
|
||||||
/// The sum of fractional ratios in the current region.
|
/// The sum of fractions in the current region.
|
||||||
fr: Fractional,
|
fr: Fraction,
|
||||||
/// Spacing and layouted nodes.
|
/// Spacing and layouted nodes.
|
||||||
items: Vec<FlowItem>,
|
items: Vec<FlowItem>,
|
||||||
/// Finished frames for previous regions.
|
/// Finished frames for previous regions.
|
||||||
@ -113,7 +113,7 @@ enum FlowItem {
|
|||||||
/// Absolute spacing between other items.
|
/// Absolute spacing between other items.
|
||||||
Absolute(Length),
|
Absolute(Length),
|
||||||
/// Fractional spacing between other items.
|
/// Fractional spacing between other items.
|
||||||
Fractional(Fractional),
|
Fractional(Fraction),
|
||||||
/// A frame for a layouted child node and how to align it.
|
/// A frame for a layouted child node and how to align it.
|
||||||
Frame(Arc<Frame>, Spec<Align>),
|
Frame(Arc<Frame>, Spec<Align>),
|
||||||
/// An absolutely placed frame.
|
/// An absolutely placed frame.
|
||||||
@ -135,7 +135,7 @@ impl FlowLayouter {
|
|||||||
expand,
|
expand,
|
||||||
full,
|
full,
|
||||||
used: Size::zero(),
|
used: Size::zero(),
|
||||||
fr: Fractional::zero(),
|
fr: Fraction::zero(),
|
||||||
items: vec![],
|
items: vec![],
|
||||||
finished: vec![],
|
finished: vec![],
|
||||||
}
|
}
|
||||||
@ -144,8 +144,8 @@ impl FlowLayouter {
|
|||||||
/// Layout spacing.
|
/// Layout spacing.
|
||||||
pub fn layout_spacing(&mut self, spacing: Spacing) {
|
pub fn layout_spacing(&mut self, spacing: Spacing) {
|
||||||
match spacing {
|
match spacing {
|
||||||
Spacing::Linear(v) => {
|
Spacing::Relative(v) => {
|
||||||
// Resolve the linear and limit it to the remaining space.
|
// Resolve the spacing and limit it to the remaining space.
|
||||||
let resolved = v.resolve(self.full.y);
|
let resolved = v.resolve(self.full.y);
|
||||||
let limited = resolved.min(self.regions.first.y);
|
let limited = resolved.min(self.regions.first.y);
|
||||||
self.regions.first.y -= limited;
|
self.regions.first.y -= limited;
|
||||||
@ -254,7 +254,7 @@ impl FlowLayouter {
|
|||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first;
|
self.full = self.regions.first;
|
||||||
self.used = Size::zero();
|
self.used = Size::zero();
|
||||||
self.fr = Fractional::zero();
|
self.fr = Fraction::zero();
|
||||||
self.finished.push(Arc::new(output));
|
self.finished.push(Arc::new(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,22 +54,24 @@ impl Layout for GridNode {
|
|||||||
/// Defines how to size a grid cell along an axis.
|
/// Defines how to size a grid cell along an axis.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum TrackSizing {
|
pub enum TrackSizing {
|
||||||
/// Fit the cell to its contents.
|
/// A track that fits its cell's contents.
|
||||||
Auto,
|
Auto,
|
||||||
/// A length stated in absolute values and/or relative to the parent's size.
|
/// A track size specified in absolute terms and relative to the parent's
|
||||||
Linear(Linear),
|
/// size.
|
||||||
/// A length that is the fraction of the remaining free space in the parent.
|
Relative(Relative),
|
||||||
Fractional(Fractional),
|
/// A track size specified as a fraction of the remaining free space in the
|
||||||
|
/// parent.
|
||||||
|
Fractional(Fraction),
|
||||||
}
|
}
|
||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
Vec<TrackSizing>,
|
Vec<TrackSizing>,
|
||||||
Expected: "integer or (auto, linear, fractional, or array thereof)",
|
Expected: "integer, auto, relative length, fraction, or array of the latter three)",
|
||||||
Value::Auto => vec![TrackSizing::Auto],
|
Value::Auto => vec![TrackSizing::Auto],
|
||||||
Value::Length(v) => vec![TrackSizing::Linear(v.into())],
|
Value::Length(v) => vec![TrackSizing::Relative(v.into())],
|
||||||
Value::Relative(v) => vec![TrackSizing::Linear(v.into())],
|
Value::Ratio(v) => vec![TrackSizing::Relative(v.into())],
|
||||||
Value::Linear(v) => vec![TrackSizing::Linear(v)],
|
Value::Relative(v) => vec![TrackSizing::Relative(v)],
|
||||||
Value::Fractional(v) => vec![TrackSizing::Fractional(v)],
|
Value::Fraction(v) => vec![TrackSizing::Fractional(v)],
|
||||||
Value::Int(v) => vec![TrackSizing::Auto; Value::Int(v).cast::<NonZeroUsize>()?.get()],
|
Value::Int(v) => vec![TrackSizing::Auto; Value::Int(v).cast::<NonZeroUsize>()?.get()],
|
||||||
Value::Array(values) => values
|
Value::Array(values) => values
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -79,12 +81,12 @@ castable! {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
TrackSizing,
|
TrackSizing,
|
||||||
Expected: "auto, linear, or fractional",
|
Expected: "auto, relative length, or fraction",
|
||||||
Value::Auto => Self::Auto,
|
Value::Auto => Self::Auto,
|
||||||
Value::Length(v) => Self::Linear(v.into()),
|
Value::Length(v) => Self::Relative(v.into()),
|
||||||
Value::Relative(v) => Self::Linear(v.into()),
|
Value::Ratio(v) => Self::Relative(v.into()),
|
||||||
Value::Linear(v) => Self::Linear(v),
|
Value::Relative(v) => Self::Relative(v),
|
||||||
Value::Fractional(v) => Self::Fractional(v),
|
Value::Fraction(v) => Self::Fractional(v),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs grid layout.
|
/// Performs grid layout.
|
||||||
@ -108,19 +110,19 @@ pub struct GridLayouter<'a> {
|
|||||||
/// The used-up size of the current region. The horizontal size is
|
/// The used-up size of the current region. The horizontal size is
|
||||||
/// determined once after columns are resolved and not touched again.
|
/// determined once after columns are resolved and not touched again.
|
||||||
used: Size,
|
used: Size,
|
||||||
/// The sum of fractional ratios in the current region.
|
/// The sum of fractions in the current region.
|
||||||
fr: Fractional,
|
fr: Fraction,
|
||||||
/// Frames for finished regions.
|
/// Frames for finished regions.
|
||||||
finished: Vec<Arc<Frame>>,
|
finished: Vec<Arc<Frame>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produced by initial row layout, auto and linear rows are already finished,
|
/// Produced by initial row layout, auto and relative rows are already finished,
|
||||||
/// fractional rows not yet.
|
/// fractional rows not yet.
|
||||||
enum Row {
|
enum Row {
|
||||||
/// Finished row frame of auto or linear row.
|
/// Finished row frame of auto or relative row.
|
||||||
Frame(Frame),
|
Frame(Frame),
|
||||||
/// Ratio of a fractional row and y index of the track.
|
/// Fractional row with y index.
|
||||||
Fr(Fractional, usize),
|
Fr(Fraction, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GridLayouter<'a> {
|
impl<'a> GridLayouter<'a> {
|
||||||
@ -150,7 +152,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let auto = TrackSizing::Auto;
|
let auto = TrackSizing::Auto;
|
||||||
let zero = TrackSizing::Linear(Linear::zero());
|
let zero = TrackSizing::Relative(Relative::zero());
|
||||||
let get_or = |tracks: &[_], idx, default| {
|
let get_or = |tracks: &[_], idx, default| {
|
||||||
tracks.get(idx).or(tracks.last()).copied().unwrap_or(default)
|
tracks.get(idx).or(tracks.last()).copied().unwrap_or(default)
|
||||||
};
|
};
|
||||||
@ -190,7 +192,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
lrows,
|
lrows,
|
||||||
full,
|
full,
|
||||||
used: Size::zero(),
|
used: Size::zero(),
|
||||||
fr: Fractional::zero(),
|
fr: Fraction::zero(),
|
||||||
finished: vec![],
|
finished: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +210,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
|
|
||||||
match self.rows[y] {
|
match self.rows[y] {
|
||||||
TrackSizing::Auto => self.layout_auto_row(ctx, y)?,
|
TrackSizing::Auto => self.layout_auto_row(ctx, y)?,
|
||||||
TrackSizing::Linear(v) => self.layout_linear_row(ctx, v, y)?,
|
TrackSizing::Relative(v) => self.layout_relative_row(ctx, v, y)?,
|
||||||
TrackSizing::Fractional(v) => {
|
TrackSizing::Fractional(v) => {
|
||||||
self.lrows.push(Row::Fr(v, y));
|
self.lrows.push(Row::Fr(v, y));
|
||||||
self.fr += v;
|
self.fr += v;
|
||||||
@ -222,28 +224,28 @@ impl<'a> GridLayouter<'a> {
|
|||||||
|
|
||||||
/// Determine all column sizes.
|
/// Determine all column sizes.
|
||||||
fn measure_columns(&mut self, ctx: &mut Context) -> TypResult<()> {
|
fn measure_columns(&mut self, ctx: &mut Context) -> TypResult<()> {
|
||||||
// Sum of sizes of resolved linear tracks.
|
// Sum of sizes of resolved relative tracks.
|
||||||
let mut linear = Length::zero();
|
let mut rel = Length::zero();
|
||||||
|
|
||||||
// Sum of fractions of all fractional tracks.
|
// Sum of fractions of all fractional tracks.
|
||||||
let mut fr = Fractional::zero();
|
let mut fr = Fraction::zero();
|
||||||
|
|
||||||
// Resolve the size of all linear columns and compute the sum of all
|
// Resolve the size of all relative columns and compute the sum of all
|
||||||
// fractional tracks.
|
// fractional tracks.
|
||||||
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
|
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
|
||||||
match col {
|
match col {
|
||||||
TrackSizing::Auto => {}
|
TrackSizing::Auto => {}
|
||||||
TrackSizing::Linear(v) => {
|
TrackSizing::Relative(v) => {
|
||||||
let resolved = v.resolve(self.regions.base.x);
|
let resolved = v.resolve(self.regions.base.x);
|
||||||
*rcol = resolved;
|
*rcol = resolved;
|
||||||
linear += resolved;
|
rel += resolved;
|
||||||
}
|
}
|
||||||
TrackSizing::Fractional(v) => fr += v,
|
TrackSizing::Fractional(v) => fr += v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size that is not used by fixed-size columns.
|
// Size that is not used by fixed-size columns.
|
||||||
let available = self.regions.first.x - linear;
|
let available = self.regions.first.x - rel;
|
||||||
if available >= Length::zero() {
|
if available >= Length::zero() {
|
||||||
// Determine size of auto columns.
|
// Determine size of auto columns.
|
||||||
let (auto, count) = self.measure_auto_columns(ctx, available)?;
|
let (auto, count) = self.measure_auto_columns(ctx, available)?;
|
||||||
@ -289,10 +291,10 @@ impl<'a> GridLayouter<'a> {
|
|||||||
let mut pod =
|
let mut pod =
|
||||||
Regions::one(size, self.regions.base, Spec::splat(false));
|
Regions::one(size, self.regions.base, Spec::splat(false));
|
||||||
|
|
||||||
// For linear rows, we can already resolve the correct
|
// For relative rows, we can already resolve the correct
|
||||||
// base, for auto it's already correct and for fr we could
|
// base, for auto it's already correct and for fr we could
|
||||||
// only guess anyway.
|
// only guess anyway.
|
||||||
if let TrackSizing::Linear(v) = self.rows[y] {
|
if let TrackSizing::Relative(v) = self.rows[y] {
|
||||||
pod.base.y = v.resolve(self.regions.base.y);
|
pod.base.y = v.resolve(self.regions.base.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +312,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Distribute remaining space to fractional columns.
|
/// Distribute remaining space to fractional columns.
|
||||||
fn grow_fractional_columns(&mut self, remaining: Length, fr: Fractional) {
|
fn grow_fractional_columns(&mut self, remaining: Length, fr: Fraction) {
|
||||||
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
|
for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) {
|
||||||
if let TrackSizing::Fractional(v) = col {
|
if let TrackSizing::Fractional(v) = col {
|
||||||
*rcol = v.resolve(fr, remaining);
|
*rcol = v.resolve(fr, remaining);
|
||||||
@ -415,12 +417,12 @@ impl<'a> GridLayouter<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Layout a row with linear height. Such a row cannot break across multiple
|
/// Layout a row with relative height. Such a row cannot break across
|
||||||
/// regions, but it may force a region break.
|
/// multiple regions, but it may force a region break.
|
||||||
fn layout_linear_row(
|
fn layout_relative_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
v: Linear,
|
v: Relative,
|
||||||
y: usize,
|
y: usize,
|
||||||
) -> TypResult<()> {
|
) -> TypResult<()> {
|
||||||
let resolved = v.resolve(self.regions.base.y);
|
let resolved = v.resolve(self.regions.base.y);
|
||||||
@ -457,7 +459,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
let size = Size::new(rcol, height);
|
let size = Size::new(rcol, height);
|
||||||
|
|
||||||
// Set the base to the region's base for auto rows and to the
|
// Set the base to the region's base for auto rows and to the
|
||||||
// size for linear and fractional rows.
|
// size for relative and fractional rows.
|
||||||
let base = Spec::new(self.cols[x], self.rows[y])
|
let base = Spec::new(self.cols[x], self.rows[y])
|
||||||
.map(|s| s == TrackSizing::Auto)
|
.map(|s| s == TrackSizing::Auto)
|
||||||
.select(self.regions.base, size);
|
.select(self.regions.base, size);
|
||||||
@ -555,7 +557,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first.y;
|
self.full = self.regions.first.y;
|
||||||
self.used.y = Length::zero();
|
self.used.y = Length::zero();
|
||||||
self.fr = Fractional::zero();
|
self.fr = Fraction::zero();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use crate::library::prelude::*;
|
|||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
pub struct PadNode {
|
pub struct PadNode {
|
||||||
/// The amount of padding.
|
/// The amount of padding.
|
||||||
pub padding: Sides<Linear>,
|
pub padding: Sides<Relative>,
|
||||||
/// The child node whose sides to pad.
|
/// The child node whose sides to pad.
|
||||||
pub child: LayoutNode,
|
pub child: LayoutNode,
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ impl Layout for PadNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Shrink a size by padding relative to the size itself.
|
/// Shrink a size by padding relative to the size itself.
|
||||||
fn shrink(size: Size, padding: Sides<Linear>) -> Size {
|
fn shrink(size: Size, padding: Sides<Relative>) -> Size {
|
||||||
size - padding.resolve(size).sum_by_axis()
|
size - padding.resolve(size).sum_by_axis()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ fn shrink(size: Size, padding: Sides<Linear>) -> Size {
|
|||||||
/// <=> w - p.rel * w - p.abs = s
|
/// <=> w - p.rel * w - p.abs = s
|
||||||
/// <=> (1 - p.rel) * w = s + p.abs
|
/// <=> (1 - p.rel) * w = s + p.abs
|
||||||
/// <=> w = (s + p.abs) / (1 - p.rel)
|
/// <=> w = (s + p.abs) / (1 - p.rel)
|
||||||
fn grow(size: Size, padding: Sides<Linear>) -> Size {
|
fn grow(size: Size, padding: Sides<Relative>) -> Size {
|
||||||
size.zip(padding.sum_by_axis())
|
size.zip(padding.sum_by_axis())
|
||||||
.map(|(s, p)| (s + p.abs).safe_div(1.0 - p.rel.get()))
|
.map(|(s, p)| (s + p.abs).safe_div(1.0 - p.rel.get()))
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ impl PageNode {
|
|||||||
/// Whether the page is flipped into landscape orientation.
|
/// Whether the page is flipped into landscape orientation.
|
||||||
pub const FLIPPED: bool = false;
|
pub const FLIPPED: bool = false;
|
||||||
/// The left margin.
|
/// The left margin.
|
||||||
pub const LEFT: Smart<Linear> = Smart::Auto;
|
pub const LEFT: Smart<Relative> = Smart::Auto;
|
||||||
/// The right margin.
|
/// The right margin.
|
||||||
pub const RIGHT: Smart<Linear> = Smart::Auto;
|
pub const RIGHT: Smart<Relative> = Smart::Auto;
|
||||||
/// The top margin.
|
/// The top margin.
|
||||||
pub const TOP: Smart<Linear> = Smart::Auto;
|
pub const TOP: Smart<Relative> = Smart::Auto;
|
||||||
/// The bottom margin.
|
/// The bottom margin.
|
||||||
pub const BOTTOM: Smart<Linear> = Smart::Auto;
|
pub const BOTTOM: Smart<Relative> = Smart::Auto;
|
||||||
/// The page's background color.
|
/// The page's background color.
|
||||||
pub const FILL: Option<Paint> = None;
|
pub const FILL: Option<Paint> = None;
|
||||||
/// How many columns the page has.
|
/// How many columns the page has.
|
||||||
@ -90,7 +90,7 @@ impl PageNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine the margins.
|
// Determine the margins.
|
||||||
let default = Linear::from(0.1190 * min);
|
let default = Relative::from(0.1190 * min);
|
||||||
let padding = Sides {
|
let padding = Sides {
|
||||||
left: styles.get(Self::LEFT).unwrap_or(default),
|
left: styles.get(Self::LEFT).unwrap_or(default),
|
||||||
right: styles.get(Self::RIGHT).unwrap_or(default),
|
right: styles.get(Self::RIGHT).unwrap_or(default),
|
||||||
|
@ -23,10 +23,10 @@ impl VNode {
|
|||||||
/// Kinds of spacing.
|
/// Kinds of spacing.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum Spacing {
|
pub enum Spacing {
|
||||||
/// A length stated in absolute values and/or relative to the parent's size.
|
/// Spacing specified in absolute terms and relative to the parent's size.
|
||||||
Linear(Linear),
|
Relative(Relative),
|
||||||
/// A length that is the fraction of the remaining free space in the parent.
|
/// Spacing specified as a fraction of the remaining free space in the parent.
|
||||||
Fractional(Fractional),
|
Fractional(Fraction),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spacing {
|
impl Spacing {
|
||||||
@ -38,15 +38,15 @@ impl Spacing {
|
|||||||
|
|
||||||
impl From<Length> for Spacing {
|
impl From<Length> for Spacing {
|
||||||
fn from(length: Length) -> Self {
|
fn from(length: Length) -> Self {
|
||||||
Self::Linear(length.into())
|
Self::Relative(length.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
Spacing,
|
Spacing,
|
||||||
Expected: "linear or fractional",
|
Expected: "relative length or fraction",
|
||||||
Value::Length(v) => Self::Linear(v.into()),
|
Value::Length(v) => Self::Relative(v.into()),
|
||||||
Value::Relative(v) => Self::Linear(v.into()),
|
Value::Ratio(v) => Self::Relative(v.into()),
|
||||||
Value::Linear(v) => Self::Linear(v),
|
Value::Relative(v) => Self::Relative(v),
|
||||||
Value::Fractional(v) => Self::Fractional(v),
|
Value::Fraction(v) => Self::Fractional(v),
|
||||||
}
|
}
|
||||||
|
@ -76,11 +76,11 @@ impl Debug for StackChild {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
StackChild,
|
StackChild,
|
||||||
Expected: "linear, fractional or content",
|
Expected: "relative length, fraction, or content",
|
||||||
Value::Length(v) => Self::Spacing(Spacing::Linear(v.into())),
|
Value::Length(v) => Self::Spacing(Spacing::Relative(v.into())),
|
||||||
Value::Relative(v) => Self::Spacing(Spacing::Linear(v.into())),
|
Value::Ratio(v) => Self::Spacing(Spacing::Relative(v.into())),
|
||||||
Value::Linear(v) => Self::Spacing(Spacing::Linear(v)),
|
Value::Relative(v) => Self::Spacing(Spacing::Relative(v)),
|
||||||
Value::Fractional(v) => Self::Spacing(Spacing::Fractional(v)),
|
Value::Fraction(v) => Self::Spacing(Spacing::Fractional(v)),
|
||||||
Value::Content(v) => Self::Node(v.pack()),
|
Value::Content(v) => Self::Node(v.pack()),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +98,8 @@ pub struct StackLayouter {
|
|||||||
full: Size,
|
full: Size,
|
||||||
/// The generic size used by the frames for the current region.
|
/// The generic size used by the frames for the current region.
|
||||||
used: Gen<Length>,
|
used: Gen<Length>,
|
||||||
/// The sum of fractional ratios in the current region.
|
/// The sum of fractions in the current region.
|
||||||
fr: Fractional,
|
fr: Fraction,
|
||||||
/// Already layouted items whose exact positions are not yet known due to
|
/// Already layouted items whose exact positions are not yet known due to
|
||||||
/// fractional spacing.
|
/// fractional spacing.
|
||||||
items: Vec<StackItem>,
|
items: Vec<StackItem>,
|
||||||
@ -112,7 +112,7 @@ enum StackItem {
|
|||||||
/// Absolute spacing between other items.
|
/// Absolute spacing between other items.
|
||||||
Absolute(Length),
|
Absolute(Length),
|
||||||
/// Fractional spacing between other items.
|
/// Fractional spacing between other items.
|
||||||
Fractional(Fractional),
|
Fractional(Fraction),
|
||||||
/// A frame for a layouted child node.
|
/// A frame for a layouted child node.
|
||||||
Frame(Arc<Frame>, Align),
|
Frame(Arc<Frame>, Align),
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ impl StackLayouter {
|
|||||||
expand,
|
expand,
|
||||||
full,
|
full,
|
||||||
used: Gen::zero(),
|
used: Gen::zero(),
|
||||||
fr: Fractional::zero(),
|
fr: Fraction::zero(),
|
||||||
items: vec![],
|
items: vec![],
|
||||||
finished: vec![],
|
finished: vec![],
|
||||||
}
|
}
|
||||||
@ -144,8 +144,8 @@ impl StackLayouter {
|
|||||||
/// Add spacing along the spacing direction.
|
/// Add spacing along the spacing direction.
|
||||||
pub fn layout_spacing(&mut self, spacing: Spacing) {
|
pub fn layout_spacing(&mut self, spacing: Spacing) {
|
||||||
match spacing {
|
match spacing {
|
||||||
Spacing::Linear(v) => {
|
Spacing::Relative(v) => {
|
||||||
// Resolve the linear and limit it to the remaining space.
|
// Resolve the spacing and limit it to the remaining space.
|
||||||
let resolved = v.resolve(self.regions.base.get(self.axis));
|
let resolved = v.resolve(self.regions.base.get(self.axis));
|
||||||
let remaining = self.regions.first.get_mut(self.axis);
|
let remaining = self.regions.first.get_mut(self.axis);
|
||||||
let limited = resolved.min(*remaining);
|
let limited = resolved.min(*remaining);
|
||||||
@ -247,7 +247,7 @@ impl StackLayouter {
|
|||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first;
|
self.full = self.regions.first;
|
||||||
self.used = Gen::zero();
|
self.used = Gen::zero();
|
||||||
self.fr = Fractional::zero();
|
self.fr = Fraction::zero();
|
||||||
self.finished.push(Arc::new(output));
|
self.finished.push(Arc::new(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,13 +167,13 @@ castable! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
Spec<Linear>,
|
Spec<Relative>,
|
||||||
Expected: "array of exactly two linears",
|
Expected: "array of two relative lengths",
|
||||||
Value::Array(array) => {
|
Value::Array(array) => {
|
||||||
match array.as_slice() {
|
match array.as_slice() {
|
||||||
[a, b] => {
|
[a, b] => {
|
||||||
let a = a.clone().cast::<Linear>()?;
|
let a = a.clone().cast::<Relative>()?;
|
||||||
let b = b.clone().cast::<Linear>()?;
|
let b = b.clone().cast::<Relative>()?;
|
||||||
Spec::new(a, b)
|
Spec::new(a, b)
|
||||||
},
|
},
|
||||||
_ => return Err("point array must contain exactly two entries".to_string()),
|
_ => return Err("point array must contain exactly two entries".to_string()),
|
||||||
|
@ -23,7 +23,7 @@ impl HeadingNode {
|
|||||||
#[property(referenced)]
|
#[property(referenced)]
|
||||||
pub const SIZE: Leveled<FontSize> = Leveled::Mapping(|level| {
|
pub const SIZE: Leveled<FontSize> = Leveled::Mapping(|level| {
|
||||||
let upscale = (1.6 - 0.1 * level as f64).max(0.75);
|
let upscale = (1.6 - 0.1 * level as f64).max(0.75);
|
||||||
FontSize(Relative::new(upscale).into())
|
FontSize(Ratio::new(upscale).into())
|
||||||
});
|
});
|
||||||
/// Whether text in the heading is strengthend.
|
/// Whether text in the heading is strengthend.
|
||||||
#[property(referenced)]
|
#[property(referenced)]
|
||||||
|
@ -34,11 +34,11 @@ impl<const L: ListKind> ListNode<L> {
|
|||||||
#[property(referenced)]
|
#[property(referenced)]
|
||||||
pub const LABEL: Label = Label::Default;
|
pub const LABEL: Label = Label::Default;
|
||||||
/// The spacing between the list items of a non-wide list.
|
/// The spacing between the list items of a non-wide list.
|
||||||
pub const SPACING: Linear = Linear::zero();
|
pub const SPACING: Relative = Relative::zero();
|
||||||
/// The indentation of each item's label.
|
/// The indentation of each item's label.
|
||||||
pub const INDENT: Linear = Relative::new(0.0).into();
|
pub const INDENT: Relative = Ratio::new(0.0).into();
|
||||||
/// The space between the label and the body of each item.
|
/// The space between the label and the body of each item.
|
||||||
pub const BODY_INDENT: Linear = Relative::new(0.5).into();
|
pub const BODY_INDENT: Relative = Ratio::new(0.5).into();
|
||||||
/// The extra padding above the list.
|
/// The extra padding above the list.
|
||||||
pub const ABOVE: Length = Length::zero();
|
pub const ABOVE: Length = Length::zero();
|
||||||
/// The extra padding below the list.
|
/// The extra padding below the list.
|
||||||
@ -91,12 +91,12 @@ impl<const L: ListKind> Show for ListNode<L> {
|
|||||||
|
|
||||||
Content::block(GridNode {
|
Content::block(GridNode {
|
||||||
tracks: Spec::with_x(vec![
|
tracks: Spec::with_x(vec![
|
||||||
TrackSizing::Linear(indent.into()),
|
TrackSizing::Relative(indent.into()),
|
||||||
TrackSizing::Auto,
|
TrackSizing::Auto,
|
||||||
TrackSizing::Linear(body_indent.into()),
|
TrackSizing::Relative(body_indent.into()),
|
||||||
TrackSizing::Auto,
|
TrackSizing::Auto,
|
||||||
]),
|
]),
|
||||||
gutter: Spec::with_y(vec![TrackSizing::Linear(gutter.into())]),
|
gutter: Spec::with_y(vec![TrackSizing::Relative(gutter.into())]),
|
||||||
children,
|
children,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -18,12 +18,12 @@ impl TableNode {
|
|||||||
pub const PRIMARY: Option<Paint> = None;
|
pub const PRIMARY: Option<Paint> = None;
|
||||||
/// The secondary cell fill color.
|
/// The secondary cell fill color.
|
||||||
pub const SECONDARY: Option<Paint> = None;
|
pub const SECONDARY: Option<Paint> = None;
|
||||||
/// How the stroke the cells.
|
/// How to stroke the cells.
|
||||||
pub const STROKE: Option<Paint> = Some(Color::BLACK.into());
|
pub const STROKE: Option<Paint> = Some(Color::BLACK.into());
|
||||||
/// The stroke's thickness.
|
/// The stroke's thickness.
|
||||||
pub const THICKNESS: Length = Length::pt(1.0);
|
pub const THICKNESS: Length = Length::pt(1.0);
|
||||||
/// How much to pad the cells's content.
|
/// How much to pad the cells's content.
|
||||||
pub const PADDING: Linear = Length::pt(5.0).into();
|
pub const PADDING: Relative = Length::pt(5.0).into();
|
||||||
|
|
||||||
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
let columns = args.named("columns")?.unwrap_or_default();
|
let columns = args.named("columns")?.unwrap_or_default();
|
||||||
|
@ -26,13 +26,13 @@ impl<const L: DecoLine> DecoNode<L> {
|
|||||||
/// Thickness of the line's strokes (dependent on scaled font size), read
|
/// Thickness of the line's strokes (dependent on scaled font size), read
|
||||||
/// from the font tables if `None`.
|
/// from the font tables if `None`.
|
||||||
#[property(shorthand)]
|
#[property(shorthand)]
|
||||||
pub const THICKNESS: Option<Linear> = None;
|
pub const THICKNESS: Option<Relative> = None;
|
||||||
/// Position of the line relative to the baseline (dependent on scaled font
|
/// Position of the line relative to the baseline (dependent on scaled font
|
||||||
/// size), read from the font tables if `None`.
|
/// size), read from the font tables if `None`.
|
||||||
pub const OFFSET: Option<Linear> = None;
|
pub const OFFSET: Option<Relative> = None;
|
||||||
/// Amount that the line will be longer or shorter than its associated text
|
/// Amount that the line will be longer or shorter than its associated text
|
||||||
/// (dependent on scaled font size).
|
/// (dependent on scaled font size).
|
||||||
pub const EXTENT: Linear = Linear::zero();
|
pub const EXTENT: Relative = Relative::zero();
|
||||||
/// Whether the line skips sections in which it would collide
|
/// Whether the line skips sections in which it would collide
|
||||||
/// with the glyphs. Does not apply to strikethrough.
|
/// with the glyphs. Does not apply to strikethrough.
|
||||||
pub const EVADE: bool = true;
|
pub const EVADE: bool = true;
|
||||||
@ -66,9 +66,9 @@ impl<const L: DecoLine> Show for DecoNode<L> {
|
|||||||
pub struct Decoration {
|
pub struct Decoration {
|
||||||
pub line: DecoLine,
|
pub line: DecoLine,
|
||||||
pub stroke: Option<Paint>,
|
pub stroke: Option<Paint>,
|
||||||
pub thickness: Option<Linear>,
|
pub thickness: Option<Relative>,
|
||||||
pub offset: Option<Linear>,
|
pub offset: Option<Relative>,
|
||||||
pub extent: Linear,
|
pub extent: Relative,
|
||||||
pub evade: bool,
|
pub evade: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ impl TextNode {
|
|||||||
/// The amount of space that should be added between characters.
|
/// The amount of space that should be added between characters.
|
||||||
pub const TRACKING: Em = Em::zero();
|
pub const TRACKING: Em = Em::zero();
|
||||||
/// The ratio by which spaces should be stretched.
|
/// The ratio by which spaces should be stretched.
|
||||||
pub const SPACING: Relative = Relative::one();
|
pub const SPACING: Ratio = Ratio::one();
|
||||||
/// Whether glyphs can hang over into the margin.
|
/// Whether glyphs can hang over into the margin.
|
||||||
pub const OVERHANG: bool = true;
|
pub const OVERHANG: bool = true;
|
||||||
/// The top end of the text bounding box.
|
/// The top end of the text bounding box.
|
||||||
@ -182,13 +182,13 @@ castable! {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
FontStretch,
|
FontStretch,
|
||||||
Expected: "relative",
|
Expected: "ratio",
|
||||||
Value::Relative(v) => Self::from_ratio(v.get() as f32),
|
Value::Ratio(v) => Self::from_ratio(v.get() as f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The size of text.
|
/// The size of text.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct FontSize(pub Linear);
|
pub struct FontSize(pub Relative);
|
||||||
|
|
||||||
impl Fold for FontSize {
|
impl Fold for FontSize {
|
||||||
type Output = Length;
|
type Output = Length;
|
||||||
@ -200,10 +200,10 @@ impl Fold for FontSize {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
FontSize,
|
FontSize,
|
||||||
Expected: "linear",
|
Expected: "relative length",
|
||||||
Value::Length(v) => Self(v.into()),
|
Value::Length(v) => Self(v.into()),
|
||||||
Value::Relative(v) => Self(v.into()),
|
Value::Ratio(v) => Self(v.into()),
|
||||||
Value::Linear(v) => Self(v),
|
Value::Relative(v) => Self(v),
|
||||||
}
|
}
|
||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
@ -214,10 +214,10 @@ castable! {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
VerticalFontMetric,
|
VerticalFontMetric,
|
||||||
Expected: "linear or string",
|
Expected: "string or relative length",
|
||||||
Value::Length(v) => Self::Linear(v.into()),
|
Value::Length(v) => Self::Relative(v.into()),
|
||||||
Value::Relative(v) => Self::Linear(v.into()),
|
Value::Ratio(v) => Self::Relative(v.into()),
|
||||||
Value::Linear(v) => Self::Linear(v),
|
Value::Relative(v) => Self::Relative(v),
|
||||||
Value::Str(string) => match string.as_str() {
|
Value::Str(string) => match string.as_str() {
|
||||||
"ascender" => Self::Ascender,
|
"ascender" => Self::Ascender,
|
||||||
"cap-height" => Self::CapHeight,
|
"cap-height" => Self::CapHeight,
|
||||||
|
@ -42,11 +42,11 @@ impl ParNode {
|
|||||||
/// will will be hyphenated if and only if justification is enabled.
|
/// will will be hyphenated if and only if justification is enabled.
|
||||||
pub const HYPHENATE: Smart<bool> = Smart::Auto;
|
pub const HYPHENATE: Smart<bool> = Smart::Auto;
|
||||||
/// The spacing between lines (dependent on scaled font size).
|
/// The spacing between lines (dependent on scaled font size).
|
||||||
pub const LEADING: Linear = Relative::new(0.65).into();
|
pub const LEADING: Relative = Ratio::new(0.65).into();
|
||||||
/// The extra spacing between paragraphs (dependent on scaled font size).
|
/// The extra spacing between paragraphs (dependent on scaled font size).
|
||||||
pub const SPACING: Linear = Relative::new(0.55).into();
|
pub const SPACING: Relative = Ratio::new(0.55).into();
|
||||||
/// The indent the first line of a consecutive paragraph should have.
|
/// The indent the first line of a consecutive paragraph should have.
|
||||||
pub const INDENT: Linear = Linear::zero();
|
pub const INDENT: Relative = Relative::zero();
|
||||||
|
|
||||||
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
// The paragraph constructor is special: It doesn't create a paragraph
|
// The paragraph constructor is special: It doesn't create a paragraph
|
||||||
@ -249,7 +249,7 @@ enum ParItem<'a> {
|
|||||||
/// Absolute spacing between other items.
|
/// Absolute spacing between other items.
|
||||||
Absolute(Length),
|
Absolute(Length),
|
||||||
/// Fractional spacing between other items.
|
/// Fractional spacing between other items.
|
||||||
Fractional(Fractional),
|
Fractional(Fraction),
|
||||||
/// A shaped text run with consistent direction.
|
/// A shaped text run with consistent direction.
|
||||||
Text(ShapedText<'a>),
|
Text(ShapedText<'a>),
|
||||||
/// A layouted child node.
|
/// A layouted child node.
|
||||||
@ -285,8 +285,8 @@ struct Line<'a> {
|
|||||||
size: Size,
|
size: Size,
|
||||||
/// The baseline of the line.
|
/// The baseline of the line.
|
||||||
baseline: Length,
|
baseline: Length,
|
||||||
/// The sum of fractional ratios in the line.
|
/// The sum of fractions in the line.
|
||||||
fr: Fractional,
|
fr: Fraction,
|
||||||
/// Whether the line ends at a mandatory break.
|
/// Whether the line ends at a mandatory break.
|
||||||
mandatory: bool,
|
mandatory: bool,
|
||||||
/// Whether the line ends with a hyphen or dash, either naturally or through
|
/// Whether the line ends with a hyphen or dash, either naturally or through
|
||||||
@ -370,7 +370,7 @@ fn prepare<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParChild::Spacing(spacing) => match *spacing {
|
ParChild::Spacing(spacing) => match *spacing {
|
||||||
Spacing::Linear(v) => {
|
Spacing::Relative(v) => {
|
||||||
let resolved = v.resolve(regions.base.x);
|
let resolved = v.resolve(regions.base.x);
|
||||||
items.push(ParItem::Absolute(resolved));
|
items.push(ParItem::Absolute(resolved));
|
||||||
ranges.push(range);
|
ranges.push(range);
|
||||||
@ -731,7 +731,7 @@ fn line<'a>(
|
|||||||
let mut width = Length::zero();
|
let mut width = Length::zero();
|
||||||
let mut top = Length::zero();
|
let mut top = Length::zero();
|
||||||
let mut bottom = Length::zero();
|
let mut bottom = Length::zero();
|
||||||
let mut fr = Fractional::zero();
|
let mut fr = Fraction::zero();
|
||||||
|
|
||||||
// Measure the size of the line.
|
// Measure the size of the line.
|
||||||
for item in first.iter().chain(items).chain(&last) {
|
for item in first.iter().chain(items).chain(&last) {
|
||||||
|
@ -15,12 +15,12 @@ pub fn rgb(_: &mut Context, args: &mut Args) -> TypResult<Value> {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
Component,
|
Component,
|
||||||
Expected: "integer or relative",
|
Expected: "integer or ratio",
|
||||||
Value::Int(v) => match v {
|
Value::Int(v) => match v {
|
||||||
0 ..= 255 => Self(v as u8),
|
0 ..= 255 => Self(v as u8),
|
||||||
_ => Err("must be between 0 and 255")?,
|
_ => Err("must be between 0 and 255")?,
|
||||||
},
|
},
|
||||||
Value::Relative(v) => if (0.0 ..= 1.0).contains(&v.get()) {
|
Value::Ratio(v) => if (0.0 ..= 1.0).contains(&v.get()) {
|
||||||
Self((v.get() * 255.0).round() as u8)
|
Self((v.get() * 255.0).round() as u8)
|
||||||
} else {
|
} else {
|
||||||
Err("must be between 0% and 100%")?
|
Err("must be between 0% and 100%")?
|
||||||
@ -42,8 +42,8 @@ pub fn cmyk(_: &mut Context, args: &mut Args) -> TypResult<Value> {
|
|||||||
|
|
||||||
castable! {
|
castable! {
|
||||||
Component,
|
Component,
|
||||||
Expected: "relative",
|
Expected: "ratio",
|
||||||
Value::Relative(v) => if (0.0 ..= 1.0).contains(&v.get()) {
|
Value::Ratio(v) => if (0.0 ..= 1.0).contains(&v.get()) {
|
||||||
Self((v.get() * 255.0).round() as u8)
|
Self((v.get() * 255.0).round() as u8)
|
||||||
} else {
|
} else {
|
||||||
Err("must be between 0% and 100%")?
|
Err("must be between 0% and 100%")?
|
||||||
|
@ -39,9 +39,11 @@ pub fn abs(_: &mut Context, args: &mut Args) -> TypResult<Value> {
|
|||||||
Value::Float(v) => Value::Float(v.abs()),
|
Value::Float(v) => Value::Float(v.abs()),
|
||||||
Value::Length(v) => Value::Length(v.abs()),
|
Value::Length(v) => Value::Length(v.abs()),
|
||||||
Value::Angle(v) => Value::Angle(v.abs()),
|
Value::Angle(v) => Value::Angle(v.abs()),
|
||||||
Value::Relative(v) => Value::Relative(v.abs()),
|
Value::Ratio(v) => Value::Ratio(v.abs()),
|
||||||
Value::Fractional(v) => Value::Fractional(v.abs()),
|
Value::Fraction(v) => Value::Fraction(v.abs()),
|
||||||
Value::Linear(_) => bail!(span, "cannot take absolute value of a linear"),
|
Value::Relative(_) => {
|
||||||
|
bail!(span, "cannot take absolute value of a relative length")
|
||||||
|
}
|
||||||
v => bail!(span, "expected numeric value, found {}", v.type_name()),
|
v => bail!(span, "expected numeric value, found {}", v.type_name()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@
|
|||||||
// Too few arguments.
|
// Too few arguments.
|
||||||
{
|
{
|
||||||
let types(x, y) = "[" + type(x) + ", " + type(y) + "]"
|
let types(x, y) = "[" + type(x) + ", " + type(y) + "]"
|
||||||
test(types(14%, 12pt), "[relative, length]")
|
test(types(14%, 12pt), "[ratio, length]")
|
||||||
|
|
||||||
// Error: 13-21 missing argument: y
|
// Error: 13-21 missing argument: y
|
||||||
test(types("nope"), "[string, none]")
|
test(types("nope"), "[string, none]")
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
{not ()}
|
{not ()}
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 2-18 cannot apply '<=' to relative length and relative
|
// Error: 2-18 cannot apply '<=' to relative length and ratio
|
||||||
{30% + 1pt <= 40%}
|
{30% + 1pt <= 40%}
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -35,7 +35,7 @@
|
|||||||
{(1 + "2", 40% - 1)}
|
{(1 + "2", 40% - 1)}
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 12-19 cannot subtract integer from relative
|
// Error: 12-19 cannot subtract integer from ratio
|
||||||
{(1234567, 40% - 1)}
|
{(1234567, 40% - 1)}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -63,14 +63,14 @@
|
|||||||
test(v + v, 2.0 * v)
|
test(v + v, 2.0 * v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linears cannot be divided by themselves.
|
// Relative lengths cannot be divided by themselves.
|
||||||
if type(v) != "relative length" {
|
if type(v) != "relative length" {
|
||||||
test(v / v, 1.0)
|
test(v / v, 1.0)
|
||||||
test(v / v == 1, true)
|
test(v / v == 1, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure length, relative and linear
|
// Make sure length, ratio and relative length
|
||||||
// - can all be added to / subtracted from each other,
|
// - can all be added to / subtracted from each other,
|
||||||
// - multiplied with integers and floats,
|
// - multiplied with integers and floats,
|
||||||
// - divided by floats.
|
// - divided by floats.
|
||||||
|
@ -42,5 +42,5 @@
|
|||||||
---
|
---
|
||||||
// Size cannot be relative because we wouldn't know
|
// Size cannot be relative because we wouldn't know
|
||||||
// relative to which axis.
|
// relative to which axis.
|
||||||
// Error: 15-18 expected length, found relative
|
// Error: 15-18 expected length, found ratio
|
||||||
#square(size: 50%)
|
#square(size: 50%)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Test relative sizing inside grids.
|
// Test relative sizing inside grids.
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test that auto and linear columns use the correct base.
|
// Test that auto and relative columns use the correct base.
|
||||||
#grid(
|
#grid(
|
||||||
columns: (auto, 60%),
|
columns: (auto, 60%),
|
||||||
rows: (auto, auto),
|
rows: (auto, auto),
|
||||||
|
@ -64,7 +64,7 @@ Emoji: 🐪, 🌋, 🏞
|
|||||||
#set text(style: "bold", weight: "thin")
|
#set text(style: "bold", weight: "thin")
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 21-23 expected linear or string, found array
|
// Error: 21-23 expected string or relative length, found array
|
||||||
#set text(top-edge: ())
|
#set text(top-edge: ())
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -32,5 +32,5 @@
|
|||||||
#rgb(0, 1)
|
#rgb(0, 1)
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 21-26 expected integer or relative, found boolean
|
// Error: 21-26 expected integer or ratio, found boolean
|
||||||
#rgb(10%, 20%, 30%, false)
|
#rgb(10%, 20%, 30%, false)
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
#mod(3.0, 0.0)
|
#mod(3.0, 0.0)
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 6-16 cannot take absolute value of a linear
|
// Error: 6-16 cannot take absolute value of a relative length
|
||||||
#abs(10pt + 50%)
|
#abs(10pt + 50%)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -528,7 +528,7 @@ fn render_links(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is an Linear-feedback shift register using XOR as its shifting
|
/// This is a Linear-feedback shift register using XOR as its shifting
|
||||||
/// function. It can be used as PRNG.
|
/// function. It can be used as PRNG.
|
||||||
struct LinearShift(u64);
|
struct LinearShift(u64);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user