mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Implement Animate trait and ComputeSquaredDistance trait for <ratio>.
I also update the wpt becasue it seems the original one lets <ratio> support the addition. However, the spec says "Addition of <ratio>s is not possible". Differential Revision: https://phabricator.services.mozilla.com/D106219
This commit is contained in:
parent
52d39fc1bc
commit
0ef2410ea0
4 changed files with 83 additions and 7 deletions
|
@ -457,7 +457,7 @@ ${helpers.predefined_type(
|
||||||
"AspectRatio",
|
"AspectRatio",
|
||||||
"computed::AspectRatio::auto()",
|
"computed::AspectRatio::auto()",
|
||||||
engines="gecko servo-2013",
|
engines="gecko servo-2013",
|
||||||
animation_value_type="discrete",
|
animation_value_type="ComputedValue",
|
||||||
spec="https://drafts.csswg.org/css-sizing-4/#aspect-ratio",
|
spec="https://drafts.csswg.org/css-sizing-4/#aspect-ratio",
|
||||||
gecko_pref="layout.css.aspect-ratio.enabled",
|
gecko_pref="layout.css.aspect-ratio.enabled",
|
||||||
servo_restyle_damage="reflow",
|
servo_restyle_damage="reflow",
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
//! `<ratio>` computed values.
|
//! `<ratio>` computed values.
|
||||||
|
|
||||||
|
use crate::values::animated::{Animate, Procedure};
|
||||||
use crate::values::computed::NonNegativeNumber;
|
use crate::values::computed::NonNegativeNumber;
|
||||||
|
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||||
use crate::values::generics::ratio::Ratio as GenericRatio;
|
use crate::values::generics::ratio::Ratio as GenericRatio;
|
||||||
use crate::{One, Zero};
|
use crate::{One, Zero};
|
||||||
use std::cmp::{Ordering, PartialOrd};
|
use std::cmp::{Ordering, PartialOrd};
|
||||||
|
@ -21,8 +23,58 @@ impl PartialOrd for Ratio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://drafts.csswg.org/css-values/#combine-ratio
|
||||||
|
impl Animate for Ratio {
|
||||||
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
|
// If either <ratio> is degenerate, the values cannot be interpolated.
|
||||||
|
if self.is_degenerate() || other.is_degenerate() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addition of <ratio>s is not possible, and based on
|
||||||
|
// https://drafts.csswg.org/css-values-4/#not-additive,
|
||||||
|
// we simply use the first value as the result value.
|
||||||
|
// Besides, the procedure for accumulation should be identical to addition here.
|
||||||
|
if matches!(procedure, Procedure::Add | Procedure::Accumulate { .. }) {
|
||||||
|
return Ok(self.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The interpolation of a <ratio> is defined by converting each <ratio> to a number by
|
||||||
|
// dividing the first value by the second (so a ratio of 3 / 2 would become 1.5), taking
|
||||||
|
// the logarithm of that result (so the 1.5 would become approximately 0.176), then
|
||||||
|
// interpolating those values.
|
||||||
|
//
|
||||||
|
// The result during the interpolation is converted back to a <ratio> by inverting the
|
||||||
|
// logarithm, then interpreting the result as a <ratio> with the result as the first value
|
||||||
|
// and 1 as the second value.
|
||||||
|
let start = self.to_f32().ln();
|
||||||
|
let end = other.to_f32().ln();
|
||||||
|
let e = std::f32::consts::E;
|
||||||
|
let result = e.powf(start.animate(&end, procedure)?);
|
||||||
|
// The range of the result is [0, inf), based on the easing function.
|
||||||
|
if result.is_zero() || result.is_infinite() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(Ratio::new(result, 1.0f32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComputeSquaredDistance for Ratio {
|
||||||
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
|
if self.is_degenerate() || other.is_degenerate() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
// Use the distance of their logarithm values. (This is used by testing, so don't need to
|
||||||
|
// care about the base. Here we use the same base as that in animate().)
|
||||||
|
self.to_f32()
|
||||||
|
.ln()
|
||||||
|
.compute_squared_distance(&other.to_f32().ln())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Ratio {
|
impl Ratio {
|
||||||
/// Returns a new Ratio.
|
/// Returns a new Ratio.
|
||||||
|
#[inline]
|
||||||
pub fn new(a: f32, b: f32) -> Self {
|
pub fn new(a: f32, b: f32) -> Self {
|
||||||
GenericRatio(a.into(), b.into())
|
GenericRatio(a.into(), b.into())
|
||||||
}
|
}
|
||||||
|
@ -36,4 +88,18 @@ impl Ratio {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this is a degenerate ratio.
|
||||||
|
/// https://drafts.csswg.org/css-values/#degenerate-ratio
|
||||||
|
#[inline]
|
||||||
|
pub fn is_degenerate(&self) -> bool {
|
||||||
|
self.0.is_zero() || self.1.is_zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the f32 value by dividing the first value by the second one.
|
||||||
|
#[inline]
|
||||||
|
fn to_f32(&self) -> f32 {
|
||||||
|
debug_assert!(!self.is_degenerate());
|
||||||
|
(self.0).0 / (self.1).0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
//! Generic types for CSS handling of specified and computed values of
|
//! Generic types for CSS handling of specified and computed values of
|
||||||
//! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position)
|
//! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position)
|
||||||
|
|
||||||
|
use crate::values::animated::ToAnimatedZero;
|
||||||
use crate::values::generics::ratio::Ratio;
|
use crate::values::generics::ratio::Ratio;
|
||||||
|
|
||||||
/// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position).
|
/// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position).
|
||||||
|
@ -163,7 +164,6 @@ impl<Integer> ZIndex<Integer> {
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
|
@ -175,7 +175,12 @@ pub enum PreferredRatio<N> {
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
None,
|
None,
|
||||||
/// With specified ratio
|
/// With specified ratio
|
||||||
Ratio(#[css(field_bound)] Ratio<N>),
|
Ratio(
|
||||||
|
#[animation(field_bound)]
|
||||||
|
#[css(field_bound)]
|
||||||
|
#[distance(field_bound)]
|
||||||
|
Ratio<N>,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A generic value for the `aspect-ratio` property, the value is `auto || <ratio>`.
|
/// A generic value for the `aspect-ratio` property, the value is `auto || <ratio>`.
|
||||||
|
@ -188,7 +193,6 @@ pub enum PreferredRatio<N> {
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
|
@ -201,7 +205,9 @@ pub struct GenericAspectRatio<N> {
|
||||||
#[css(represents_keyword)]
|
#[css(represents_keyword)]
|
||||||
pub auto: bool,
|
pub auto: bool,
|
||||||
/// The preferred aspect-ratio value.
|
/// The preferred aspect-ratio value.
|
||||||
|
#[animation(field_bound)]
|
||||||
#[css(field_bound)]
|
#[css(field_bound)]
|
||||||
|
#[distance(field_bound)]
|
||||||
pub ratio: PreferredRatio<N>,
|
pub ratio: PreferredRatio<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,3 +223,10 @@ impl<N> AspectRatio<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> ToAnimatedZero for AspectRatio<N> {
|
||||||
|
#[inline]
|
||||||
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,15 +10,12 @@ use style_traits::{CssWriter, ToCss};
|
||||||
|
|
||||||
/// A generic value for the `<ratio>` value.
|
/// A generic value for the `<ratio>` value.
|
||||||
#[derive(
|
#[derive(
|
||||||
Animate,
|
|
||||||
Clone,
|
Clone,
|
||||||
ComputeSquaredDistance,
|
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue