From 113778afaf2a6210f55537206aa181c82a78a32c Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 20 Oct 2015 13:20:56 +1000 Subject: [PATCH] Fix start and end points for linear gradients with angle specified. Previously, this was most noticeable with 45deg gradients, where the gradient would end too early, and the remainder was filled with a solid color. (This also fixes gradients on webrender, which relies on the start and stop points being correct). --- components/layout/display_list_builder.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 299f0155e4d..6f52f90b9cf 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -555,10 +555,17 @@ impl FragmentDisplayListBuilding for Fragment { // between the starting point and the ending point. let delta = match gradient.angle_or_corner { AngleOrCorner::Angle(angle) => { - Point2D::new(Au::from_f32_px(angle.radians().sin() * - absolute_bounds.size.width.to_f32_px() / 2.0), - Au::from_f32_px(-angle.radians().cos() * - absolute_bounds.size.height.to_f32_px() / 2.0)) + // Get correct gradient line length, based on: + // https://drafts.csswg.org/css-images-3/#linear-gradients + let dir = Point2D::new(angle.radians().sin(), -angle.radians().cos()); + + let line_length = (dir.x * absolute_bounds.size.width.to_f32_px()).abs() + + (dir.y * absolute_bounds.size.height.to_f32_px()).abs(); + + let inv_dir_length = 1.0 / (dir.x * dir.x + dir.y * dir.y).sqrt(); + + Point2D::new(Au::from_f32_px(dir.x * inv_dir_length * line_length / 2.0), + Au::from_f32_px(dir.y * inv_dir_length * line_length / 2.0)) } AngleOrCorner::Corner(horizontal, vertical) => { let x_factor = match horizontal {