diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 1936bacc3c4..79287e178d3 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -27,14 +27,12 @@ use hash::FxHashMap; use super::ComputedValues; use values::CSSFloat; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; -use values::animated::color::Color as AnimatedColor; use values::animated::effects::Filter as AnimatedFilter; #[cfg(feature = "gecko")] use values::computed::TransitionProperty; use values::computed::Angle; use values::computed::{ClipRect, Context}; use values::computed::{Length, LengthOrPercentage}; -use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; -use values::computed::length::NonNegativeLengthOrPercentage; +use values::computed::{Number, Percentage}; use values::computed::ToComputedValue; use values::computed::transform::{DirectionVector, Matrix, Matrix3D}; use values::computed::transform::TransformOperation as ComputedTransformOperation; @@ -42,12 +40,9 @@ use values::computed::transform::Transform as ComputedTransform; use values::computed::transform::Rotate as ComputedRotate; use values::computed::transform::Translate as ComputedTranslate; use values::computed::transform::Scale as ComputedScale; -use values::computed::url::ComputedUrl; use values::generics::transform::{self, Rotate, Translate, Scale, Transform, TransformOperation}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::effects::Filter; -use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber, SVGPaint}; -use values::generics::svg::{SVGPaintKind, SVGStrokeDashArray, SVGOpacity}; use void::{self, Void}; /// Convert nsCSSPropertyID to TransitionProperty @@ -2535,205 +2530,6 @@ impl ComputeSquaredDistance for ComputedTransform { } } -/// Animated SVGPaint -pub type IntermediateSVGPaint = SVGPaint; - -/// Animated SVGPaintKind -pub type IntermediateSVGPaintKind = SVGPaintKind; - -impl ToAnimatedZero for IntermediateSVGPaint { - #[inline] - fn to_animated_zero(&self) -> Result { - Ok(IntermediateSVGPaint { - kind: self.kind.to_animated_zero()?, - fallback: self.fallback.and_then(|v| v.to_animated_zero().ok()), - }) - } -} - -impl From for NumberOrPercentage { - fn from(lop: NonNegativeLengthOrPercentage) -> NumberOrPercentage { - lop.0.into() - } -} - -impl From for NumberOrPercentage { - fn from(num: NonNegativeNumber) -> NumberOrPercentage { - num.0.into() - } -} - -impl From for NumberOrPercentage { - fn from(lop: LengthOrPercentage) -> NumberOrPercentage { - match lop { - LengthOrPercentage::Length(len) => NumberOrPercentage::Number(len.px()), - LengthOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p), - LengthOrPercentage::Calc(_) => { - panic!("We dont't expected calc interpolation for SvgLengthOrPercentageOrNumber"); - }, - } - } -} - -impl From for NumberOrPercentage { - fn from(num: Number) -> NumberOrPercentage { - NumberOrPercentage::Number(num) - } -} - -fn convert_to_number_or_percentage( - from: SvgLengthOrPercentageOrNumber) - -> NumberOrPercentage - where LengthOrPercentageType: Into, - NumberType: Into -{ - match from { - SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { - lop.into() - } - SvgLengthOrPercentageOrNumber::Number(num) => { - num.into() - } - } -} - -fn convert_from_number_or_percentage( - from: NumberOrPercentage) - -> SvgLengthOrPercentageOrNumber - where LengthOrPercentageType: From, - NumberType: From -{ - match from { - NumberOrPercentage::Number(num) => - SvgLengthOrPercentageOrNumber::Number(num.into()), - NumberOrPercentage::Percentage(p) => - SvgLengthOrPercentageOrNumber::LengthOrPercentage( - (LengthOrPercentage::Percentage(p)).into()) - } -} - -impl Animate for SvgLengthOrPercentageOrNumber -where - L: Animate + From + Into + Copy, - N: Animate + From + Into, - LengthOrPercentage: From, - Self: Copy, -{ - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - if self.has_calc() || other.has_calc() { - // TODO: We need to treat calc value. - // https://bugzilla.mozilla.org/show_bug.cgi?id=1386967 - return Err(()); - } - - let this = convert_to_number_or_percentage(*self); - let other = convert_to_number_or_percentage(*other); - - match (this, other) { - ( - NumberOrPercentage::Number(ref this), - NumberOrPercentage::Number(ref other), - ) => { - Ok(convert_from_number_or_percentage( - NumberOrPercentage::Number(this.animate(other, procedure)?) - )) - }, - ( - NumberOrPercentage::Percentage(ref this), - NumberOrPercentage::Percentage(ref other), - ) => { - Ok(convert_from_number_or_percentage( - NumberOrPercentage::Percentage(this.animate(other, procedure)?) - )) - }, - _ => Err(()), - } - } -} - -impl Animate for SVGLength -where - L: Animate + Clone, -{ - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - match (self, other) { - (&SVGLength::Length(ref this), &SVGLength::Length(ref other)) => { - Ok(SVGLength::Length(this.animate(other, procedure)?)) - }, - _ => Err(()), - } - } -} - -/// -impl Animate for SVGStrokeDashArray -where - L: Clone + Animate, -{ - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - if matches!(procedure, Procedure::Add | Procedure::Accumulate { .. }) { - // Non-additive. - return Err(()); - } - match (self, other) { - (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { - Ok(SVGStrokeDashArray::Values(this.animate_repeatable_list(other, procedure)?)) - }, - _ => Err(()), - } - } -} - -impl ComputeSquaredDistance for SVGStrokeDashArray -where - L: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { - this.squared_distance_repeatable_list(other) - }, - _ => Err(()), - } - } -} - -impl ToAnimatedZero for SVGStrokeDashArray -where - L: ToAnimatedZero, -{ - #[inline] - fn to_animated_zero(&self) -> Result { - match *self { - SVGStrokeDashArray::Values(ref values) => { - Ok(SVGStrokeDashArray::Values( - values.iter().map(ToAnimatedZero::to_animated_zero).collect::, _>>()?, - )) - } - SVGStrokeDashArray::ContextValue => Ok(SVGStrokeDashArray::ContextValue), - } - } -} - -impl Animate for SVGOpacity -where - O: Animate + Clone, -{ - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - match (self, other) { - (&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => { - Ok(SVGOpacity::Opacity(this.animate(other, procedure)?)) - }, - _ => Err(()), - } - } -} - <% FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale', 'HueRotate', 'Invert', 'Opacity', 'Saturate', diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index 5c90a1a1fd3..3fe369c4e91 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -22,6 +22,7 @@ pub mod color; pub mod effects; mod font; mod length; +mod svg; /// The category a property falls into for ordering purposes. /// diff --git a/components/style/values/animated/svg.rs b/components/style/values/animated/svg.rs new file mode 100644 index 00000000000..49641a8e376 --- /dev/null +++ b/components/style/values/animated/svg.rs @@ -0,0 +1,213 @@ +/* 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/. */ + +//! Animation implementations for various SVG-related types. + +use properties::animated_properties::ListAnimation; +use values::animated::color::Color as AnimatedColor; +use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, LengthOrPercentage}; +use values::computed::url::ComputedUrl; +use values::computed::length::NonNegativeLengthOrPercentage; +use values::distance::{ComputeSquaredDistance, SquaredDistance}; +use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber, SVGPaint}; +use values::generics::svg::{SVGPaintKind, SVGStrokeDashArray, SVGOpacity}; +use super::{Animate, Procedure, ToAnimatedZero}; + +/// Animated SVGPaint. +pub type IntermediateSVGPaint = SVGPaint; + +impl ToAnimatedZero for IntermediateSVGPaint { + #[inline] + fn to_animated_zero(&self) -> Result { + Ok(IntermediateSVGPaint { + kind: self.kind.to_animated_zero()?, + fallback: self.fallback.and_then(|v| v.to_animated_zero().ok()), + }) + } +} + +impl From for NumberOrPercentage { + fn from(lop: NonNegativeLengthOrPercentage) -> NumberOrPercentage { + lop.0.into() + } +} + +impl From for NumberOrPercentage { + fn from(num: NonNegativeNumber) -> NumberOrPercentage { + num.0.into() + } +} + +impl From for NumberOrPercentage { + fn from(lop: LengthOrPercentage) -> NumberOrPercentage { + match lop { + LengthOrPercentage::Length(len) => NumberOrPercentage::Number(len.px()), + LengthOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p), + LengthOrPercentage::Calc(_) => { + panic!("We dont't expected calc interpolation for SvgLengthOrPercentageOrNumber"); + }, + } + } +} + +impl From for NumberOrPercentage { + fn from(num: Number) -> NumberOrPercentage { + NumberOrPercentage::Number(num) + } +} + +fn convert_to_number_or_percentage( + from: SvgLengthOrPercentageOrNumber, +) -> NumberOrPercentage +where + LengthOrPercentageType: Into, + NumberType: Into, +{ + match from { + SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { + lop.into() + } + SvgLengthOrPercentageOrNumber::Number(num) => { + num.into() + } + } +} + +fn convert_from_number_or_percentage( + from: NumberOrPercentage, +) -> SvgLengthOrPercentageOrNumber +where + LengthOrPercentageType: From, + NumberType: From, +{ + match from { + NumberOrPercentage::Number(num) => + SvgLengthOrPercentageOrNumber::Number(num.into()), + NumberOrPercentage::Percentage(p) => + SvgLengthOrPercentageOrNumber::LengthOrPercentage( + (LengthOrPercentage::Percentage(p)).into()) + } +} + +impl Animate for SvgLengthOrPercentageOrNumber +where + L: Animate + From + Into + Copy, + N: Animate + From + Into, + LengthOrPercentage: From, + Self: Copy, +{ + #[inline] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + if self.has_calc() || other.has_calc() { + // TODO: We need to treat calc value. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1386967 + return Err(()); + } + + let this = convert_to_number_or_percentage(*self); + let other = convert_to_number_or_percentage(*other); + + match (this, other) { + ( + NumberOrPercentage::Number(ref this), + NumberOrPercentage::Number(ref other), + ) => { + Ok(convert_from_number_or_percentage( + NumberOrPercentage::Number(this.animate(other, procedure)?) + )) + }, + ( + NumberOrPercentage::Percentage(ref this), + NumberOrPercentage::Percentage(ref other), + ) => { + Ok(convert_from_number_or_percentage( + NumberOrPercentage::Percentage(this.animate(other, procedure)?) + )) + }, + _ => Err(()), + } + } +} + +impl Animate for SVGLength +where + L: Animate + Clone, +{ + #[inline] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + match (self, other) { + (&SVGLength::Length(ref this), &SVGLength::Length(ref other)) => { + Ok(SVGLength::Length(this.animate(other, procedure)?)) + }, + _ => Err(()), + } + } +} + +/// +impl Animate for SVGStrokeDashArray +where + L: Clone + Animate, +{ + #[inline] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + if matches!(procedure, Procedure::Add | Procedure::Accumulate { .. }) { + // Non-additive. + return Err(()); + } + match (self, other) { + (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { + Ok(SVGStrokeDashArray::Values(this.animate_repeatable_list(other, procedure)?)) + }, + _ => Err(()), + } + } +} + +impl ComputeSquaredDistance for SVGStrokeDashArray +where + L: ComputeSquaredDistance, +{ + #[inline] + fn compute_squared_distance(&self, other: &Self) -> Result { + match (self, other) { + (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { + this.squared_distance_repeatable_list(other) + }, + _ => Err(()), + } + } +} + +impl ToAnimatedZero for SVGStrokeDashArray +where + L: ToAnimatedZero, +{ + #[inline] + fn to_animated_zero(&self) -> Result { + match *self { + SVGStrokeDashArray::Values(ref values) => { + Ok(SVGStrokeDashArray::Values( + values.iter().map(ToAnimatedZero::to_animated_zero).collect::, _>>()?, + )) + } + SVGStrokeDashArray::ContextValue => Ok(SVGStrokeDashArray::ContextValue), + } + } +} + +impl Animate for SVGOpacity +where + O: Animate + Clone, +{ + #[inline] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + match (self, other) { + (&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => { + Ok(SVGOpacity::Opacity(this.animate(other, procedure)?)) + }, + _ => Err(()), + } + } +}