aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko_conversions.rs25
-rw-r--r--components/style/properties/gecko.mako.rs104
-rw-r--r--ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs10
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 {