mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +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 gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use stylesheets::Stylesheet;
|
use stylesheets::Stylesheet;
|
||||||
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
|
use values::computed::{CalcLengthOrPercentage, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
|
|
||||||
unsafe impl HasFFI for Stylesheet {
|
unsafe impl HasFFI for Stylesheet {
|
||||||
type FFIType = RawServoStyleSheet;
|
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 {
|
impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
|
||||||
fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
|
fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
|
||||||
match (other.mHasPercent, other.mLength) {
|
match (other.mHasPercent, other.mLength) {
|
||||||
|
|
|
@ -999,7 +999,7 @@ fn static_assert() {
|
||||||
<% skip_background_longhands = """background-color background-repeat
|
<% skip_background_longhands = """background-color background-repeat
|
||||||
background-image background-clip
|
background-image background-clip
|
||||||
background-origin background-attachment
|
background-origin background-attachment
|
||||||
background-position""" %>
|
background-size background-position""" %>
|
||||||
<%self:impl_trait style_struct_name="Background"
|
<%self:impl_trait style_struct_name="Background"
|
||||||
skip_longhands="${skip_background_longhands}"
|
skip_longhands="${skip_background_longhands}"
|
||||||
skip_additionals="*">
|
skip_additionals="*">
|
||||||
|
@ -1058,6 +1058,78 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
</%self:simple_background_array_property>
|
</%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) {
|
pub fn copy_background_position_from(&mut self, other: &Self) {
|
||||||
self.gecko.mImage.mPositionXCount = cmp::min(1, other.gecko.mImage.mPositionXCount);
|
self.gecko.mImage.mPositionXCount = cmp::min(1, other.gecko.mImage.mPositionXCount);
|
||||||
self.gecko.mImage.mPositionYCount = cmp::min(1, other.gecko.mImage.mPositionYCount);
|
self.gecko.mImage.mPositionYCount = cmp::min(1, other.gecko.mImage.mPositionYCount);
|
||||||
|
@ -1120,6 +1192,7 @@ fn static_assert() {
|
||||||
use gecko_bindings::structs::nsStyleCoord;
|
use gecko_bindings::structs::nsStyleCoord;
|
||||||
use values::computed::Image;
|
use values::computed::Image;
|
||||||
use values::specified::AngleOrCorner;
|
use values::specified::AngleOrCorner;
|
||||||
|
use values::specified::{HorizontalDirection, VerticalDirection};
|
||||||
use cssparser::Color as CSSColor;
|
use cssparser::Color as CSSColor;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1156,10 +1229,31 @@ fn static_assert() {
|
||||||
stop_count as u32)
|
stop_count as u32)
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: figure out what gecko does in the `corner` case.
|
match gradient.angle_or_corner {
|
||||||
if let AngleOrCorner::Angle(angle) = gradient.angle_or_corner {
|
AngleOrCorner::Angle(angle) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*gecko_gradient).mAngle.set(angle);
|
(*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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
impl nsStyleSides {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn data_at(&self, index: usize) -> SidesData {
|
pub fn data_at(&self, index: usize) -> SidesData {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue