Bug 1353202 - Support additive animation of font-stretch
Although there are no specific tests for this yet (that's
bug 1363246), if any
code does try to perform addition or accumulation with a font-stretch value
(e.g. dom/animation/test/crashtests/1304886-1.html) it will likely fail the
bounds check in the Into trait. To avoid that, this patch provides an basic
implementation of add_weighted for font-stretch that should work correctly with
portions whose sum is outside the [0.0, 1.0] range.
MozReview-Commit-ID: 2tNMOh9HyP0
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -1368,21 +1368,26 @@ impl Animatable for FontWeight {
let b = (*other as u32) as f64;
a.compute_distance(&b)
}
}
/// https://drafts.csswg.org/css-fonts/#font-stretch-prop
impl Animatable for FontStretch {
#[inline]
- fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
+ fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
+ -> Result<Self, ()>
+ {
let from = f64::from(*self);
- let to = f64::from(*other);
- let interpolated_mapped_index = ((from * self_portion + to * other_portion) + 0.5).floor();
- Ok(interpolated_mapped_index.into())
+ let to = f64::from(*other);
+ // FIXME: When `const fn` is available in release rust, make |normal|, below, const.
+ let normal = f64::from(FontStretch::normal);
+ let result = (from - normal) * self_portion + (to - normal) * other_portion + normal;
+
+ Ok(result.into())
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
let from = f64::from(*self);
let to = f64::from(*other);
from.compute_distance(&to)
}
@@ -1405,21 +1410,21 @@ impl From<FontStretch> for f64 {
ultra_expanded => 9.0,
}
}
}
impl Into<FontStretch> for f64 {
fn into(self) -> FontStretch {
use properties::longhands::font_stretch::computed_value::T::*;
- debug_assert!(self >= 1.0 && self <= 9.0);
+ let index = (self + 0.5).floor().min(9.0).max(1.0);
static FONT_STRETCH_ENUM_MAP: [FontStretch; 9] =
[ ultra_condensed, extra_condensed, condensed, semi_condensed, normal,
semi_expanded, expanded, extra_expanded, ultra_expanded ];
- FONT_STRETCH_ENUM_MAP[(self - 1.0) as usize]
+ FONT_STRETCH_ENUM_MAP[(index - 1.0) as usize]
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl<H: Animatable, V: Animatable> Animatable for generic_position::Position<H, V> {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
Ok(generic_position::Position {