mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
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 -->
This commit is contained in:
commit
c46003eb05
3 changed files with 133 additions and 6 deletions
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue