mirror of
https://github.com/servo/servo.git
synced 2025-10-17 08:49:21 +01:00
Auto merge of #17774 - servo:derive-all-the-things, r=emilio
Prepare some code for future derivation 🌊 <!-- 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/17774) <!-- Reviewable:end -->
This commit is contained in:
commit
d76d097891
18 changed files with 402 additions and 251 deletions
|
@ -11,7 +11,7 @@ use properties::longhands::text_shadow::computed_value::T as ComputedTextShadowL
|
|||
use std::cmp;
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
use values::Impossible;
|
||||
use values::animated::ToAnimatedValue;
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::computed::{Angle, Number};
|
||||
use values::computed::length::Length;
|
||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
|
@ -66,7 +66,7 @@ impl ToAnimatedValue for ComputedBoxShadowList {
|
|||
|
||||
impl<S> Animatable for ShadowList<S>
|
||||
where
|
||||
S: Animatable + Clone,
|
||||
S: Animatable + Clone + ToAnimatedZero,
|
||||
{
|
||||
#[inline]
|
||||
fn add_weighted(
|
||||
|
@ -83,10 +83,10 @@ where
|
|||
shadow.add_weighted(other, self_portion, other_portion)?
|
||||
},
|
||||
(Some(shadow), None) => {
|
||||
shadow.add_weighted(&shadow.get_zero_value()?, self_portion, other_portion)?
|
||||
shadow.add_weighted(&shadow.to_animated_zero()?, self_portion, other_portion)?
|
||||
},
|
||||
(None, Some(shadow)) => {
|
||||
shadow.get_zero_value()?.add_weighted(&shadow, self_portion, other_portion)?
|
||||
shadow.to_animated_zero()?.add_weighted(&shadow, self_portion, other_portion)?
|
||||
},
|
||||
(None, None) => unreachable!(),
|
||||
});
|
||||
|
@ -102,6 +102,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> ToAnimatedZero for ShadowList<S> {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(ShadowList(vec![]))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedValue for ComputedTextShadowList {
|
||||
type AnimatedValue = TextShadowList;
|
||||
|
||||
|
@ -134,15 +141,6 @@ impl Animatable for BoxShadow {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_zero_value(&self) -> Result<Self, ()> {
|
||||
Ok(BoxShadow {
|
||||
base: self.base.get_zero_value()?,
|
||||
spread: self.spread.get_zero_value()?,
|
||||
inset: self.inset,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
|
@ -160,6 +158,17 @@ impl Animatable for BoxShadow {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for BoxShadow {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(BoxShadow {
|
||||
base: self.base.to_animated_zero()?,
|
||||
spread: self.spread.to_animated_zero()?,
|
||||
inset: self.inset,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedValue for ComputedFilterList {
|
||||
type AnimatedValue = FilterList;
|
||||
|
||||
|
@ -188,6 +197,13 @@ impl ToAnimatedValue for ComputedFilterList {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for FilterList {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(FilterList(vec![]))
|
||||
}
|
||||
}
|
||||
|
||||
impl Animatable for SimpleShadow {
|
||||
#[inline]
|
||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
|
@ -204,16 +220,6 @@ impl Animatable for SimpleShadow {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_zero_value(&self) -> Result<Self, ()> {
|
||||
Ok(SimpleShadow {
|
||||
color: IntermediateColor::transparent(),
|
||||
horizontal: self.horizontal.get_zero_value()?,
|
||||
vertical: self.vertical.get_zero_value()?,
|
||||
blur: self.blur.get_zero_value()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
|
@ -229,3 +235,15 @@ impl Animatable for SimpleShadow {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for SimpleShadow {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(SimpleShadow {
|
||||
color: IntermediateColor::transparent(),
|
||||
horizontal: self.horizontal.to_animated_zero()?,
|
||||
vertical: self.vertical.to_animated_zero()?,
|
||||
blur: self.blur.to_animated_zero()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,3 +88,34 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a value similar to `self` that represents zero.
|
||||
pub trait ToAnimatedZero: Sized {
|
||||
/// Returns a value that, when added with an underlying value, will produce the underlying
|
||||
/// value. This is used for SMIL animation's "by-animation" where SMIL first interpolates from
|
||||
/// the zero value to the 'by' value, and then adds the result to the underlying value.
|
||||
///
|
||||
/// This is not the necessarily the same as the initial value of a property. For example, the
|
||||
/// initial value of 'stroke-width' is 1, but the zero value is 0, since adding 1 to the
|
||||
/// underlying value will not produce the underlying value.
|
||||
fn to_animated_zero(&self) -> Result<Self, ()>;
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for Au {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(Au(0)) }
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for f32 {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(0.) }
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for f64 {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(0.) }
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for i32 {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Ok(0) }
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//! Computed types for CSS values related to backgrounds.
|
||||
|
||||
use properties::animated_properties::{Animatable, RepeatableListAnimatable};
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::length::LengthOrPercentageOrAuto;
|
||||
use values::generics::background::BackgroundSize as GenericBackgroundSize;
|
||||
|
||||
|
@ -50,3 +51,8 @@ impl Animatable for BackgroundSize {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for BackgroundSize {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
use app_units::Au;
|
||||
use properties::animated_properties::Animatable;
|
||||
use values::{CSSInteger, CSSFloat};
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::length::{Length, LengthOrPercentage};
|
||||
use values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use values::generics::text::LineHeight as GenericLineHeight;
|
||||
|
@ -61,3 +62,8 @@ impl Animatable for LineHeight {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for LineHeight {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//! Computed types for CSS values that are related to transformations.
|
||||
|
||||
use properties::animated_properties::Animatable;
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::{Length, LengthOrPercentage, Number, Percentage};
|
||||
use values::generics::transform::TimingFunction as GenericTimingFunction;
|
||||
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
|
||||
|
@ -51,3 +52,14 @@ impl Animatable for TransformOrigin {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for TransformOrigin {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
Ok(Self::new(
|
||||
self.horizontal.to_animated_zero()?,
|
||||
self.vertical.to_animated_zero()?,
|
||||
self.depth.to_animated_zero()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use cssparser::Parser;
|
|||
use parser::ParserContext;
|
||||
use properties::animated_properties::Animatable;
|
||||
use style_traits::ParseError;
|
||||
use values::animated::ToAnimatedZero;
|
||||
|
||||
/// A generic value for the `initial-letter` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -93,6 +94,14 @@ impl<Value> Animatable for Spacing<Value>
|
|||
}
|
||||
}
|
||||
|
||||
impl<V> ToAnimatedZero for Spacing<V>
|
||||
where
|
||||
V: From<Au>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
||||
}
|
||||
|
||||
/// A generic value for the `line-height` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
//! Generic types for CSS values that are related to transformations.
|
||||
|
||||
use euclid::Point2D;
|
||||
use std::fmt;
|
||||
use style_traits::{HasViewportPercentage, ToCss};
|
||||
use values::CSSFloat;
|
||||
|
@ -44,7 +43,8 @@ pub enum TimingFunction<Integer, Number> {
|
|||
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
||||
Keyword(TimingKeyword),
|
||||
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
|
||||
CubicBezier(Point2D<Number>, Point2D<Number>),
|
||||
#[allow(missing_docs)]
|
||||
CubicBezier { x1: Number, y1: Number, x2: Number, y2: Number },
|
||||
/// `step-start | step-end | steps(<integer>, [ start | end ]?)`
|
||||
Steps(Integer, StepPosition),
|
||||
/// `frames(<integer>)`
|
||||
|
@ -100,15 +100,15 @@ where
|
|||
{
|
||||
match *self {
|
||||
TimingFunction::Keyword(keyword) => keyword.to_css(dest),
|
||||
TimingFunction::CubicBezier(ref p1, ref p2) => {
|
||||
TimingFunction::CubicBezier { ref x1, ref y1, ref x2, ref y2 } => {
|
||||
dest.write_str("cubic-bezier(")?;
|
||||
p1.x.to_css(dest)?;
|
||||
x1.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p1.y.to_css(dest)?;
|
||||
y1.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p2.x.to_css(dest)?;
|
||||
x2.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
p2.y.to_css(dest)?;
|
||||
y2.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
},
|
||||
TimingFunction::Steps(ref intervals, position) => {
|
||||
|
@ -130,15 +130,16 @@ where
|
|||
}
|
||||
|
||||
impl TimingKeyword {
|
||||
/// Returns this timing keyword as a pair of `cubic-bezier()` points.
|
||||
/// Returns the keyword as a quadruplet of Bezier point coordinates
|
||||
/// `(x1, y1, x2, y2)`.
|
||||
#[inline]
|
||||
pub fn to_bezier_points(self) -> (Point2D<CSSFloat>, Point2D<CSSFloat>) {
|
||||
pub fn to_bezier(self) -> (CSSFloat, CSSFloat, CSSFloat, CSSFloat) {
|
||||
match self {
|
||||
TimingKeyword::Linear => (Point2D::new(0., 0.), Point2D::new(1., 1.)),
|
||||
TimingKeyword::Ease => (Point2D::new(0.25, 0.1), Point2D::new(0.25, 1.)),
|
||||
TimingKeyword::EaseIn => (Point2D::new(0.42, 0.), Point2D::new(1., 1.)),
|
||||
TimingKeyword::EaseOut => (Point2D::new(0., 0.), Point2D::new(0.58, 1.)),
|
||||
TimingKeyword::EaseInOut => (Point2D::new(0.42, 0.), Point2D::new(0.58, 1.)),
|
||||
TimingKeyword::Linear => (0., 0., 1., 1.),
|
||||
TimingKeyword::Ease => (0.25, 0.1, 0.25, 1.),
|
||||
TimingKeyword::EaseIn => (0.42, 0., 1., 1.),
|
||||
TimingKeyword::EaseOut => (0., 0., 0.58, 1.),
|
||||
TimingKeyword::EaseInOut => (0.42, 0., 0.58, 1.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
//! Specified types for CSS values that are related to transformations.
|
||||
|
||||
use cssparser::Parser;
|
||||
use euclid::Point2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use selectors::parser::SelectorParseError;
|
||||
use style_traits::{ParseError, StyleParseError};
|
||||
|
@ -160,20 +159,19 @@ impl Parse for TimingFunction {
|
|||
input.parse_nested_block(move |i| {
|
||||
(match_ignore_ascii_case! { &function,
|
||||
"cubic-bezier" => {
|
||||
let p1x = Number::parse(context, i)?;
|
||||
let x1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let p1y = Number::parse(context, i)?;
|
||||
let y1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let p2x = Number::parse(context, i)?;
|
||||
let x2 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let p2y = Number::parse(context, i)?;
|
||||
let y2 = Number::parse(context, i)?;
|
||||
|
||||
if p1x.get() < 0.0 || p1x.get() > 1.0 || p2x.get() < 0.0 || p2x.get() > 1.0 {
|
||||
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
||||
return Err(StyleParseError::UnspecifiedError.into());
|
||||
}
|
||||
|
||||
let (p1, p2) = (Point2D::new(p1x, p1y), Point2D::new(p2x, p2y));
|
||||
Ok(GenericTimingFunction::CubicBezier(p1, p2))
|
||||
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||
},
|
||||
"steps" => {
|
||||
let steps = Integer::parse_positive(context, i)?;
|
||||
|
@ -206,17 +204,13 @@ impl ToComputedValue for TimingFunction {
|
|||
GenericTimingFunction::Keyword(keyword) => {
|
||||
GenericTimingFunction::Keyword(keyword)
|
||||
},
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
GenericTimingFunction::CubicBezier(
|
||||
Point2D::new(
|
||||
p1.x.to_computed_value(context),
|
||||
p1.y.to_computed_value(context),
|
||||
),
|
||||
Point2D::new(
|
||||
p2.x.to_computed_value(context),
|
||||
p2.y.to_computed_value(context),
|
||||
),
|
||||
)
|
||||
GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||
GenericTimingFunction::CubicBezier {
|
||||
x1: x1.to_computed_value(context),
|
||||
y1: y1.to_computed_value(context),
|
||||
x2: x2.to_computed_value(context),
|
||||
y2: y2.to_computed_value(context),
|
||||
}
|
||||
},
|
||||
GenericTimingFunction::Steps(steps, position) => {
|
||||
GenericTimingFunction::Steps(
|
||||
|
@ -238,17 +232,13 @@ impl ToComputedValue for TimingFunction {
|
|||
GenericTimingFunction::Keyword(keyword) => {
|
||||
GenericTimingFunction::Keyword(keyword)
|
||||
},
|
||||
GenericTimingFunction::CubicBezier(p1, p2) => {
|
||||
GenericTimingFunction::CubicBezier(
|
||||
Point2D::new(
|
||||
Number::from_computed_value(&p1.x),
|
||||
Number::from_computed_value(&p1.y),
|
||||
),
|
||||
Point2D::new(
|
||||
Number::from_computed_value(&p2.x),
|
||||
Number::from_computed_value(&p2.y),
|
||||
),
|
||||
)
|
||||
GenericTimingFunction::CubicBezier { ref x1, ref y1, ref x2, ref y2 } => {
|
||||
GenericTimingFunction::CubicBezier {
|
||||
x1: Number::from_computed_value(x1),
|
||||
y1: Number::from_computed_value(y1),
|
||||
x2: Number::from_computed_value(x2),
|
||||
y2: Number::from_computed_value(y2),
|
||||
}
|
||||
},
|
||||
GenericTimingFunction::Steps(steps, position) => {
|
||||
GenericTimingFunction::Steps(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue