From e338bd3addaa996fcaa179bd9a0c8f708fd01955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 17 Aug 2018 20:26:29 +0200 Subject: [PATCH] style: Serialize clip-path and shape-outside using Servo. Differential Revision: https://phabricator.services.mozilla.com/D3653 --- components/style/gecko/conversions.rs | 112 +++++++++++++-------- components/style/values/computed/border.rs | 16 +++ 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 154ad95bc43..3c1fcde28cd 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -19,6 +19,7 @@ use stylesheets::{Origin, RulesMutateError}; use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto}; use values::computed::{Percentage, TextAlign}; +use values::computed::image::LineDirection; use values::computed::url::ComputedImageUrl; use values::generics::box_::VerticalAlign; use values::generics::grid::{TrackListValue, TrackSize}; @@ -139,6 +140,68 @@ impl Angle { } } +fn line_direction( + horizontal: LengthOrPercentage, + vertical: LengthOrPercentage, +) -> LineDirection { + use values::computed::position::Position; + use values::specified::position::{X, Y}; + + let horizontal_percentage = match horizontal { + LengthOrPercentage::Percentage(percentage) => Some(percentage.0), + _ => None, + }; + + let vertical_percentage = match vertical { + LengthOrPercentage::Percentage(percentage) => Some(percentage.0), + _ => None, + }; + + let horizontal_as_corner = horizontal_percentage.and_then(|percentage| { + if percentage == 0.0 { + Some(X::Left) + } else if percentage == 1.0 { + Some(X::Right) + } else { + None + } + }); + + let vertical_as_corner = vertical_percentage.and_then(|percentage| { + if percentage == 0.0 { + Some(Y::Top) + } else if percentage == 1.0 { + Some(Y::Bottom) + } else { + None + } + }); + + if let (Some(hc), Some(vc)) = (horizontal_as_corner, vertical_as_corner) { + return LineDirection::Corner(hc, vc) + } + + if let Some(hc) = horizontal_as_corner { + if vertical_percentage == Some(0.5) { + return LineDirection::Horizontal(hc) + } + } + + if let Some(vc) = vertical_as_corner { + if horizontal_percentage == Some(0.5) { + return LineDirection::Vertical(vc) + } + } + + LineDirection::MozPosition( + Some(Position { + horizontal, + vertical, + }), + None, + ) +} + impl nsStyleImage { /// Set a given Servo `Image` value into this `nsStyleImage`. pub fn set(&mut self, image: Image) { @@ -174,13 +237,13 @@ impl nsStyleImage { } } + // FIXME(emilio): This is really complex, we should use cbindgen for this. fn set_gradient(&mut self, gradient: Gradient) { use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER; use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE; use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER; use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE; use self::structs::nsStyleCoord; - use values::computed::image::LineDirection; use values::generics::image::{Circle, Ellipse, EndingShape, GradientKind, ShapeExtent}; use values::specified::position::{X, Y}; @@ -437,12 +500,11 @@ impl nsStyleImage { use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE; use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER; use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE; - use values::computed::{Length, LengthOrPercentage}; + use values::computed::Length; use values::computed::image::LineDirection; use values::computed::position::Position; use values::generics::image::{Circle, ColorStop, CompatMode, Ellipse}; use values::generics::image::{EndingShape, GradientKind, ShapeExtent}; - use values::specified::position::{X, Y}; let gecko_gradient = bindings::Gecko_GetGradientImageValue(self) .as_ref() @@ -456,41 +518,7 @@ impl nsStyleImage { let line_direction = match (angle, horizontal_style, vertical_style) { (Some(a), None, None) => LineDirection::Angle(a), (None, Some(horizontal), Some(vertical)) => { - let horizontal_as_corner = match horizontal { - LengthOrPercentage::Percentage(percentage) => { - if percentage.0 == 0.0 { - Some(X::Left) - } else if percentage.0 == 1.0 { - Some(X::Right) - } else { - None - } - }, - _ => None, - }; - let vertical_as_corner = match vertical { - LengthOrPercentage::Percentage(percentage) => { - if percentage.0 == 0.0 { - Some(Y::Top) - } else if percentage.0 == 1.0 { - Some(Y::Bottom) - } else { - None - } - }, - _ => None, - }; - - match (horizontal_as_corner, vertical_as_corner) { - (Some(hc), Some(vc)) => LineDirection::Corner(hc, vc), - _ => LineDirection::MozPosition( - Some(Position { - horizontal, - vertical, - }), - None, - ), - } + line_direction(horizontal, vertical) }, (Some(_), Some(horizontal), Some(vertical)) => LineDirection::MozPosition( Some(Position { @@ -743,17 +771,15 @@ pub mod basic_shape { let r = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[1]); let b = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[2]); let l = LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[3]); - let round = (&other.mRadius).into(); + let round: BorderRadius = (&other.mRadius).into(); + let round = if round.all_zero() { None } else { Some(round) }; let rect = Rect::new( t.expect("inset() offset should be a length, percentage, or calc value"), r.expect("inset() offset should be a length, percentage, or calc value"), b.expect("inset() offset should be a length, percentage, or calc value"), l.expect("inset() offset should be a length, percentage, or calc value"), ); - GenericBasicShape::Inset(InsetRect { - rect: rect, - round: Some(round), - }) + GenericBasicShape::Inset(InsetRect { rect, round }) }, StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle { radius: (&other.mCoordinates[0]).into(), diff --git a/components/style/values/computed/border.rs b/components/style/values/computed/border.rs index cf97a96ad73..8c54aeba43b 100644 --- a/components/style/values/computed/border.rs +++ b/components/style/values/computed/border.rs @@ -81,3 +81,19 @@ impl ToAnimatedZero for BorderCornerRadius { Err(()) } } + +impl BorderRadius { + /// Returns whether all the values are `0px`. + pub fn all_zero(&self) -> bool { + fn all(corner: &BorderCornerRadius) -> bool { + fn is_zero(l: &LengthOrPercentage) -> bool { + *l == LengthOrPercentage::zero() + } + is_zero(corner.0.width()) && is_zero(corner.0.height()) + } + all(&self.top_left) && + all(&self.top_right) && + all(&self.bottom_left) && + all(&self.bottom_right) + } +}