mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Add fix_gradient_stops function.
Render gradients where the last stop is the same position as the previous one like Chrome and Firefox do.
This commit is contained in:
parent
b230be8aaf
commit
f7f077c334
1 changed files with 31 additions and 3 deletions
|
@ -650,7 +650,8 @@ fn convert_gradient_stops(gradient_items: &[GradientItem],
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Evenly space stops without position.
|
// Step 3: Evenly space stops without position.
|
||||||
let mut stops = Vec::with_capacity(stop_items.len());
|
// Note: Remove the + 1 if fix_gradient_stops is changed.
|
||||||
|
let mut stops = Vec::with_capacity(stop_items.len() + 1);
|
||||||
let mut stop_run = None;
|
let mut stop_run = None;
|
||||||
for (i, stop) in stop_items.iter().enumerate() {
|
for (i, stop) in stop_items.iter().enumerate() {
|
||||||
let offset = match stop.position {
|
let offset = match stop.position {
|
||||||
|
@ -696,6 +697,25 @@ fn convert_gradient_stops(gradient_items: &[GradientItem],
|
||||||
stops
|
stops
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Duplicate the last stop if its position is smaller 100%.
|
||||||
|
///
|
||||||
|
/// Explanation by pyfisch:
|
||||||
|
/// If the last stop is at the same position as the previous stop the
|
||||||
|
/// last color is ignored by webrender. This differs from the spec
|
||||||
|
/// (I think so). The implementations of Chrome and Firefox seem
|
||||||
|
/// to have the same problem but work fine if the position of the last
|
||||||
|
/// stop is smaller than 100%. (Otherwise they ignore the last stop.)
|
||||||
|
fn fix_gradient_stops(stops: &mut Vec<GradientStop>) {
|
||||||
|
if stops.last().unwrap().offset < 1.0 {
|
||||||
|
let color = stops.last().unwrap().color;
|
||||||
|
stops.push(GradientStop {
|
||||||
|
offset: 1.0,
|
||||||
|
color: color,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the the distance to the nearest or farthest corner depending on the comperator.
|
/// Returns the the distance to the nearest or farthest corner depending on the comperator.
|
||||||
fn get_distance_to_corner<F>(size: &Size2D<Au>, center: &Point2D<Au>, cmp: F) -> Au
|
fn get_distance_to_corner<F>(size: &Size2D<Au>, center: &Point2D<Au>, cmp: F) -> Au
|
||||||
where F: Fn(Au, Au) -> Au
|
where F: Fn(Au, Au) -> Au
|
||||||
|
@ -1110,7 +1130,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let length = Au::from_f32_px(
|
let length = Au::from_f32_px(
|
||||||
(delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0));
|
(delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0));
|
||||||
|
|
||||||
let stops = convert_gradient_stops(stops, length, style);
|
let mut stops = convert_gradient_stops(stops, length, style);
|
||||||
|
if !repeating {
|
||||||
|
fix_gradient_stops(&mut stops);
|
||||||
|
}
|
||||||
|
|
||||||
let center = Point2D::new(bounds.size.width / 2, bounds.size.height / 2);
|
let center = Point2D::new(bounds.size.width / 2, bounds.size.height / 2);
|
||||||
|
|
||||||
|
@ -1145,7 +1168,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
=> convert_ellipse_size_keyword(word, &bounds.size, ¢er),
|
=> convert_ellipse_size_keyword(word, &bounds.size, ¢er),
|
||||||
};
|
};
|
||||||
let length = Au::from_f32_px(radius.width.to_f32_px().hypot(radius.height.to_f32_px()));
|
let length = Au::from_f32_px(radius.width.to_f32_px().hypot(radius.height.to_f32_px()));
|
||||||
let stops = convert_gradient_stops(stops, length, style);
|
|
||||||
|
let mut stops = convert_gradient_stops(stops, length, style);
|
||||||
|
if !repeating {
|
||||||
|
fix_gradient_stops(&mut stops);
|
||||||
|
}
|
||||||
|
|
||||||
display_list::RadialGradient {
|
display_list::RadialGradient {
|
||||||
center: center,
|
center: center,
|
||||||
radius: radius,
|
radius: radius,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue