Skip to content
Browse files

Handle overlapping gradient stops for linear gradients

From `addColorStop(offset, color)`s spec:
If multiple stops are added at the same offset on a gradient, they must
be placed in the order added, with the first one closest to the start of
the gradient, and each subsequent one infinitesimally further along
towards the end point (in effect causing all but the first and last stop
added at each point to be ignored)
  • Loading branch information
pylbrecht committed Dec 7, 2019
1 parent 04e9523 commit 1cdcbb25fa990cbeb773798ea6c872df4d2bcda6
Showing with 10 additions and 3 deletions.
  1. +10 −3 components/canvas/
@@ -243,15 +243,19 @@ impl GenericDrawTarget for raqote::DrawTarget {
raqote::DrawTarget::copy_surface(self, &dt, source.to_box2d(), destination);
// TODO(pylbrecht)
// unused code?
fn create_gradient_stops(
gradient_stops: Vec<GradientStop>,
_extend_mode: ExtendMode,
) -> GradientStops {
let stops = gradient_stops
let mut stops = gradient_stops
.map(|item| item.as_raqote().clone())
stops.sort_by(|a, b| a.position.partial_cmp(&b.position).unwrap());
fn create_path_builder(&self) -> Box<dyn GenericPathBuilder> {
@@ -730,7 +734,10 @@ impl<'a> ToRaqoteSource<'a> for FillOrStrokeStyle {,
LinearGradient(style) => {
let stops = style.stops.into_iter().map(|s| s.to_raqote()).collect();
let mut stops: Vec<raqote::GradientStop> =
style.stops.into_iter().map(|s| s.to_raqote()).collect();
stops.sort_by(|a, b| a.position.partial_cmp(&b.position).unwrap());
let mut gradient = raqote::Gradient { stops };
let start = Point2D::new(style.x0 as f32, style.y0 as f32);
let end = Point2D::new(style.x1 as f32, style.y1 as f32);

0 comments on commit 1cdcbb2

Please sign in to comment.
You can’t perform that action at this time.