mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Treat 3d translate/scale as 2d if the value can be expressed as 2d.
For the individual transform properties if they spec a value that can be expressed as 2d we treat as 2d and serialize accordingly. We drop Translate::Translate and Scale::Scale, and then rename Translate::Translate3D as Translate::Translate, Scale::Scale3D as Scale::Scale. So now we use Translate::Translate to represent 2d and 3d translation, and Scale::Scale to represent 2d and 3d scale. There is no difference between 2d and 3d translate/scale in Gecko because we always convert them into 3d format to layers (on the compositor thread), so this change makes things simpler. Differential Revision: https://phabricator.services.mozilla.com/D52931
This commit is contained in:
parent
bb06ed7206
commit
b420293a57
3 changed files with 149 additions and 154 deletions
|
@ -139,10 +139,10 @@ impl ComputeSquaredDistance for MatrixDecomposed2D {
|
||||||
const RAD_PER_DEG: f64 = std::f64::consts::PI / 180.0;
|
const RAD_PER_DEG: f64 = std::f64::consts::PI / 180.0;
|
||||||
let angle1 = self.angle as f64 * RAD_PER_DEG;
|
let angle1 = self.angle as f64 * RAD_PER_DEG;
|
||||||
let angle2 = other.angle as f64 * RAD_PER_DEG;
|
let angle2 = other.angle as f64 * RAD_PER_DEG;
|
||||||
Ok(self.translate.compute_squared_distance(&other.translate)? +
|
Ok(self.translate.compute_squared_distance(&other.translate)?
|
||||||
self.scale.compute_squared_distance(&other.scale)? +
|
+ self.scale.compute_squared_distance(&other.scale)?
|
||||||
angle1.compute_squared_distance(&angle2)? +
|
+ angle1.compute_squared_distance(&angle2)?
|
||||||
self.matrix.compute_squared_distance(&other.matrix)?)
|
+ self.matrix.compute_squared_distance(&other.matrix)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,9 +316,9 @@ impl ComputeSquaredDistance for Skew {
|
||||||
// ComputeSquaredDistance manually.
|
// ComputeSquaredDistance manually.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
Ok(self.0.atan().compute_squared_distance(&other.0.atan())? +
|
Ok(self.0.atan().compute_squared_distance(&other.0.atan())?
|
||||||
self.1.atan().compute_squared_distance(&other.1.atan())? +
|
+ self.1.atan().compute_squared_distance(&other.1.atan())?
|
||||||
self.2.atan().compute_squared_distance(&other.2.atan())?)
|
+ self.2.atan().compute_squared_distance(&other.2.atan())?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,9 +394,9 @@ impl Animate for Quaternion {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
// Doule EPSILON since both this_weight and other_weght have calculation errors
|
// Doule EPSILON since both this_weight and other_weght have calculation errors
|
||||||
// which are approximately equal to EPSILON.
|
// which are approximately equal to EPSILON.
|
||||||
(this_weight + other_weight - 1.0f64).abs() <= f64::EPSILON * 2.0 ||
|
(this_weight + other_weight - 1.0f64).abs() <= f64::EPSILON * 2.0
|
||||||
other_weight == 1.0f64 ||
|
|| other_weight == 1.0f64
|
||||||
other_weight == 0.0f64,
|
|| other_weight == 0.0f64,
|
||||||
"animate should only be used for interpolating or accumulating transforms"
|
"animate should only be used for interpolating or accumulating transforms"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -830,17 +830,17 @@ fn is_matched_operation(
|
||||||
second: &ComputedTransformOperation,
|
second: &ComputedTransformOperation,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match (first, second) {
|
match (first, second) {
|
||||||
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..)) |
|
(&TransformOperation::Matrix(..), &TransformOperation::Matrix(..))
|
||||||
(&TransformOperation::Matrix3D(..), &TransformOperation::Matrix3D(..)) |
|
| (&TransformOperation::Matrix3D(..), &TransformOperation::Matrix3D(..))
|
||||||
(&TransformOperation::Skew(..), &TransformOperation::Skew(..)) |
|
| (&TransformOperation::Skew(..), &TransformOperation::Skew(..))
|
||||||
(&TransformOperation::SkewX(..), &TransformOperation::SkewX(..)) |
|
| (&TransformOperation::SkewX(..), &TransformOperation::SkewX(..))
|
||||||
(&TransformOperation::SkewY(..), &TransformOperation::SkewY(..)) |
|
| (&TransformOperation::SkewY(..), &TransformOperation::SkewY(..))
|
||||||
(&TransformOperation::Rotate(..), &TransformOperation::Rotate(..)) |
|
| (&TransformOperation::Rotate(..), &TransformOperation::Rotate(..))
|
||||||
(&TransformOperation::Rotate3D(..), &TransformOperation::Rotate3D(..)) |
|
| (&TransformOperation::Rotate3D(..), &TransformOperation::Rotate3D(..))
|
||||||
(&TransformOperation::RotateX(..), &TransformOperation::RotateX(..)) |
|
| (&TransformOperation::RotateX(..), &TransformOperation::RotateX(..))
|
||||||
(&TransformOperation::RotateY(..), &TransformOperation::RotateY(..)) |
|
| (&TransformOperation::RotateY(..), &TransformOperation::RotateY(..))
|
||||||
(&TransformOperation::RotateZ(..), &TransformOperation::RotateZ(..)) |
|
| (&TransformOperation::RotateZ(..), &TransformOperation::RotateZ(..))
|
||||||
(&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => true,
|
| (&TransformOperation::Perspective(..), &TransformOperation::Perspective(..)) => true,
|
||||||
// Match functions that have the same primitive transform function
|
// Match functions that have the same primitive transform function
|
||||||
(a, b) if a.is_translate() && b.is_translate() => true,
|
(a, b) if a.is_translate() && b.is_translate() => true,
|
||||||
(a, b) if a.is_scale() && b.is_scale() => true,
|
(a, b) if a.is_scale() && b.is_scale() => true,
|
||||||
|
@ -895,21 +895,21 @@ impl Animate for ComputedTransform {
|
||||||
Procedure::Add => {
|
Procedure::Add => {
|
||||||
debug_assert!(false, "Should have already dealt with add by the point");
|
debug_assert!(false, "Should have already dealt with add by the point");
|
||||||
return Err(());
|
return Err(());
|
||||||
},
|
}
|
||||||
Procedure::Interpolate { progress } => {
|
Procedure::Interpolate { progress } => {
|
||||||
result.push(TransformOperation::InterpolateMatrix {
|
result.push(TransformOperation::InterpolateMatrix {
|
||||||
from_list: Transform(this_remainder.to_vec().into()),
|
from_list: Transform(this_remainder.to_vec().into()),
|
||||||
to_list: Transform(other_remainder.to_vec().into()),
|
to_list: Transform(other_remainder.to_vec().into()),
|
||||||
progress: Percentage(progress as f32),
|
progress: Percentage(progress as f32),
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
Procedure::Accumulate { count } => {
|
Procedure::Accumulate { count } => {
|
||||||
result.push(TransformOperation::AccumulateMatrix {
|
result.push(TransformOperation::AccumulateMatrix {
|
||||||
from_list: Transform(this_remainder.to_vec().into()),
|
from_list: Transform(this_remainder.to_vec().into()),
|
||||||
to_list: Transform(other_remainder.to_vec().into()),
|
to_list: Transform(other_remainder.to_vec().into()),
|
||||||
count: cmp::min(count, i32::max_value() as u64) as i32,
|
count: cmp::min(count, i32::max_value() as u64) as i32,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
// If there is a remainder from just one list, then one list must be shorter but
|
// If there is a remainder from just one list, then one list must be shorter but
|
||||||
// completely match the type of the corresponding functions in the longer list.
|
// completely match the type of the corresponding functions in the longer list.
|
||||||
|
@ -925,8 +925,8 @@ impl Animate for ComputedTransform {
|
||||||
match transform {
|
match transform {
|
||||||
// We can't interpolate/accumulate ___Matrix types directly with a
|
// We can't interpolate/accumulate ___Matrix types directly with a
|
||||||
// matrix. Instead we need to wrap it in another ___Matrix type.
|
// matrix. Instead we need to wrap it in another ___Matrix type.
|
||||||
TransformOperation::AccumulateMatrix { .. } |
|
TransformOperation::AccumulateMatrix { .. }
|
||||||
TransformOperation::InterpolateMatrix { .. } => {
|
| TransformOperation::InterpolateMatrix { .. } => {
|
||||||
let transform_list = Transform(vec![transform.clone()].into());
|
let transform_list = Transform(vec![transform.clone()].into());
|
||||||
let identity_list = Transform(vec![identity].into());
|
let identity_list = Transform(vec![identity].into());
|
||||||
let (from_list, to_list) = if fill_right {
|
let (from_list, to_list) = if fill_right {
|
||||||
|
@ -943,7 +943,7 @@ impl Animate for ComputedTransform {
|
||||||
to_list,
|
to_list,
|
||||||
progress: Percentage(progress as f32),
|
progress: Percentage(progress as f32),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
Procedure::Accumulate { count } => {
|
Procedure::Accumulate { count } => {
|
||||||
Ok(TransformOperation::AccumulateMatrix {
|
Ok(TransformOperation::AccumulateMatrix {
|
||||||
from_list,
|
from_list,
|
||||||
|
@ -951,9 +951,9 @@ impl Animate for ComputedTransform {
|
||||||
count: cmp::min(count, i32::max_value() as u64)
|
count: cmp::min(count, i32::max_value() as u64)
|
||||||
as i32,
|
as i32,
|
||||||
})
|
})
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let (lhs, rhs) = if fill_right {
|
let (lhs, rhs) = if fill_right {
|
||||||
(transform, &identity)
|
(transform, &identity)
|
||||||
|
@ -961,13 +961,13 @@ impl Animate for ComputedTransform {
|
||||||
(&identity, transform)
|
(&identity, transform)
|
||||||
};
|
};
|
||||||
lhs.animate(rhs, procedure)
|
lhs.animate(rhs, procedure)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
(None, None) => {},
|
(None, None) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Transform(result.into()))
|
Ok(Transform(result.into()))
|
||||||
|
@ -999,10 +999,10 @@ impl Animate for ComputedTransformOperation {
|
||||||
Ok(TransformOperation::Matrix3D(
|
Ok(TransformOperation::Matrix3D(
|
||||||
this.animate(other, procedure)?,
|
this.animate(other, procedure)?,
|
||||||
))
|
))
|
||||||
},
|
}
|
||||||
(&TransformOperation::Matrix(ref this), &TransformOperation::Matrix(ref other)) => {
|
(&TransformOperation::Matrix(ref this), &TransformOperation::Matrix(ref other)) => {
|
||||||
Ok(TransformOperation::Matrix(this.animate(other, procedure)?))
|
Ok(TransformOperation::Matrix(this.animate(other, procedure)?))
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Skew(ref fx, ref fy),
|
&TransformOperation::Skew(ref fx, ref fy),
|
||||||
&TransformOperation::Skew(ref tx, ref ty),
|
&TransformOperation::Skew(ref tx, ref ty),
|
||||||
|
@ -1012,10 +1012,10 @@ impl Animate for ComputedTransformOperation {
|
||||||
)),
|
)),
|
||||||
(&TransformOperation::SkewX(ref f), &TransformOperation::SkewX(ref t)) => {
|
(&TransformOperation::SkewX(ref f), &TransformOperation::SkewX(ref t)) => {
|
||||||
Ok(TransformOperation::SkewX(f.animate(t, procedure)?))
|
Ok(TransformOperation::SkewX(f.animate(t, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::SkewY(ref f), &TransformOperation::SkewY(ref t)) => {
|
(&TransformOperation::SkewY(ref f), &TransformOperation::SkewY(ref t)) => {
|
||||||
Ok(TransformOperation::SkewY(f.animate(t, procedure)?))
|
Ok(TransformOperation::SkewY(f.animate(t, procedure)?))
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Translate3D(ref fx, ref fy, ref fz),
|
&TransformOperation::Translate3D(ref fx, ref fy, ref fz),
|
||||||
&TransformOperation::Translate3D(ref tx, ref ty, ref tz),
|
&TransformOperation::Translate3D(ref tx, ref ty, ref tz),
|
||||||
|
@ -1033,13 +1033,13 @@ impl Animate for ComputedTransformOperation {
|
||||||
)),
|
)),
|
||||||
(&TransformOperation::TranslateX(ref f), &TransformOperation::TranslateX(ref t)) => {
|
(&TransformOperation::TranslateX(ref f), &TransformOperation::TranslateX(ref t)) => {
|
||||||
Ok(TransformOperation::TranslateX(f.animate(t, procedure)?))
|
Ok(TransformOperation::TranslateX(f.animate(t, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::TranslateY(ref f), &TransformOperation::TranslateY(ref t)) => {
|
(&TransformOperation::TranslateY(ref f), &TransformOperation::TranslateY(ref t)) => {
|
||||||
Ok(TransformOperation::TranslateY(f.animate(t, procedure)?))
|
Ok(TransformOperation::TranslateY(f.animate(t, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::TranslateZ(ref f), &TransformOperation::TranslateZ(ref t)) => {
|
(&TransformOperation::TranslateZ(ref f), &TransformOperation::TranslateZ(ref t)) => {
|
||||||
Ok(TransformOperation::TranslateZ(f.animate(t, procedure)?))
|
Ok(TransformOperation::TranslateZ(f.animate(t, procedure)?))
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Scale3D(ref fx, ref fy, ref fz),
|
&TransformOperation::Scale3D(ref fx, ref fy, ref fz),
|
||||||
&TransformOperation::Scale3D(ref tx, ref ty, ref tz),
|
&TransformOperation::Scale3D(ref tx, ref ty, ref tz),
|
||||||
|
@ -1072,25 +1072,25 @@ impl Animate for ComputedTransformOperation {
|
||||||
.animate(&Rotate::Rotate3D(tx, ty, tz, ta), procedure)?;
|
.animate(&Rotate::Rotate3D(tx, ty, tz, ta), procedure)?;
|
||||||
let (fx, fy, fz, fa) = ComputedRotate::resolve(&animated);
|
let (fx, fy, fz, fa) = ComputedRotate::resolve(&animated);
|
||||||
Ok(TransformOperation::Rotate3D(fx, fy, fz, fa))
|
Ok(TransformOperation::Rotate3D(fx, fy, fz, fa))
|
||||||
},
|
}
|
||||||
(&TransformOperation::RotateX(fa), &TransformOperation::RotateX(ta)) => {
|
(&TransformOperation::RotateX(fa), &TransformOperation::RotateX(ta)) => {
|
||||||
Ok(TransformOperation::RotateX(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::RotateX(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::RotateY(fa), &TransformOperation::RotateY(ta)) => {
|
(&TransformOperation::RotateY(fa), &TransformOperation::RotateY(ta)) => {
|
||||||
Ok(TransformOperation::RotateY(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::RotateY(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::RotateZ(fa), &TransformOperation::RotateZ(ta)) => {
|
(&TransformOperation::RotateZ(fa), &TransformOperation::RotateZ(ta)) => {
|
||||||
Ok(TransformOperation::RotateZ(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::RotateZ(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::Rotate(fa), &TransformOperation::Rotate(ta)) => {
|
(&TransformOperation::Rotate(fa), &TransformOperation::Rotate(ta)) => {
|
||||||
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::Rotate(fa), &TransformOperation::RotateZ(ta)) => {
|
(&TransformOperation::Rotate(fa), &TransformOperation::RotateZ(ta)) => {
|
||||||
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(&TransformOperation::RotateZ(fa), &TransformOperation::Rotate(ta)) => {
|
(&TransformOperation::RotateZ(fa), &TransformOperation::Rotate(ta)) => {
|
||||||
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
Ok(TransformOperation::Rotate(fa.animate(&ta, procedure)?))
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Perspective(ref fd),
|
&TransformOperation::Perspective(ref fd),
|
||||||
&TransformOperation::Perspective(ref td),
|
&TransformOperation::Perspective(ref td),
|
||||||
|
@ -1120,13 +1120,13 @@ impl Animate for ComputedTransformOperation {
|
||||||
Ok(TransformOperation::Perspective(CSSPixelLength::new(
|
Ok(TransformOperation::Perspective(CSSPixelLength::new(
|
||||||
used_value,
|
used_value,
|
||||||
)))
|
)))
|
||||||
},
|
}
|
||||||
_ if self.is_translate() && other.is_translate() => self
|
_ if self.is_translate() && other.is_translate() => self
|
||||||
.to_translate_3d()
|
.to_translate_3d()
|
||||||
.animate(&other.to_translate_3d(), procedure),
|
.animate(&other.to_translate_3d(), procedure),
|
||||||
_ if self.is_scale() && other.is_scale() => {
|
_ if self.is_scale() && other.is_scale() => {
|
||||||
self.to_scale_3d().animate(&other.to_scale_3d(), procedure)
|
self.to_scale_3d().animate(&other.to_scale_3d(), procedure)
|
||||||
},
|
}
|
||||||
_ if self.is_rotate() && other.is_rotate() => self
|
_ if self.is_rotate() && other.is_rotate() => self
|
||||||
.to_rotate_3d()
|
.to_rotate_3d()
|
||||||
.animate(&other.to_rotate_3d(), procedure),
|
.animate(&other.to_rotate_3d(), procedure),
|
||||||
|
@ -1144,20 +1144,20 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&TransformOperation::Matrix3D(ref this), &TransformOperation::Matrix3D(ref other)) => {
|
(&TransformOperation::Matrix3D(ref this), &TransformOperation::Matrix3D(ref other)) => {
|
||||||
this.compute_squared_distance(other)
|
this.compute_squared_distance(other)
|
||||||
},
|
}
|
||||||
(&TransformOperation::Matrix(ref this), &TransformOperation::Matrix(ref other)) => {
|
(&TransformOperation::Matrix(ref this), &TransformOperation::Matrix(ref other)) => {
|
||||||
let this: Matrix3D = (*this).into();
|
let this: Matrix3D = (*this).into();
|
||||||
let other: Matrix3D = (*other).into();
|
let other: Matrix3D = (*other).into();
|
||||||
this.compute_squared_distance(&other)
|
this.compute_squared_distance(&other)
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Skew(ref fx, ref fy),
|
&TransformOperation::Skew(ref fx, ref fy),
|
||||||
&TransformOperation::Skew(ref tx, ref ty),
|
&TransformOperation::Skew(ref tx, ref ty),
|
||||||
) => Ok(fx.compute_squared_distance(&tx)? + fy.compute_squared_distance(&ty)?),
|
) => Ok(fx.compute_squared_distance(&tx)? + fy.compute_squared_distance(&ty)?),
|
||||||
(&TransformOperation::SkewX(ref f), &TransformOperation::SkewX(ref t)) |
|
(&TransformOperation::SkewX(ref f), &TransformOperation::SkewX(ref t))
|
||||||
(&TransformOperation::SkewY(ref f), &TransformOperation::SkewY(ref t)) => {
|
| (&TransformOperation::SkewY(ref f), &TransformOperation::SkewY(ref t)) => {
|
||||||
f.compute_squared_distance(&t)
|
f.compute_squared_distance(&t)
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Translate3D(ref fx, ref fy, ref fz),
|
&TransformOperation::Translate3D(ref fx, ref fy, ref fz),
|
||||||
&TransformOperation::Translate3D(ref tx, ref ty, ref tz),
|
&TransformOperation::Translate3D(ref tx, ref ty, ref tz),
|
||||||
|
@ -1173,33 +1173,33 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
|
||||||
let tx = tx.length_component().px();
|
let tx = tx.length_component().px();
|
||||||
let ty = ty.length_component().px();
|
let ty = ty.length_component().px();
|
||||||
|
|
||||||
Ok(fx.compute_squared_distance(&tx)? +
|
Ok(fx.compute_squared_distance(&tx)?
|
||||||
fy.compute_squared_distance(&ty)? +
|
+ fy.compute_squared_distance(&ty)?
|
||||||
fz.compute_squared_distance(&tz)?)
|
+ fz.compute_squared_distance(&tz)?)
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Scale3D(ref fx, ref fy, ref fz),
|
&TransformOperation::Scale3D(ref fx, ref fy, ref fz),
|
||||||
&TransformOperation::Scale3D(ref tx, ref ty, ref tz),
|
&TransformOperation::Scale3D(ref tx, ref ty, ref tz),
|
||||||
) => Ok(fx.compute_squared_distance(&tx)? +
|
) => Ok(fx.compute_squared_distance(&tx)?
|
||||||
fy.compute_squared_distance(&ty)? +
|
+ fy.compute_squared_distance(&ty)?
|
||||||
fz.compute_squared_distance(&tz)?),
|
+ fz.compute_squared_distance(&tz)?),
|
||||||
(
|
(
|
||||||
&TransformOperation::Rotate3D(fx, fy, fz, fa),
|
&TransformOperation::Rotate3D(fx, fy, fz, fa),
|
||||||
&TransformOperation::Rotate3D(tx, ty, tz, ta),
|
&TransformOperation::Rotate3D(tx, ty, tz, ta),
|
||||||
) => Rotate::Rotate3D(fx, fy, fz, fa)
|
) => Rotate::Rotate3D(fx, fy, fz, fa)
|
||||||
.compute_squared_distance(&Rotate::Rotate3D(tx, ty, tz, ta)),
|
.compute_squared_distance(&Rotate::Rotate3D(tx, ty, tz, ta)),
|
||||||
(&TransformOperation::RotateX(fa), &TransformOperation::RotateX(ta)) |
|
(&TransformOperation::RotateX(fa), &TransformOperation::RotateX(ta))
|
||||||
(&TransformOperation::RotateY(fa), &TransformOperation::RotateY(ta)) |
|
| (&TransformOperation::RotateY(fa), &TransformOperation::RotateY(ta))
|
||||||
(&TransformOperation::RotateZ(fa), &TransformOperation::RotateZ(ta)) |
|
| (&TransformOperation::RotateZ(fa), &TransformOperation::RotateZ(ta))
|
||||||
(&TransformOperation::Rotate(fa), &TransformOperation::Rotate(ta)) => {
|
| (&TransformOperation::Rotate(fa), &TransformOperation::Rotate(ta)) => {
|
||||||
fa.compute_squared_distance(&ta)
|
fa.compute_squared_distance(&ta)
|
||||||
},
|
}
|
||||||
(
|
(
|
||||||
&TransformOperation::Perspective(ref fd),
|
&TransformOperation::Perspective(ref fd),
|
||||||
&TransformOperation::Perspective(ref td),
|
&TransformOperation::Perspective(ref td),
|
||||||
) => fd.compute_squared_distance(td),
|
) => fd.compute_squared_distance(td),
|
||||||
(&TransformOperation::Perspective(ref p), &TransformOperation::Matrix3D(ref m)) |
|
(&TransformOperation::Perspective(ref p), &TransformOperation::Matrix3D(ref m))
|
||||||
(&TransformOperation::Matrix3D(ref m), &TransformOperation::Perspective(ref p)) => {
|
| (&TransformOperation::Matrix3D(ref m), &TransformOperation::Perspective(ref p)) => {
|
||||||
// FIXME(emilio): Is this right? Why interpolating this with
|
// FIXME(emilio): Is this right? Why interpolating this with
|
||||||
// Perspective but not with anything else?
|
// Perspective but not with anything else?
|
||||||
let mut p_matrix = Matrix3D::identity();
|
let mut p_matrix = Matrix3D::identity();
|
||||||
|
@ -1207,7 +1207,7 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
|
||||||
p_matrix.m34 = -1. / p.px();
|
p_matrix.m34 = -1. / p.px();
|
||||||
}
|
}
|
||||||
p_matrix.compute_squared_distance(&m)
|
p_matrix.compute_squared_distance(&m)
|
||||||
},
|
}
|
||||||
// Gecko cross-interpolates amongst all translate and all scale
|
// Gecko cross-interpolates amongst all translate and all scale
|
||||||
// functions (See ToPrimitive in layout/style/StyleAnimationValue.cpp)
|
// functions (See ToPrimitive in layout/style/StyleAnimationValue.cpp)
|
||||||
// without falling back to InterpolateMatrix
|
// without falling back to InterpolateMatrix
|
||||||
|
@ -1256,7 +1256,7 @@ impl Animate for ComputedRotate {
|
||||||
fz,
|
fz,
|
||||||
fa.animate(&Angle::zero(), procedure)?,
|
fa.animate(&Angle::zero(), procedure)?,
|
||||||
))
|
))
|
||||||
},
|
}
|
||||||
(&Rotate::None, &Rotate::Rotate3D(tx, ty, tz, ta)) => {
|
(&Rotate::None, &Rotate::Rotate3D(tx, ty, tz, ta)) => {
|
||||||
// No need to normalize `none`, so animate angle directly.
|
// No need to normalize `none`, so animate angle directly.
|
||||||
Ok(Rotate::Rotate3D(
|
Ok(Rotate::Rotate3D(
|
||||||
|
@ -1265,7 +1265,7 @@ impl Animate for ComputedRotate {
|
||||||
tz,
|
tz,
|
||||||
Angle::zero().animate(&ta, procedure)?,
|
Angle::zero().animate(&ta, procedure)?,
|
||||||
))
|
))
|
||||||
},
|
}
|
||||||
(&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => {
|
(&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
let (mut fx, mut fy, mut fz, fa) =
|
let (mut fx, mut fy, mut fz, fa) =
|
||||||
|
@ -1301,12 +1301,12 @@ impl Animate for ComputedRotate {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Rotate::Rotate3D(x, y, z, Angle::from_radians(angle)))
|
Ok(Rotate::Rotate3D(x, y, z, Angle::from_radians(angle)))
|
||||||
},
|
}
|
||||||
(&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => {
|
(&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => {
|
||||||
// If this is a 2D rotation, we just animate the <angle>
|
// If this is a 2D rotation, we just animate the <angle>
|
||||||
let (from, to) = (self.resolve().3, other.resolve().3);
|
let (from, to) = (self.resolve().3, other.resolve().3);
|
||||||
Ok(Rotate::Rotate(from.animate(&to, procedure)?))
|
Ok(Rotate::Rotate(from.animate(&to, procedure)?))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1316,10 +1316,10 @@ impl ComputeSquaredDistance for ComputedRotate {
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&Rotate::None, &Rotate::None) => Ok(SquaredDistance::from_sqrt(0.)),
|
(&Rotate::None, &Rotate::None) => Ok(SquaredDistance::from_sqrt(0.)),
|
||||||
(&Rotate::Rotate3D(_, _, _, a), &Rotate::None) |
|
(&Rotate::Rotate3D(_, _, _, a), &Rotate::None)
|
||||||
(&Rotate::None, &Rotate::Rotate3D(_, _, _, a)) => {
|
| (&Rotate::None, &Rotate::Rotate3D(_, _, _, a)) => {
|
||||||
a.compute_squared_distance(&Angle::zero())
|
a.compute_squared_distance(&Angle::zero())
|
||||||
},
|
}
|
||||||
(&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => {
|
(&Rotate::Rotate3D(_, ..), _) | (_, &Rotate::Rotate3D(_, ..)) => {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
let (mut fx, mut fy, mut fz, angle1) =
|
let (mut fx, mut fy, mut fz, angle1) =
|
||||||
|
@ -1346,7 +1346,7 @@ impl ComputeSquaredDistance for ComputedRotate {
|
||||||
let q2 = Quaternion::from_direction_and_angle(&v2, angle2.radians64());
|
let q2 = Quaternion::from_direction_and_angle(&v2, angle2.radians64());
|
||||||
q1.compute_squared_distance(&q2)
|
q1.compute_squared_distance(&q2)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
(&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => self
|
(&Rotate::Rotate(_), _) | (_, &Rotate::Rotate(_)) => self
|
||||||
.resolve()
|
.resolve()
|
||||||
.3
|
.3
|
||||||
|
@ -1368,8 +1368,7 @@ impl ComputedTranslate {
|
||||||
LengthPercentage::zero(),
|
LengthPercentage::zero(),
|
||||||
Length::zero(),
|
Length::zero(),
|
||||||
),
|
),
|
||||||
Translate::Translate3D(tx, ty, tz) => (tx, ty, tz),
|
Translate::Translate(tx, ty, tz) => (tx, ty, tz),
|
||||||
Translate::Translate(tx, ty) => (tx, ty, Length::zero()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1379,21 +1378,14 @@ impl Animate for ComputedTranslate {
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&Translate::None, &Translate::None) => Ok(Translate::None),
|
(&Translate::None, &Translate::None) => Ok(Translate::None),
|
||||||
(&Translate::Translate3D(_, ..), _) | (_, &Translate::Translate3D(_, ..)) => {
|
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
|
||||||
Ok(Translate::Translate3D(
|
|
||||||
from.0.animate(&to.0, procedure)?,
|
|
||||||
from.1.animate(&to.1, procedure)?,
|
|
||||||
from.2.animate(&to.2, procedure)?,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
(&Translate::Translate(_, ..), _) | (_, &Translate::Translate(_, ..)) => {
|
(&Translate::Translate(_, ..), _) | (_, &Translate::Translate(_, ..)) => {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
Ok(Translate::Translate(
|
Ok(Translate::Translate(
|
||||||
from.0.animate(&to.0, procedure)?,
|
from.0.animate(&to.0, procedure)?,
|
||||||
from.1.animate(&to.1, procedure)?,
|
from.1.animate(&to.1, procedure)?,
|
||||||
|
from.2.animate(&to.2, procedure)?,
|
||||||
))
|
))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1402,9 +1394,9 @@ impl ComputeSquaredDistance for ComputedTranslate {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
Ok(from.0.compute_squared_distance(&to.0)? +
|
Ok(from.0.compute_squared_distance(&to.0)?
|
||||||
from.1.compute_squared_distance(&to.1)? +
|
+ from.1.compute_squared_distance(&to.1)?
|
||||||
from.2.compute_squared_distance(&to.2)?)
|
+ from.2.compute_squared_distance(&to.2)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1417,8 +1409,7 @@ impl ComputedScale {
|
||||||
// Unspecified scales default to 1
|
// Unspecified scales default to 1
|
||||||
match *self {
|
match *self {
|
||||||
Scale::None => (1.0, 1.0, 1.0),
|
Scale::None => (1.0, 1.0, 1.0),
|
||||||
Scale::Scale3D(sx, sy, sz) => (sx, sy, sz),
|
Scale::Scale(sx, sy, sz) => (sx, sy, sz),
|
||||||
Scale::Scale(sx, sy) => (sx, sy, 1.),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1428,7 +1419,7 @@ impl Animate for ComputedScale {
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&Scale::None, &Scale::None) => Ok(Scale::None),
|
(&Scale::None, &Scale::None) => Ok(Scale::None),
|
||||||
(&Scale::Scale3D(_, ..), _) | (_, &Scale::Scale3D(_, ..)) => {
|
(&Scale::Scale(_, ..), _) | (_, &Scale::Scale(_, ..)) => {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
// For transform lists, we add by appending to the list of
|
// For transform lists, we add by appending to the list of
|
||||||
// transform functions. However, ComputedScale cannot be
|
// transform functions. However, ComputedScale cannot be
|
||||||
|
@ -1436,26 +1427,14 @@ impl Animate for ComputedScale {
|
||||||
// result here.
|
// result here.
|
||||||
if procedure == Procedure::Add {
|
if procedure == Procedure::Add {
|
||||||
// scale(x1,y1,z1)*scale(x2,y2,z2) = scale(x1*x2, y1*y2, z1*z2)
|
// scale(x1,y1,z1)*scale(x2,y2,z2) = scale(x1*x2, y1*y2, z1*z2)
|
||||||
return Ok(Scale::Scale3D(from.0 * to.0, from.1 * to.1, from.2 * to.2));
|
return Ok(Scale::Scale(from.0 * to.0, from.1 * to.1, from.2 * to.2));
|
||||||
}
|
|
||||||
Ok(Scale::Scale3D(
|
|
||||||
animate_multiplicative_factor(from.0, to.0, procedure)?,
|
|
||||||
animate_multiplicative_factor(from.1, to.1, procedure)?,
|
|
||||||
animate_multiplicative_factor(from.2, to.2, procedure)?,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
(&Scale::Scale(_, ..), _) | (_, &Scale::Scale(_, ..)) => {
|
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
|
||||||
// As with Scale3D, addition needs special handling.
|
|
||||||
if procedure == Procedure::Add {
|
|
||||||
// scale(x1,y1)*scale(x2,y2) = scale(x1*x2, y1*y2)
|
|
||||||
return Ok(Scale::Scale(from.0 * to.0, from.1 * to.1));
|
|
||||||
}
|
}
|
||||||
Ok(Scale::Scale(
|
Ok(Scale::Scale(
|
||||||
animate_multiplicative_factor(from.0, to.0, procedure)?,
|
animate_multiplicative_factor(from.0, to.0, procedure)?,
|
||||||
animate_multiplicative_factor(from.1, to.1, procedure)?,
|
animate_multiplicative_factor(from.1, to.1, procedure)?,
|
||||||
|
animate_multiplicative_factor(from.2, to.2, procedure)?,
|
||||||
))
|
))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1464,8 +1443,8 @@ impl ComputeSquaredDistance for ComputedScale {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
||||||
let (from, to) = (self.resolve(), other.resolve());
|
let (from, to) = (self.resolve(), other.resolve());
|
||||||
Ok(from.0.compute_squared_distance(&to.0)? +
|
Ok(from.0.compute_squared_distance(&to.0)?
|
||||||
from.1.compute_squared_distance(&to.1)? +
|
+ from.1.compute_squared_distance(&to.1)?
|
||||||
from.2.compute_squared_distance(&to.2)?)
|
+ from.2.compute_squared_distance(&to.2)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@ where
|
||||||
match *self {
|
match *self {
|
||||||
Translate(..) | Translate3D(..) | TranslateX(..) | TranslateY(..) | TranslateZ(..) => {
|
Translate(..) | Translate3D(..) | TranslateX(..) | TranslateY(..) | TranslateZ(..) => {
|
||||||
true
|
true
|
||||||
},
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,8 +415,8 @@ where
|
||||||
fn is_3d(&self) -> bool {
|
fn is_3d(&self) -> bool {
|
||||||
use self::TransformOperation::*;
|
use self::TransformOperation::*;
|
||||||
match *self {
|
match *self {
|
||||||
Translate3D(..) | TranslateZ(..) | Rotate3D(..) | RotateX(..) | RotateY(..) |
|
Translate3D(..) | TranslateZ(..) | Rotate3D(..) | RotateX(..) | RotateY(..)
|
||||||
RotateZ(..) | Scale3D(..) | ScaleZ(..) | Perspective(..) | Matrix3D(..) => true,
|
| RotateZ(..) | Scale3D(..) | ScaleZ(..) | Perspective(..) | Matrix3D(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,23 +444,23 @@ where
|
||||||
az as f64,
|
az as f64,
|
||||||
euclid::Angle::radians(theta),
|
euclid::Angle::radians(theta),
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
RotateX(theta) => {
|
RotateX(theta) => {
|
||||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||||
Transform3D::create_rotation(1., 0., 0., theta)
|
Transform3D::create_rotation(1., 0., 0., theta)
|
||||||
},
|
}
|
||||||
RotateY(theta) => {
|
RotateY(theta) => {
|
||||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||||
Transform3D::create_rotation(0., 1., 0., theta)
|
Transform3D::create_rotation(0., 1., 0., theta)
|
||||||
},
|
}
|
||||||
RotateZ(theta) | Rotate(theta) => {
|
RotateZ(theta) | Rotate(theta) => {
|
||||||
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
|
||||||
Transform3D::create_rotation(0., 0., 1., theta)
|
Transform3D::create_rotation(0., 0., 1., theta)
|
||||||
},
|
}
|
||||||
Perspective(ref d) => {
|
Perspective(ref d) => {
|
||||||
let m = create_perspective_matrix(d.to_pixel_length(None)?);
|
let m = create_perspective_matrix(d.to_pixel_length(None)?);
|
||||||
m.cast()
|
m.cast()
|
||||||
},
|
}
|
||||||
Scale3D(sx, sy, sz) => Transform3D::create_scale(sx.into(), sy.into(), sz.into()),
|
Scale3D(sx, sy, sz) => Transform3D::create_scale(sx.into(), sy.into(), sz.into()),
|
||||||
Scale(sx, sy) => Transform3D::create_scale(sx.into(), sy.into(), 1.),
|
Scale(sx, sy) => Transform3D::create_scale(sx.into(), sy.into(), 1.),
|
||||||
ScaleX(s) => Transform3D::create_scale(s.into(), 1., 1.),
|
ScaleX(s) => Transform3D::create_scale(s.into(), 1., 1.),
|
||||||
|
@ -470,23 +470,23 @@ where
|
||||||
let tx = tx.to_pixel_length(reference_width)? as f64;
|
let tx = tx.to_pixel_length(reference_width)? as f64;
|
||||||
let ty = ty.to_pixel_length(reference_height)? as f64;
|
let ty = ty.to_pixel_length(reference_height)? as f64;
|
||||||
Transform3D::create_translation(tx, ty, tz.to_pixel_length(None)? as f64)
|
Transform3D::create_translation(tx, ty, tz.to_pixel_length(None)? as f64)
|
||||||
},
|
}
|
||||||
Translate(ref tx, ref ty) => {
|
Translate(ref tx, ref ty) => {
|
||||||
let tx = tx.to_pixel_length(reference_width)? as f64;
|
let tx = tx.to_pixel_length(reference_width)? as f64;
|
||||||
let ty = ty.to_pixel_length(reference_height)? as f64;
|
let ty = ty.to_pixel_length(reference_height)? as f64;
|
||||||
Transform3D::create_translation(tx, ty, 0.)
|
Transform3D::create_translation(tx, ty, 0.)
|
||||||
},
|
}
|
||||||
TranslateX(ref t) => {
|
TranslateX(ref t) => {
|
||||||
let t = t.to_pixel_length(reference_width)? as f64;
|
let t = t.to_pixel_length(reference_width)? as f64;
|
||||||
Transform3D::create_translation(t, 0., 0.)
|
Transform3D::create_translation(t, 0., 0.)
|
||||||
},
|
}
|
||||||
TranslateY(ref t) => {
|
TranslateY(ref t) => {
|
||||||
let t = t.to_pixel_length(reference_height)? as f64;
|
let t = t.to_pixel_length(reference_height)? as f64;
|
||||||
Transform3D::create_translation(0., t, 0.)
|
Transform3D::create_translation(0., t, 0.)
|
||||||
},
|
}
|
||||||
TranslateZ(ref z) => {
|
TranslateZ(ref z) => {
|
||||||
Transform3D::create_translation(0., 0., z.to_pixel_length(None)? as f64)
|
Transform3D::create_translation(0., 0., z.to_pixel_length(None)? as f64)
|
||||||
},
|
}
|
||||||
Skew(theta_x, theta_y) => Transform3D::create_skew(
|
Skew(theta_x, theta_y) => Transform3D::create_skew(
|
||||||
euclid::Angle::radians(theta_x.radians64()),
|
euclid::Angle::radians(theta_x.radians64()),
|
||||||
euclid::Angle::radians(theta_y.radians64()),
|
euclid::Angle::radians(theta_y.radians64()),
|
||||||
|
@ -509,7 +509,7 @@ where
|
||||||
// return an identity matrix.
|
// return an identity matrix.
|
||||||
// Note: DOMMatrix doesn't go into this arm.
|
// Note: DOMMatrix doesn't go into this arm.
|
||||||
Transform3D::identity()
|
Transform3D::identity()
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
Ok(matrix)
|
Ok(matrix)
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ where
|
||||||
}
|
}
|
||||||
dest.write_char(' ')?;
|
dest.write_char(' ')?;
|
||||||
angle.to_css(dest)
|
angle.to_css(dest)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -700,38 +700,50 @@ where
|
||||||
pub enum GenericScale<Number> {
|
pub enum GenericScale<Number> {
|
||||||
/// 'none'
|
/// 'none'
|
||||||
None,
|
None,
|
||||||
/// '<number>{1,2}'
|
/// '<number>{1,3}'
|
||||||
Scale(Number, Number),
|
Scale(Number, Number, Number),
|
||||||
/// '<number>{3}'
|
|
||||||
Scale3D(Number, Number, Number),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::GenericScale as Scale;
|
pub use self::GenericScale as Scale;
|
||||||
|
|
||||||
impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
|
impl<Number> ToCss for Scale<Number>
|
||||||
|
where
|
||||||
|
Number: ToCss + PartialEq + Copy,
|
||||||
|
f32: From<Number>,
|
||||||
|
{
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
W: fmt::Write,
|
W: fmt::Write,
|
||||||
|
f32: From<Number>,
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
Scale::None => dest.write_str("none"),
|
Scale::None => dest.write_str("none"),
|
||||||
Scale::Scale(ref x, ref y) => {
|
Scale::Scale(ref x, ref y, ref z) => {
|
||||||
x.to_css(dest)?;
|
x.to_css(dest)?;
|
||||||
if x != y {
|
|
||||||
|
let is_3d = f32::from(*z) != 1.0;
|
||||||
|
if is_3d || x != y {
|
||||||
dest.write_char(' ')?;
|
dest.write_char(' ')?;
|
||||||
y.to_css(dest)?;
|
y.to_css(dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_3d {
|
||||||
|
dest.write_char(' ')?;
|
||||||
|
z.to_css(dest)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
|
||||||
Scale::Scale3D(ref x, ref y, ref z) => {
|
|
||||||
x.to_css(dest)?;
|
|
||||||
dest.write_char(' ')?;
|
|
||||||
y.to_css(dest)?;
|
|
||||||
dest.write_char(' ')?;
|
|
||||||
z.to_css(dest)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn y_axis_and_z_axis_are_zero<LengthPercentage: Zero, Length: Zero>(
|
||||||
|
_: &LengthPercentage,
|
||||||
|
y: &LengthPercentage,
|
||||||
|
z: &Length,
|
||||||
|
) -> bool {
|
||||||
|
y.is_zero() && z.is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -755,25 +767,24 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
|
||||||
/// or two values (per usual, if the second value is 0px, the default, it must
|
/// or two values (per usual, if the second value is 0px, the default, it must
|
||||||
/// be omitted when serializing).
|
/// be omitted when serializing).
|
||||||
///
|
///
|
||||||
/// If a 3d translation is specified, all three values must be serialized.
|
/// If a 3d translation is specified and the value can be expressed as 2d, we treat as 2d and
|
||||||
///
|
/// serialize accoringly. Otherwise, we serialize all three values.
|
||||||
/// We don't omit the 3rd component even if it is 0px for now, and the
|
/// https://github.com/w3c/csswg-drafts/issues/3305
|
||||||
/// related spec issue is https://github.com/w3c/csswg-drafts/issues/3305
|
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
|
/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
|
||||||
pub enum GenericTranslate<LengthPercentage, Length>
|
pub enum GenericTranslate<LengthPercentage, Length>
|
||||||
where
|
where
|
||||||
LengthPercentage: Zero,
|
LengthPercentage: Zero,
|
||||||
|
Length: Zero,
|
||||||
{
|
{
|
||||||
/// 'none'
|
/// 'none'
|
||||||
None,
|
None,
|
||||||
/// '<length-percentage>' or '<length-percentage> <length-percentage>'
|
/// <length-percentage> [ <length-percentage> <length>? ]?
|
||||||
Translate(
|
Translate(
|
||||||
LengthPercentage,
|
LengthPercentage,
|
||||||
#[css(skip_if = "Zero::is_zero")] LengthPercentage,
|
#[css(contextual_skip_if = "y_axis_and_z_axis_are_zero")] LengthPercentage,
|
||||||
|
#[css(skip_if = "Zero::is_zero")] Length,
|
||||||
),
|
),
|
||||||
/// '<length-percentage> <length-percentage> <length>'
|
|
||||||
Translate3D(LengthPercentage, LengthPercentage, Length),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::GenericTranslate as Translate;
|
pub use self::GenericTranslate as Translate;
|
||||||
|
|
|
@ -421,17 +421,22 @@ impl Parse for Translate {
|
||||||
if let Ok(ty) = input.try(|i| specified::LengthPercentage::parse(context, i)) {
|
if let Ok(ty) = input.try(|i| specified::LengthPercentage::parse(context, i)) {
|
||||||
if let Ok(tz) = input.try(|i| specified::Length::parse(context, i)) {
|
if let Ok(tz) = input.try(|i| specified::Length::parse(context, i)) {
|
||||||
// 'translate: <length-percentage> <length-percentage> <length>'
|
// 'translate: <length-percentage> <length-percentage> <length>'
|
||||||
return Ok(generic::Translate::Translate3D(tx, ty, tz));
|
return Ok(generic::Translate::Translate(tx, ty, tz));
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate: <length-percentage> <length-percentage>'
|
// translate: <length-percentage> <length-percentage>'
|
||||||
return Ok(generic::Translate::Translate(tx, ty));
|
return Ok(generic::Translate::Translate(
|
||||||
|
tx,
|
||||||
|
ty,
|
||||||
|
specified::Length::zero(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'translate: <length-percentage> '
|
// 'translate: <length-percentage> '
|
||||||
Ok(generic::Translate::Translate(
|
Ok(generic::Translate::Translate(
|
||||||
tx,
|
tx,
|
||||||
specified::LengthPercentage::zero(),
|
specified::LengthPercentage::zero(),
|
||||||
|
specified::Length::zero(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,14 +457,14 @@ impl Parse for Scale {
|
||||||
if let Ok(sy) = input.try(|i| Number::parse(context, i)) {
|
if let Ok(sy) = input.try(|i| Number::parse(context, i)) {
|
||||||
if let Ok(sz) = input.try(|i| Number::parse(context, i)) {
|
if let Ok(sz) = input.try(|i| Number::parse(context, i)) {
|
||||||
// 'scale: <number> <number> <number>'
|
// 'scale: <number> <number> <number>'
|
||||||
return Ok(generic::Scale::Scale3D(sx, sy, sz));
|
return Ok(generic::Scale::Scale(sx, sy, sz));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'scale: <number> <number>'
|
// 'scale: <number> <number>'
|
||||||
return Ok(generic::Scale::Scale(sx, sy));
|
return Ok(generic::Scale::Scale(sx, sy, Number::new(1.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'scale: <number>'
|
// 'scale: <number>'
|
||||||
Ok(generic::Scale::Scale(sx, sx))
|
Ok(generic::Scale::Scale(sx, sx, Number::new(1.0)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue