diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c424ca705a7..4b921b88009 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1597,7 +1597,9 @@ fn static_assert() { background-image background-clip background-origin background-attachment background-size background-position - background-blend-mode""" %> + background-blend-mode + background-position-x + background-position-y""" %> <%self:impl_trait style_struct_name="Background" skip_longhands="${skip_background_longhands}" skip_additionals="*"> @@ -1635,6 +1637,56 @@ fn static_assert() { T::luminosity => structs::NS_STYLE_BLEND_LUMINOSITY as u8, } + + % for orientation in [("x", "Horizontal"), ("y", "Vertical")]: + pub fn copy_background_position_${orientation[0]}_from(&mut self, other: &Self) { + use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; + + self.gecko.mImage.mPosition${orientation[0].upper()}Count + = cmp::min(1, other.gecko.mImage.mPosition${orientation[0].upper()}Count); + self.gecko.mImage.mLayers.mFirstElement.mPosition = + other.gecko.mImage.mLayers.mFirstElement.mPosition; + unsafe { + Gecko_EnsureImageLayersLength(&mut self.gecko.mImage, + other.gecko.mImage.mLayers.len(), + LayerType::Background); + } + for (layer, other) in self.gecko.mImage.mLayers.iter_mut() + .zip(other.gecko.mImage.mLayers.iter()) { + layer.mPosition.m${orientation[0].upper()}Position + = other.mPosition.m${orientation[0].upper()}Position; + } + self.gecko.mImage.mPosition${orientation[0].upper()}Count + = other.gecko.mImage.mPosition${orientation[0].upper()}Count; + } + + pub fn clone_background_position_${orientation[0]}(&self) + -> longhands::background_position_${orientation[0]}::computed_value::T { + use values::computed::position::${orientation[1]}Position; + longhands::background_position_${orientation[0]}::computed_value::T( + self.gecko.mImage.mLayers.iter() + .take(self.gecko.mImage.mPosition${orientation[0].upper()}Count as usize) + .map(|position| ${orientation[1]}Position(position.mPosition.m${orientation[0].upper()}Position.into())) + .collect() + ) + } + + pub fn set_background_position_${orientation[0]}(&mut self, + v: longhands::background_position_${orientation[0]}::computed_value::T) { + use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; + + unsafe { + Gecko_EnsureImageLayersLength(&mut self.gecko.mImage, v.0.len(), + LayerType::Background); + } + + self.gecko.mImage.mPosition${orientation[0].upper()}Count = v.0.len() as u32; + for (servo, geckolayer) in v.0.into_iter().zip(self.gecko.mImage + .mLayers.iter_mut()) { + geckolayer.mPosition.m${orientation[0].upper()}Position = servo.0.into(); + } + } + % endfor <%self:impl_trait style_struct_name="List" diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 1053e8e6958..b5fbfc79c58 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -26,7 +26,7 @@ use values::Either; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderRadiusSize, LengthOrNone}; use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; -use values::computed::position::Position; +use values::computed::position::{HorizontalPosition, Position, VerticalPosition}; use values::computed::ToComputedValue; @@ -581,6 +581,45 @@ impl Interpolate for BackgroundPosition { } } +/// https://drafts.csswg.org/css-transitions/#animtype-simple-list +impl Interpolate for HorizontalPosition { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + Ok(HorizontalPosition(try!(self.0.interpolate(&other.0, progress)))) + } +} + +impl RepeatableListInterpolate for HorizontalPosition {} + +/// https://drafts.csswg.org/css-transitions/#animtype-simple-list +impl Interpolate for VerticalPosition { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + Ok(VerticalPosition(try!(self.0.interpolate(&other.0, progress)))) + } +} + +impl RepeatableListInterpolate for VerticalPosition {} + +% if product == "gecko": + use properties::longhands::background_position_x::computed_value::T as BackgroundPositionX; + use properties::longhands::background_position_y::computed_value::T as BackgroundPositionY; + + impl Interpolate for BackgroundPositionX { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + Ok(BackgroundPositionX(try!(self.0.interpolate(&other.0, progress)))) + } + } + + impl Interpolate for BackgroundPositionY { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + Ok(BackgroundPositionY(try!(self.0.interpolate(&other.0, progress)))) + } + } +% endif + /// https://drafts.csswg.org/css-transitions/#animtype-shadow-list impl Interpolate for TextShadow { #[inline] diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 7c49ea4ea5a..dad4e841c26 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -131,6 +131,92 @@ ${helpers.predefined_type("background-color", "CSSColor", } +<%helpers:vector_longhand name="background-position-x" products="gecko" animatable="True"> + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::HorizontalPosition; + + pub mod computed_value { + use values::computed::position::HorizontalPosition; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + + pub type T = HorizontalPosition; + } + + pub type SpecifiedValue = HorizontalPosition; + + #[inline] + pub fn get_initial_value() -> computed_value::T { + use values::computed::position::HorizontalPosition; + HorizontalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::position::Keyword; + HorizontalPosition { + keyword: Some(Keyword::Left), + position: None, + } + } + #[inline] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), + } + } + + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result { + HorizontalPosition::parse(context, input) + } + + +<%helpers:vector_longhand name="background-position-y" products="gecko" animatable="True"> + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::VerticalPosition; + + pub mod computed_value { + use values::computed::position::VerticalPosition; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + + pub type T = VerticalPosition; + } + + pub type SpecifiedValue = VerticalPosition; + + #[inline] + pub fn get_initial_value() -> computed_value::T { + use values::computed::position::VerticalPosition; + VerticalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::position::Keyword; + VerticalPosition { + keyword: Some(Keyword::Top), + position: None, + } + } + #[inline] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), + } + } + + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result { + VerticalPosition::parse(context, input) + } + + ${helpers.single_keyword("background-repeat", "repeat repeat-x repeat-y space round no-repeat", vector=True, diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index 253bccdc95b..f93d59db99c 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -27,6 +27,8 @@ impl ToCss for Position { } } +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct HorizontalPosition(pub LengthOrPercentage); impl ToCss for HorizontalPosition { @@ -35,6 +37,8 @@ impl ToCss for HorizontalPosition { } } +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct VerticalPosition(pub LengthOrPercentage); impl ToCss for VerticalPosition {