summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author+merlan #flirora <flirora@flirora.xyz>2025-02-12 07:38:40 -0500
committerGitHub <noreply@github.com>2025-02-12 12:38:40 +0000
commit02cd43e27f2aafd7c332d7672a837e1b11cce120 (patch)
treee6165259b163ef8364c45645f8b03d507f8e7e63
parent83ad407d3ccff4a8de1e7ffe198bfed874f5c0c7 (diff)
`Gradient::repeat`: Fix floating-point error in stop calculation (#5837)
-rw-r--r--crates/typst-library/src/visualize/gradient.rs7
-rw-r--r--tests/suite/visualize/gradient.typ8
2 files changed, 11 insertions, 4 deletions
diff --git a/crates/typst-library/src/visualize/gradient.rs b/crates/typst-library/src/visualize/gradient.rs
index 431f07dd..d6530dd0 100644
--- a/crates/typst-library/src/visualize/gradient.rs
+++ b/crates/typst-library/src/visualize/gradient.rs
@@ -582,12 +582,11 @@ impl Gradient {
let mut stops = stops
.iter()
.map(move |&(color, offset)| {
- let t = i as f64 / n as f64;
let r = offset.get();
if i % 2 == 1 && mirror {
- (color, Ratio::new(t + (1.0 - r) / n as f64))
+ (color, Ratio::new((i as f64 + 1.0 - r) / n as f64))
} else {
- (color, Ratio::new(t + r / n as f64))
+ (color, Ratio::new((i as f64 + r) / n as f64))
}
})
.collect::<Vec<_>>();
@@ -1230,7 +1229,7 @@ fn process_stops(stops: &[Spanned<GradientStop>]) -> SourceResult<Vec<(Color, Ra
};
if stop.get() < last_stop {
- bail!(*span, "offsets must be in strictly monotonic order");
+ bail!(*span, "offsets must be in monotonic order");
}
last_stop = stop.get();
diff --git a/tests/suite/visualize/gradient.typ b/tests/suite/visualize/gradient.typ
index b221f411..811b8b60 100644
--- a/tests/suite/visualize/gradient.typ
+++ b/tests/suite/visualize/gradient.typ
@@ -658,3 +658,11 @@ $ A = mat(
height: 10pt,
fill: gradient.linear(violet, blue, space: cmyk)
)
+
+--- issue-5819-gradient-repeat ---
+// Ensure the gradient constructor generates monotonic stops which can be fed
+// back into the gradient constructor itself.
+#let my-gradient = gradient.linear(red, blue).repeat(5)
+#let _ = gradient.linear(..my-gradient.stops())
+#let my-gradient2 = gradient.linear(red, blue).repeat(5, mirror: true)
+#let _ = gradient.linear(..my-gradient2.stops())