diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 0349e7ec220..fde7f315199 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -20,6 +20,7 @@ use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use values::generics::grid::TrackSize; use values::generics::image::{CompatMode, Image as GenericImage, GradientItem}; +use values::generics::rect::Rect; use values::specified::length::Percentage; impl From for nsStyleCoord_CalcValue { @@ -635,3 +636,28 @@ impl TrackSize { } } } + +impl Rect where T: GeckoStyleCoordConvertible { + /// Convert this generic Rect to given Gecko fields. + pub fn to_gecko_rect(&self, sides: &mut ::gecko_bindings::structs::nsStyleSides) { + self.0.to_gecko_style_coord(&mut sides.data_at_mut(0)); + self.1.to_gecko_style_coord(&mut sides.data_at_mut(1)); + self.2.to_gecko_style_coord(&mut sides.data_at_mut(2)); + self.3.to_gecko_style_coord(&mut sides.data_at_mut(3)); + } + + /// Convert from given Gecko data to generic Rect. + pub fn from_gecko_rect(sides: &::gecko_bindings::structs::nsStyleSides) + -> Option<::values::generics::rect::Rect> { + use values::generics::rect::Rect; + + Some( + Rect::new( + T::from_gecko_style_coord(&sides.data_at(0)).expect("coord[0] cound not convert"), + T::from_gecko_style_coord(&sides.data_at(1)).expect("coord[1] cound not convert"), + T::from_gecko_style_coord(&sides.data_at(2)).expect("coord[2] cound not convert"), + T::from_gecko_style_coord(&sides.data_at(3)).expect("coord[3] cound not convert") + ) + ) + } +} diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 3796a98b58c..73dbf480591 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -581,6 +581,35 @@ def set_gecko_property(ffi_name, expr): % endif +<%def name="impl_style_sides(ident)"> + <% gecko_ffi_name = "m" + to_camel_case(ident) %> + + #[allow(non_snake_case)] + pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { + v.to_gecko_rect(&mut self.gecko.${gecko_ffi_name}); + } + + <%self:copy_sides_style_coord ident="${ident}"> + + #[allow(non_snake_case)] + pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { + longhands::${ident}::computed_value::T::from_gecko_rect(&self.gecko.${gecko_ffi_name}) + .expect("clone for ${ident} failed") + } + + +<%def name="copy_sides_style_coord(ident)"> + <% gecko_ffi_name = "m" + to_camel_case(ident) %> + #[allow(non_snake_case)] + pub fn copy_${ident}_from(&mut self, other: &Self) { + % for side in SIDES: + self.gecko.${gecko_ffi_name}.data_at_mut(${side.index}) + .copy_from(&other.gecko.${gecko_ffi_name}.data_at(${side.index})); + % endfor + ${ caller.body() } + } + + <%def name="impl_corner_style_coord(ident, gecko_ffi_name, x_index, y_index, need_clone)"> #[allow(non_snake_case)] pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { @@ -1019,18 +1048,7 @@ fn static_assert() { } } - pub fn set_border_image_outset(&mut self, v: longhands::border_image_outset::computed_value::T) { - % for side in SIDES: - v.${side.index}.to_gecko_style_coord(&mut self.gecko.mBorderImageOutset.data_at_mut(${side.index})); - % endfor - } - - 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 - } + <% impl_style_sides("border_image_outset") %> <% border_image_repeat_keywords = ["Stretch", "Repeat", "Round", "Space"] @@ -1071,37 +1089,12 @@ fn static_assert() { 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) - }, - BorderImageSideWidth::Length(l) => { - l.to_gecko_style_coord(&mut self.gecko.mBorderImageWidth.data_at_mut(${side.index})) - }, - BorderImageSideWidth::Number(n) => { - self.gecko.mBorderImageWidth.data_at_mut(${side.index}).set_value(CoordDataValue::Factor(n)) - }, - } - % endfor - } - - pub fn copy_border_image_width_from(&mut self, other: &Self) { - % for side in SIDES: - self.gecko.mBorderImageWidth.data_at_mut(${side.index}) - .copy_from(&other.gecko.mBorderImageWidth.data_at(${side.index})); - % endfor - } + <% impl_style_sides("border_image_width") %> pub fn set_border_image_slice(&mut self, v: longhands::border_image_slice::computed_value::T) { use gecko_bindings::structs::{NS_STYLE_BORDER_IMAGE_SLICE_NOFILL, NS_STYLE_BORDER_IMAGE_SLICE_FILL}; - % for side in SIDES: - v.offsets.${side.index}.to_gecko_style_coord(&mut self.gecko.mBorderImageSlice.data_at_mut(${side.index})); - % endfor + v.offsets.to_gecko_rect(&mut self.gecko.mBorderImageSlice); let fill = if v.fill { NS_STYLE_BORDER_IMAGE_SLICE_FILL @@ -1111,12 +1104,21 @@ fn static_assert() { self.gecko.mBorderImageFill = fill as u8; } - pub fn copy_border_image_slice_from(&mut self, other: &Self) { - for i in 0..4 { - self.gecko.mBorderImageSlice.data_at_mut(i) - .copy_from(&other.gecko.mBorderImageSlice.data_at(i)); - } + <%self:copy_sides_style_coord ident="border_image_slice"> self.gecko.mBorderImageFill = other.gecko.mBorderImageFill; + + + pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T { + use gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL; + use values::computed::{BorderImageSlice, NumberOrPercentage}; + type NumberOrPercentageRect = ::values::generics::rect::Rect; + + BorderImageSlice { + offsets: + NumberOrPercentageRect::from_gecko_rect(&self.gecko.mBorderImageSlice) + .expect("mBorderImageSlice[${side.index}] could not convert to NumberOrPercentageRect"), + fill: self.gecko.mBorderImageFill as u32 == NS_STYLE_BORDER_IMAGE_SLICE_FILL + } } diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index d984a2d80d5..ea68b59c887 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -209,7 +209,7 @@ ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", 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", + animation_value_type="discrete", boxed=True)} <%helpers:longhand name="border-image-repeat" animation_value_type="discrete" @@ -273,12 +273,66 @@ ${helpers.predefined_type("border-image-width", "BorderImageWidth", initial_value="computed::BorderImageSideWidth::one().into()", initial_specified_value="specified::BorderImageSideWidth::one().into()", spec="https://drafts.csswg.org/css-backgrounds/#border-image-width", - animation_value_type="none", + animation_value_type="discrete", boxed=True)} ${helpers.predefined_type("border-image-slice", "BorderImageSlice", initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()", initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage(1.)).into()", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", - animation_value_type="none", + animation_value_type="discrete", boxed=True)} + +#[cfg(feature = "gecko")] +impl ::values::computed::BorderImageWidth { + pub fn to_gecko_rect(&self, sides: &mut ::gecko_bindings::structs::nsStyleSides) { + use gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue}; + use gecko::values::GeckoStyleCoordConvertible; + use values::generics::border::BorderImageSideWidth; + + % for i in range(0, 4): + match self.${i} { + BorderImageSideWidth::Auto => { + sides.data_at_mut(${i}).set_value(CoordDataValue::Auto) + }, + BorderImageSideWidth::Length(l) => { + l.to_gecko_style_coord(&mut sides.data_at_mut(${i})) + }, + BorderImageSideWidth::Number(n) => { + sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n)) + }, + } + % endfor + } + + pub fn from_gecko_rect(sides: &::gecko_bindings::structs::nsStyleSides) + -> Option<::values::computed::BorderImageWidth> { + use gecko_bindings::structs::nsStyleUnit::{eStyleUnit_Factor, eStyleUnit_Auto}; + use gecko_bindings::sugar::ns_style_coord::CoordData; + use gecko::values::GeckoStyleCoordConvertible; + use values::computed::{LengthOrPercentage, Number}; + use values::generics::border::BorderImageSideWidth; + + Some( + ::values::computed::BorderImageWidth::new( + % for i in range(0, 4): + match sides.data_at(${i}).unit() { + eStyleUnit_Auto => { + BorderImageSideWidth::Auto + }, + eStyleUnit_Factor => { + BorderImageSideWidth::Number( + Number::from_gecko_style_coord(&sides.data_at(${i})) + .expect("sides[${i}] could not convert to Number")) + }, + _ => { + BorderImageSideWidth::Length( + LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i})) + .expect("sides[${i}] could not convert to LengthOrPercentager")) + }, + }, + % endfor + ) + ) + } +}