mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
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().
This commit is contained in:
parent
09e728b43d
commit
2d808bf162
1 changed files with 77 additions and 102 deletions
|
@ -1002,114 +1002,89 @@ impl Interpolate for ClipRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list
|
<%def name="impl_interpolate_for_shadow(item, transparent_color)">
|
||||||
impl Interpolate for TextShadow {
|
impl Interpolate for ${item} {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
||||||
Ok(TextShadow {
|
% if "Box" in item:
|
||||||
offset_x: try!(self.offset_x.interpolate(&other.offset_x, progress)),
|
// It can't be interpolated if inset does not match.
|
||||||
offset_y: try!(self.offset_y.interpolate(&other.offset_y, progress)),
|
if self.inset != other.inset {
|
||||||
blur_radius: try!(self.blur_radius.interpolate(&other.blur_radius, progress)),
|
return Err(());
|
||||||
color: try!(self.color.interpolate(&other.color, progress)),
|
}
|
||||||
})
|
% 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
|
/// https://drafts.csswg.org/css-transitions/#animtype-shadow-list
|
||||||
impl Interpolate for TextShadowList {
|
impl Interpolate for ${item}List {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
||||||
let zero = TextShadow {
|
// The inset value must change
|
||||||
offset_x: Au(0),
|
% if "Box" in item:
|
||||||
offset_y: Au(0),
|
let mut zero = ${item} {
|
||||||
blur_radius: Au(0),
|
% else:
|
||||||
color: CSSParserColor::RGBA(RGBA::transparent()),
|
let zero = ${item} {
|
||||||
};
|
% endif
|
||||||
|
offset_x: Au(0),
|
||||||
let max_len = cmp::max(self.0.len(), other.0.len());
|
offset_y: Au(0),
|
||||||
let mut result = Vec::with_capacity(max_len);
|
blur_radius: Au(0),
|
||||||
|
color: ${transparent_color},
|
||||||
for i in 0..max_len {
|
% if "Box" in item:
|
||||||
let shadow = match (self.0.get(i), other.0.get(i)) {
|
spread_radius: Au(0),
|
||||||
(Some(shadow), Some(other))
|
inset: false,
|
||||||
=> try!(shadow.interpolate(other, progress)),
|
% endif
|
||||||
(Some(shadow), None) => {
|
|
||||||
shadow.interpolate(&zero, progress).unwrap()
|
|
||||||
}
|
|
||||||
(None, Some(shadow)) => {
|
|
||||||
zero.interpolate(&shadow, progress).unwrap()
|
|
||||||
}
|
|
||||||
(None, None) => unreachable!(),
|
|
||||||
};
|
};
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
}
|
</%def>
|
||||||
|
|
||||||
|
${impl_interpolate_for_shadow('BoxShadow', 'CSSParserColor::RGBA(RGBA::transparent())',)}
|
||||||
impl Interpolate for BoxShadowList {
|
${impl_interpolate_for_shadow('TextShadow', 'CSSParserColor::RGBA(RGBA::transparent())',)}
|
||||||
#[inline]
|
|
||||||
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
|
||||||
// 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<Self, ()> {
|
|
||||||
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 LengthOrNone {
|
impl Interpolate for LengthOrNone {
|
||||||
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue