mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Introduce ComputeSquaredDistance
This allows us to merge the former Animatable methods compute_distance and compute_squared_distance, reducing code size.
This commit is contained in:
parent
b14e68f915
commit
51b740033b
21 changed files with 641 additions and 551 deletions
|
@ -117,5 +117,15 @@ macro_rules! define_keyword_type {
|
|||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> { Ok($name) }
|
||||
}
|
||||
|
||||
impl $crate::values::distance::ComputeSquaredDistance for $name {
|
||||
#[inline]
|
||||
fn compute_squared_distance(
|
||||
&self,
|
||||
_other: &Self
|
||||
) -> Result<$crate::values::distance::SquaredDistance, ()> {
|
||||
Ok($crate::values::distance::SquaredDistance::Value(0.))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
% if need_animatable or animation_value_type == "ComputedValue":
|
||||
use properties::animated_properties::Animatable;
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
impl Animatable for T {
|
||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
|
||||
|
@ -142,14 +143,11 @@
|
|||
fn add(&self, other: &Self) -> Result<Self, ()> {
|
||||
self.0.add(&other.0).map(T)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for T {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.0.compute_distance(&other.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToC
|
|||
use values::computed::{NonNegativeAu, NonNegativeNumber, PositiveIntegerOrAuto};
|
||||
use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal};
|
||||
use values::computed::length::NonNegativeLengthOrPercentage;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::{GreaterThanOrEqualToOne, NonNegative};
|
||||
use values::generics::effects::Filter;
|
||||
use values::generics::position as generic_position;
|
||||
|
@ -83,16 +84,6 @@ pub trait Animatable: Sized {
|
|||
fn accumulate(&self, other: &Self, count: u64) -> Result<Self, ()> {
|
||||
self.add_weighted(other, count as f64, 1.0)
|
||||
}
|
||||
|
||||
/// Compute distance between a value and another for a given property.
|
||||
fn compute_distance(&self, _other: &Self) -> Result<f64, ()> { Err(()) }
|
||||
|
||||
/// In order to compute the Euclidean distance of a list or property value with multiple
|
||||
/// components, we need to compute squared distance for each element, so the vector can sum it
|
||||
/// and then get its squared root as the distance.
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_distance(other).map(|d| d * d)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-repeatable-list
|
||||
|
@ -741,28 +732,31 @@ impl Animatable for AnimationValue {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl ComputeSquaredDistance for AnimationValue {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
% for prop in data.longhands:
|
||||
% if prop.animatable:
|
||||
% if prop.animation_value_type != "discrete":
|
||||
(&AnimationValue::${prop.camel_case}(ref from),
|
||||
&AnimationValue::${prop.camel_case}(ref to)) => {
|
||||
from.compute_distance(to)
|
||||
},
|
||||
% else:
|
||||
(&AnimationValue::${prop.camel_case}(ref _from),
|
||||
&AnimationValue::${prop.camel_case}(ref _to)) => {
|
||||
Err(())
|
||||
},
|
||||
% endif
|
||||
% endif
|
||||
% if prop.animatable:
|
||||
% if prop.animation_value_type != "discrete":
|
||||
(&AnimationValue::${prop.camel_case}(ref this), &AnimationValue::${prop.camel_case}(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
% else:
|
||||
(&AnimationValue::${prop.camel_case}(_), &AnimationValue::${prop.camel_case}(_)) => {
|
||||
Err(())
|
||||
},
|
||||
% endif
|
||||
% endif
|
||||
% endfor
|
||||
_ => {
|
||||
panic!("Expected compute_distance of computed values of the same \
|
||||
property, got: {:?}, {:?}", self, other);
|
||||
}
|
||||
panic!(
|
||||
"computed values should be of the same property, got: {:?}, {:?}",
|
||||
self,
|
||||
other
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -802,22 +796,21 @@ macro_rules! repeated_vec_impl {
|
|||
me.add_weighted(you, self_portion, other_portion)
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ComputeSquaredDistance for $ty
|
||||
where
|
||||
T: ComputeSquaredDistance + RepeatableListAnimatable,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
// If the length of either list is zero, the least common multiple is undefined.
|
||||
if cmp::min(self.len(), other.len()) < 1 {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
if self.is_empty() || other.is_empty() {
|
||||
return Err(());
|
||||
}
|
||||
use num_integer::lcm;
|
||||
let len = lcm(self.len(), other.len());
|
||||
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
|
||||
me.compute_squared_distance(you)
|
||||
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(this, other)| {
|
||||
this.compute_squared_distance(other)
|
||||
}).sum()
|
||||
}
|
||||
})*
|
||||
|
@ -832,11 +825,6 @@ impl Animatable for Au {
|
|||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
Ok(Au((self.0 as f64 * self_portion + other.0 as f64 * other_portion).round() as i32))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.0.compute_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> Animatable for Option<T>
|
||||
|
@ -852,28 +840,6 @@ impl <T> Animatable for Option<T>
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&Some(ref this), &Some(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(&None, &None) => Ok(0.0),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&Some(ref this), &Some(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&None, &None) => Ok(0.0),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
|
@ -882,11 +848,6 @@ impl Animatable for f32 {
|
|||
fn add_weighted(&self, other: &f32, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
Ok((*self as f64 * self_portion + *other as f64 * other_portion) as f32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok((*self - *other).abs() as f64)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
|
@ -895,11 +856,6 @@ impl Animatable for f64 {
|
|||
fn add_weighted(&self, other: &f64, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
Ok(*self * self_portion + *other * other_portion)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok((*self - *other).abs())
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-integer
|
||||
|
@ -908,11 +864,6 @@ impl Animatable for i32 {
|
|||
fn add_weighted(&self, other: &i32, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
Ok((*self as f64 * self_portion + *other as f64 * other_portion).round() as i32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok((*self - *other).abs() as f64)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||
|
@ -934,13 +885,6 @@ impl Animatable for Angle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
// Use the formula for calculating the distance between angles defined in SVG:
|
||||
// https://www.w3.org/TR/SVG/animate.html#complexDistances
|
||||
Ok((self.radians64() - other.radians64()).abs())
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-percentage
|
||||
|
@ -949,11 +893,6 @@ impl Animatable for Percentage {
|
|||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok((self.0 as f64 - other.0 as f64).abs())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for Percentage {
|
||||
|
@ -977,14 +916,12 @@ impl Animatable for Visibility {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for Visibility {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
if *self == *other {
|
||||
Ok(0.0)
|
||||
} else {
|
||||
Ok(1.0)
|
||||
}
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(SquaredDistance::Value(if *self == *other { 0. } else { 1. }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1003,16 +940,6 @@ impl<T: Animatable + Copy> Animatable for Size2D<T> {
|
|||
|
||||
Ok(Size2D::new(width, height))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.width.compute_squared_distance(&other.width)? + self.height.compute_squared_distance(&other.height)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Animatable + Copy> Animatable for Point2D<T> {
|
||||
|
@ -1044,15 +971,20 @@ impl Animatable for VerticalAlign {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for VerticalAlign {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(VerticalAlign::LengthOrPercentage(ref this),
|
||||
VerticalAlign::LengthOrPercentage(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&VerticalAlign::LengthOrPercentage(ref this), &VerticalAlign::LengthOrPercentage(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))`
|
||||
// if `self` and `other` are the same keyword value?
|
||||
Err(())
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1087,18 +1019,6 @@ impl Animatable for CalcLengthOrPercentage {
|
|||
let percentage = add_weighted_half(self.percentage, other.percentage, self_portion, other_portion)?;
|
||||
Ok(CalcLengthOrPercentage::with_clamping_mode(length, percentage, self.clamping_mode))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sq| sq.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let length_diff = (self.unclamped_length().0 - other.unclamped_length().0) as f64;
|
||||
let percentage_diff = (self.percentage() - other.percentage()) as f64;
|
||||
Ok(length_diff * length_diff + percentage_diff * percentage_diff)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
|
||||
|
@ -1131,48 +1051,6 @@ impl Animatable for LengthOrPercentage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentage::Length(ref this),
|
||||
LengthOrPercentage::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(LengthOrPercentage::Percentage(ref this),
|
||||
LengthOrPercentage::Percentage(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
let this: CalcLengthOrPercentage = From::from(this);
|
||||
let other: CalcLengthOrPercentage = From::from(other);
|
||||
this.compute_distance(&other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentage::Length(ref this),
|
||||
LengthOrPercentage::Length(ref other)) => {
|
||||
let diff = (this.0 - other.0) as f64;
|
||||
Ok(diff * diff)
|
||||
},
|
||||
(LengthOrPercentage::Percentage(ref this),
|
||||
LengthOrPercentage::Percentage(ref other)) => {
|
||||
let diff = this.0 as f64 - other.0 as f64;
|
||||
Ok(diff * diff)
|
||||
},
|
||||
(this, other) => {
|
||||
let this: CalcLengthOrPercentage = From::from(this);
|
||||
let other: CalcLengthOrPercentage = From::from(other);
|
||||
let length_diff = (this.unclamped_length().0 - other.unclamped_length().0) as f64;
|
||||
let percentage_diff = (this.percentage() - other.percentage()) as f64;
|
||||
Ok(length_diff * length_diff + percentage_diff * percentage_diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for LengthOrPercentage {
|
||||
|
@ -1210,53 +1088,6 @@ impl Animatable for LengthOrPercentageOrAuto {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrAuto::Length(ref this),
|
||||
LengthOrPercentageOrAuto::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(LengthOrPercentageOrAuto::Percentage(ref this),
|
||||
LengthOrPercentageOrAuto::Percentage(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
// If one of the element is Auto, Option<> will be None, and the returned distance is Err(())
|
||||
let this: Option<CalcLengthOrPercentage> = From::from(this);
|
||||
let other: Option<CalcLengthOrPercentage> = From::from(other);
|
||||
this.compute_distance(&other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrAuto::Length(ref this),
|
||||
LengthOrPercentageOrAuto::Length(ref other)) => {
|
||||
let diff = (this.0 - other.0) as f64;
|
||||
Ok(diff * diff)
|
||||
},
|
||||
(LengthOrPercentageOrAuto::Percentage(ref this),
|
||||
LengthOrPercentageOrAuto::Percentage(ref other)) => {
|
||||
let diff = this.0 as f64 - other.0 as f64;
|
||||
Ok(diff * diff)
|
||||
},
|
||||
(this, other) => {
|
||||
let this: Option<CalcLengthOrPercentage> = From::from(this);
|
||||
let other: Option<CalcLengthOrPercentage> = From::from(other);
|
||||
if let (Some(this), Some(other)) = (this, other) {
|
||||
let length_diff = (this.unclamped_length().0 - other.unclamped_length().0) as f64;
|
||||
let percentage_diff = (this.percentage() - other.percentage()) as f64;
|
||||
Ok(length_diff * length_diff + percentage_diff * percentage_diff)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for LengthOrPercentageOrAuto {
|
||||
|
@ -1301,26 +1132,6 @@ impl Animatable for LengthOrPercentageOrNone {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrNone::Length(ref this),
|
||||
LengthOrPercentageOrNone::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(LengthOrPercentageOrNone::Percentage(ref this),
|
||||
LengthOrPercentageOrNone::Percentage(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
// If one of the element is Auto, Option<> will be None, and the returned distance is Err(())
|
||||
let this = <Option<CalcLengthOrPercentage>>::from(this);
|
||||
let other = <Option<CalcLengthOrPercentage>>::from(other);
|
||||
this.compute_distance(&other)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for LengthOrPercentageOrNone {
|
||||
|
@ -1350,17 +1161,6 @@ impl Animatable for MozLength {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(MozLength::LengthOrPercentageOrAuto(ref this),
|
||||
MozLength::LengthOrPercentageOrAuto(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for MozLength {
|
||||
|
@ -1388,17 +1188,6 @@ impl Animatable for MaxLength {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(MaxLength::LengthOrPercentageOrNone(ref this),
|
||||
MaxLength::LengthOrPercentageOrNone(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for MaxLength {
|
||||
|
@ -1417,13 +1206,6 @@ impl Animatable for FontWeight {
|
|||
let weight = (weight.max(100.).min(900.) / 100.).round() * 100.;
|
||||
Ok(FontWeight(weight as u16))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let a = self.0 as f64;
|
||||
let b = other.0 as f64;
|
||||
a.compute_distance(&b)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for FontWeight {
|
||||
|
@ -1447,12 +1229,12 @@ impl Animatable for FontStretch {
|
|||
|
||||
Ok(result.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for FontStretch {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let from = f64::from(*self);
|
||||
let to = f64::from(*other);
|
||||
from.compute_distance(&to)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
f64::from(*self).compute_squared_distance(&(*other).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1500,17 +1282,6 @@ impl<H: Animatable, V: Animatable> Animatable for generic_position::Position<H,
|
|||
vertical: self.vertical.add_weighted(&other.vertical, self_portion, other_portion)?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
self.vertical.compute_squared_distance(&other.vertical)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, V> ToAnimatedZero for generic_position::Position<H, V>
|
||||
|
@ -1542,22 +1313,6 @@ impl Animatable for ClipRect {
|
|||
left: self.left.add_weighted(&other.left, self_portion, other_portion)?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let list = [
|
||||
self.top.compute_distance(&other.top)?,
|
||||
self.right.compute_distance(&other.right)?,
|
||||
self.bottom.compute_distance(&other.bottom)?,
|
||||
self.left.compute_distance(&other.left)?
|
||||
];
|
||||
Ok(list.iter().fold(0.0f64, |sum, diff| sum + diff * diff))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for ClipRect {
|
||||
|
@ -2641,6 +2396,14 @@ impl Animatable for TransformList {
|
|||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for TransformList {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, _other: &Self) -> Result<SquaredDistance, ()> {
|
||||
// FIXME: This should be implemented.
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for TransformList {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
|
@ -2666,32 +2429,6 @@ impl<T, U> Animatable for Either<T, U>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&Either::First(ref this), &Either::First(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(&Either::Second(ref this), &Either::Second(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&Either::First(ref this), &Either::First(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&Either::Second(ref this), &Either::Second(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B> ToAnimatedZero for Either<A, B>
|
||||
|
@ -2789,28 +2526,14 @@ impl Animatable for IntermediateRGBA {
|
|||
Ok(IntermediateRGBA::new(red, green, blue, alpha))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for IntermediateRGBA {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sq| sq.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let start = [ self.alpha,
|
||||
self.red * self.alpha,
|
||||
self.green * self.alpha,
|
||||
self.blue * self.alpha ];
|
||||
let end = [ other.alpha,
|
||||
other.red * other.alpha,
|
||||
other.green * other.alpha,
|
||||
other.blue * other.alpha ];
|
||||
let diff = start.iter().zip(&end)
|
||||
.fold(0.0f64, |n, (&a, &b)| {
|
||||
let diff = (a - b) as f64;
|
||||
n + diff * diff
|
||||
});
|
||||
Ok(diff)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
let start = [ self.alpha, self.red * self.alpha, self.green * self.alpha, self.blue * self.alpha ];
|
||||
let end = [ other.alpha, other.red * other.alpha, other.green * other.alpha, other.blue * other.alpha ];
|
||||
start.iter().zip(&end).map(|(this, other)| this.compute_squared_distance(other)).sum()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2930,31 +2653,35 @@ impl Animatable for IntermediateColor {
|
|||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for IntermediateColor {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sq| sq.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
// All comments in add_weighted also applies here.
|
||||
if self.foreground_ratio == other.foreground_ratio {
|
||||
if self.is_currentcolor() {
|
||||
Ok(0.)
|
||||
Ok(SquaredDistance::Value(0.))
|
||||
} else {
|
||||
self.color.compute_squared_distance(&other.color)
|
||||
}
|
||||
} else if self.is_currentcolor() && other.is_numeric() {
|
||||
Ok(IntermediateRGBA::transparent().compute_squared_distance(&other.color)? + 1.)
|
||||
Ok(
|
||||
IntermediateRGBA::transparent().compute_squared_distance(&other.color)? +
|
||||
SquaredDistance::Value(1.),
|
||||
)
|
||||
} else if self.is_numeric() && other.is_currentcolor() {
|
||||
Ok(self.color.compute_squared_distance(&IntermediateRGBA::transparent())? + 1.)
|
||||
Ok(
|
||||
self.color.compute_squared_distance(&IntermediateRGBA::transparent())? +
|
||||
SquaredDistance::Value(1.),
|
||||
)
|
||||
} else {
|
||||
let self_color = self.effective_intermediate_rgba();
|
||||
let other_color = other.effective_intermediate_rgba();
|
||||
let dist = self_color.compute_squared_distance(&other_color)?;
|
||||
let ratio_diff = (self.foreground_ratio - other.foreground_ratio) as f64;
|
||||
Ok(dist + ratio_diff * ratio_diff)
|
||||
Ok(
|
||||
self_color.compute_squared_distance(&other_color)? +
|
||||
self.foreground_ratio.compute_squared_distance(&other.foreground_ratio)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2978,16 +2705,15 @@ impl Animatable for IntermediateSVGPaint {
|
|||
fallback: self.fallback.add_weighted(&other.fallback, self_portion, other_portion)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for IntermediateSVGPaint {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sq| sq.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.kind.compute_squared_distance(&other.kind)? +
|
||||
self.fallback.compute_squared_distance(&other.fallback)?)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.kind.compute_squared_distance(&other.kind)? +
|
||||
self.fallback.compute_squared_distance(&other.fallback)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3016,16 +2742,20 @@ impl Animatable for IntermediateSVGPaintKind {
|
|||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for IntermediateSVGPaintKind {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&SVGPaintKind::Color(ref self_color), &SVGPaintKind::Color(ref other_color)) => {
|
||||
self_color.compute_distance(other_color)
|
||||
(&SVGPaintKind::Color(ref this), &SVGPaintKind::Color(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
}
|
||||
(&SVGPaintKind::None, &SVGPaintKind::None) |
|
||||
(&SVGPaintKind::ContextFill, &SVGPaintKind::ContextFill) |
|
||||
(&SVGPaintKind::ContextStroke, &SVGPaintKind::ContextStroke)=> Ok(0.0),
|
||||
(&SVGPaintKind::ContextStroke, &SVGPaintKind::ContextStroke) => {
|
||||
Ok(SquaredDistance::Value(0.))
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
@ -3060,16 +2790,6 @@ impl<LengthType> Animatable for SVGLength<LengthType>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&SVGLength::Length(ref this), &SVGLength::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
}
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthType> ToAnimatedZero for SVGLength<LengthType> where LengthType : ToAnimatedZero {
|
||||
|
@ -3097,16 +2817,6 @@ impl<LengthType> Animatable for SVGStrokeDashArray<LengthType>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
}
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthType> ToAnimatedZero for SVGStrokeDashArray<LengthType>
|
||||
|
@ -3138,16 +2848,6 @@ impl<OpacityType> Animatable for SVGOpacity<OpacityType>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
}
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<OpacityType> ToAnimatedZero for SVGOpacity<OpacityType>
|
||||
|
@ -3246,9 +2946,7 @@ fn add_weighted_filter_function(from: Option<<&AnimatedFilter>,
|
|||
}
|
||||
}
|
||||
|
||||
fn compute_filter_square_distance(from: &AnimatedFilter,
|
||||
to: &AnimatedFilter)
|
||||
-> Result<f64, ()> {
|
||||
fn compute_filter_square_distance(from: &AnimatedFilter, to: &AnimatedFilter) -> Result<SquaredDistance, ()> {
|
||||
match (from, to) {
|
||||
% for func in FILTER_FUNCTIONS :
|
||||
(&Filter::${func}(f),
|
||||
|
@ -3296,29 +2994,24 @@ impl Animatable for AnimatedFilterList {
|
|||
fn add(&self, other: &Self) -> Result<Self, ()> {
|
||||
Ok(AnimatedFilterList(self.0.iter().chain(other.0.iter()).cloned().collect()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for AnimatedFilterList {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
|
||||
let mut square_distance: f64 = 0.0;
|
||||
for it in self.0.iter().zip_longest(other.0.iter()) {
|
||||
square_distance += match it {
|
||||
self.0.iter().zip_longest(other.0.iter()).map(|it| {
|
||||
match it {
|
||||
EitherOrBoth::Both(from, to) => {
|
||||
compute_filter_square_distance(&from, &to)?
|
||||
compute_filter_square_distance(&from, &to)
|
||||
},
|
||||
EitherOrBoth::Left(list) | EitherOrBoth::Right(list)=> {
|
||||
let none = add_weighted_filter_function(Some(list), Some(list), 0.0, 0.0)?;
|
||||
compute_filter_square_distance(&none, &list)?
|
||||
compute_filter_square_distance(&none, &list)
|
||||
},
|
||||
};
|
||||
}
|
||||
Ok(square_distance)
|
||||
}
|
||||
}).sum()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3382,11 +3075,6 @@ impl<T> Animatable for NonNegative<T>
|
|||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
self.0.add_weighted(&other.0, self_portion, other_portion).map(NonNegative::<T>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.0.compute_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedZero for NonNegative<T>
|
||||
|
@ -3405,11 +3093,6 @@ impl<T> Animatable for GreaterThanOrEqualToOne<T>
|
|||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
self.0.add_weighted(&other.0, self_portion, other_portion).map(GreaterThanOrEqualToOne::<T>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.0.compute_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedZero for GreaterThanOrEqualToOne<T>
|
||||
|
|
|
@ -480,6 +480,8 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
}
|
||||
|
||||
pub mod computed_value {
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
/// As of CSS Fonts Module Level 3, only the following values are
|
||||
/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
||||
///
|
||||
|
@ -489,6 +491,13 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
pub struct T(pub u16);
|
||||
|
||||
impl ComputeSquaredDistance for T {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl T {
|
||||
/// Value for normal
|
||||
pub fn normal() -> Self {
|
||||
|
@ -1118,6 +1127,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
use properties::animated_properties::Animatable;
|
||||
use values::CSSFloat;
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, ToCss)]
|
||||
|
@ -1145,12 +1155,13 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for T {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(T::Number(ref number), T::Number(ref other)) =>
|
||||
number.compute_distance(other),
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&T::Number(ref this), &T::Number(ref other)) => this.compute_squared_distance(other),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
|
|||
pub mod computed_value {
|
||||
use properties::animated_properties::Animatable;
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::computed::NonNegativeAu;
|
||||
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -49,16 +50,15 @@ ${helpers.single_keyword("caption-side", "top bottom",
|
|||
self_portion, other_portion)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for T {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
self.vertical.compute_squared_distance(&other.vertical)?)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
self.vertical.compute_squared_distance(&other.vertical)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ use values::Impossible;
|
|||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::computed::{Angle, NonNegativeNumber};
|
||||
use values::computed::length::{Length, NonNegativeLength};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use values::generics::effects::Filter as GenericFilter;
|
||||
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||
|
@ -102,6 +103,14 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> ComputeSquaredDistance for ShadowList<S> {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, _other: &Self) -> Result<SquaredDistance, ()> {
|
||||
// FIXME: This should be implemented.
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> ToAnimatedZero for ShadowList<S> {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
|
@ -140,14 +149,11 @@ impl Animatable for BoxShadow {
|
|||
inset: self.inset,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for BoxShadow {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
if self.inset != other.inset {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -219,14 +225,11 @@ impl Animatable for SimpleShadow {
|
|||
blur: blur,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for SimpleShadow {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.color.compute_squared_distance(&other.color)? +
|
||||
self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
|
|
|
@ -8,6 +8,7 @@ use properties::animated_properties::{Animatable, RepeatableListAnimatable};
|
|||
use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::computed::length::LengthOrPercentageOrAuto;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::background::BackgroundSize as GenericBackgroundSize;
|
||||
|
||||
/// A computed value for the `background-size` property.
|
||||
|
@ -30,14 +31,11 @@ impl Animatable for BackgroundSize {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for BackgroundSize {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(
|
||||
&GenericBackgroundSize::Explicit { width: self_width, height: self_height },
|
||||
|
|
|
@ -12,6 +12,7 @@ use style_traits::values::specified::AllowedLengthType;
|
|||
use super::{Number, ToComputedValue, Context, Percentage};
|
||||
use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified};
|
||||
use values::computed::{NonNegativeAu, NonNegativeNumber};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::NonNegative;
|
||||
use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
|
||||
use values::specified::length::ViewportPercentageLength;
|
||||
|
@ -71,6 +72,18 @@ pub struct CalcLengthOrPercentage {
|
|||
pub percentage: Option<Percentage>,
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for CalcLengthOrPercentage {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
// FIXME(nox): This looks incorrect to me, to add a distance between lengths
|
||||
// with a distance between percentages.
|
||||
Ok(
|
||||
self.unclamped_length().compute_squared_distance(&other.unclamped_length())? +
|
||||
self.percentage().compute_squared_distance(&other.percentage())?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl CalcLengthOrPercentage {
|
||||
/// Returns a new `CalcLengthOrPercentage`.
|
||||
#[inline]
|
||||
|
@ -257,6 +270,23 @@ pub enum LengthOrPercentage {
|
|||
Calc(CalcLengthOrPercentage),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&LengthOrPercentage::Length(ref this), &LengthOrPercentage::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&LengthOrPercentage::Percentage(ref this), &LengthOrPercentage::Percentage(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
CalcLengthOrPercentage::compute_squared_distance(&(*this).into(), &(*other).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Au> for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn from(length: Au) -> Self {
|
||||
|
@ -382,6 +412,23 @@ pub enum LengthOrPercentageOrAuto {
|
|||
Calc(CalcLengthOrPercentage),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for LengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&LengthOrPercentageOrAuto::Length(ref this), &LengthOrPercentageOrAuto::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&LengthOrPercentageOrAuto::Percentage(ref this), &LengthOrPercentageOrAuto::Percentage(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
<Option<CalcLengthOrPercentage>>::compute_squared_distance(&(*this).into(), &(*other).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthOrPercentageOrAuto {
|
||||
/// Returns true if the computed value is absolute 0 or 0%.
|
||||
///
|
||||
|
@ -460,6 +507,23 @@ pub enum LengthOrPercentageOrNone {
|
|||
None,
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for LengthOrPercentageOrNone {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&LengthOrPercentageOrNone::Length(ref this), &LengthOrPercentageOrNone::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&LengthOrPercentageOrNone::Percentage(ref this), &LengthOrPercentageOrNone::Percentage(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(this, other) => {
|
||||
<Option<CalcLengthOrPercentage>>::compute_squared_distance(&(*this).into(), &(*other).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthOrPercentageOrNone {
|
||||
/// Returns the used value.
|
||||
pub fn to_used_value(&self, containing_length: Au) -> Option<Au> {
|
||||
|
@ -607,6 +671,22 @@ pub enum MozLength {
|
|||
ExtremumLength(ExtremumLength),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for MozLength {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&MozLength::LengthOrPercentageOrAuto(ref this), &MozLength::LengthOrPercentageOrAuto(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(1.))`
|
||||
// when `self` and `other` are the same extremum value?
|
||||
Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MozLength {
|
||||
/// Returns the `auto` value.
|
||||
pub fn auto() -> Self {
|
||||
|
@ -651,6 +731,22 @@ pub enum MaxLength {
|
|||
ExtremumLength(ExtremumLength),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for MaxLength {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&MaxLength::LengthOrPercentageOrNone(ref this), &MaxLength::LengthOrPercentageOrNone(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(1.))`
|
||||
// when `self` and `other` are the same extremum value?
|
||||
Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MaxLength {
|
||||
/// Returns the `none` value.
|
||||
pub fn none() -> Self {
|
||||
|
|
|
@ -22,6 +22,7 @@ use std::fmt;
|
|||
use std::sync::Arc;
|
||||
use style_traits::ToCss;
|
||||
use super::{CSSFloat, CSSInteger};
|
||||
use super::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::generics::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize};
|
||||
use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||
|
@ -338,6 +339,15 @@ pub enum Angle {
|
|||
Turn(CSSFloat),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for Angle {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
// Use the formula for calculating the distance between angles defined in SVG:
|
||||
// https://www.w3.org/TR/SVG/animate.html#complexDistances
|
||||
self.radians64().compute_squared_distance(&other.radians64())
|
||||
}
|
||||
}
|
||||
|
||||
impl Angle {
|
||||
/// Construct a computed `Angle` value from a radian amount.
|
||||
pub fn from_radians(radians: CSSFloat) -> Self {
|
||||
|
@ -544,6 +554,18 @@ pub struct ClipRect {
|
|||
pub left: Option<Au>,
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for ClipRect {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.top.compute_squared_distance(&other.top)? +
|
||||
self.right.compute_squared_distance(&other.right)? +
|
||||
self.bottom.compute_squared_distance(&other.bottom)? +
|
||||
self.left.compute_squared_distance(&other.left)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for ClipRect {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
dest.write_str("rect(")?;
|
||||
|
@ -653,6 +675,13 @@ impl From<Au> for NonNegativeAu {
|
|||
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
|
||||
pub struct Percentage(pub CSSFloat);
|
||||
|
||||
impl ComputeSquaredDistance for Percentage {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Percentage {
|
||||
/// 0%
|
||||
#[inline]
|
||||
|
|
|
@ -9,6 +9,7 @@ use values::{CSSInteger, CSSFloat};
|
|||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::{NonNegativeAu, NonNegativeNumber};
|
||||
use values::computed::length::{Length, LengthOrPercentage};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use values::generics::text::LineHeight as GenericLineHeight;
|
||||
use values::generics::text::Spacing;
|
||||
|
@ -45,19 +46,25 @@ impl Animatable for LineHeight {
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for LineHeight {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (*self, *other) {
|
||||
(GenericLineHeight::Length(ref this), GenericLineHeight::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&GenericLineHeight::Length(ref this), &GenericLineHeight::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(GenericLineHeight::Number(ref this), GenericLineHeight::Number(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
(&GenericLineHeight::Number(ref this), &GenericLineHeight::Number(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&GenericLineHeight::Normal, &GenericLineHeight::Normal) => {
|
||||
Ok(SquaredDistance::Value(0.))
|
||||
},
|
||||
(GenericLineHeight::Normal, GenericLineHeight::Normal) => Ok(0.),
|
||||
#[cfg(feature = "gecko")]
|
||||
(GenericLineHeight::MozBlockHeight, GenericLineHeight::MozBlockHeight) => Ok(0.),
|
||||
(&GenericLineHeight::MozBlockHeight, &GenericLineHeight::MozBlockHeight) => {
|
||||
Ok(SquaredDistance::Value(0.))
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
use properties::animated_properties::Animatable;
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::{Length, LengthOrPercentage, Number, Percentage};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::transform::TimingFunction as GenericTimingFunction;
|
||||
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
|
||||
|
||||
|
@ -37,14 +38,11 @@ impl Animatable for TransformOrigin {
|
|||
self.depth.add_weighted(&other.depth, self_portion, other_portion)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for TransformOrigin {
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.compute_squared_distance(other).map(f64::sqrt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
self.vertical.compute_squared_distance(&other.vertical)? +
|
||||
|
|
124
components/style/values/distance.rs
Normal file
124
components/style/values/distance.rs
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Machinery to compute distances between animatable values.
|
||||
|
||||
use app_units::Au;
|
||||
use euclid::Size2D;
|
||||
use std::iter::Sum;
|
||||
use std::ops::Add;
|
||||
|
||||
/// A trait to compute squared distances between two animatable values.
|
||||
pub trait ComputeSquaredDistance {
|
||||
/// Computes the squared distance between two animatable values.
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;
|
||||
}
|
||||
|
||||
/// A distance between two animatable values.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum SquaredDistance {
|
||||
/// Represented as the square root of the squared distance.
|
||||
Sqrt(f64),
|
||||
/// Represented as the squared distance itself.
|
||||
Value(f64),
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for u16 {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(SquaredDistance::Sqrt(((*self as f64) - (*other as f64)).abs()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for i32 {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(SquaredDistance::Sqrt((*self - *other).abs() as f64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for f32 {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(SquaredDistance::Sqrt((*self - *other).abs() as f64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for f64 {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(SquaredDistance::Sqrt((*self - *other).abs()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeSquaredDistance for Au {
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ComputeSquaredDistance for Option<T>
|
||||
where T: ComputeSquaredDistance
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self.as_ref(), other.as_ref()) {
|
||||
(Some(this), Some(other)) => this.compute_squared_distance(other),
|
||||
(None, None) => Ok(SquaredDistance::Value(0.)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ComputeSquaredDistance for Size2D<T>
|
||||
where T: ComputeSquaredDistance
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(self.width.compute_squared_distance(&other.width)? + self.height.compute_squared_distance(&other.height)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl SquaredDistance {
|
||||
/// Returns the square root of this squared distance.
|
||||
pub fn sqrt(self) -> f64 {
|
||||
match self {
|
||||
SquaredDistance::Sqrt(this) => this,
|
||||
SquaredDistance::Value(this) => this.sqrt(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SquaredDistance> for f64 {
|
||||
#[inline]
|
||||
fn from(distance: SquaredDistance) -> Self {
|
||||
match distance {
|
||||
SquaredDistance::Sqrt(this) => this * this,
|
||||
SquaredDistance::Value(this) => this,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for SquaredDistance {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
SquaredDistance::Value(f64::from(self) + f64::from(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl Sum for SquaredDistance {
|
||||
fn sum<I>(mut iter: I) -> Self
|
||||
where
|
||||
I: Iterator<Item = Self>,
|
||||
{
|
||||
let first = match iter.next() {
|
||||
Some(first) => first,
|
||||
None => return SquaredDistance::Value(0.),
|
||||
};
|
||||
iter.fold(first, Add::add)
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ use std::fmt;
|
|||
use style_traits::{HasViewportPercentage, ToCss};
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::border::BorderRadius;
|
||||
use values::generics::position::Position;
|
||||
use values::generics::rect::Rect;
|
||||
|
@ -144,20 +145,16 @@ where
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(
|
||||
&ShapeSource::Shape(ref this, ref this_box),
|
||||
&ShapeSource::Shape(ref other, ref other_box),
|
||||
) if this_box == other_box => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
// FIXME(nox): Implement ComputeSquaredDistance for T types and stop
|
||||
// using PartialEq here.
|
||||
impl<B, T, U> ComputeSquaredDistance for ShapeSource<B, T, U>
|
||||
where
|
||||
B: ComputeSquaredDistance,
|
||||
T: PartialEq,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(
|
||||
&ShapeSource::Shape(ref this, ref this_box),
|
||||
|
@ -209,26 +206,15 @@ where
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&BasicShape::Circle(ref this), &BasicShape::Circle(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(&BasicShape::Ellipse(ref this), &BasicShape::Ellipse(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(&BasicShape::Inset(ref this), &BasicShape::Inset(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
(&BasicShape::Polygon(ref this), &BasicShape::Polygon(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<H, V, L> ComputeSquaredDistance for BasicShape<H, V, L>
|
||||
where
|
||||
H: ComputeSquaredDistance,
|
||||
V: ComputeSquaredDistance,
|
||||
L: ComputeSquaredDistance + Copy,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&BasicShape::Circle(ref this), &BasicShape::Circle(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
|
@ -261,12 +247,13 @@ where
|
|||
let round = self.round.add_weighted(&other.round, self_portion, other_portion)?;
|
||||
Ok(InsetRect { rect, round })
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<L> ComputeSquaredDistance for InsetRect<L>
|
||||
where
|
||||
L: ComputeSquaredDistance + Copy,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.rect.compute_squared_distance(&other.rect)? +
|
||||
self.round.compute_squared_distance(&other.round)?,
|
||||
|
@ -304,12 +291,15 @@ where
|
|||
let radius = self.radius.add_weighted(&other.radius, self_portion, other_portion)?;
|
||||
Ok(Circle { position, radius })
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<H, V, L> ComputeSquaredDistance for Circle<H, V, L>
|
||||
where
|
||||
H: ComputeSquaredDistance,
|
||||
V: ComputeSquaredDistance,
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.position.compute_squared_distance(&other.position)? +
|
||||
self.radius.compute_squared_distance(&other.radius)?,
|
||||
|
@ -334,12 +324,15 @@ where
|
|||
let semiaxis_y = self.semiaxis_y.add_weighted(&other.semiaxis_y, self_portion, other_portion)?;
|
||||
Ok(Ellipse { position, semiaxis_x, semiaxis_y })
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<H, V, L> ComputeSquaredDistance for Ellipse<H, V, L>
|
||||
where
|
||||
H: ComputeSquaredDistance,
|
||||
V: ComputeSquaredDistance,
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.position.compute_squared_distance(&other.position)? +
|
||||
self.semiaxis_x.compute_squared_distance(&other.semiaxis_x)? +
|
||||
|
@ -365,17 +358,13 @@ where
|
|||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&ShapeRadius::Length(ref this), &ShapeRadius::Length(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<L> ComputeSquaredDistance for ShapeRadius<L>
|
||||
where
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&ShapeRadius::Length(ref this), &ShapeRadius::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
|
@ -413,12 +402,13 @@ where
|
|||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(Polygon { fill: self.fill, coordinates })
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<L> ComputeSquaredDistance for Polygon<L>
|
||||
where
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
if self.fill != other.fill {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -426,9 +416,10 @@ where
|
|||
return Err(());
|
||||
}
|
||||
self.coordinates.iter().zip(other.coordinates.iter()).map(|(this, other)| {
|
||||
let x = this.0.compute_squared_distance(&other.0)?;
|
||||
let y = this.1.compute_squared_distance(&other.1)?;
|
||||
Ok(x + y)
|
||||
Ok(
|
||||
this.0.compute_squared_distance(&other.0)? +
|
||||
this.1.compute_squared_distance(&other.1)?,
|
||||
)
|
||||
}).sum()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use euclid::Size2D;
|
|||
use properties::animated_properties::Animatable;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use values::generics::rect::Rect;
|
||||
|
||||
/// A generic value for a single side of a `border-image-width` property.
|
||||
|
@ -129,12 +130,13 @@ where
|
|||
let bl = self.bottom_left.add_weighted(&other.bottom_left, self_portion, other_portion)?;
|
||||
Ok(BorderRadius::new(tl, tr, br, bl))
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
Ok(self.compute_squared_distance(other)?.sqrt())
|
||||
}
|
||||
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
impl<L> ComputeSquaredDistance for BorderRadius<L>
|
||||
where
|
||||
L: ComputeSquaredDistance + Copy,
|
||||
{
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.top_left.compute_squared_distance(&other.top_left)? +
|
||||
self.top_right.compute_squared_distance(&other.top_right)? +
|
||||
|
@ -189,14 +191,14 @@ where
|
|||
) -> Result<Self, ()> {
|
||||
Ok(BorderCornerRadius(self.0.add_weighted(&other.0, self_portion, other_portion)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> ComputeSquaredDistance for BorderCornerRadius<L>
|
||||
where
|
||||
L: ComputeSquaredDistance + Copy,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
self.0.compute_distance(&other.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use parser::{Parse, ParserContext};
|
|||
use std::fmt;
|
||||
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
|
||||
use super::CustomIdent;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
pub mod background;
|
||||
pub mod basic_shape;
|
||||
|
@ -271,7 +272,27 @@ impl ToCss for FontSettingTagFloat {
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
pub struct NonNegative<T>(pub T);
|
||||
|
||||
impl<T> ComputeSquaredDistance for NonNegative<T>
|
||||
where
|
||||
T: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper of greater-than-or-equal-to-one values.
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToComputedValue, ToCss)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
pub struct GreaterThanOrEqualToOne<T>(pub T);
|
||||
|
||||
impl<T> ComputeSquaredDistance for GreaterThanOrEqualToOne<T>
|
||||
where
|
||||
T: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
self.0.compute_squared_distance(&other.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//! Generic types for CSS handling of specified and computed values of
|
||||
//! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position)
|
||||
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
/// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position).
|
||||
|
@ -24,3 +26,17 @@ impl<H, V> Position<H, V> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, V> ComputeSquaredDistance for Position<H, V>
|
||||
where
|
||||
H: ComputeSquaredDistance,
|
||||
V: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||
self.vertical.compute_squared_distance(&other.vertical)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use parser::{Parse, ParserContext};
|
|||
use properties::animated_properties::Animatable;
|
||||
use std::fmt;
|
||||
use style_traits::{ToCss, ParseError};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
/// A CSS value made of four components, where its `ToCss` impl will try to
|
||||
/// serialize as few components as possible, like for example in `border-width`.
|
||||
|
@ -70,6 +71,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<L> ComputeSquaredDistance for Rect<L>
|
||||
where
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
Ok(
|
||||
self.0.compute_squared_distance(&other.0)? +
|
||||
self.1.compute_squared_distance(&other.1)? +
|
||||
self.2.compute_squared_distance(&other.2)? +
|
||||
self.3.compute_squared_distance(&other.3)?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Rect<T>
|
||||
where T: Clone
|
||||
{
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext};
|
||||
use properties::animated_properties::RepeatableListAnimatable;
|
||||
use std::fmt;
|
||||
use style_traits::{ParseError, StyleParseError, ToCss};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
/// An SVG paint value
|
||||
///
|
||||
|
@ -105,6 +107,25 @@ pub enum SVGLength<LengthType> {
|
|||
ContextValue,
|
||||
}
|
||||
|
||||
impl<L> ComputeSquaredDistance for SVGLength<L>
|
||||
where
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&SVGLength::Length(ref this), &SVGLength::Length(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))`
|
||||
// if `self` and `other` are the same keyword value?
|
||||
Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic value for stroke-dasharray.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, PartialEq, HasViewportPercentage, ToAnimatedValue, ToComputedValue)]
|
||||
|
@ -115,6 +136,25 @@ pub enum SVGStrokeDashArray<LengthType> {
|
|||
ContextValue,
|
||||
}
|
||||
|
||||
impl<L> ComputeSquaredDistance for SVGStrokeDashArray<L>
|
||||
where
|
||||
L: ComputeSquaredDistance + RepeatableListAnimatable,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))`
|
||||
// if `self` and `other` are the same keyword value?
|
||||
Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthType> ToCss for SVGStrokeDashArray<LengthType> where LengthType: ToCss {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match self {
|
||||
|
@ -150,3 +190,22 @@ pub enum SVGOpacity<OpacityType> {
|
|||
/// `context-stroke-opacity`
|
||||
ContextStrokeOpacity,
|
||||
}
|
||||
|
||||
impl<L> ComputeSquaredDistance for SVGOpacity<L>
|
||||
where
|
||||
L: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
}
|
||||
_ => {
|
||||
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))`
|
||||
// if `self` and `other` are the same keyword value?
|
||||
Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use parser::ParserContext;
|
|||
use properties::animated_properties::Animatable;
|
||||
use style_traits::ParseError;
|
||||
use values::animated::ToAnimatedZero;
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
/// A generic value for the `initial-letter` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -84,13 +85,18 @@ impl<Value> Animatable for Spacing<Value>
|
|||
let other = other.value().unwrap_or(&zero);
|
||||
this.add_weighted(other, self_portion, other_portion).map(Spacing::Value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> ComputeSquaredDistance for Spacing<V>
|
||||
where
|
||||
V: ComputeSquaredDistance + From<Au>,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
let zero = Value::from(Au(0));
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
let zero = V::from(Au(0));
|
||||
let this = self.value().unwrap_or(&zero);
|
||||
let other = other.value().unwrap_or(&zero);
|
||||
this.compute_distance(other)
|
||||
this.compute_squared_distance(other)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,11 @@ use std::ascii::AsciiExt;
|
|||
use std::fmt::{self, Debug};
|
||||
use std::hash;
|
||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
|
||||
pub mod animated;
|
||||
pub mod computed;
|
||||
pub mod distance;
|
||||
pub mod generics;
|
||||
pub mod specified;
|
||||
|
||||
|
@ -59,6 +61,25 @@ pub enum Either<A, B> {
|
|||
Second(B),
|
||||
}
|
||||
|
||||
impl<A, B> ComputeSquaredDistance for Either<A, B>
|
||||
where
|
||||
A: ComputeSquaredDistance,
|
||||
B: ComputeSquaredDistance,
|
||||
{
|
||||
#[inline]
|
||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||
match (self, other) {
|
||||
(&Either::First(ref this), &Either::First(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
(&Either::Second(ref this), &Either::Second(ref other)) => {
|
||||
this.compute_squared_distance(other)
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Debug, B: Debug> Debug for Either<A, B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
|
|
@ -126,6 +126,7 @@ use style::traversal_flags::{TraversalFlags, self};
|
|||
use style::values::{CustomIdent, KeyframesName};
|
||||
use style::values::animated::ToAnimatedZero;
|
||||
use style::values::computed::Context;
|
||||
use style::values::distance::ComputeSquaredDistance;
|
||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss};
|
||||
use super::error_reporter::ErrorReporter;
|
||||
use super::stylesheet_loader::StylesheetLoader;
|
||||
|
@ -375,7 +376,7 @@ pub extern "C" fn Servo_AnimationValues_ComputeDistance(from: RawServoAnimationV
|
|||
-> f64 {
|
||||
let from_value = AnimationValue::as_arc(&from);
|
||||
let to_value = AnimationValue::as_arc(&to);
|
||||
from_value.compute_distance(to_value).unwrap_or(0.0)
|
||||
from_value.compute_squared_distance(to_value).map(|d| d.sqrt()).unwrap_or(0.0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue