Make gradient evaluation follow the ramp's interpolation space attribute (#4414)

This commit is contained in:
Keavon Chambers
2026-09-15 14:39:40 +02:00
committed by Dennis Kobert
parent a43b3eaa00
commit 11436cfc80
7 changed files with 52 additions and 34 deletions
@@ -37,13 +37,16 @@ mod blend_std {
}
impl Blend<Color> for Gradient {
// TODO: This joining is unfaithful in several ways: it samples only at stop positions so midpoint curves flatten away;
// it evaluates both sources with the default spread and interpolation rather than their own attributes (which this
// element-level impl cannot read); and the output keeps over's attributes despite being sampled in the default space
fn blend(&self, under: &Self, blend_fn: impl Fn(Color, Color) -> Color) -> Self {
let mut combined_stops = self.positions().into_iter().chain(under.positions()).collect::<Vec<_>>();
combined_stops.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
combined_stops.dedup_by(|a, b| (*a - *b).abs() < 1e-6);
let stops = combined_stops.into_iter().map(|position| {
let over_color = self.evaluate(position, Default::default());
let under_color = under.evaluate(position, Default::default());
let over_color = self.evaluate(position, Default::default(), Default::default());
let under_color = under.evaluate(position, Default::default(), Default::default());
let color = blend_fn(over_color, under_color);
GradientStop { position, midpoint: 0.5, color }
});