From aa0ed0c2edece61d1f4b2b39bdb110b8be97a409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io> Date: Fri, 7 Dec 2018 12:40:53 -0500 Subject: [PATCH 1/2] transform3d: Introduce Transform3D::project_to_2d to flatten a transform. Need to use this for https://github.com/servo/webrender/issues/3394. The normalization of perspective is not necessary but Gecko does it as a performance optimization, and ScaleOffset in WR wouldn't handle this. See: https://bugzilla.mozilla.org/show_bug.cgi?id=1241161 But in any case I'm happy to teach ScaleOffset about that case instead if you think it's better. --- src/transform3d.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/transform3d.rs b/src/transform3d.rs index 94b2e458..224ae5fc 100644 --- a/src/transform3d.rs +++ b/src/transform3d.rs @@ -520,6 +520,42 @@ where T: Copy + Clone + self.post_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z)) } + /// Returns a projection of this transform in 2d space. + pub fn project_to_2d(&self) -> Self { + let (_0, _1): (T, T) = (Zero::zero(), One::one()); + + let mut result = self.clone(); + + result.m31 = _0; + result.m32 = _0; + result.m13 = _0; + result.m23 = _0; + result.m33 = _1; + result.m43 = _0; + result.m34 = _0; + + // Try to normalize perspective when possible to convert to a 2d matrix. + // Some matrices, such as those derived from perspective transforms, can + // modify m44 from 1, while leaving the rest of the fourth column + // (m14, m24) at 0. In this case, after resetting the third row and + // third column above, the value of m44 functions only to scale the + // coordinate transform divide by W. The matrix can be converted to + // a true 2D matrix by normalizing out the scaling effect of m44 on + // the remaining components ahead of time. + if self.m14 == _0 && self.m24 == _0 && self.m44 != _0 && self.m44 != _1 { + let scale = _1 / self.m44; + result.m11 = result.m11 * scale; + result.m12 = result.m12 * scale; + result.m21 = result.m21 * scale; + result.m22 = result.m22 * scale; + result.m41 = result.m41 * scale; + result.m42 = result.m42 * scale; + result.m44 = _1; + } + + result + } + /// Create a 3d scale transform pub fn create_scale(x: T, y: T, z: T) -> Self { let (_0, _1): (T, T) = (Zero::zero(), One::one()); From 1c620631be11331523aa62ff16038d43978f3654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io> Date: Fri, 7 Dec 2018 14:26:21 -0500 Subject: [PATCH 2/2] Minor version bump. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 812672ed..bdbec9f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "euclid" -version = "0.19.3" +version = "0.19.4" authors = ["The Servo Project Developers"] description = "Geometry primitives" documentation = "https://docs.rs/euclid/"