mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Add angle data type 📐
This commit is contained in:
parent
8275b186ba
commit
3b2a28ca8e
172
src/geom/angle.rs
Normal file
172
src/geom/angle.rs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// An angle.
|
||||||
|
#[derive(Default, Copy, Clone, PartialEq, PartialOrd)]
|
||||||
|
pub struct Angle {
|
||||||
|
/// The angle in raw units.
|
||||||
|
raw: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Angle {
|
||||||
|
/// The zero angle.
|
||||||
|
pub const ZERO: Self = Self { raw: 0.0 };
|
||||||
|
|
||||||
|
/// Create an angle from a number of radians.
|
||||||
|
pub fn rad(rad: f64) -> Self {
|
||||||
|
Self::with_unit(rad, AngularUnit::Rad)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an angle from a number of degrees.
|
||||||
|
pub fn deg(deg: f64) -> Self {
|
||||||
|
Self::with_unit(deg, AngularUnit::Deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an angle from a number of raw units.
|
||||||
|
pub fn raw(raw: f64) -> Self {
|
||||||
|
Self { raw }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert this to a number of radians.
|
||||||
|
pub fn to_rad(self) -> f64 {
|
||||||
|
self.to_unit(AngularUnit::Rad)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert this to a number of degrees.
|
||||||
|
pub fn to_deg(self) -> f64 {
|
||||||
|
self.to_unit(AngularUnit::Deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the value of this angle in raw units.
|
||||||
|
pub fn to_raw(self) -> f64 {
|
||||||
|
self.raw
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an angle from a value in a unit.
|
||||||
|
pub fn with_unit(val: f64, unit: AngularUnit) -> Self {
|
||||||
|
Self { raw: val * unit.raw_scale() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the value of this length in unit.
|
||||||
|
pub fn to_unit(self, unit: AngularUnit) -> f64 {
|
||||||
|
self.raw / unit.raw_scale()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Angle {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}{}", self.to_deg(), AngularUnit::Deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Angle {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Neg for Angle {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self {
|
||||||
|
Self { raw: -self.raw }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Angle {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Self) -> Self {
|
||||||
|
Self { raw: self.raw + other.raw }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_impl!(Angle - Angle -> Angle);
|
||||||
|
|
||||||
|
impl Mul<f64> for Angle {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, other: f64) -> Self {
|
||||||
|
Self { raw: self.raw * other }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<Angle> for f64 {
|
||||||
|
type Output = Angle;
|
||||||
|
|
||||||
|
fn mul(self, other: Angle) -> Angle {
|
||||||
|
other * self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<f64> for Angle {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn div(self, other: f64) -> Self {
|
||||||
|
Self { raw: self.raw / other }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div for Angle {
|
||||||
|
type Output = f64;
|
||||||
|
|
||||||
|
fn div(self, other: Self) -> f64 {
|
||||||
|
self.raw / other.raw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_impl!(Angle += Angle);
|
||||||
|
assign_impl!(Angle -= Angle);
|
||||||
|
assign_impl!(Angle *= f64);
|
||||||
|
assign_impl!(Angle /= f64);
|
||||||
|
|
||||||
|
impl Sum for Angle {
|
||||||
|
fn sum<I: Iterator<Item = Angle>>(iter: I) -> Self {
|
||||||
|
iter.fold(Angle::ZERO, Add::add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Different units of angular measurement.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
pub enum AngularUnit {
|
||||||
|
/// Radians.
|
||||||
|
Rad,
|
||||||
|
/// Degrees.
|
||||||
|
Deg,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AngularUnit {
|
||||||
|
/// How many raw units correspond to a value of `1.0` in this unit.
|
||||||
|
fn raw_scale(self) -> f64 {
|
||||||
|
match self {
|
||||||
|
Self::Rad => 1.0,
|
||||||
|
Self::Deg => PI / 180.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AngularUnit {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
f.pad(match self {
|
||||||
|
Self::Rad => "rad",
|
||||||
|
Self::Deg => "deg",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for AngularUnit {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_angle_unit_conversion() {
|
||||||
|
assert!((Angle::rad(2.0 * PI).to_deg() - 360.0) < 1e-4);
|
||||||
|
assert!((Angle::deg(45.0).to_rad() - 0.7854) < 1e-4);
|
||||||
|
}
|
||||||
|
}
|
@ -13,22 +13,22 @@ impl Length {
|
|||||||
|
|
||||||
/// Create a length from a number of points.
|
/// Create a length from a number of points.
|
||||||
pub fn pt(pt: f64) -> Self {
|
pub fn pt(pt: f64) -> Self {
|
||||||
Self::with_unit(pt, Unit::Pt)
|
Self::with_unit(pt, LengthUnit::Pt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of millimeters.
|
/// Create a length from a number of millimeters.
|
||||||
pub fn mm(mm: f64) -> Self {
|
pub fn mm(mm: f64) -> Self {
|
||||||
Self::with_unit(mm, Unit::Mm)
|
Self::with_unit(mm, LengthUnit::Mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of centimeters.
|
/// Create a length from a number of centimeters.
|
||||||
pub fn cm(cm: f64) -> Self {
|
pub fn cm(cm: f64) -> Self {
|
||||||
Self::with_unit(cm, Unit::Cm)
|
Self::with_unit(cm, LengthUnit::Cm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of inches.
|
/// Create a length from a number of inches.
|
||||||
pub fn inches(inches: f64) -> Self {
|
pub fn inches(inches: f64) -> Self {
|
||||||
Self::with_unit(inches, Unit::In)
|
Self::with_unit(inches, LengthUnit::In)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a number of raw units.
|
/// Create a length from a number of raw units.
|
||||||
@ -38,22 +38,22 @@ impl Length {
|
|||||||
|
|
||||||
/// Convert this to a number of points.
|
/// Convert this to a number of points.
|
||||||
pub fn to_pt(self) -> f64 {
|
pub fn to_pt(self) -> f64 {
|
||||||
self.to_unit(Unit::Pt)
|
self.to_unit(LengthUnit::Pt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this to a number of millimeters.
|
/// Convert this to a number of millimeters.
|
||||||
pub fn to_mm(self) -> f64 {
|
pub fn to_mm(self) -> f64 {
|
||||||
self.to_unit(Unit::Mm)
|
self.to_unit(LengthUnit::Mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this to a number of centimeters.
|
/// Convert this to a number of centimeters.
|
||||||
pub fn to_cm(self) -> f64 {
|
pub fn to_cm(self) -> f64 {
|
||||||
self.to_unit(Unit::Cm)
|
self.to_unit(LengthUnit::Cm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this to a number of inches.
|
/// Convert this to a number of inches.
|
||||||
pub fn to_inches(self) -> f64 {
|
pub fn to_inches(self) -> f64 {
|
||||||
self.to_unit(Unit::In)
|
self.to_unit(LengthUnit::In)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value of this length in raw units.
|
/// Get the value of this length in raw units.
|
||||||
@ -62,12 +62,12 @@ impl Length {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a length from a value in a unit.
|
/// Create a length from a value in a unit.
|
||||||
pub fn with_unit(val: f64, unit: Unit) -> Self {
|
pub fn with_unit(val: f64, unit: LengthUnit) -> Self {
|
||||||
Self { raw: val * unit.raw_scale() }
|
Self { raw: val * unit.raw_scale() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value of this length in unit.
|
/// Get the value of this length in unit.
|
||||||
pub fn to_unit(self, unit: Unit) -> f64 {
|
pub fn to_unit(self, unit: LengthUnit) -> f64 {
|
||||||
self.raw / unit.raw_scale()
|
self.raw / unit.raw_scale()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +86,9 @@ impl Display for Length {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
// Format small lengths as points and large ones as centimeters.
|
// Format small lengths as points and large ones as centimeters.
|
||||||
let (val, unit) = if self.to_pt().abs() < 25.0 {
|
let (val, unit) = if self.to_pt().abs() < 25.0 {
|
||||||
(self.to_pt(), Unit::Pt)
|
(self.to_pt(), LengthUnit::Pt)
|
||||||
} else {
|
} else {
|
||||||
(self.to_cm(), Unit::Cm)
|
(self.to_cm(), LengthUnit::Cm)
|
||||||
};
|
};
|
||||||
write!(f, "{}{}", (val * 100.0).round() / 100.0, unit)
|
write!(f, "{}{}", (val * 100.0).round() / 100.0, unit)
|
||||||
}
|
}
|
||||||
@ -161,9 +161,9 @@ impl Sum for Length {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Different units of measurement.
|
/// Different units of length measurement.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub enum Unit {
|
pub enum LengthUnit {
|
||||||
/// Points.
|
/// Points.
|
||||||
Pt,
|
Pt,
|
||||||
/// Millimeters.
|
/// Millimeters.
|
||||||
@ -174,30 +174,30 @@ pub enum Unit {
|
|||||||
In,
|
In,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unit {
|
impl LengthUnit {
|
||||||
/// How many raw units correspond to a value of `1.0` in this unit.
|
/// How many raw units correspond to a value of `1.0` in this unit.
|
||||||
fn raw_scale(self) -> f64 {
|
fn raw_scale(self) -> f64 {
|
||||||
match self {
|
match self {
|
||||||
Unit::Pt => 1.0,
|
LengthUnit::Pt => 1.0,
|
||||||
Unit::Mm => 2.83465,
|
LengthUnit::Mm => 2.83465,
|
||||||
Unit::Cm => 28.3465,
|
LengthUnit::Cm => 28.3465,
|
||||||
Unit::In => 72.0,
|
LengthUnit::In => 72.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Unit {
|
impl Display for LengthUnit {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
f.pad(match self {
|
f.pad(match self {
|
||||||
Unit::Mm => "mm",
|
LengthUnit::Mm => "mm",
|
||||||
Unit::Pt => "pt",
|
LengthUnit::Pt => "pt",
|
||||||
Unit::Cm => "cm",
|
LengthUnit::Cm => "cm",
|
||||||
Unit::In => "in",
|
LengthUnit::In => "in",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Unit {
|
impl Debug for LengthUnit {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
Display::fmt(self, f)
|
Display::fmt(self, f)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
mod align;
|
mod align;
|
||||||
|
mod angle;
|
||||||
mod dir;
|
mod dir;
|
||||||
mod gen;
|
mod gen;
|
||||||
mod length;
|
mod length;
|
||||||
@ -14,6 +15,7 @@ mod size;
|
|||||||
mod spec;
|
mod spec;
|
||||||
|
|
||||||
pub use align::*;
|
pub use align::*;
|
||||||
|
pub use angle::*;
|
||||||
pub use dir::*;
|
pub use dir::*;
|
||||||
pub use gen::*;
|
pub use gen::*;
|
||||||
pub use length::*;
|
pub use length::*;
|
||||||
|
@ -5,7 +5,7 @@ use std::fmt::Debug;
|
|||||||
use super::parse;
|
use super::parse;
|
||||||
use crate::color::RgbaColor;
|
use crate::color::RgbaColor;
|
||||||
use crate::diag::{Diag, Level, Pass};
|
use crate::diag::{Diag, Level, Pass};
|
||||||
use crate::geom::Unit;
|
use crate::geom::LengthUnit;
|
||||||
use crate::syntax::*;
|
use crate::syntax::*;
|
||||||
|
|
||||||
use BinOp::*;
|
use BinOp::*;
|
||||||
@ -549,7 +549,7 @@ fn test_parse_expressions() {
|
|||||||
t!(r#"{"x"+"y"}"# Block(Binary(Str("x"), Add, Str("y"))));
|
t!(r#"{"x"+"y"}"# Block(Binary(Str("x"), Add, Str("y"))));
|
||||||
t!("{1-2}" Block(Binary(Int(1), Sub, Int(2))));
|
t!("{1-2}" Block(Binary(Int(1), Sub, Int(2))));
|
||||||
t!("{a * b}" Block(Binary(Id("a"), Mul, Id("b"))));
|
t!("{a * b}" Block(Binary(Id("a"), Mul, Id("b"))));
|
||||||
t!("{12pt/.4}" Block(Binary(Length(12.0, Unit::Pt), Div, Float(0.4))));
|
t!("{12pt/.4}" Block(Binary(Length(12.0, LengthUnit::Pt), Div, Float(0.4))));
|
||||||
|
|
||||||
// Associativity.
|
// Associativity.
|
||||||
t!("{1+2+3}" Block(Binary(Binary(Int(1), Add, Int(2)), Add, Int(3))));
|
t!("{1+2+3}" Block(Binary(Binary(Int(1), Add, Int(2)), Add, Int(3))));
|
||||||
@ -593,8 +593,8 @@ fn test_parse_values() {
|
|||||||
t!("{1.0e-4}" Block(Float(1e-4)));
|
t!("{1.0e-4}" Block(Float(1e-4)));
|
||||||
t!("{3.15}" Block(Float(3.15)));
|
t!("{3.15}" Block(Float(3.15)));
|
||||||
t!("{50%}" Block(Percent(50.0)));
|
t!("{50%}" Block(Percent(50.0)));
|
||||||
t!("{4.5cm}" Block(Length(4.5, Unit::Cm)));
|
t!("{4.5cm}" Block(Length(4.5, LengthUnit::Cm)));
|
||||||
t!("{12e1pt}" Block(Length(12e1, Unit::Pt)));
|
t!("{12e1pt}" Block(Length(12e1, LengthUnit::Pt)));
|
||||||
|
|
||||||
// Strings.
|
// Strings.
|
||||||
t!(r#"{"hi"}"# Block(Str("hi")));
|
t!(r#"{"hi"}"# Block(Str("hi")));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
|
|
||||||
use super::{is_newline, Scanner};
|
use super::{is_newline, Scanner};
|
||||||
use crate::geom::Unit;
|
use crate::geom::LengthUnit;
|
||||||
use crate::syntax::*;
|
use crate::syntax::*;
|
||||||
|
|
||||||
use TokenMode::*;
|
use TokenMode::*;
|
||||||
@ -349,7 +349,7 @@ fn parse_percent(string: &str) -> Option<f64> {
|
|||||||
string.strip_suffix('%').and_then(|prefix| prefix.parse::<f64>().ok())
|
string.strip_suffix('%').and_then(|prefix| prefix.parse::<f64>().ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_length(string: &str) -> Option<(f64, Unit)> {
|
fn parse_length(string: &str) -> Option<(f64, LengthUnit)> {
|
||||||
let len = string.len();
|
let len = string.len();
|
||||||
|
|
||||||
// We need at least some number and the unit.
|
// We need at least some number and the unit.
|
||||||
@ -362,10 +362,10 @@ fn parse_length(string: &str) -> Option<(f64, Unit)> {
|
|||||||
let split = len - 2;
|
let split = len - 2;
|
||||||
let bytes = string.as_bytes();
|
let bytes = string.as_bytes();
|
||||||
let unit = match &bytes[split ..] {
|
let unit = match &bytes[split ..] {
|
||||||
b"pt" => Unit::Pt,
|
b"pt" => LengthUnit::Pt,
|
||||||
b"mm" => Unit::Mm,
|
b"mm" => LengthUnit::Mm,
|
||||||
b"cm" => Unit::Cm,
|
b"cm" => LengthUnit::Cm,
|
||||||
b"in" => Unit::In,
|
b"in" => LengthUnit::In,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -378,9 +378,9 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::parse::tests::check;
|
use crate::parse::tests::check;
|
||||||
|
|
||||||
|
use LengthUnit::*;
|
||||||
use Option::None;
|
use Option::None;
|
||||||
use Token::{Ident, *};
|
use Token::{Ident, *};
|
||||||
use Unit::*;
|
|
||||||
|
|
||||||
fn Raw(text: &str, backticks: usize, terminated: bool) -> Token {
|
fn Raw(text: &str, backticks: usize, terminated: bool) -> Token {
|
||||||
Token::Raw(TokenRaw { text, backticks, terminated })
|
Token::Raw(TokenRaw { text, backticks, terminated })
|
||||||
@ -737,7 +737,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test lengths.
|
// Test lengths.
|
||||||
for &unit in &[Unit::Mm, Unit::Pt, Unit::Cm, Unit::In] {
|
for &unit in &[
|
||||||
|
LengthUnit::Mm,
|
||||||
|
LengthUnit::Pt,
|
||||||
|
LengthUnit::Cm,
|
||||||
|
LengthUnit::In,
|
||||||
|
] {
|
||||||
for (s, v) in nums.clone() {
|
for (s, v) in nums.clone() {
|
||||||
t!(Header[" /"]: format!("{}{}", s, unit) => Length(v, unit));
|
t!(Header[" /"]: format!("{}{}", s, unit) => Length(v, unit));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::color::RgbaColor;
|
use crate::color::RgbaColor;
|
||||||
use crate::geom::Unit;
|
use crate::geom::LengthUnit;
|
||||||
|
|
||||||
/// An expression.
|
/// An expression.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -16,7 +16,7 @@ pub enum Expr {
|
|||||||
/// A floating-point literal: `1.2`, `10e-4`.
|
/// A floating-point literal: `1.2`, `10e-4`.
|
||||||
Float(f64),
|
Float(f64),
|
||||||
/// A length literal: `12pt`, `3cm`.
|
/// A length literal: `12pt`, `3cm`.
|
||||||
Length(f64, Unit),
|
Length(f64, LengthUnit),
|
||||||
/// A percent literal: `50%`.
|
/// A percent literal: `50%`.
|
||||||
///
|
///
|
||||||
/// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the
|
/// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::geom::Unit;
|
use crate::geom::LengthUnit;
|
||||||
|
|
||||||
/// A minimal semantic entity of source code.
|
/// A minimal semantic entity of source code.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
@ -70,7 +70,7 @@ pub enum Token<'s> {
|
|||||||
/// A floating-point number: `1.2`, `10e-4`.
|
/// A floating-point number: `1.2`, `10e-4`.
|
||||||
Float(f64),
|
Float(f64),
|
||||||
/// A length: `12pt`, `3cm`.
|
/// A length: `12pt`, `3cm`.
|
||||||
Length(f64, Unit),
|
Length(f64, LengthUnit),
|
||||||
/// A percentage: `50%`.
|
/// A percentage: `50%`.
|
||||||
///
|
///
|
||||||
/// _Note_: `50%` is stored as `50.0` here, as in the corresponding
|
/// _Note_: `50%` is stored as `50.0` here, as in the corresponding
|
||||||
|
Loading…
x
Reference in New Issue
Block a user