diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-09-04 03:45:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-04 03:45:05 -0500 |
commit | c46003eb05cca0ea779fee73d0f6325c85e19357 (patch) | |
tree | f3b7e9b7627aafc83a1210a28dc3ab42cebcd666 | |
parent | fe9d9096ec3e78e2d5d53d32f181dc519512a40a (diff) | |
parent | 66c8cd9cf36518533633a546ca8c9dc2b490869a (diff) | |
download | servo-c46003eb05cca0ea779fee73d0f6325c85e19357.tar.gz servo-c46003eb05cca0ea779fee73d0f6325c85e19357.zip |
Auto merge of #13157 - Manishearth:background-size, r=emilio
stylo: support background-size and corner gradients
Forgot to fix this in the midst of all other things fixed in #12945
<s>(not yet tested, need to figure out how to test bg-size with gradients)</s>
r? @bholley
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13157)
<!-- Reviewable:end -->
-rw-r--r-- | components/style/gecko_conversions.rs | 25 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 104 | ||||
-rw-r--r-- | ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs | 10 |
3 files changed, 133 insertions, 6 deletions
diff --git a/components/style/gecko_conversions.rs b/components/style/gecko_conversions.rs index 71457a7dc3a..851dbe90947 100644 --- a/components/style/gecko_conversions.rs +++ b/components/style/gecko_conversions.rs @@ -14,7 +14,7 @@ use gecko_bindings::structs::nsStyleCoord_CalcValue; use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; use properties::ComputedValues; use stylesheets::Stylesheet; -use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; +use values::computed::{CalcLengthOrPercentage, LengthOrPercentage, LengthOrPercentageOrAuto}; unsafe impl HasFFI for Stylesheet { type FFIType = RawServoStyleSheet; @@ -72,6 +72,29 @@ impl From<LengthOrPercentage> for nsStyleCoord_CalcValue { } } +impl LengthOrPercentageOrAuto { + pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> { + match *self { + LengthOrPercentageOrAuto::Length(au) => { + Some(nsStyleCoord_CalcValue { + mLength: au.0, + mPercent: 0.0, + mHasPercent: false, + }) + }, + LengthOrPercentageOrAuto::Percentage(pc) => { + Some(nsStyleCoord_CalcValue { + mLength: 0, + mPercent: pc, + mHasPercent: true, + }) + }, + LengthOrPercentageOrAuto::Calc(calc) => Some(calc.into()), + LengthOrPercentageOrAuto::Auto => None, + } + } +} + impl From<nsStyleCoord_CalcValue> for LengthOrPercentage { fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage { match (other.mHasPercent, other.mLength) { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 9d8191aad6b..ae801790653 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -999,7 +999,7 @@ fn static_assert() { <% skip_background_longhands = """background-color background-repeat background-image background-clip background-origin background-attachment - background-position""" %> + background-size background-position""" %> <%self:impl_trait style_struct_name="Background" skip_longhands="${skip_background_longhands}" skip_additionals="*"> @@ -1058,6 +1058,78 @@ fn static_assert() { } </%self:simple_background_array_property> + <%self:simple_background_array_property name="size" field_name="mSize"> + use gecko_bindings::structs::nsStyleImageLayers_Size_Dimension; + use gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType; + use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImageLayers_Size}; + use properties::longhands::background_size::single_value::computed_value::T; + use values::computed::LengthOrPercentageOrAuto; + + let mut width = nsStyleCoord_CalcValue::new(); + let mut height = nsStyleCoord_CalcValue::new(); + + let (w_type, h_type) = match servo { + T::Explicit(size) => { + let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto; + let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto; + if let Some(w) = size.width.to_calc_value() { + width = w; + w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; + } + if let Some(h) = size.height.to_calc_value() { + height = h; + h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; + } + (w_type, h_type) + } + T::Cover => (nsStyleImageLayers_Size_DimensionType::eCover, + nsStyleImageLayers_Size_DimensionType::eCover), + T::Contain => (nsStyleImageLayers_Size_DimensionType::eContain, + nsStyleImageLayers_Size_DimensionType::eContain), + }; + + nsStyleImageLayers_Size { + mWidth: nsStyleImageLayers_Size_Dimension { _base: width }, + mHeight: nsStyleImageLayers_Size_Dimension { _base: height }, + mWidthType: w_type as u8, + mHeightType: h_type as u8, + } + </%self:simple_background_array_property> + + pub fn clone_background_size(&self) -> longhands::background_size::computed_value::T { + use gecko_bindings::structs::nsStyleCoord_CalcValue as CalcValue; + use gecko_bindings::structs::nsStyleImageLayers_Size_DimensionType as DimensionType; + use properties::longhands::background_size::single_value::computed_value::{ExplicitSize, T}; + use values::computed::LengthOrPercentageOrAuto; + + fn to_servo(value: CalcValue, ty: u8) -> LengthOrPercentageOrAuto { + if ty == DimensionType::eAuto as u8 { + LengthOrPercentageOrAuto::Auto + } else { + debug_assert!(ty == DimensionType::eLengthPercentage as u8); + LengthOrPercentageOrAuto::Calc(value.into()) + } + } + + longhands::background_size::computed_value::T( + self.gecko.mImage.mLayers.iter().map(|ref layer| { + if DimensionType::eCover as u8 == layer.mSize.mWidthType { + debug_assert!(layer.mSize.mHeightType == DimensionType::eCover as u8); + return T::Cover + } + if DimensionType::eContain as u8 == layer.mSize.mWidthType { + debug_assert!(layer.mSize.mHeightType == DimensionType::eContain as u8); + return T::Contain + } + + T::Explicit(ExplicitSize { + width: to_servo(layer.mSize.mWidth._base, layer.mSize.mWidthType), + height: to_servo(layer.mSize.mHeight._base, layer.mSize.mHeightType), + }) + }).collect() + ) + } + pub fn copy_background_position_from(&mut self, other: &Self) { self.gecko.mImage.mPositionXCount = cmp::min(1, other.gecko.mImage.mPositionXCount); self.gecko.mImage.mPositionYCount = cmp::min(1, other.gecko.mImage.mPositionYCount); @@ -1120,6 +1192,7 @@ fn static_assert() { use gecko_bindings::structs::nsStyleCoord; use values::computed::Image; use values::specified::AngleOrCorner; + use values::specified::{HorizontalDirection, VerticalDirection}; use cssparser::Color as CSSColor; unsafe { @@ -1156,10 +1229,31 @@ fn static_assert() { stop_count as u32) }; - // TODO: figure out what gecko does in the `corner` case. - if let AngleOrCorner::Angle(angle) = gradient.angle_or_corner { - unsafe { - (*gecko_gradient).mAngle.set(angle); + match gradient.angle_or_corner { + AngleOrCorner::Angle(angle) => { + unsafe { + (*gecko_gradient).mAngle.set(angle); + (*gecko_gradient).mBgPosX.set_value(CoordDataValue::None); + (*gecko_gradient).mBgPosY.set_value(CoordDataValue::None); + } + } + AngleOrCorner::Corner(horiz, vert) => { + let percent_x = match horiz { + HorizontalDirection::Left => 0.0, + HorizontalDirection::Right => 1.0, + }; + let percent_y = match vert { + VerticalDirection::Top => 0.0, + VerticalDirection::Bottom => 1.0, + }; + + unsafe { + (*gecko_gradient).mAngle.set_value(CoordDataValue::None); + (*gecko_gradient).mBgPosX + .set_value(CoordDataValue::Percent(percent_x)); + (*gecko_gradient).mBgPosY + .set_value(CoordDataValue::Percent(percent_y)); + } } } diff --git a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs index 881da7e0e39..b850142c0f6 100644 --- a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs +++ b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs @@ -40,6 +40,16 @@ impl CoordDataMut for nsStyleCoord { } } +impl nsStyleCoord_CalcValue { + pub fn new() -> Self { + nsStyleCoord_CalcValue { + mLength: 0, + mPercent: 0.0, + mHasPercent: false, + } + } +} + impl nsStyleSides { #[inline] pub fn data_at(&self, index: usize) -> SidesData { |