AI import: gradient stops listed upwards aren't reversed, so a midpoint stays on the stop that starts its part of the ramp

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EricKuck 2026-10-12 18:27:47 -04:00 committed by bflatastic
parent 5203f4f047
commit 48d5bd1aee
2 changed files with 18 additions and 2 deletions

View File

@ -158,8 +158,11 @@ impl GradientDef {
if self.gradient.stops.is_empty() {
return None;
}
// Stops come last first: reversed, stops sharing a ramp point keep their order.
self.gradient.stops.reverse();
// Stops are listed along the ramp from either end: listed downwards they're reversed, so
// stops sharing a ramp point keep their order (and each its midpoint, to the next stop).
if self.gradient.stops.first().zip(self.gradient.stops.last()).is_some_and(|(first, last)| first.offset > last.offset) {
self.gradient.stops.reverse();
}
self.gradient.stops.sort_by(|a, b| a.offset.total_cmp(&b.offset));
Some((self.name, self.gradient))
}

View File

@ -410,6 +410,19 @@ fn stops_sharing_a_ramp_point_keep_their_order() {
assert_eq!(colors, [Color::rgb(0.0, 0.0, 1.0), Color::rgb(0.0, 1.0, 0.0), Color::rgb(1.0, 0.0, 0.0)]);
}
#[test]
fn stops_listed_upwards_keep_the_midpoint_of_the_one_that_starts_the_ramp() {
// GUARDS: reversing a list that runs upwards swaps two stops at 0, and the ramp to 100 takes the
// midpoint of the zero-length part between them.
let defs = "%AI5_BeginGradient: (U)\n(U) 0 3 Bd\n[\n<00FF>\n0\n%_0 0 0 0 1 1 1 2 1 6 50 0 Bs\n\
%_0 0 0 0 1 1 1 2 1 6 87 0 Bs\n%_0 0 0 0 0 0 0 2 1 6 50 100 Bs\nBD\n%AI5_EndGradient\n";
let art_ = format!("{}Bb\n1 (U) 0 0 0 1 1 0 0 1 0 0 1 Bg\n10 0 0 10 100 50 Xm\nf\n0 BB\n", rect_path(0.0, 0.0, 200.0, 100.0));
let doc = read_ok(&format!("{defs}{}", layer(&art_))).doc;
let Paint::Gradient(g) = fill(&art(&doc)[0]) else { panic!() };
let midpoints: Vec<_> = g.gradient.stops.iter().map(|s| s.midpoint).collect();
assert_eq!(midpoints, [0.5, 0.87, 0.5]);
}
#[test]
fn per_anchor_data_reads() {
let art_ = format!("{RED}{}f\n(00800080) Xt 0 XD\n%_(00004000) Xt 1 XD\n", rect_path(0.0, 0.0, 10.0, 10.0));