mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Remove floating point rounding from colors (and more) (#3557)
This commit is contained in:
parent
82617a6a3c
commit
2bc3c96bc9
@ -719,7 +719,7 @@ fn to_typst(synt::Color { r, g, b, a }: synt::Color) -> Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn to_syn(color: Color) -> synt::Color {
|
fn to_syn(color: Color) -> synt::Color {
|
||||||
let [r, g, b, a] = color.to_vec4_u8();
|
let [r, g, b, a] = color.to_rgb().to_vec4_u8();
|
||||||
synt::Color { r, g, b, a }
|
synt::Color { r, g, b, a }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,6 @@ pub type Hsl = palette::hsl::Hsla<encoding::Srgb, f32>;
|
|||||||
pub type Hsv = palette::hsv::Hsva<encoding::Srgb, f32>;
|
pub type Hsv = palette::hsv::Hsva<encoding::Srgb, f32>;
|
||||||
pub type Luma = palette::luma::Lumaa<encoding::Srgb, f32>;
|
pub type Luma = palette::luma::Lumaa<encoding::Srgb, f32>;
|
||||||
|
|
||||||
/// Equivalent of [`std::f32::EPSILON`] but for hue angles.
|
|
||||||
const ANGLE_EPSILON: f32 = 1e-5;
|
|
||||||
|
|
||||||
/// The ICC profile used to convert from CMYK to RGB.
|
/// The ICC profile used to convert from CMYK to RGB.
|
||||||
///
|
///
|
||||||
/// This is a minimal CMYK profile that only contains the necessary information
|
/// This is a minimal CMYK profile that only contains the necessary information
|
||||||
@ -749,129 +746,72 @@ impl Color {
|
|||||||
#[default(true)]
|
#[default(true)]
|
||||||
alpha: bool,
|
alpha: bool,
|
||||||
) -> Array {
|
) -> Array {
|
||||||
match self {
|
let mut components = match self {
|
||||||
Self::Luma(c) => {
|
Self::Luma(c) => {
|
||||||
if alpha {
|
array![Ratio::new(c.luma.into()), Ratio::new(c.alpha.into())]
|
||||||
array![Ratio::new(c.luma as _), Ratio::new(c.alpha as _)]
|
|
||||||
} else {
|
|
||||||
array![Ratio::new(c.luma as _)]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Oklab(c) => {
|
Self::Oklab(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Ratio::new(c.l as _),
|
Ratio::new(c.l.into()),
|
||||||
(c.a as f64 * 1000.0).round() / 1000.0,
|
f64::from(c.a),
|
||||||
(c.b as f64 * 1000.0).round() / 1000.0,
|
f64::from(c.b),
|
||||||
Ratio::new(c.alpha as _),
|
Ratio::new(c.alpha.into())
|
||||||
]
|
]
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Ratio::new(c.l as _),
|
|
||||||
(c.a as f64 * 1000.0).round() / 1000.0,
|
|
||||||
(c.b as f64 * 1000.0).round() / 1000.0,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Oklch(c) => {
|
Self::Oklch(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Ratio::new(c.l as _),
|
Ratio::new(c.l.into()),
|
||||||
(c.chroma as f64 * 1000.0).round() / 1000.0,
|
f64::from(c.chroma),
|
||||||
Angle::deg(
|
hue_angle(c.hue.into_degrees()),
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
Ratio::new(c.alpha.into()),
|
||||||
),
|
|
||||||
Ratio::new(c.alpha as _),
|
|
||||||
]
|
]
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Ratio::new(c.l as _),
|
|
||||||
(c.chroma as f64 * 1000.0).round() / 1000.0,
|
|
||||||
Angle::deg(
|
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
|
||||||
),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::LinearRgb(c) => {
|
Self::LinearRgb(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Ratio::new(c.red as _),
|
Ratio::new(c.red.into()),
|
||||||
Ratio::new(c.green as _),
|
Ratio::new(c.green.into()),
|
||||||
Ratio::new(c.blue as _),
|
Ratio::new(c.blue.into()),
|
||||||
Ratio::new(c.alpha as _),
|
Ratio::new(c.alpha.into()),
|
||||||
]
|
]
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Ratio::new(c.red as _),
|
|
||||||
Ratio::new(c.green as _),
|
|
||||||
Ratio::new(c.blue as _),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Rgb(c) => {
|
Self::Rgb(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Ratio::new(c.red as _),
|
Ratio::new(c.red.into()),
|
||||||
Ratio::new(c.green as _),
|
Ratio::new(c.green.into()),
|
||||||
Ratio::new(c.blue as _),
|
Ratio::new(c.blue.into()),
|
||||||
Ratio::new(c.alpha as _),
|
Ratio::new(c.alpha.into()),
|
||||||
]
|
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Ratio::new(c.red as _),
|
|
||||||
Ratio::new(c.green as _),
|
|
||||||
Ratio::new(c.blue as _),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Self::Cmyk(c) => {
|
||||||
|
array![
|
||||||
|
Ratio::new(c.c.into()),
|
||||||
|
Ratio::new(c.m.into()),
|
||||||
|
Ratio::new(c.y.into()),
|
||||||
|
Ratio::new(c.k.into())
|
||||||
|
]
|
||||||
}
|
}
|
||||||
Self::Cmyk(c) => array![
|
|
||||||
Ratio::new(c.c as _),
|
|
||||||
Ratio::new(c.m as _),
|
|
||||||
Ratio::new(c.y as _),
|
|
||||||
Ratio::new(c.k as _),
|
|
||||||
],
|
|
||||||
Self::Hsl(c) => {
|
Self::Hsl(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Angle::deg(
|
hue_angle(c.hue.into_degrees()),
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
Ratio::new(c.saturation.into()),
|
||||||
),
|
Ratio::new(c.lightness.into()),
|
||||||
Ratio::new(c.saturation as _),
|
Ratio::new(c.alpha.into()),
|
||||||
Ratio::new(c.lightness as _),
|
|
||||||
Ratio::new(c.alpha as _),
|
|
||||||
]
|
]
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Angle::deg(
|
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
|
||||||
),
|
|
||||||
Ratio::new(c.saturation as _),
|
|
||||||
Ratio::new(c.lightness as _),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Hsv(c) => {
|
Self::Hsv(c) => {
|
||||||
if alpha {
|
|
||||||
array![
|
array![
|
||||||
Angle::deg(
|
hue_angle(c.hue.into_degrees()),
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
Ratio::new(c.saturation.into()),
|
||||||
),
|
Ratio::new(c.value.into()),
|
||||||
Ratio::new(c.saturation as _),
|
Ratio::new(c.alpha.into()),
|
||||||
Ratio::new(c.value as _),
|
|
||||||
Ratio::new(c.alpha as _),
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
array![
|
|
||||||
Angle::deg(
|
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON) as _
|
|
||||||
),
|
|
||||||
Ratio::new(c.saturation as _),
|
|
||||||
Ratio::new(c.value as _),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
// Remove the alpha component if the corresponding argument was set.
|
||||||
|
if !alpha && !matches!(self, Self::Cmyk(_)) {
|
||||||
|
let _ = components.pop();
|
||||||
}
|
}
|
||||||
}
|
components
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the constructor function for this color's space:
|
/// Returns the constructor function for this color's space:
|
||||||
@ -1259,10 +1199,10 @@ impl Color {
|
|||||||
/// Construct a new RGBA color from 8-bit values.
|
/// Construct a new RGBA color from 8-bit values.
|
||||||
pub fn from_u8(r: u8, g: u8, b: u8, a: u8) -> Self {
|
pub fn from_u8(r: u8, g: u8, b: u8, a: u8) -> Self {
|
||||||
Self::Rgb(Rgb::new(
|
Self::Rgb(Rgb::new(
|
||||||
r as f32 / 255.0,
|
f32::from(r) / 255.0,
|
||||||
g as f32 / 255.0,
|
f32::from(g) / 255.0,
|
||||||
b as f32 / 255.0,
|
f32::from(b) / 255.0,
|
||||||
a as f32 / 255.0,
|
f32::from(a) / 255.0,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,33 +1276,27 @@ impl Color {
|
|||||||
match self {
|
match self {
|
||||||
Color::Luma(c) => [c.luma, c.luma, c.luma, c.alpha],
|
Color::Luma(c) => [c.luma, c.luma, c.luma, c.alpha],
|
||||||
Color::Oklab(c) => [c.l, c.a, c.b, c.alpha],
|
Color::Oklab(c) => [c.l, c.a, c.b, c.alpha],
|
||||||
Color::Oklch(c) => [
|
Color::Oklch(c) => {
|
||||||
c.l,
|
[c.l, c.chroma, c.hue.into_degrees().rem_euclid(360.0), c.alpha]
|
||||||
c.chroma,
|
}
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON),
|
|
||||||
c.alpha,
|
|
||||||
],
|
|
||||||
Color::Rgb(c) => [c.red, c.green, c.blue, c.alpha],
|
Color::Rgb(c) => [c.red, c.green, c.blue, c.alpha],
|
||||||
Color::LinearRgb(c) => [c.red, c.green, c.blue, c.alpha],
|
Color::LinearRgb(c) => [c.red, c.green, c.blue, c.alpha],
|
||||||
Color::Cmyk(c) => [c.c, c.m, c.y, c.k],
|
Color::Cmyk(c) => [c.c, c.m, c.y, c.k],
|
||||||
Color::Hsl(c) => [
|
Color::Hsl(c) => [
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON),
|
c.hue.into_degrees().rem_euclid(360.0),
|
||||||
c.saturation,
|
c.saturation,
|
||||||
c.lightness,
|
c.lightness,
|
||||||
c.alpha,
|
c.alpha,
|
||||||
],
|
],
|
||||||
Color::Hsv(c) => [
|
Color::Hsv(c) => {
|
||||||
c.hue.into_degrees().rem_euclid(360.0 + ANGLE_EPSILON),
|
[c.hue.into_degrees().rem_euclid(360.0), c.saturation, c.value, c.alpha]
|
||||||
c.saturation,
|
}
|
||||||
c.value,
|
|
||||||
c.alpha,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the color's RGB(A) representation as an array of 8-bit values.
|
/// Converts the color to a vec of four [`u8`]s.
|
||||||
pub fn to_vec4_u8(&self) -> [u8; 4] {
|
pub fn to_vec4_u8(&self) -> [u8; 4] {
|
||||||
self.to_rgb().to_vec4().map(|x| (x * 255.0).round() as u8)
|
self.to_vec4().map(|x| (x * 255.0).round() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_space(self, space: ColorSpace) -> Self {
|
pub fn to_space(self, space: ColorSpace) -> Self {
|
||||||
@ -1530,12 +1464,12 @@ impl Repr for Color {
|
|||||||
match self {
|
match self {
|
||||||
Self::Luma(c) => {
|
Self::Luma(c) => {
|
||||||
if c.alpha == 1.0 {
|
if c.alpha == 1.0 {
|
||||||
eco_format!("luma({})", Ratio::new(c.luma as _).repr())
|
eco_format!("luma({})", Ratio::new(c.luma.into()).repr())
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"luma({}, {})",
|
"luma({}, {})",
|
||||||
Ratio::new(c.luma as _).repr(),
|
Ratio::new(c.luma.into()).repr(),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1544,44 +1478,44 @@ impl Repr for Color {
|
|||||||
if c.alpha == 1.0 {
|
if c.alpha == 1.0 {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"color.linear-rgb({}, {}, {})",
|
"color.linear-rgb({}, {}, {})",
|
||||||
Ratio::new(c.red as _).repr(),
|
Ratio::new(c.red.into()).repr(),
|
||||||
Ratio::new(c.green as _).repr(),
|
Ratio::new(c.green.into()).repr(),
|
||||||
Ratio::new(c.blue as _).repr(),
|
Ratio::new(c.blue.into()).repr(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"color.linear-rgb({}, {}, {}, {})",
|
"color.linear-rgb({}, {}, {}, {})",
|
||||||
Ratio::new(c.red as _).repr(),
|
Ratio::new(c.red.into()).repr(),
|
||||||
Ratio::new(c.green as _).repr(),
|
Ratio::new(c.green.into()).repr(),
|
||||||
Ratio::new(c.blue as _).repr(),
|
Ratio::new(c.blue.into()).repr(),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Cmyk(c) => {
|
Self::Cmyk(c) => {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"cmyk({}, {}, {}, {})",
|
"cmyk({}, {}, {}, {})",
|
||||||
Ratio::new(c.c as _).repr(),
|
Ratio::new(c.c.into()).repr(),
|
||||||
Ratio::new(c.m as _).repr(),
|
Ratio::new(c.m.into()).repr(),
|
||||||
Ratio::new(c.y as _).repr(),
|
Ratio::new(c.y.into()).repr(),
|
||||||
Ratio::new(c.k as _).repr(),
|
Ratio::new(c.k.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Self::Oklab(c) => {
|
Self::Oklab(c) => {
|
||||||
if c.alpha == 1.0 {
|
if c.alpha == 1.0 {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"oklab({}, {}, {})",
|
"oklab({}, {}, {})",
|
||||||
Ratio::new(c.l as _).repr(),
|
Ratio::new(c.l.into()).repr(),
|
||||||
repr::format_float_component(c.a as _),
|
repr::format_float_component(c.a.into()),
|
||||||
repr::format_float_component(c.b as _),
|
repr::format_float_component(c.b.into()),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"oklab({}, {}, {}, {})",
|
"oklab({}, {}, {}, {})",
|
||||||
Ratio::new(c.l as _).repr(),
|
Ratio::new(c.l.into()).repr(),
|
||||||
repr::format_float_component(c.a as _),
|
repr::format_float_component(c.a.into()),
|
||||||
repr::format_float_component(c.b as _),
|
repr::format_float_component(c.b.into()),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1589,17 +1523,17 @@ impl Repr for Color {
|
|||||||
if c.alpha == 1.0 {
|
if c.alpha == 1.0 {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"oklch({}, {}, {})",
|
"oklch({}, {}, {})",
|
||||||
Ratio::new(c.l as _).repr(),
|
Ratio::new(c.l.into()).repr(),
|
||||||
repr::format_float_component(c.chroma as _),
|
repr::format_float_component(c.chroma.into()),
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"oklch({}, {}, {}, {})",
|
"oklch({}, {}, {}, {})",
|
||||||
Ratio::new(c.l as _).repr(),
|
Ratio::new(c.l.into()).repr(),
|
||||||
repr::format_float_component(c.chroma as _),
|
repr::format_float_component(c.chroma.into()),
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1608,16 +1542,16 @@ impl Repr for Color {
|
|||||||
eco_format!(
|
eco_format!(
|
||||||
"color.hsl({}, {}, {})",
|
"color.hsl({}, {}, {})",
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
Ratio::new(c.saturation as _).repr(),
|
Ratio::new(c.saturation.into()).repr(),
|
||||||
Ratio::new(c.lightness as _).repr(),
|
Ratio::new(c.lightness.into()).repr(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"color.hsl({}, {}, {}, {})",
|
"color.hsl({}, {}, {}, {})",
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
Ratio::new(c.saturation as _).repr(),
|
Ratio::new(c.saturation.into()).repr(),
|
||||||
Ratio::new(c.lightness as _).repr(),
|
Ratio::new(c.lightness.into()).repr(),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1626,16 +1560,16 @@ impl Repr for Color {
|
|||||||
eco_format!(
|
eco_format!(
|
||||||
"color.hsv({}, {}, {})",
|
"color.hsv({}, {}, {})",
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
Ratio::new(c.saturation as _).repr(),
|
Ratio::new(c.saturation.into()).repr(),
|
||||||
Ratio::new(c.value as _).repr(),
|
Ratio::new(c.value.into()).repr(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
eco_format!(
|
eco_format!(
|
||||||
"color.hsv({}, {}, {}, {})",
|
"color.hsv({}, {}, {}, {})",
|
||||||
hue_angle(c.hue.into_degrees()).repr(),
|
hue_angle(c.hue.into_degrees()).repr(),
|
||||||
Ratio::new(c.saturation as _).repr(),
|
Ratio::new(c.saturation.into()).repr(),
|
||||||
Ratio::new(c.value as _).repr(),
|
Ratio::new(c.value.into()).repr(),
|
||||||
Ratio::new(c.alpha as _).repr(),
|
Ratio::new(c.alpha.into()).repr(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1644,7 +1578,7 @@ impl Repr for Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hue_angle(degrees: f32) -> Angle {
|
fn hue_angle(degrees: f32) -> Angle {
|
||||||
Angle::deg(degrees.rem_euclid(360.0 + ANGLE_EPSILON) as _)
|
Angle::deg(f64::from(degrees).rem_euclid(360.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Color {
|
impl PartialEq for Color {
|
||||||
@ -1824,9 +1758,9 @@ impl Cmyk {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Rgb::new(
|
Rgb::new(
|
||||||
dest[0] as f32 / 255.0,
|
f32::from(dest[0]) / 255.0,
|
||||||
dest[1] as f32 / 255.0,
|
f32::from(dest[1]) / 255.0,
|
||||||
dest[2] as f32 / 255.0,
|
f32::from(dest[2]) / 255.0,
|
||||||
1.0,
|
1.0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1857,7 +1791,7 @@ impl WeightedColor {
|
|||||||
|
|
||||||
cast! {
|
cast! {
|
||||||
WeightedColor,
|
WeightedColor,
|
||||||
self => array![self.color, Value::Float(self.weight as _)].into_value(),
|
self => array![self.color, Value::Float(self.weight)].into_value(),
|
||||||
color: Color => Self { color, weight: 1.0 },
|
color: Color => Self { color, weight: 1.0 },
|
||||||
v: Array => {
|
v: Array => {
|
||||||
let mut iter = v.into_iter();
|
let mut iter = v.into_iter();
|
||||||
|
@ -126,17 +126,32 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test color '.components()' without conversions
|
// Test color '.components()' without conversions
|
||||||
#test-repr(rgb(1, 2, 3, 4).components(), (0.39%, 0.78%, 1.18%, 1.57%))
|
|
||||||
#test-repr(luma(40).components(), (15.69%, 100%))
|
#let test-components(col, ref, has-alpha: true) = {
|
||||||
#test-repr(luma(40, 50%).components(), (15.69%, 50%))
|
// Perform an approximate scalar comparison.
|
||||||
#test-repr(cmyk(4%, 5%, 6%, 7%).components(), (4%, 5%, 6%, 7%))
|
let are-equal((a, b)) = {
|
||||||
#test-repr(oklab(10%, 0.2, 0.3).components(), (10%, 0.2, 0.3, 100%))
|
let to-float(x) = if type(x) == angle { x.rad() } else { float(x) }
|
||||||
#test-repr(oklch(10%, 0.2, 90deg).components(), (10%, 0.2, 90deg, 100%))
|
let epsilon = 1e-4 // The maximum error between both numbers
|
||||||
#test-repr(oklab(10%, 50%, 75%).components(), (10%, 0.2, 0.3, 100%))
|
assert.eq(type(a), type(b))
|
||||||
#test-repr(oklch(10%, 50%, 90deg).components(), (10%, 0.2, 90deg, 100%))
|
calc.abs(to-float(a) - to-float(b)) < epsilon
|
||||||
#test-repr(color.linear-rgb(10%, 20%, 30%).components(), (10%, 20%, 30%, 100%))
|
}
|
||||||
#test-repr(color.hsv(10deg, 20%, 30%).components(), (10deg, 20%, 30%, 100%))
|
|
||||||
#test-repr(color.hsl(10deg, 20%, 30%).components(), (10deg, 20%, 30%, 100%))
|
let ref-without-alpha = if has-alpha { ref.slice(0, -1) } else { ref }
|
||||||
|
assert.eq(col.components().len(), ref.len())
|
||||||
|
assert(col.components().zip(ref).all(are-equal))
|
||||||
|
assert(col.components(alpha: false).zip(ref-without-alpha).all(are-equal))
|
||||||
|
}
|
||||||
|
#test-components(rgb(1, 2, 3, 4), (0.39%, 0.78%, 1.18%, 1.57%))
|
||||||
|
#test-components(luma(40), (15.69%, 100%))
|
||||||
|
#test-components(luma(40, 50%), (15.69%, 50%))
|
||||||
|
#test-components(cmyk(4%, 5%, 6%, 7%), (4%, 5%, 6%, 7%), has-alpha: false)
|
||||||
|
#test-components(oklab(10%, 0.2, 0.4), (10%, 0.2, 0.4, 100%))
|
||||||
|
#test-components(oklch(10%, 0.2, 90deg), (10%, 0.2, 90deg, 100%))
|
||||||
|
#test-components(oklab(10%, 50%, 200%), (10%, 0.2, 0.8, 100%))
|
||||||
|
#test-components(oklch(10%, 50%, 90deg), (10%, 0.2, 90deg, 100%))
|
||||||
|
#test-components(color.linear-rgb(10%, 20%, 30%), (10%, 20%, 30%, 100%))
|
||||||
|
#test-components(color.hsv(10deg, 20%, 30%), (10deg, 20%, 30%, 100%))
|
||||||
|
#test-components(color.hsl(10deg, 20%, 30%), (10deg, 20%, 30%, 100%))
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test color conversions.
|
// Test color conversions.
|
||||||
@ -144,9 +159,9 @@
|
|||||||
#test(rgb(1, 2, 3, 4).to-hex(), "#01020304")
|
#test(rgb(1, 2, 3, 4).to-hex(), "#01020304")
|
||||||
#test(luma(40).to-hex(), "#282828")
|
#test(luma(40).to-hex(), "#282828")
|
||||||
#test-repr(cmyk(4%, 5%, 6%, 7%).to-hex(), "#e0dcda")
|
#test-repr(cmyk(4%, 5%, 6%, 7%).to-hex(), "#e0dcda")
|
||||||
#test-repr(rgb(cmyk(4%, 5%, 6%, 7%)).components(), (87.84%, 86.27%, 85.49%, 100%))
|
#test-repr(rgb(cmyk(4%, 5%, 6%, 7%)), rgb(87.84%, 86.27%, 85.49%, 100%))
|
||||||
#test-repr(rgb(luma(40%)).components(alpha: false), (40%, 40%, 40%))
|
#test-repr(rgb(luma(40%)), rgb(40%, 40%, 40%))
|
||||||
#test-repr(cmyk(luma(40)).components(), (11.76%, 10.67%, 10.51%, 14.12%))
|
#test-repr(cmyk(luma(40)), cmyk(11.76%, 10.67%, 10.51%, 14.12%))
|
||||||
#test-repr(cmyk(rgb(1, 2, 3)), cmyk(66.67%, 33.33%, 0%, 98.82%))
|
#test-repr(cmyk(rgb(1, 2, 3)), cmyk(66.67%, 33.33%, 0%, 98.82%))
|
||||||
#test-repr(luma(rgb(1, 2, 3)), luma(0.73%))
|
#test-repr(luma(rgb(1, 2, 3)), luma(0.73%))
|
||||||
#test-repr(color.hsl(luma(40)), color.hsl(0deg, 0%, 15.69%))
|
#test-repr(color.hsl(luma(40)), color.hsl(0deg, 0%, 15.69%))
|
||||||
@ -155,11 +170,11 @@
|
|||||||
#test-repr(color.linear-rgb(rgb(1, 2, 3)), color.linear-rgb(0.03%, 0.06%, 0.09%))
|
#test-repr(color.linear-rgb(rgb(1, 2, 3)), color.linear-rgb(0.03%, 0.06%, 0.09%))
|
||||||
#test-repr(color.hsl(rgb(1, 2, 3)), color.hsl(-150deg, 50%, 0.78%))
|
#test-repr(color.hsl(rgb(1, 2, 3)), color.hsl(-150deg, 50%, 0.78%))
|
||||||
#test-repr(color.hsv(rgb(1, 2, 3)), color.hsv(-150deg, 66.67%, 1.18%))
|
#test-repr(color.hsv(rgb(1, 2, 3)), color.hsv(-150deg, 66.67%, 1.18%))
|
||||||
#test-repr(oklab(luma(40)).components(), (27.68%, 0.0, 0.0, 100%))
|
#test-repr(oklab(luma(40)), oklab(27.68%, 0.0, 0.0, 100%))
|
||||||
#test-repr(oklab(rgb(1, 2, 3)).components(), (8.23%, -0.004, -0.007, 100%))
|
#test-repr(oklab(rgb(1, 2, 3)), oklab(8.23%, -0.004, -0.007, 100%))
|
||||||
#test-repr(oklch(oklab(40%, 0.2, 0.2)).components(), (40%, 0.283, 45deg, 100%))
|
#test-repr(oklch(oklab(40%, 0.2, 0.2)), oklch(40%, 0.283, 45deg, 100%))
|
||||||
#test-repr(oklch(luma(40)).components(), (27.68%, 0.0, 72.49deg, 100%))
|
#test-repr(oklch(luma(40)), oklch(27.68%, 0.0, 72.49deg, 100%))
|
||||||
#test-repr(oklch(rgb(1, 2, 3)).components(), (8.23%, 0.008, 240.75deg, 100%))
|
#test-repr(oklch(rgb(1, 2, 3)), oklch(8.23%, 0.008, 240.75deg, 100%))
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test gradient functions.
|
// Test gradient functions.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user