summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrozolotl <44589151+frozolotl@users.noreply.github.com>2023-11-13 15:48:54 +0100
committerGitHub <noreply@github.com>2023-11-13 15:48:54 +0100
commitd16ab29068552584879902562e41d0e95f328179 (patch)
treefde4e45f77896a110de2a1c4cda4a201e43b37b9
parent67422e664b9e7089e8eb4de65c5a25b2817a00c0 (diff)
Make Oklab and Oklch chroma ratios relative to 0.4 (#2642)
-rw-r--r--crates/typst/src/geom/color.rs35
-rw-r--r--tests/typ/compiler/methods.typ2
2 files changed, 22 insertions, 15 deletions
diff --git a/crates/typst/src/geom/color.rs b/crates/typst/src/geom/color.rs
index ab827c19..3c86a306 100644
--- a/crates/typst/src/geom/color.rs
+++ b/crates/typst/src/geom/color.rs
@@ -295,8 +295,10 @@ impl Color {
/// A linear Oklab color is represented internally by an array of four
/// components:
/// - lightness ([`ratio`]($ratio))
- /// - a ([`float`]($float) in the range `[-0.4..0.4]`)
- /// - b ([`float`]($float) in the range `[-0.4..0.4]`)
+ /// - a ([`float`]($float) in the range `[-0.4..0.4]`
+ /// or [`ratio`]($ratio) in the range `[-100%..100%]`)
+ /// - b ([`float`]($float) in the range `[-0.4..0.4]`
+ /// or [`ratio`]($ratio) in the range `[-100%..100%]`)
/// - alpha ([`ratio`]($ratio))
///
/// These components are also available using the
@@ -317,10 +319,10 @@ impl Color {
lightness: RatioComponent,
/// The a ("green/red") component.
#[external]
- a: ABComponent,
+ a: ChromaComponent,
/// The b ("blue/yellow") component.
#[external]
- b: ABComponent,
+ b: ChromaComponent,
/// The alpha component.
#[external]
alpha: RatioComponent,
@@ -334,8 +336,8 @@ impl Color {
color.to_oklab()
} else {
let RatioComponent(l) = args.expect("lightness component")?;
- let ABComponent(a) = args.expect("A component")?;
- let ABComponent(b) = args.expect("B component")?;
+ let ChromaComponent(a) = args.expect("A component")?;
+ let ChromaComponent(b) = args.expect("B component")?;
let RatioComponent(alpha) =
args.eat()?.unwrap_or(RatioComponent(Ratio::one()));
Self::Oklab(Oklab::new(
@@ -357,7 +359,8 @@ impl Color {
/// A linear Oklch color is represented internally by an array of four
/// components:
/// - lightness ([`ratio`]($ratio))
- /// - chroma ([`float`]($float) in the range `[-0.4..0.4]`)
+ /// - chroma ([`float`]($float) in the range `[0.0..0.4]`
+ /// or [`ratio`]($ratio) in the range `[0%..100%]`)
/// - hue ([`angle`]($angle))
/// - alpha ([`ratio`]($ratio))
///
@@ -379,7 +382,7 @@ impl Color {
lightness: RatioComponent,
/// The chroma component.
#[external]
- chroma: ABComponent,
+ chroma: ChromaComponent,
/// The hue component.
#[external]
hue: Angle,
@@ -396,7 +399,7 @@ impl Color {
color.to_oklch()
} else {
let RatioComponent(l) = args.expect("lightness component")?;
- let ABComponent(c) = args.expect("chroma component")?;
+ let ChromaComponent(c) = args.expect("chroma component")?;
let h: Angle = args.expect("hue component")?;
let RatioComponent(alpha) =
args.eat()?.unwrap_or(RatioComponent(Ratio::one()));
@@ -1730,15 +1733,17 @@ cast! {
},
}
-/// A component that must be a ratio between -40% and 40%.
-pub struct ABComponent(Ratio);
+/// A component that must either be a value between:
+/// - -100% and 100%, in which case it is relative to 0.4.
+/// - -0.4 and 0.4, in which case it is taken literally.
+pub struct ChromaComponent(Ratio);
cast! {
- ABComponent,
- v: Ratio => if (-0.4 ..= 0.4).contains(&v.get()) {
- Self(v)
+ ChromaComponent,
+ v: Ratio => if (-1.0 ..= 1.0).contains(&v.get()) {
+ Self(v * 0.4)
} else {
- bail!("ratio must be between -40% and 40%");
+ bail!("ratio must be between -100% and 100%");
},
v: f64 => if (-0.4 ..= 0.4).contains(&v) {
Self(Ratio::new(v))
diff --git a/tests/typ/compiler/methods.typ b/tests/typ/compiler/methods.typ
index 0ae17ae7..4c483786 100644
--- a/tests/typ/compiler/methods.typ
+++ b/tests/typ/compiler/methods.typ
@@ -109,6 +109,8 @@
#test-repr(cmyk(4%, 5%, 6%, 7%).components(), (4%, 5%, 6%, 7%))
#test-repr(oklab(10%, 0.2, 0.3).components(), (10%, 0.2, 0.3, 100%))
#test-repr(oklch(10%, 0.2, 90deg).components(), (10%, 0.2, 90deg, 100%))
+#test-repr(oklab(10%, 50%, 75%).components(), (10%, 0.2, 0.3, 100%))
+#test-repr(oklch(10%, 50%, 90deg).components(), (10%, 0.2, 90deg, 100%))
#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%))