From 2d808bf162badeb545ddb9e683e698ba6afc476a Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Mon, 24 Apr 2017 15:31:04 +0900 Subject: [PATCH] Introduce a macro to implement Interpolate trait for box-shadow and text-shadow. This macro will be used for implementation of intermediate type shadows as well. In the case of intermediate types transparent_color will be IntermediateRGB::transparent(). --- .../helpers/animated_properties.mako.rs | 179 ++++++++---------- 1 file changed, 77 insertions(+), 102 deletions(-) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 7121688f750..a90214d89d6 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -1002,114 +1002,89 @@ impl Interpolate for ClipRect { } } -/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list -impl Interpolate for TextShadow { - #[inline] - fn interpolate(&self, other: &Self, progress: f64) -> Result { - Ok(TextShadow { - offset_x: try!(self.offset_x.interpolate(&other.offset_x, progress)), - offset_y: try!(self.offset_y.interpolate(&other.offset_y, progress)), - blur_radius: try!(self.blur_radius.interpolate(&other.blur_radius, progress)), - color: try!(self.color.interpolate(&other.color, progress)), - }) +<%def name="impl_interpolate_for_shadow(item, transparent_color)"> + impl Interpolate for ${item} { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + % if "Box" in item: + // It can't be interpolated if inset does not match. + if self.inset != other.inset { + return Err(()); + } + % endif + + let x = try!(self.offset_x.interpolate(&other.offset_x, progress)); + let y = try!(self.offset_y.interpolate(&other.offset_y, progress)); + let color = try!(self.color.interpolate(&other.color, progress)); + let blur = try!(self.blur_radius.interpolate(&other.blur_radius, progress)); + % if "Box" in item: + let spread = try!(self.spread_radius.interpolate(&other.spread_radius, progress)); + % endif + + Ok(${item} { + offset_x: x, + offset_y: y, + blur_radius: blur, + color: color, + % if "Box" in item: + spread_radius: spread, + inset: self.inset, + % endif + }) + } } -} -/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list -impl Interpolate for TextShadowList { - #[inline] - fn interpolate(&self, other: &Self, progress: f64) -> Result { - let zero = TextShadow { - offset_x: Au(0), - offset_y: Au(0), - blur_radius: Au(0), - color: CSSParserColor::RGBA(RGBA::transparent()), - }; - - let max_len = cmp::max(self.0.len(), other.0.len()); - let mut result = Vec::with_capacity(max_len); - - for i in 0..max_len { - let shadow = match (self.0.get(i), other.0.get(i)) { - (Some(shadow), Some(other)) - => try!(shadow.interpolate(other, progress)), - (Some(shadow), None) => { - shadow.interpolate(&zero, progress).unwrap() - } - (None, Some(shadow)) => { - zero.interpolate(&shadow, progress).unwrap() - } - (None, None) => unreachable!(), + /// https://drafts.csswg.org/css-transitions/#animtype-shadow-list + impl Interpolate for ${item}List { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + // The inset value must change + % if "Box" in item: + let mut zero = ${item} { + % else: + let zero = ${item} { + % endif + offset_x: Au(0), + offset_y: Au(0), + blur_radius: Au(0), + color: ${transparent_color}, + % if "Box" in item: + spread_radius: Au(0), + inset: false, + % endif }; - result.push(shadow); + + let max_len = cmp::max(self.0.len(), other.0.len()); + let mut result = Vec::with_capacity(max_len); + + for i in 0..max_len { + let shadow = match (self.0.get(i), other.0.get(i)) { + (Some(shadow), Some(other)) + => try!(shadow.interpolate(other, progress)), + (Some(shadow), None) => { + % if "Box" in item: + zero.inset = shadow.inset; + % endif + shadow.interpolate(&zero, progress).unwrap() + } + (None, Some(shadow)) => { + % if "Box" in item: + zero.inset = shadow.inset; + % endif + zero.interpolate(&shadow, progress).unwrap() + } + (None, None) => unreachable!(), + }; + result.push(shadow); + } + + Ok(${item}List(result)) } - - Ok(TextShadowList(result)) } -} + - -impl Interpolate for BoxShadowList { - #[inline] - fn interpolate(&self, other: &Self, progress: f64) -> Result { - // The inset value must change - let mut zero = BoxShadow { - offset_x: Au(0), - offset_y: Au(0), - spread_radius: Au(0), - blur_radius: Au(0), - color: CSSParserColor::RGBA(RGBA::transparent()), - inset: false, - }; - - let max_len = cmp::max(self.0.len(), other.0.len()); - let mut result = Vec::with_capacity(max_len); - - for i in 0..max_len { - let shadow = match (self.0.get(i), other.0.get(i)) { - (Some(shadow), Some(other)) - => try!(shadow.interpolate(other, progress)), - (Some(shadow), None) => { - zero.inset = shadow.inset; - shadow.interpolate(&zero, progress).unwrap() - } - (None, Some(shadow)) => { - zero.inset = shadow.inset; - zero.interpolate(&shadow, progress).unwrap() - } - (None, None) => unreachable!(), - }; - result.push(shadow); - } - - Ok(BoxShadowList(result)) - } -} - -/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list -impl Interpolate for BoxShadow { - #[inline] - fn interpolate(&self, other: &Self, progress: f64) -> Result { - if self.inset != other.inset { - return Err(()); - } - - let x = try!(self.offset_x.interpolate(&other.offset_x, progress)); - let y = try!(self.offset_y.interpolate(&other.offset_y, progress)); - let color = try!(self.color.interpolate(&other.color, progress)); - let spread = try!(self.spread_radius.interpolate(&other.spread_radius, progress)); - let blur = try!(self.blur_radius.interpolate(&other.blur_radius, progress)); - - Ok(BoxShadow { - offset_x: x, - offset_y: y, - blur_radius: blur, - spread_radius: spread, - color: color, - inset: self.inset, - }) - } -} +${impl_interpolate_for_shadow('BoxShadow', 'CSSParserColor::RGBA(RGBA::transparent())',)} +${impl_interpolate_for_shadow('TextShadow', 'CSSParserColor::RGBA(RGBA::transparent())',)} impl Interpolate for LengthOrNone { fn interpolate(&self, other: &Self, progress: f64) -> Result {