aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Chiou <boris.chiou@gmail.com>2017-08-08 14:07:28 +0800
committerBoris Chiou <boris.chiou@gmail.com>2017-08-08 18:47:43 +0800
commit9603266f9ae5e1a2bbbb0405aaf75fa46b2039ec (patch)
tree1c4a4ea32b9befa4a483cb3dbbd74c0cfff3d3ca
parent69f02f4f7f102a3fe3f82d5f000533a9277d233e (diff)
downloadservo-9603266f9ae5e1a2bbbb0405aaf75fa46b2039ec.tar.gz
servo-9603266f9ae5e1a2bbbb0405aaf75fa46b2039ec.zip
Don't apply the rotation if it cannot be normalized.
According to the spec, the computed value of transform is as specified, but with relative lengths converted into absolute lengths, so in Gecko, we do nothing while computing the value of rotate3d(), and do normalization in ProcessRotate3D(). If the direction cannot be normalized, we treat it as an identity matrix. However, in Servo, we do normalization in to_computed_value(), and looks like we are trying to normalize any kind of direction vectors, so according to the spec, let's move the normalization into Fragment::transform_matrix(), and return an identity matrix if we cannot normalize its direction vector.
-rw-r--r--components/layout/fragment.rs13
-rw-r--r--components/style/properties/longhand/box.mako.rs3
2 files changed, 12 insertions, 4 deletions
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index fd2d5698efd..2510b185d1c 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -2887,8 +2887,17 @@ impl Fragment {
for operation in operations {
let matrix = match *operation {
transform::ComputedOperation::Rotate(ax, ay, az, theta) => {
- let theta = 2.0f32 * f32::consts::PI - theta.radians();
- Transform3D::create_rotation(ax, ay, az, Radians::new(theta))
+ // https://www.w3.org/TR/css-transforms-1/#funcdef-rotate3d
+ // A direction vector that cannot be normalized, such as [0, 0, 0], will cause
+ // the rotation to not be applied, so we use identity matrix in this case.
+ let len = (ax * ax + ay * ay + az * az).sqrt();
+ if len > 0. {
+ let theta = 2.0f32 * f32::consts::PI - theta.radians();
+ Transform3D::create_rotation(ax / len, ay / len, az / len,
+ Radians::new(theta))
+ } else {
+ Transform3D::identity()
+ }
}
transform::ComputedOperation::Perspective(d) => {
create_perspective_matrix(d)
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 7bdb7c1c1c5..7b7b71db574 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -1416,8 +1416,7 @@ ${helpers.predefined_type(
let ay = ay.to_computed_value(context);
let az = az.to_computed_value(context);
let theta = theta.to_computed_value(context);
- let len = (ax * ax + ay * ay + az * az).sqrt();
- result.push(computed_value::ComputedOperation::Rotate(ax / len, ay / len, az / len, theta));
+ result.push(computed_value::ComputedOperation::Rotate(ax, ay, az, theta));
}
SpecifiedOperation::Skew(theta_x, None) => {
let theta_x = theta_x.to_computed_value(context);