Bug 1368610 - Part 4: Implements numeric field type properties animatable. r?hiro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 09 Jun 2017 18:25:07 +0900
changeset 591656 2dd576e14a12eb5d2ed89a7618ae67c61d5f1fc8
parent 591655 0e16bfda4e558fcba80e04cc4ed0e1b8472c8733
child 591657 001c2312048da9afafdef4e5b98317fff8b2eadc
push id63112
push userbmo:dakatsuka@mozilla.com
push dateFri, 09 Jun 2017 09:30:24 +0000
reviewershiro
bugs1368610
milestone55.0a1
Bug 1368610 - Part 4: Implements numeric field type properties animatable. r?hiro In this patch, implements following properties that consist numeric fields in Gecko: * border-image-repeat * -moz-box-ordinal-group * font-language-override * -moz-force-broken-image-icon * initial-letter * -webkit-text-stroke-width MozReview-Commit-ID: 9unwNX5fyjR
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/text.mako.rs
servo/components/style/properties/longhand/ui.mako.rs
servo/components/style/properties/longhand/xul.mako.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1012,38 +1012,55 @@ fn static_assert() {
 
     pub fn copy_border_image_outset_from(&mut self, other: &Self) {
         % for side in SIDES:
             self.gecko.mBorderImageOutset.data_at_mut(${side.index})
                 .copy_from(&other.gecko.mBorderImageOutset.data_at(${side.index}));
         % endfor
     }
 
+    <%
+    border_image_repeat_keywords = ["Stretch", "Repeat", "Round", "Space"]
+    %>
+
     pub fn set_border_image_repeat(&mut self, v: longhands::border_image_repeat::computed_value::T) {
         use properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
-        use gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH, NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT};
-        use gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_REPEAT_ROUND, NS_STYLE_BORDER_IMAGE_REPEAT_SPACE};
+        use gecko_bindings::structs;
 
         % for i, side in enumerate(["H", "V"]):
             let k = match v.${i} {
-                RepeatKeyword::Stretch => NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH,
-                RepeatKeyword::Repeat => NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT,
-                RepeatKeyword::Round => NS_STYLE_BORDER_IMAGE_REPEAT_ROUND,
-                RepeatKeyword::Space => NS_STYLE_BORDER_IMAGE_REPEAT_SPACE,
+                % for keyword in border_image_repeat_keywords:
+                RepeatKeyword::${keyword} => structs::NS_STYLE_BORDER_IMAGE_REPEAT_${keyword.upper()},
+                % endfor
             };
 
             self.gecko.mBorderImageRepeat${side} = k as u8;
         % endfor
     }
 
     pub fn copy_border_image_repeat_from(&mut self, other: &Self) {
         self.gecko.mBorderImageRepeatH = other.gecko.mBorderImageRepeatH;
         self.gecko.mBorderImageRepeatV = other.gecko.mBorderImageRepeatV;
     }
 
+    pub fn clone_border_image_repeat(&self) -> longhands::border_image_repeat::computed_value::T {
+        use properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
+        use gecko_bindings::structs;
+
+        % for side in ["H", "V"]:
+        let servo_${side.lower()} = match self.gecko.mBorderImageRepeat${side} as u32 {
+            % for keyword in border_image_repeat_keywords:
+            structs::NS_STYLE_BORDER_IMAGE_REPEAT_${keyword.upper()} => RepeatKeyword::${keyword},
+            % endfor
+            x => panic!("Found unexpected value in mBorderImageRepeat${side}: {:?}", x),
+        };
+        % endfor
+        longhands::border_image_repeat::computed_value::T(servo_h, servo_v)
+    }
+
     pub fn set_border_image_width(&mut self, v: longhands::border_image_width::computed_value::T) {
         use values::generics::border::BorderImageSideWidth;
 
         % for side in SIDES:
         match v.${side.index} {
             BorderImageSideWidth::Auto => {
                 self.gecko.mBorderImageWidth.data_at_mut(${side.index}).set_value(CoordDataValue::Auto)
             },
@@ -1800,20 +1817,17 @@ fn static_assert() {
 
     #[allow(non_snake_case)]
     pub fn copy__x_lang_from(&mut self, other: &Self) {
         unsafe {
             Gecko_nsStyleFont_CopyLangFrom(&mut self.gecko, &other.gecko);
         }
     }
 
-    pub fn set_font_language_override(&mut self, v: longhands::font_language_override::computed_value::T) {
-        self.gecko.mFont.languageOverride = v.0;
-    }
-    ${impl_simple_copy('font_language_override', 'mFont.languageOverride')}
+    <% impl_simple_type_with_conversion("font_language_override", "mFont.languageOverride") %>
 
     pub fn set_font_variant_alternates(&mut self, v: longhands::font_variant_alternates::computed_value::T) {
         self.gecko.mFont.variantAlternates = v.to_gecko_keyword()
     }
 
     #[allow(non_snake_case)]
     pub fn copy_font_variant_alternates_from(&mut self, other: &Self) {
         self.gecko.mFont.variantAlternates = other.gecko.mFont.variantAlternates;
@@ -3667,17 +3681,17 @@ fn static_assert() {
         self.clear_text_emphasis_style_if_string();
         if other.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_STRING as u8 {
             self.gecko.mTextEmphasisStyleString
                       .assign(&*other.gecko.mTextEmphasisStyleString)
         }
         self.gecko.mTextEmphasisStyle = other.gecko.mTextEmphasisStyle;
     }
 
-    <%call expr="impl_app_units('_webkit_text_stroke_width', 'mWebkitTextStrokeWidth', need_clone=False)"></%call>
+    <%call expr="impl_app_units('_webkit_text_stroke_width', 'mWebkitTextStrokeWidth', need_clone=True)"></%call>
 
     #[allow(non_snake_case)]
     pub fn set__moz_tab_size(&mut self, v: longhands::_moz_tab_size::computed_value::T) {
         use values::Either;
 
         match v {
             Either::Second(number) => {
                 self.gecko.mTabSize.set_value(CoordDataValue::Factor(number));
@@ -3769,16 +3783,28 @@ fn static_assert() {
         }
     }
 
     pub fn copy_initial_letter_from(&mut self, other: &Self) {
         self.gecko.mInitialLetterSize = other.gecko.mInitialLetterSize;
         self.gecko.mInitialLetterSink = other.gecko.mInitialLetterSink;
     }
 
+    pub fn clone_initial_letter(&self) -> longhands::initial_letter::computed_value::T {
+        use values::generics::text::InitialLetter;
+
+        if self.gecko.mInitialLetterSize == 0. && self.gecko.mInitialLetterSink == 0 {
+            InitialLetter::Normal
+        } else if self.gecko.mInitialLetterSize.floor() as i32 == self.gecko.mInitialLetterSink {
+            InitialLetter::Specified(self.gecko.mInitialLetterSize, None)
+        } else {
+            InitialLetter::Specified(self.gecko.mInitialLetterSize, Some(self.gecko.mInitialLetterSink))
+        }
+    }
+
     #[inline]
     pub fn has_underline(&self) -> bool {
         (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
     }
 
     #[inline]
     pub fn has_overline(&self) -> bool {
         (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
@@ -4322,32 +4348,32 @@ clip-path
             unsafe {
                 bindings::Gecko_CopyCounter${counter_property}sFrom(&mut self.gecko, &other.gecko)
             }
         }
     % endfor
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="UI" skip_longhands="-moz-force-broken-image-icon">
-    #[allow(non_snake_case)]
-    pub fn set__moz_force_broken_image_icon(&mut self, v: longhands::_moz_force_broken_image_icon::computed_value::T) {
-        self.gecko.mForceBrokenImageIcon = v.0 as u8;
-    }
-
-    ${impl_simple_copy("_moz_force_broken_image_icon", "mForceBrokenImageIcon")}
+    ${impl_simple_type_with_conversion("_moz_force_broken_image_icon", "mForceBrokenImageIcon")}
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="XUL"
                   skip_longhands="-moz-box-ordinal-group">
     #[allow(non_snake_case)]
     pub fn set__moz_box_ordinal_group(&mut self, v: i32) {
         self.gecko.mBoxOrdinal = v as u32;
     }
 
     ${impl_simple_copy("_moz_box_ordinal_group", "mBoxOrdinal")}
+
+    #[allow(non_snake_case)]
+    pub fn clone__moz_box_ordinal_group(&self) -> i32{
+        self.gecko.mBoxOrdinal as i32
+    }
 </%self:impl_trait>
 
 <%def name="define_ffi_struct_accessor(style_struct)">
 #[no_mangle]
 #[allow(non_snake_case, unused_variables)]
 pub unsafe extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values:
         ServoComputedValuesBorrowedOrNull) -> *const ${style_struct.gecko_ffi_name} {
     ComputedValues::arc_from_borrowed(&computed_values).unwrap().get_${style_struct.name_lower}().get_gecko()
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -207,17 +207,17 @@
 ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect",
     parse_method="parse_non_negative",
     initial_value="computed::LengthOrNumber::zero().into()",
     initial_specified_value="specified::LengthOrNumber::zero().into()",
     spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
     animation_value_type="none",
     boxed=True)}
 
-<%helpers:longhand name="border-image-repeat" animation_value_type="none"
+<%helpers:longhand name="border-image-repeat" animation_value_type="discrete"
                    spec="https://drafts.csswg.org/css-backgrounds/#border-image-repeat">
     use std::fmt;
     use style_traits::ToCss;
 
     no_viewport_percentage!(SpecifiedValue);
 
     pub mod computed_value {
         pub use super::RepeatKeyword;
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -1924,17 +1924,17 @@ https://drafts.csswg.org/css-fonts-4/#lo
     }
 
     /// normal | <feature-tag-value>#
     pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         computed_value::T::parse(context, input)
     }
 </%helpers:longhand>
 
-<%helpers:longhand name="font-language-override" products="gecko" animation_value_type="none"
+<%helpers:longhand name="font-language-override" products="gecko" animation_value_type="discrete"
                    extra_prefixes="moz" boxed="True"
                    spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override">
     use properties::longhands::system_font::SystemFont;
     use std::fmt;
     use style_traits::ToCss;
     use byteorder::{BigEndian, ByteOrder};
     no_viewport_percentage!(SpecifiedValue);
 
@@ -2061,16 +2061,30 @@ https://drafts.csswg.org/css-fonts-4/#lo
         if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
             Ok(SpecifiedValue::Normal)
         } else {
             input.expect_string().map(|cow| {
                 SpecifiedValue::Override(cow.into_owned())
             })
         }
     }
+
+    #[cfg(feature = "gecko")]
+    impl From<u32> for computed_value::T {
+        fn from(bits: u32) -> computed_value::T {
+            computed_value::T(bits)
+        }
+    }
+
+    #[cfg(feature = "gecko")]
+    impl From<computed_value::T> for u32 {
+        fn from(v: computed_value::T) -> u32 {
+            v.0
+        }
+    }
 </%helpers:longhand>
 
 <%helpers:longhand name="-x-lang" products="gecko" animation_value_type="none" internal="True"
                    spec="Internal (not web-exposed)">
     use values::computed::ComputedValueAsSpecified;
     pub use self::computed_value::T as SpecifiedValue;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
--- a/servo/components/style/properties/longhand/text.mako.rs
+++ b/servo/components/style/properties/longhand/text.mako.rs
@@ -288,11 +288,11 @@
     ignored_when_colors_disabled=True,
     spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color")}
 
 ${helpers.predefined_type(
     "initial-letter",
     "InitialLetter",
     "computed::InitialLetter::normal()",
     initial_specified_value="specified::InitialLetter::normal()",
-    animation_value_type="none",
+    animation_value_type="discrete",
     products="gecko",
     spec="https://drafts.csswg.org/css-inline/#sizing-drop-initials")}
--- a/servo/components/style/properties/longhand/ui.mako.rs
+++ b/servo/components/style/properties/longhand/ui.mako.rs
@@ -37,17 +37,17 @@
                          gecko_constant_prefix="NS_STYLE_WINDOW_SHADOW",
                          gecko_inexhaustive=True,
                          animation_value_type="discrete",
                          internal=True,
                          spec="None (Nonstandard internal property)")}
 
 <%helpers:longhand name="-moz-force-broken-image-icon"
                    products="gecko"
-                   animation_value_type="none"
+                   animation_value_type="discrete"
                    spec="None (Nonstandard Firefox-only property)">
     use std::fmt;
     use style_traits::ToCss;
     use values::computed::ComputedValueAsSpecified;
 
     no_viewport_percentage!(SpecifiedValue);
 
     pub mod computed_value {
@@ -78,9 +78,26 @@
 
     pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         match try!(input.expect_integer()) {
             0 => Ok(computed_value::T(false)),
             1 => Ok(computed_value::T(true)),
             _ => Err(()),
         }
     }
+
+    #[cfg(feature = "gecko")]
+    impl From<u8> for SpecifiedValue {
+        fn from(bits: u8) -> SpecifiedValue {
+            SpecifiedValue(bits == 1)
+        }
+    }
+
+    #[cfg(feature = "gecko")]
+    impl From<SpecifiedValue> for u8 {
+        fn from(v: SpecifiedValue) -> u8 {
+            match v.0 {
+                true => 1u8,
+                false => 0u8,
+            }
+        }
+    }
 </%helpers:longhand>
--- a/servo/components/style/properties/longhand/xul.mako.rs
+++ b/servo/components/style/properties/longhand/xul.mako.rs
@@ -54,10 +54,10 @@
                          animation_value_type="discrete",
                          spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-stack-sizing)")}
 
 ${helpers.predefined_type("-moz-box-ordinal-group", "Integer", "0",
                           parse_method="parse_non_negative",
                           products="gecko",
                           alias="-webkit-box-ordinal-group",
                           gecko_ffi_name="mBoxOrdinal",
-                          animation_value_type="none",
+                          animation_value_type="discrete",
                           spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-box-ordinal-group)")}