From 3723042937909ec01683b500706d05457d7ab6a7 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Fri, 26 Oct 2018 18:03:35 +0000 Subject: [PATCH] style: Generate StyleTimingFunction and drop ns_timing_function.rs. First, we generate StyleComputedTimingFunction by cbindgen from Rust, and use it in nsTimingFunction, so we could copy it directly without handling the different memory layout. However, we have to rewrite the nsTimingFunction and mozilla::ComputedTimingFunction for this. Second, the rust-bindgen seems cannot generate the correct generic members from complex C++ templates, especially for the nested template struct, (https://github.com/rust-lang-nursery/rust-bindgen/issues/1429) So we have to hide StyleTimingFunction to avoid the compilation errors. Differential Revision: https://phabricator.services.mozilla.com/D9313 --- components/style/cbindgen.toml | 2 + components/style/gecko_bindings/sugar/mod.rs | 1 - .../sugar/ns_timing_function.rs | 139 ------------------ components/style/properties/gecko.mako.rs | 12 +- components/style/values/computed/easing.rs | 7 +- components/style/values/generics/easing.rs | 3 + components/style/values/specified/easing.rs | 24 +++ 7 files changed, 42 insertions(+), 146 deletions(-) delete mode 100644 components/style/gecko_bindings/sugar/ns_timing_function.rs diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 8bcba69c057..1c8d14e16e8 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -42,12 +42,14 @@ include = [ "StyleComputedFontStretchRange", "StyleComputedFontStyleDescriptor", "StyleComputedFontWeightRange", + "StyleComputedTimingFunction", "StyleDisplay", "StyleDisplayMode", "StyleFillRule", "StyleFontDisplay", "StyleFontFaceSourceListComponent", "StyleFontLanguageOverride", + "StyleTimingFunction", "StylePathCommand", "StyleUnicodeRange", ] diff --git a/components/style/gecko_bindings/sugar/mod.rs b/components/style/gecko_bindings/sugar/mod.rs index a455cf2b714..6ca9881b750 100644 --- a/components/style/gecko_bindings/sugar/mod.rs +++ b/components/style/gecko_bindings/sugar/mod.rs @@ -12,7 +12,6 @@ pub mod ns_css_value; mod ns_style_auto_array; pub mod ns_style_coord; mod ns_t_array; -mod ns_timing_function; pub mod origin_flags; pub mod ownership; pub mod refptr; diff --git a/components/style/gecko_bindings/sugar/ns_timing_function.rs b/components/style/gecko_bindings/sugar/ns_timing_function.rs deleted file mode 100644 index 3eb3b96bb5f..00000000000 --- a/components/style/gecko_bindings/sugar/ns_timing_function.rs +++ /dev/null @@ -1,139 +0,0 @@ -/* 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/. */ - -use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type}; -use std::mem; -use values::computed::ToComputedValue; -use values::computed::easing::TimingFunction as ComputedTimingFunction; -use values::generics::easing::{StepPosition, TimingKeyword}; -use values::generics::easing::TimingFunction as GenericTimingFunction; -use values::specified::easing::TimingFunction; - -impl nsTimingFunction { - fn set_as_step(&mut self, function_type: nsTimingFunction_Type, steps: i32) { - debug_assert!( - function_type == nsTimingFunction_Type::StepStart || - function_type == nsTimingFunction_Type::StepEnd, - "function_type should be step-start or step-end" - ); - self.mType = function_type; - unsafe { - self.__bindgen_anon_1 - .__bindgen_anon_1 - .as_mut() - .mSteps = steps as u32; - } - } - - fn set_as_bezier( - &mut self, - function_type: nsTimingFunction_Type, - x1: f32, - y1: f32, - x2: f32, - y2: f32, - ) { - self.mType = function_type; - unsafe { - let ref mut gecko_cubic_bezier = self.__bindgen_anon_1.mFunc.as_mut(); - gecko_cubic_bezier.mX1 = x1; - gecko_cubic_bezier.mY1 = y1; - gecko_cubic_bezier.mX2 = x2; - gecko_cubic_bezier.mY2 = y2; - } - } -} - -impl From for nsTimingFunction { - fn from(function: ComputedTimingFunction) -> nsTimingFunction { - TimingFunction::from_computed_value(&function).into() - } -} - -impl From for nsTimingFunction { - fn from(function: TimingFunction) -> nsTimingFunction { - let mut tf: nsTimingFunction = unsafe { mem::zeroed() }; - - match function { - GenericTimingFunction::Steps(steps, StepPosition::Start) => { - debug_assert!(steps.value() >= 0); - tf.set_as_step(nsTimingFunction_Type::StepStart, steps.value()); - }, - GenericTimingFunction::Steps(steps, StepPosition::End) => { - debug_assert!(steps.value() >= 0); - tf.set_as_step(nsTimingFunction_Type::StepEnd, steps.value()); - }, - GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => { - tf.set_as_bezier( - nsTimingFunction_Type::CubicBezier, - x1.get(), - y1.get(), - x2.get(), - y2.get(), - ); - }, - GenericTimingFunction::Keyword(keyword) => { - let (x1, y1, x2, y2) = keyword.to_bezier(); - tf.set_as_bezier(keyword.into(), x1, y1, x2, y2); - }, - } - tf - } -} - -impl From for ComputedTimingFunction { - fn from(function: nsTimingFunction) -> ComputedTimingFunction { - match function.mType { - nsTimingFunction_Type::StepStart => GenericTimingFunction::Steps( - unsafe { - function - .__bindgen_anon_1 - .__bindgen_anon_1 - .as_ref() - .mSteps as i32 - }, - StepPosition::Start, - ), - nsTimingFunction_Type::StepEnd => GenericTimingFunction::Steps( - unsafe { - function - .__bindgen_anon_1 - .__bindgen_anon_1 - .as_ref() - .mSteps as i32 - }, - StepPosition::End, - ), - nsTimingFunction_Type::Ease => GenericTimingFunction::Keyword(TimingKeyword::Ease), - nsTimingFunction_Type::Linear => GenericTimingFunction::Keyword(TimingKeyword::Linear), - nsTimingFunction_Type::EaseIn => GenericTimingFunction::Keyword(TimingKeyword::EaseIn), - nsTimingFunction_Type::EaseOut => { - GenericTimingFunction::Keyword(TimingKeyword::EaseOut) - }, - nsTimingFunction_Type::EaseInOut => { - GenericTimingFunction::Keyword(TimingKeyword::EaseInOut) - }, - nsTimingFunction_Type::CubicBezier => unsafe { - GenericTimingFunction::CubicBezier { - x1: function.__bindgen_anon_1.mFunc.as_ref().mX1, - y1: function.__bindgen_anon_1.mFunc.as_ref().mY1, - x2: function.__bindgen_anon_1.mFunc.as_ref().mX2, - y2: function.__bindgen_anon_1.mFunc.as_ref().mY2, - } - }, - } - } -} - -impl From for nsTimingFunction_Type { - fn from(keyword: TimingKeyword) -> Self { - match keyword { - TimingKeyword::Linear => nsTimingFunction_Type::Linear, - TimingKeyword::Ease => nsTimingFunction_Type::Ease, - TimingKeyword::EaseIn => nsTimingFunction_Type::EaseIn, - TimingKeyword::EaseOut => nsTimingFunction_Type::EaseOut, - TimingKeyword::EaseInOut => nsTimingFunction_Type::EaseInOut, - } - } -} diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c0c01b5120f..d54c8418689 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -2855,7 +2855,7 @@ fn static_assert() { ${impl_simple_copy('_moz_min_font_size_ratio', 'mMinFontSizeRatio')} -<%def name="impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name)"> +<%def name="impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name, member=None)"> #[allow(non_snake_case)] pub fn copy_${type}_${ident}_from(&mut self, other: &Self) { self.gecko.m${type.capitalize()}s.ensure_len(other.gecko.m${type.capitalize()}s.len()); @@ -2868,7 +2868,11 @@ fn static_assert() { ); for (ours, others) in iter { + % if member: + ours.m${gecko_ffi_name}.${member} = others.m${gecko_ffi_name}.${member}; + % else: ours.m${gecko_ffi_name} = others.m${gecko_ffi_name}; + % endif } } @@ -2923,14 +2927,14 @@ fn static_assert() { self.gecko.m${type.capitalize()}TimingFunctionCount = input_len as u32; for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().take(input_len as usize).zip(v) { - gecko.mTimingFunction = servo.into(); + gecko.mTimingFunction.mTiming = servo; } } ${impl_animation_or_transition_count(type, 'timing_function', 'TimingFunction')} - ${impl_copy_animation_or_transition_value(type, 'timing_function', 'TimingFunction')} + ${impl_copy_animation_or_transition_value(type, 'timing_function', "TimingFunction", "mTiming")} pub fn ${type}_timing_function_at(&self, index: usize) -> longhands::${type}_timing_function::computed_value::SingleComputedValue { - self.gecko.m${type.capitalize()}s[index].mTimingFunction.into() + self.gecko.m${type.capitalize()}s[index].mTimingFunction.mTiming } diff --git a/components/style/values/computed/easing.rs b/components/style/values/computed/easing.rs index 47a24efae66..394cf3ea41e 100644 --- a/components/style/values/computed/easing.rs +++ b/components/style/values/computed/easing.rs @@ -5,7 +5,10 @@ //! Computed types for CSS Easing functions. use values::computed::{Integer, Number}; -use values::generics::easing::TimingFunction as GenericTimingFunction; +use values::generics::easing; /// A computed timing function. -pub type TimingFunction = GenericTimingFunction; +pub type ComputedTimingFunction = easing::TimingFunction; + +/// An alias of the computed timing function. +pub type TimingFunction = ComputedTimingFunction; diff --git a/components/style/values/generics/easing.rs b/components/style/values/generics/easing.rs index 41d60765baa..018f51bba8f 100644 --- a/components/style/values/generics/easing.rs +++ b/components/style/values/generics/easing.rs @@ -10,6 +10,7 @@ use values::CSSFloat; /// A generic easing function. #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] #[value_info(ty = "TIMING_FUNCTION")] +#[repr(u8, C)] pub enum TimingFunction { /// `linear | ease | ease-in | ease-out | ease-in-out` Keyword(TimingKeyword), @@ -42,6 +43,7 @@ pub enum TimingFunction { ToComputedValue, ToCss, )] +#[repr(u8)] pub enum TimingKeyword { Linear, Ease, @@ -53,6 +55,7 @@ pub enum TimingKeyword { #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)] +#[repr(u8)] pub enum StepPosition { Start, End, diff --git a/components/style/values/specified/easing.rs b/components/style/values/specified/easing.rs index 48b2bcd3233..1bc92e0dd48 100644 --- a/components/style/values/specified/easing.rs +++ b/components/style/values/specified/easing.rs @@ -8,6 +8,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use selectors::parser::SelectorParseErrorKind; use style_traits::{ParseError, StyleParseErrorKind}; +use values::computed::easing::TimingFunction as ComputedTimingFunction; use values::generics::easing::{StepPosition, TimingKeyword}; use values::generics::easing::TimingFunction as GenericTimingFunction; use values::specified::{Integer, Number}; @@ -71,3 +72,26 @@ impl Parse for TimingFunction { }) } } + +// We need this for converting the specified TimingFunction into computed TimingFunction without +// Context (for some FFIs in glue.rs). In fact, we don't really need Context to get the computed +// value of TimingFunction. +impl TimingFunction { + /// Generate the ComputedTimingFunction without Context. + pub fn to_computed_value_without_context(&self) -> ComputedTimingFunction { + match *self { + GenericTimingFunction::Steps(steps, pos) => { + GenericTimingFunction::Steps(steps.value(), pos) + }, + GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => { + GenericTimingFunction::CubicBezier { + x1: x1.get(), + y1: y1.get(), + x2: x2.get(), + y2: y2.get(), + } + }, + GenericTimingFunction::Keyword(keyword) => GenericTimingFunction::Keyword(keyword), + } + } +}