Bug 1374233 - Part 12: Implement ToAnimatedValue for LineHeight. draft
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 24 Jul 2017 17:25:47 +0800
changeset 615003 3321c2b8ddb7d5c80c960906e1499fa339788cc6
parent 615002 08021c6fe85f8410f739deb72cef6bded7841b70
child 615004 2e2639f238bef340aa2f66db95c7bf4edf4dd0a2
push id70205
push userbmo:boris.chiou@gmail.com
push dateTue, 25 Jul 2017 08:53:17 +0000
bugs1374233
milestone56.0a1
Bug 1374233 - Part 12: Implement ToAnimatedValue for LineHeight. Besides, we replace its type with GenericLineHeight<NonNegativeNumber, NonNegativeAu>. MozReview-Commit-ID: GGOGXyUFJsJ
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/helpers/animated_properties.mako.rs
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/components/style/values/computed/text.rs
servo/components/style/values/specified/text.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -4047,30 +4047,31 @@ fn static_assert() {
         longhands::text_shadow::computed_value::T(buf)
     }
 
     pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
         use values::generics::text::LineHeight;
         // FIXME: Align binary representations and ditch |match| for cast + static_asserts
         let en = match v {
             LineHeight::Normal => CoordDataValue::Normal,
-            LineHeight::Length(val) => CoordDataValue::Coord(val.0),
-            LineHeight::Number(val) => CoordDataValue::Factor(val),
+            LineHeight::Length(val) => CoordDataValue::Coord(val.value()),
+            LineHeight::Number(val) => CoordDataValue::Factor(val.0),
             LineHeight::MozBlockHeight =>
                     CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
         };
         self.gecko.mLineHeight.set_value(en);
     }
 
     pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
+        use values::computed::NonNegativeNumber;
         use values::generics::text::LineHeight;
         return match self.gecko.mLineHeight.as_value() {
             CoordDataValue::Normal => LineHeight::Normal,
-            CoordDataValue::Coord(coord) => LineHeight::Length(Au(coord)),
-            CoordDataValue::Factor(n) => LineHeight::Number(n),
+            CoordDataValue::Coord(coord) => LineHeight::Length(NonNegativeAu(Au(coord))),
+            CoordDataValue::Factor(n) => LineHeight::Number(NonNegativeNumber(n)),
             CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
                 LineHeight::MozBlockHeight,
             _ => panic!("this should not happen"),
         }
     }
 
     <%call expr="impl_coord_copy('line_height', 'mLineHeight')"></%call>
 
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -16,16 +16,17 @@ use euclid::{Point2D, Size2D};
 #[cfg(feature = "gecko")] use gecko_string_cache::Atom;
 use properties::{CSSWideKeyword, PropertyDeclaration};
 use properties::longhands;
 use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
 use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
 use properties::longhands::font_weight::computed_value::T as FontWeight;
 use properties::longhands::font_size_adjust::computed_value::T as FontSizeAdjust;
 use properties::longhands::font_stretch::computed_value::T as FontStretch;
+use properties::longhands::line_height::computed_value::T as LineHeight;
 use properties::longhands::stroke_dasharray::computed_value::T as StrokeDasharray;
 use properties::longhands::transform::computed_value::ComputedMatrix;
 use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
 use properties::longhands::transform::computed_value::T as TransformList;
 use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
 use properties::longhands::visibility::computed_value::T as Visibility;
 #[cfg(feature = "gecko")] use properties::{PropertyId, PropertyDeclarationId, LonghandId};
 #[cfg(feature = "gecko")] use properties::{ShorthandId};
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -4,17 +4,17 @@
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Keyword %>
 <% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
 
 ${helpers.predefined_type("line-height",
                           "LineHeight",
                           "computed::LineHeight::normal()",
-                          animation_value_type="ComputedValue",
+                          animation_value_type="LineHeight",
                           flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
                           spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height")}
 
 // CSS Text Module Level 3
 
 // TODO(pcwalton): `full-width`
 ${helpers.single_keyword("text-transform",
                          "none capitalize uppercase lowercase",
--- a/servo/components/style/values/computed/text.rs
+++ b/servo/components/style/values/computed/text.rs
@@ -1,34 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Computed types for text properties.
 
-use app_units::Au;
 use properties::animated_properties::Animatable;
 use values::{CSSInteger, CSSFloat};
-use values::animated::ToAnimatedZero;
+use values::animated::{ToAnimatedValue, ToAnimatedZero};
+use values::computed::{NonNegativeAu, NonNegativeNumber};
 use values::computed::length::{Length, LengthOrPercentage};
 use values::generics::text::InitialLetter as GenericInitialLetter;
 use values::generics::text::LineHeight as GenericLineHeight;
 use values::generics::text::Spacing;
 
 /// A computed value for the `initial-letter` property.
 pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
 
 /// A computed value for the `letter-spacing` property.
 pub type LetterSpacing = Spacing<Length>;
 
 /// A computed value for the `word-spacing` property.
 pub type WordSpacing = Spacing<LengthOrPercentage>;
 
 /// A computed value for the `line-height` property.
-pub type LineHeight = GenericLineHeight<CSSFloat, Au>;
+pub type LineHeight = GenericLineHeight<NonNegativeNumber, NonNegativeAu>;
 
 impl Animatable for LineHeight {
     #[inline]
     fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
         match (*self, *other) {
             (GenericLineHeight::Length(ref this), GenericLineHeight::Length(ref other)) => {
                 this.add_weighted(other, self_portion, other_portion).map(GenericLineHeight::Length)
             },
@@ -62,8 +62,30 @@ impl Animatable for LineHeight {
         }
     }
 }
 
 impl ToAnimatedZero for LineHeight {
     #[inline]
     fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
 }
+
+impl ToAnimatedValue for LineHeight {
+    type AnimatedValue = Self;
+
+    #[inline]
+    fn to_animated_value(self) -> Self {
+        self
+    }
+
+    #[inline]
+    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
+        match animated {
+            GenericLineHeight::Length(len) => {
+                GenericLineHeight::Length(ToAnimatedValue::from_animated_value(len))
+            },
+            GenericLineHeight::Number(number) =>{
+                GenericLineHeight::Number(ToAnimatedValue::from_animated_value(number))
+            },
+            _ => animated
+        }
+    }
+}
--- a/servo/components/style/values/specified/text.rs
+++ b/servo/components/style/values/specified/text.rs
@@ -4,35 +4,36 @@
 
 //! Specified types for text properties.
 
 use cssparser::Parser;
 use parser::{Parse, ParserContext};
 use selectors::parser::SelectorParseError;
 use std::ascii::AsciiExt;
 use style_traits::ParseError;
-use values::computed::{Context, ToComputedValue};
+use values::computed::{Context, NonNegativeAu, ToComputedValue};
 use values::computed::text::LineHeight as ComputedLineHeight;
 use values::generics::text::InitialLetter as GenericInitialLetter;
 use values::generics::text::LineHeight as GenericLineHeight;
 use values::generics::text::Spacing;
-use values::specified::{AllowQuirks, Integer, Number};
+use values::specified::{AllowQuirks, Integer, NonNegativeNumber, Number};
 use values::specified::length::{FontRelativeLength, Length, LengthOrPercentage, NoCalcLength};
+use values::specified::length::NonNegativeLengthOrPercentage;
 
 /// A specified type for the `initial-letter` property.
 pub type InitialLetter = GenericInitialLetter<Number, Integer>;
 
 /// A specified value for the `letter-spacing` property.
 pub type LetterSpacing = Spacing<Length>;
 
 /// A specified value for the `word-spacing` property.
 pub type WordSpacing = Spacing<LengthOrPercentage>;
 
 /// A specified value for the `line-height` property.
-pub type LineHeight = GenericLineHeight<Number, LengthOrPercentage>;
+pub type LineHeight = GenericLineHeight<NonNegativeNumber, NonNegativeLengthOrPercentage>;
 
 impl Parse for InitialLetter {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
             return Ok(GenericInitialLetter::Normal);
         }
         let size = Number::parse_at_least_one(context, input)?;
         let sink = input.try(|i| Integer::parse_positive(context, i)).ok();
@@ -54,20 +55,20 @@ impl Parse for WordSpacing {
             LengthOrPercentage::parse_quirky(c, i, AllowQuirks::Yes)
         })
     }
 }
 
 impl Parse for LineHeight {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         if let Ok(number) = input.try(|i| Number::parse_non_negative(context, i)) {
-            return Ok(GenericLineHeight::Number(number))
+            return Ok(GenericLineHeight::Number(NonNegativeNumber(number)))
         }
         if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
-            return Ok(GenericLineHeight::Length(lop))
+            return Ok(GenericLineHeight::Length(NonNegativeLengthOrPercentage(lop)))
         }
         let ident = input.expect_ident()?;
         match ident {
             ref ident if ident.eq_ignore_ascii_case("normal") => {
                 Ok(GenericLineHeight::Normal)
             },
             #[cfg(feature = "gecko")]
             ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => {
@@ -89,50 +90,56 @@ impl ToComputedValue for LineHeight {
             },
             #[cfg(feature = "gecko")]
             GenericLineHeight::MozBlockHeight => {
                 GenericLineHeight::MozBlockHeight
             },
             GenericLineHeight::Number(number) => {
                 GenericLineHeight::Number(number.to_computed_value(context))
             },
-            GenericLineHeight::Length(LengthOrPercentage::Length(ref length)) => {
-                GenericLineHeight::Length(length.to_computed_value(context))
-            },
-            GenericLineHeight::Length(LengthOrPercentage::Percentage(p)) => {
-                let font_relative_length =
-                    Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(p.0)));
-                GenericLineHeight::Length(font_relative_length.to_computed_value(context))
-            },
-            GenericLineHeight::Length(LengthOrPercentage::Calc(ref calc)) => {
-                let computed_calc = calc.to_computed_value(context);
-                let font_relative_length =
-                    Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(computed_calc.percentage())));
-                let absolute_length = computed_calc.unclamped_length();
-                let computed_length = computed_calc.clamping_mode.clamp(
-                    absolute_length + font_relative_length.to_computed_value(context)
-                );
-                GenericLineHeight::Length(computed_length)
-            },
+            GenericLineHeight::Length(ref non_negative_lop) => {
+                let result = match non_negative_lop.0 {
+                    LengthOrPercentage::Length(ref len) => {
+                        len.to_computed_value(context)
+                    },
+                    LengthOrPercentage::Percentage(ref p) => {
+                        let font_relative_length =
+                            Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(p.0)));
+                        font_relative_length.to_computed_value(context)
+                    }
+                    LengthOrPercentage::Calc(ref calc) => {
+                        let computed_calc = calc.to_computed_value(context);
+                        let font_relative_length =
+                            Length::NoCalc(NoCalcLength::FontRelative(
+                                FontRelativeLength::Em(computed_calc.percentage())));
+                        let absolute_length = computed_calc.unclamped_length();
+                        computed_calc.clamping_mode.clamp(
+                            absolute_length + font_relative_length.to_computed_value(context)
+                        )
+                    }
+                };
+                GenericLineHeight::Length(NonNegativeAu(result))
+            }
         }
     }
 
     #[inline]
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         match *computed {
             GenericLineHeight::Normal => {
                 GenericLineHeight::Normal
             },
             #[cfg(feature = "gecko")]
             GenericLineHeight::MozBlockHeight => {
                 GenericLineHeight::MozBlockHeight
             },
             GenericLineHeight::Number(ref number) => {
-                GenericLineHeight::Number(Number::from_computed_value(number))
+                GenericLineHeight::Number(NonNegativeNumber::from_computed_value(number))
             },
             GenericLineHeight::Length(ref length) => {
-                GenericLineHeight::Length(LengthOrPercentage::Length(
-                    NoCalcLength::from_computed_value(length)
+                GenericLineHeight::Length(
+                    NonNegativeLengthOrPercentage(
+                        LengthOrPercentage::Length(NoCalcLength::from_computed_value(&length.0))
                 ))
             }
         }
     }
 }