diff --git a/geometry/src/basic/line_segment.rs b/geometry/src/basic/line_segment.rs index 5494451f..3657ded9 100644 --- a/geometry/src/basic/line_segment.rs +++ b/geometry/src/basic/line_segment.rs @@ -97,8 +97,10 @@ impl LineSegmentF32 { let (from_from, to_to) = (self.0.xyxy(), self.0.zwzw()); let d_d = to_to - from_from; let mid_mid = from_from + d_d * F32x4::splat(t); - (LineSegmentF32(from_from.concat_xy_xy(mid_mid)), - LineSegmentF32(mid_mid.concat_xy_xy(to_to))) + ( + LineSegmentF32(from_from.concat_xy_xy(mid_mid)), + LineSegmentF32(mid_mid.concat_xy_xy(to_to)), + ) } // Returns the left segment first, followed by the right segment. @@ -248,7 +250,12 @@ impl LineSegmentF32 { if self.is_zero_length() { *self } else { - *self + self.vector().yx().normalize().scale_xy(Point2DF32::new(-distance, distance)) + *self + + self + .vector() + .yx() + .normalize() + .scale_xy(Point2DF32::new(-distance, distance)) } } diff --git a/geometry/src/basic/rect.rs b/geometry/src/basic/rect.rs index ed781170..701c6d00 100644 --- a/geometry/src/basic/rect.rs +++ b/geometry/src/basic/rect.rs @@ -55,13 +55,19 @@ impl RectF32 { #[inline] pub fn contains_point(&self, point: Point2DF32) -> bool { // self.origin <= point && point <= self.lower_right - self.0.concat_xy_xy(point.0).packed_le(point.0.concat_xy_zw(self.0)).is_all_ones() + self.0 + .concat_xy_xy(point.0) + .packed_le(point.0.concat_xy_zw(self.0)) + .is_all_ones() } #[inline] pub fn contains_rect(&self, other: RectF32) -> bool { // self.origin <= other.origin && other.lower_right <= self.lower_right - self.0.concat_xy_zw(other.0).packed_le(other.0.concat_xy_zw(self.0)).is_all_ones() + self.0 + .concat_xy_zw(other.0) + .packed_le(other.0.concat_xy_zw(self.0)) + .is_all_ones() } #[inline] @@ -76,14 +82,19 @@ impl RectF32 { #[inline] pub fn union_rect(&self, other: RectF32) -> RectF32 { - RectF32::from_points(self.origin().min(other.origin()), - self.lower_right().max(other.lower_right())) + RectF32::from_points( + self.origin().min(other.origin()), + self.lower_right().max(other.lower_right()), + ) } #[inline] pub fn intersects(&self, other: RectF32) -> bool { // self.origin < other.lower_right && other.origin < self.lower_right - self.0.concat_xy_xy(other.0).packed_lt(other.0.concat_zw_zw(self.0)).is_all_ones() + self.0 + .concat_xy_xy(other.0) + .packed_lt(other.0.concat_zw_zw(self.0)) + .is_all_ones() } #[inline] @@ -91,8 +102,10 @@ impl RectF32 { if !self.intersects(other) { None } else { - Some(RectF32::from_points(self.origin().max(other.origin()), - self.lower_right().min(other.lower_right()))) + Some(RectF32::from_points( + self.origin().max(other.origin()), + self.lower_right().min(other.lower_right()), + )) } } @@ -200,7 +213,10 @@ impl RectI32 { pub fn contains_point(&self, point: Point2DI32) -> bool { // self.origin <= point && point <= self.lower_right - 1 let lower_right = self.lower_right() - Point2DI32::splat(1); - self.0.concat_xy_xy(point.0).packed_le(point.0.concat_xy_xy(lower_right.0)).is_all_ones() + self.0 + .concat_xy_xy(point.0) + .packed_le(point.0.concat_xy_xy(lower_right.0)) + .is_all_ones() } #[inline] diff --git a/geometry/src/basic/transform2d.rs b/geometry/src/basic/transform2d.rs index f9972f2e..112b4779 100644 --- a/geometry/src/basic/transform2d.rs +++ b/geometry/src/basic/transform2d.rs @@ -82,13 +82,21 @@ impl Matrix2x2F32 { } #[inline] - pub fn m11(&self) -> f32 { self.0[0] } + pub fn m11(&self) -> f32 { + self.0[0] + } #[inline] - pub fn m21(&self) -> f32 { self.0[1] } + pub fn m21(&self) -> f32 { + self.0[1] + } #[inline] - pub fn m12(&self) -> f32 { self.0[2] } + pub fn m12(&self) -> f32 { + self.0[2] + } #[inline] - pub fn m22(&self) -> f32 { self.0[3] } + pub fn m22(&self) -> f32 { + self.0[3] + } } impl Sub for Matrix2x2F32 { @@ -140,16 +148,20 @@ impl Transform2DF32 { } #[inline] - pub fn from_scale_rotation_translation(scale: Point2DF32, theta: f32, translation: Point2DF32) - -> Transform2DF32 { + pub fn from_scale_rotation_translation( + scale: Point2DF32, + theta: f32, + translation: Point2DF32, + ) -> Transform2DF32 { let rotation = Transform2DF32::from_rotation(theta); let translation = Transform2DF32::from_translation(&translation); - Transform2DF32::from_scale(&scale).post_mul(&rotation).post_mul(&translation) + Transform2DF32::from_scale(&scale) + .post_mul(&rotation) + .post_mul(&translation) } #[inline] - pub fn row_major(m11: f32, m12: f32, m21: f32, m22: f32, m31: f32, m32: f32) - -> Transform2DF32 { + pub fn row_major(m11: f32, m12: f32, m21: f32, m22: f32, m31: f32, m32: f32) -> Transform2DF32 { Transform2DF32 { matrix: Matrix2x2F32::row_major(m11, m12, m21, m22), vector: Point2DF32::new(m31, m32), @@ -187,10 +199,24 @@ impl Transform2DF32 { // TODO(pcwalton): Optimize better with SIMD. #[inline] pub fn to_3d(&self) -> Transform3DF32 { - Transform3DF32::row_major(self.matrix.0[0], self.matrix.0[1], 0.0, self.vector.x(), - self.matrix.0[2], self.matrix.0[3], 0.0, self.vector.y(), - 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + self.matrix.0[0], + self.matrix.0[1], + 0.0, + self.vector.x(), + self.matrix.0[2], + self.matrix.0[3], + 0.0, + self.vector.y(), + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + ) } #[inline] @@ -199,13 +225,21 @@ impl Transform2DF32 { } #[inline] - pub fn m11(&self) -> f32 { self.matrix.m11() } + pub fn m11(&self) -> f32 { + self.matrix.m11() + } #[inline] - pub fn m21(&self) -> f32 { self.matrix.m21() } + pub fn m21(&self) -> f32 { + self.matrix.m21() + } #[inline] - pub fn m12(&self) -> f32 { self.matrix.m12() } + pub fn m12(&self) -> f32 { + self.matrix.m12() + } #[inline] - pub fn m22(&self) -> f32 { self.matrix.m22() } + pub fn m22(&self) -> f32 { + self.matrix.m22() + } #[inline] pub fn post_translate(&self, vector: Point2DF32) -> Transform2DF32 { diff --git a/geometry/src/basic/transform3d.rs b/geometry/src/basic/transform3d.rs index 5abf477a..d5222d86 100644 --- a/geometry/src/basic/transform3d.rs +++ b/geometry/src/basic/transform3d.rs @@ -43,11 +43,24 @@ impl Default for Transform3DF32 { impl Transform3DF32 { #[inline] - pub fn row_major(m00: f32, m01: f32, m02: f32, m03: f32, - m10: f32, m11: f32, m12: f32, m13: f32, - m20: f32, m21: f32, m22: f32, m23: f32, - m30: f32, m31: f32, m32: f32, m33: f32) - -> Transform3DF32 { + pub fn row_major( + m00: f32, + m01: f32, + m02: f32, + m03: f32, + m10: f32, + m11: f32, + m12: f32, + m13: f32, + m20: f32, + m21: f32, + m22: f32, + m23: f32, + m30: f32, + m31: f32, + m32: f32, + m33: f32, + ) -> Transform3DF32 { Transform3DF32 { c0: F32x4::new(m00, m10, m20, m30), c1: F32x4::new(m01, m11, m21, m31), @@ -58,10 +71,9 @@ impl Transform3DF32 { #[inline] pub fn from_scale(x: f32, y: f32, z: f32) -> Transform3DF32 { - Transform3DF32::row_major( x, 0.0, 0.0, 0.0, - 0.0, y, 0.0, 0.0, - 0.0, 0.0, z, 0.0, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, + ) } #[inline] @@ -71,17 +83,16 @@ impl Transform3DF32 { #[inline] pub fn from_translation(x: f32, y: f32, z: f32) -> Transform3DF32 { - Transform3DF32::row_major(1.0, 0.0, 0.0, x, - 0.0, 1.0, 0.0, y, - 0.0, 0.0, 1.0, z, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + 1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0, + ) } // TODO(pcwalton): Optimize. pub fn from_rotation(yaw: f32, pitch: f32, roll: f32) -> Transform3DF32 { - let (cos_b, sin_b) = (yaw.cos(), yaw.sin()); + let (cos_b, sin_b) = (yaw.cos(), yaw.sin()); let (cos_c, sin_c) = (pitch.cos(), pitch.sin()); - let (cos_a, sin_a) = (roll.cos(), roll.sin()); + let (cos_a, sin_a) = (roll.cos(), roll.sin()); let m00 = cos_a * cos_b; let m01 = cos_a * sin_b * sin_c - sin_a * cos_c; let m02 = cos_a * sin_b * cos_c + sin_a * sin_c; @@ -91,10 +102,9 @@ impl Transform3DF32 { let m20 = -sin_b; let m21 = cos_b * sin_c; let m22 = cos_b * cos_c; - Transform3DF32::row_major(m00, m01, m02, 0.0, - m10, m11, m12, 0.0, - m20, m21, m22, 0.0, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + m00, m01, m02, 0.0, m10, m11, m12, 0.0, m20, m21, m22, 0.0, 0.0, 0.0, 0.0, 1.0, + ) } /// Creates a rotation matrix from the given quaternion. @@ -104,30 +114,66 @@ impl Transform3DF32 { pub fn from_rotation_quaternion(q: F32x4) -> Transform3DF32 { // TODO(pcwalton): Optimize better with more shuffles. let (mut sq, mut w, mut xy_xz_yz) = (q * q, q.wwww() * q, q.xxyy() * q.yzzy()); - sq += sq; w += w; xy_xz_yz += xy_xz_yz; + sq += sq; + w += w; + xy_xz_yz += xy_xz_yz; let diag = F32x4::splat(1.0) - (sq.yxxy() + sq.zzyy()); let (wx2, wy2, wz2) = (w.x(), w.y(), w.z()); let (xy2, xz2, yz2) = (xy_xz_yz.x(), xy_xz_yz.y(), xy_xz_yz.z()); - Transform3DF32::row_major(diag.x(), xy2 - wz2, xz2 + wy2, 0.0, - xy2 + wz2, diag.y(), yz2 - wx2, 0.0, - xz2 - wy2, yz2 + wx2, diag.z(), 0.0, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + diag.x(), + xy2 - wz2, + xz2 + wy2, + 0.0, + xy2 + wz2, + diag.y(), + yz2 - wx2, + 0.0, + xz2 - wy2, + yz2 + wx2, + diag.z(), + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + ) } /// Just like `glOrtho()`. #[inline] - pub fn from_ortho(left: f32, right: f32, bottom: f32, top: f32, near_val: f32, far_val: f32) - -> Transform3DF32 { + pub fn from_ortho( + left: f32, + right: f32, + bottom: f32, + top: f32, + near_val: f32, + far_val: f32, + ) -> Transform3DF32 { let x_inv = 1.0 / (right - left); let y_inv = 1.0 / (top - bottom); let z_inv = 1.0 / (far_val - near_val); let tx = -(right + left) * x_inv; let ty = -(top + bottom) * y_inv; let tz = -(far_val + near_val) * z_inv; - Transform3DF32::row_major(2.0 * x_inv, 0.0, 0.0, tx, - 0.0, 2.0 * y_inv, 0.0, ty, - 0.0, 0.0, -2.0 * z_inv, tz, - 0.0, 0.0, 0.0, 1.0) + Transform3DF32::row_major( + 2.0 * x_inv, + 0.0, + 0.0, + tx, + 0.0, + 2.0 * y_inv, + 0.0, + ty, + 0.0, + 0.0, + -2.0 * z_inv, + tz, + 0.0, + 0.0, + 0.0, + 1.0, + ) } /// Just like `gluPerspective()`. @@ -140,10 +186,9 @@ impl Transform3DF32 { let m22 = (z_far + z_near) * z_denom; let m23 = 2.0 * z_far * z_near * z_denom; let m32 = -1.0; - Transform3DF32::row_major(m00, 0.0, 0.0, 0.0, - 0.0, m11, 0.0, 0.0, - 0.0, 0.0, m22, m23, - 0.0, 0.0, m32, 0.0) + Transform3DF32::row_major( + m00, 0.0, 0.0, 0.0, 0.0, m11, 0.0, 0.0, 0.0, 0.0, m22, m23, 0.0, 0.0, m32, 0.0, + ) } // +- -+ @@ -151,8 +196,12 @@ impl Transform3DF32 { // | C D | // +- -+ #[inline] - pub fn from_submatrices(a: Matrix2x2F32, b: Matrix2x2F32, c: Matrix2x2F32, d: Matrix2x2F32) - -> Transform3DF32 { + pub fn from_submatrices( + a: Matrix2x2F32, + b: Matrix2x2F32, + c: Matrix2x2F32, + d: Matrix2x2F32, + ) -> Transform3DF32 { Transform3DF32 { c0: a.0.concat_xy_xy(c.0), c1: a.0.concat_zw_zw(c.0), @@ -232,17 +281,17 @@ impl Transform3DF32 { // Compute new submatrices. let (a_new, b_new) = (a_inv + z.post_mul(&y).post_mul(&x), (-z).post_mul(&y)); - let (c_new, d_new) = ((-y).post_mul(&x), y); + let (c_new, d_new) = ((-y).post_mul(&x), y); // Construct inverse. Transform3DF32::from_submatrices(a_new, b_new, c_new, d_new) } pub fn approx_eq(&self, other: &Transform3DF32, epsilon: f32) -> bool { - self.c0.approx_eq(other.c0, epsilon) && - self.c1.approx_eq(other.c1, epsilon) && - self.c2.approx_eq(other.c2, epsilon) && - self.c3.approx_eq(other.c3, epsilon) + self.c0.approx_eq(other.c0, epsilon) + && self.c1.approx_eq(other.c1, epsilon) + && self.c2.approx_eq(other.c2, epsilon) + && self.c3.approx_eq(other.c3, epsilon) } #[inline] @@ -276,15 +325,20 @@ pub struct Perspective { impl Perspective { #[inline] pub fn new(transform: &Transform3DF32, window_size: Point2DI32) -> Perspective { - Perspective { transform: *transform, window_size } + Perspective { + transform: *transform, + window_size, + } } #[inline] pub fn transform_point_2d(&self, point: &Point2DF32) -> Point2DF32 { - let point = self.transform - .transform_point(point.to_3d()) - .perspective_divide() - .to_2d() * Point2DF32::new(1.0, -1.0); + let point = self + .transform + .transform_point(point.to_3d()) + .perspective_divide() + .to_2d() + * Point2DF32::new(1.0, -1.0); (point + Point2DF32::splat(1.0)) * self.window_size.to_f32().scale(0.5) } @@ -328,13 +382,22 @@ where fn next(&mut self) -> Option { let mut segment = self.iter.next()?; if !segment.is_none() { - segment.baseline.set_from(&self.perspective - .transform_point_2d(&segment.baseline.from())); - segment.baseline.set_to(&self.perspective.transform_point_2d(&segment.baseline.to())); + segment.baseline.set_from( + &self + .perspective + .transform_point_2d(&segment.baseline.from()), + ); + segment + .baseline + .set_to(&self.perspective.transform_point_2d(&segment.baseline.to())); if !segment.is_line() { - segment.ctrl.set_from(&self.perspective.transform_point_2d(&segment.ctrl.from())); + segment + .ctrl + .set_from(&self.perspective.transform_point_2d(&segment.ctrl.from())); if !segment.is_quadratic() { - segment.ctrl.set_to(&self.perspective.transform_point_2d(&segment.ctrl.to())); + segment + .ctrl + .set_to(&self.perspective.transform_point_2d(&segment.ctrl.to())); } } } @@ -348,7 +411,10 @@ where { #[inline] pub fn new(iter: I, perspective: &Perspective) -> PerspectivePathIter { - PerspectivePathIter { iter, perspective: *perspective } + PerspectivePathIter { + iter, + perspective: *perspective, + } } } @@ -359,44 +425,39 @@ mod test { #[test] fn test_post_mul() { - let a = Transform3DF32::row_major(3.0, 1.0, 4.0, 5.0, - 9.0, 2.0, 6.0, 5.0, - 3.0, 5.0, 8.0, 9.0, - 7.0, 9.0, 3.0, 2.0); - let b = Transform3DF32::row_major(3.0, 8.0, 4.0, 6.0, - 2.0, 6.0, 4.0, 3.0, - 3.0, 8.0, 3.0, 2.0, - 7.0, 9.0, 5.0, 0.0); - let c = Transform3DF32::row_major(58.0, 107.0, 53.0, 29.0, - 84.0, 177.0, 87.0, 72.0, - 106.0, 199.0, 101.0, 49.0, - 62.0, 152.0, 83.0, 75.0); + let a = Transform3DF32::row_major( + 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, + ); + let b = Transform3DF32::row_major( + 3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0, + ); + let c = Transform3DF32::row_major( + 58.0, 107.0, 53.0, 29.0, 84.0, 177.0, 87.0, 72.0, 106.0, 199.0, 101.0, 49.0, 62.0, + 152.0, 83.0, 75.0, + ); assert_eq!(a.post_mul(&b), c); } #[test] fn test_pre_mul() { - let a = Transform3DF32::row_major(3.0, 1.0, 4.0, 5.0, - 9.0, 2.0, 6.0, 5.0, - 3.0, 5.0, 8.0, 9.0, - 7.0, 9.0, 3.0, 2.0); - let b = Transform3DF32::row_major(3.0, 8.0, 4.0, 6.0, - 2.0, 6.0, 4.0, 3.0, - 3.0, 8.0, 3.0, 2.0, - 7.0, 9.0, 5.0, 0.0); - let c = Transform3DF32::row_major(135.0, 93.0, 110.0, 103.0, - 93.0, 61.0, 85.0, 82.0, - 104.0, 52.0, 90.0, 86.0, - 117.0, 50.0, 122.0, 125.0); + let a = Transform3DF32::row_major( + 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, + ); + let b = Transform3DF32::row_major( + 3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0, + ); + let c = Transform3DF32::row_major( + 135.0, 93.0, 110.0, 103.0, 93.0, 61.0, 85.0, 82.0, 104.0, 52.0, 90.0, 86.0, 117.0, + 50.0, 122.0, 125.0, + ); assert_eq!(a.pre_mul(&b), c); } #[test] fn test_transform_point() { - let a = Transform3DF32::row_major(3.0, 1.0, 4.0, 5.0, - 9.0, 2.0, 6.0, 5.0, - 3.0, 5.0, 8.0, 9.0, - 7.0, 9.0, 3.0, 2.0); + let a = Transform3DF32::row_major( + 3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0, + ); let p = Point3DF32::new(3.0, 8.0, 4.0, 6.0); let q = Point3DF32::new(63.0, 97.0, 135.0, 117.0); assert_eq!(a.transform_point(p), q); @@ -405,18 +466,32 @@ mod test { #[test] fn test_inverse() { // Random matrix. - let m = Transform3DF32::row_major(0.86277982, 0.15986552, 0.90739898, 0.60066808, - 0.17386167, 0.016353 , 0.8535783 , 0.12969608, - 0.0946466 , 0.43248631, 0.63480505, 0.08154603, - 0.50305436, 0.48359687, 0.51057162, 0.24812012); + let m = Transform3DF32::row_major( + 0.86277982, 0.15986552, 0.90739898, 0.60066808, 0.17386167, 0.016353, 0.8535783, + 0.12969608, 0.0946466, 0.43248631, 0.63480505, 0.08154603, 0.50305436, 0.48359687, + 0.51057162, 0.24812012, + ); let p0 = Point3DF32::new(0.95536648, 0.80633691, 0.16357357, 0.5477598); let p1 = m.transform_point(p0); let m_inv = m.inverse(); - let m_inv_exp = - Transform3DF32::row_major(-2.47290136 , 3.48865688, -6.12298336 , 6.17536696 , - 0.00124033357, -1.72561993, 2.16876606 , 0.186227748, - -0.375021729 , 1.53883017, -0.0558194403, 0.121857058, - 5.78300323 , -6.87635769, 8.30196620 , -9.10374060); + let m_inv_exp = Transform3DF32::row_major( + -2.47290136, + 3.48865688, + -6.12298336, + 6.17536696, + 0.00124033357, + -1.72561993, + 2.16876606, + 0.186227748, + -0.375021729, + 1.53883017, + -0.0558194403, + 0.121857058, + 5.78300323, + -6.87635769, + 8.30196620, + -9.10374060, + ); assert!(m_inv.approx_eq(&m_inv_exp, 0.0001)); let p2 = m_inv.transform_point(p1); assert!(p0.approx_eq(&p2, 0.0001)); diff --git a/geometry/src/clip.rs b/geometry/src/clip.rs index 81734302..d15f63c3 100644 --- a/geometry/src/clip.rs +++ b/geometry/src/clip.rs @@ -53,9 +53,9 @@ impl TEdge for AxisAlignedEdge { #[inline] fn point_is_inside(&self, point: &Point2DF32) -> bool { match *self { - AxisAlignedEdge::Left(x) => point.x() >= x, - AxisAlignedEdge::Top(y) => point.y() >= y, - AxisAlignedEdge::Right(x) => point.x() <= x, + AxisAlignedEdge::Left(x) => point.x() >= x, + AxisAlignedEdge::Top(y) => point.y() >= y, + AxisAlignedEdge::Right(x) => point.x() <= x, AxisAlignedEdge::Bottom(y) => point.y() <= y, } } @@ -63,8 +63,8 @@ impl TEdge for AxisAlignedEdge { fn intersect_line_segment(&self, segment: &LineSegmentF32) -> ArrayVec<[f32; 3]> { let mut results = ArrayVec::new(); let t = match *self { - AxisAlignedEdge::Left(x) | AxisAlignedEdge::Right(x) => segment.solve_t_for_x(x), - AxisAlignedEdge::Top(y) | AxisAlignedEdge::Bottom(y) => segment.solve_t_for_y(y), + AxisAlignedEdge::Left(x) | AxisAlignedEdge::Right(x) => segment.solve_t_for_x(x), + AxisAlignedEdge::Top(y) | AxisAlignedEdge::Bottom(y) => segment.solve_t_for_y(y), }; if t >= 0.0 && t <= 1.0 { results.push(t); @@ -79,7 +79,12 @@ trait TEdge: Debug { fn trivially_test_segment(&self, segment: &Segment) -> EdgeRelativeLocation { let from_inside = self.point_is_inside(&segment.baseline.from()); - debug!("point {:?} inside {:?}: {:?}", segment.baseline.from(), self, from_inside); + debug!( + "point {:?} inside {:?}: {:?}", + segment.baseline.from(), + self, + from_inside + ); if from_inside != self.point_is_inside(&segment.baseline.to()) { return EdgeRelativeLocation::Intersecting; } @@ -93,7 +98,11 @@ trait TEdge: Debug { } } } - if from_inside { EdgeRelativeLocation::Inside } else { EdgeRelativeLocation::Outside } + if from_inside { + EdgeRelativeLocation::Inside + } else { + EdgeRelativeLocation::Outside + } } fn intersect_segment(&self, segment: &Segment) -> ArrayVec<[f32; 3]> { @@ -110,7 +119,7 @@ trait TEdge: Debug { let mut prev_t = 0.0; while !results.is_full() { if prev_t >= 1.0 { - break + break; } let next_t = match self.intersect_cubic_segment(&segment, prev_t, 1.0) { None => break, @@ -124,15 +133,24 @@ trait TEdge: Debug { const EPSILON: f32 = 0.0001; } - fn intersect_cubic_segment(&self, segment: &Segment, mut t_min: f32, mut t_max: f32) - -> Option { - debug!("... intersect_cubic_segment({:?}, {:?}, t=({}, {}))", self, segment, t_min, t_max); + fn intersect_cubic_segment( + &self, + segment: &Segment, + mut t_min: f32, + mut t_max: f32, + ) -> Option { + debug!( + "... intersect_cubic_segment({:?}, {:?}, t=({}, {}))", + self, segment, t_min, t_max + ); let mut segment = segment.as_cubic_segment().split_after(t_min); - segment = segment.as_cubic_segment().split_before(t_max / (1.0 - t_min)); + segment = segment + .as_cubic_segment() + .split_before(t_max / (1.0 - t_min)); if !self.intersects_cubic_segment_hull(segment.as_cubic_segment()) { - return None + return None; } loop { @@ -156,13 +174,16 @@ trait TEdge: Debug { fn intersects_cubic_segment_hull(&self, cubic_segment: CubicSegment) -> bool { let inside = self.point_is_inside(&cubic_segment.0.baseline.from()); - inside != self.point_is_inside(&cubic_segment.0.ctrl.from()) || - inside != self.point_is_inside(&cubic_segment.0.ctrl.to()) || - inside != self.point_is_inside(&cubic_segment.0.baseline.to()) + inside != self.point_is_inside(&cubic_segment.0.ctrl.from()) + || inside != self.point_is_inside(&cubic_segment.0.ctrl.to()) + || inside != self.point_is_inside(&cubic_segment.0.baseline.to()) } } -trait ContourClipper where Self::Edge: TEdge + Debug { +trait ContourClipper +where + Self::Edge: TEdge + Debug, +{ type Edge; fn contour_mut(&mut self) -> &mut Contour; @@ -209,11 +230,10 @@ trait ContourClipper where Self::Edge: TEdge + Debug { let (before_split, after_split) = segment.split((t - last_t) / (1.0 - last_t)); // Push the split segment if appropriate. - debug!("... ... edge={:?} before_split={:?} t={:?} starts_inside={:?}", - edge, - before_split, - t, - starts_inside); + debug!( + "... ... edge={:?} before_split={:?} t={:?} starts_inside={:?}", + edge, before_split, t, starts_inside + ); if starts_inside { debug!("... split segment case, pushing segment"); self.push_segment(&before_split); @@ -255,8 +275,8 @@ trait ContourClipper where Self::Edge: TEdge + Debug { (None, EdgeRelativeLocation::Inside) => { result = Some(FastClipResult::AllInside); } - (Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside) | - (Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {} + (Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside) + | (Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {} (_, _) => return FastClipResult::SlowPath, } } @@ -290,7 +310,10 @@ impl ContourClipper for ContourPolygonClipper { impl ContourPolygonClipper { #[inline] pub(crate) fn new(clip_polygon: &[Point2DF32], contour: Contour) -> ContourPolygonClipper { - ContourPolygonClipper { clip_polygon: SmallVec::from_slice(clip_polygon), contour } + ContourPolygonClipper { + clip_polygon: SmallVec::from_slice(clip_polygon), + contour, + } } pub(crate) fn clip(mut self) -> Contour { @@ -341,7 +364,7 @@ impl ContourRectClipper { pub(crate) fn clip(mut self) -> Contour { if self.clip_rect.contains_rect(self.contour.bounds()) { - return self.contour + return self.contour; } self.clip_against(AxisAlignedEdge::Left(self.clip_rect.min_x())); @@ -412,7 +435,7 @@ enum Edge3D { Bottom, Top, Near, - Far + Far, } impl Edge3D { @@ -420,23 +443,26 @@ impl Edge3D { fn point_is_inside(self, point: Point3DF32) -> bool { let w = point.w(); match self { - Edge3D::Left => point.x() >= -w, Edge3D::Right => point.x() <= w, - Edge3D::Bottom => point.y() >= -w, Edge3D::Top => point.y() <= w, - Edge3D::Near => point.z() >= -w, Edge3D::Far => point.z() <= w, + Edge3D::Left => point.x() >= -w, + Edge3D::Right => point.x() <= w, + Edge3D::Bottom => point.y() >= -w, + Edge3D::Top => point.y() <= w, + Edge3D::Near => point.z() >= -w, + Edge3D::Far => point.z() <= w, } } // Blinn & Newell, "Clipping using homogeneous coordinates", SIGGRAPH 1978. fn line_intersection(self, prev: Point3DF32, next: Point3DF32) -> Point3DF32 { let (x0, x1) = match self { - Edge3D::Left | Edge3D::Right => (prev.x(), next.x()), - Edge3D::Bottom | Edge3D::Top => (prev.y(), next.y()), - Edge3D::Near | Edge3D::Far => (prev.z(), next.z()), + Edge3D::Left | Edge3D::Right => (prev.x(), next.x()), + Edge3D::Bottom | Edge3D::Top => (prev.y(), next.y()), + Edge3D::Near | Edge3D::Far => (prev.z(), next.z()), }; let (w0, w1) = (prev.w(), next.w()); let sign = match self { - Edge3D::Left | Edge3D::Bottom | Edge3D::Near => -1.0, - Edge3D::Right | Edge3D::Top | Edge3D::Far => 1.0, + Edge3D::Left | Edge3D::Bottom | Edge3D::Near => -1.0, + Edge3D::Right | Edge3D::Top | Edge3D::Far => 1.0, }; let alpha = ((x0 - sign * w0) as f64) / ((sign * (w1 - w0) - (x1 - x0)) as f64); prev.lerp(next, alpha as f32) @@ -449,17 +475,30 @@ impl Edge3D { pub(crate) fn rect_is_outside_polygon(rect: RectF32, polygon_points: &[Point2DF32]) -> bool { let mut outcode = Outcode::all(); for point in polygon_points { - if point.x() > rect.min_x() { outcode.remove(Outcode::LEFT); } - if point.x() < rect.max_x() { outcode.remove(Outcode::RIGHT); } - if point.y() > rect.min_y() { outcode.remove(Outcode::TOP); } - if point.y() < rect.max_y() { outcode.remove(Outcode::BOTTOM); } + if point.x() > rect.min_x() { + outcode.remove(Outcode::LEFT); + } + if point.x() < rect.max_x() { + outcode.remove(Outcode::RIGHT); + } + if point.y() > rect.min_y() { + outcode.remove(Outcode::TOP); + } + if point.y() < rect.max_y() { + outcode.remove(Outcode::BOTTOM); + } } if !outcode.is_empty() { - return true + return true; } // FIXME(pcwalton): Check winding! - let rect_points = [rect.origin(), rect.upper_right(), rect.lower_left(), rect.lower_right()]; + let rect_points = [ + rect.origin(), + rect.upper_right(), + rect.lower_left(), + rect.lower_right(), + ]; for (next_point_index, &next) in polygon_points.iter().enumerate() { let prev_point_index = if next_point_index == 0 { polygon_points.len() - 1 @@ -468,8 +507,11 @@ pub(crate) fn rect_is_outside_polygon(rect: RectF32, polygon_points: &[Point2DF3 }; let prev = polygon_points[prev_point_index]; let polygon_edge_vector = next - prev; - if rect_points.iter().all(|&rect_point| polygon_edge_vector.det(rect_point - prev) < 0.0) { - return true + if rect_points + .iter() + .all(|&rect_point| polygon_edge_vector.det(rect_point - prev) < 0.0) + { + return true; } } @@ -479,7 +521,12 @@ pub(crate) fn rect_is_outside_polygon(rect: RectF32, polygon_points: &[Point2DF3 // Edge equation method. Requires that the polygon be convex. pub(crate) fn rect_is_inside_polygon(rect: RectF32, polygon_points: &[Point2DF32]) -> bool { // FIXME(pcwalton): Check winding! - let rect_points = [rect.origin(), rect.upper_right(), rect.lower_left(), rect.lower_right()]; + let rect_points = [ + rect.origin(), + rect.upper_right(), + rect.lower_left(), + rect.lower_right(), + ]; for (next_point_index, &next) in polygon_points.iter().enumerate() { let prev_point_index = if next_point_index == 0 { polygon_points.len() - 1 diff --git a/geometry/src/color.rs b/geometry/src/color.rs index e25e89e3..cdf3dd81 100644 --- a/geometry/src/color.rs +++ b/geometry/src/color.rs @@ -42,12 +42,14 @@ impl Debug for ColorU { if self.a == 255 { write!(formatter, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b) } else { - write!(formatter, - "rgba({}, {}, {}, {})", - self.r, - self.g, - self.b, - self.a as f32 / 255.0) + write!( + formatter, + "rgba({}, {}, {}, {})", + self.r, + self.g, + self.b, + self.a as f32 / 255.0 + ) } } } diff --git a/geometry/src/dilation.rs b/geometry/src/dilation.rs index 925c5e74..beeac163 100644 --- a/geometry/src/dilation.rs +++ b/geometry/src/dilation.rs @@ -19,16 +19,23 @@ pub struct ContourDilator<'a> { } impl<'a> ContourDilator<'a> { - pub fn new(contour: &'a mut Contour, amount: Point2DF32, orientation: Orientation) - -> ContourDilator<'a> { - ContourDilator { contour, amount, orientation } + pub fn new( + contour: &'a mut Contour, + amount: Point2DF32, + orientation: Orientation, + ) -> ContourDilator<'a> { + ContourDilator { + contour, + amount, + orientation, + } } pub fn dilate(&mut self) { // Determine orientation. let scale = self.amount.scale_xy(match self.orientation { - Orientation::Ccw => Point2DF32::new( 1.0, -1.0), - Orientation::Cw => Point2DF32::new(-1.0, 1.0), + Orientation::Ccw => Point2DF32::new(1.0, -1.0), + Orientation::Cw => Point2DF32::new(-1.0, 1.0), }); // Find the starting and previous positions. @@ -68,10 +75,10 @@ impl<'a> ContourDilator<'a> { } let next_vector = (next_position - position).normalize(); - debug!("prev={} cur={} next={}", - prev_point_index, - current_point_index, - next_point_index); + debug!( + "prev={} cur={} next={}", + prev_point_index, current_point_index, next_point_index + ); // Calculate new position by moving the point by the bisector. let bisector = prev_vector.yx() + next_vector.yx(); @@ -83,16 +90,18 @@ impl<'a> ContourDilator<'a> { }; let new_position = position - scaled_bisector; - debug!("dilate(): prev={}({:?}) cur={}({:?}) next={}({:?}) bisector={:?}({:?}, {:?})", - prev_point_index, - prev_position, - current_point_index, - position, - next_point_index, - next_position, - bisector, - bisector_length, - scaled_bisector); + debug!( + "dilate(): prev={}({:?}) cur={}({:?}) next={}({:?}) bisector={:?}({:?}, {:?})", + prev_point_index, + prev_position, + current_point_index, + position, + next_point_index, + next_position, + bisector, + bisector_length, + scaled_bisector + ); // Update all points. let mut point_index = current_point_index; diff --git a/geometry/src/outline.rs b/geometry/src/outline.rs index f5ce65ac..8cd939ac 100644 --- a/geometry/src/outline.rs +++ b/geometry/src/outline.rs @@ -46,7 +46,10 @@ bitflags! { impl Outline { #[inline] pub fn new() -> Outline { - Outline { contours: vec![], bounds: RectF32::default() } + Outline { + contours: vec![], + bounds: RectF32::default(), + } } #[inline] @@ -85,9 +88,11 @@ impl Outline { if !segment.is_line() { current_contour.push_point(segment.ctrl.from(), PointFlags::CONTROL_POINT_0, true); if !segment.is_quadratic() { - current_contour.push_point(segment.ctrl.to(), - PointFlags::CONTROL_POINT_1, - true); + current_contour.push_point( + segment.ctrl.to(), + PointFlags::CONTROL_POINT_1, + true, + ); } } @@ -131,13 +136,20 @@ impl Outline { pub fn dilate(&mut self, amount: Point2DF32) { let orientation = Orientation::from_outline(self); - self.contours.iter_mut().for_each(|contour| contour.dilate(amount, orientation)); + self.contours + .iter_mut() + .for_each(|contour| contour.dilate(amount, orientation)); self.bounds = self.bounds.dilate(amount); } pub fn prepare_for_tiling(&mut self, view_box: RectF32) { - self.contours.iter_mut().for_each(|contour| contour.prepare_for_tiling(view_box)); - self.bounds = self.bounds.intersection(view_box).unwrap_or_else(|| RectF32::default()); + self.contours + .iter_mut() + .for_each(|contour| contour.prepare_for_tiling(view_box)); + self.bounds = self + .bounds + .intersection(view_box) + .unwrap_or_else(|| RectF32::default()); } pub fn is_outside_polygon(&self, clip_polygon: &[Point2DF32]) -> bool { @@ -197,24 +209,35 @@ impl Debug for Outline { impl Contour { #[inline] pub fn new() -> Contour { - Contour { points: vec![], flags: vec![], bounds: RectF32::default(), closed: false } + Contour { + points: vec![], + flags: vec![], + bounds: RectF32::default(), + closed: false, + } } // Replaces this contour with a new one, with arrays preallocated to match `self`. #[inline] pub(crate) fn take(&mut self) -> Contour { let length = self.len() as usize; - mem::replace(self, Contour { - points: Vec::with_capacity(length), - flags: Vec::with_capacity(length), - bounds: RectF32::default(), - closed: false, - }) + mem::replace( + self, + Contour { + points: Vec::with_capacity(length), + flags: Vec::with_capacity(length), + bounds: RectF32::default(), + closed: false, + }, + ) } #[inline] pub fn iter(&self) -> ContourIter { - ContourIter { contour: self, index: 1 } + ContourIter { + contour: self, + index: 1, + } } #[inline] @@ -254,10 +277,7 @@ impl Contour { // TODO(pcwalton): SIMD. #[inline] - pub(crate) fn push_point(&mut self, - point: Point2DF32, - flags: PointFlags, - update_bounds: bool) { + pub(crate) fn push_point(&mut self, point: Point2DF32, flags: PointFlags, update_bounds: bool) { debug_assert!(!point.x().is_nan() && !point.y().is_nan()); if update_bounds { @@ -272,7 +292,7 @@ impl Contour { #[inline] pub(crate) fn push_segment(&mut self, segment: Segment, update_bounds: bool) { if segment.is_none() { - return + return; } if self.is_empty() { @@ -280,9 +300,17 @@ impl Contour { } if !segment.is_line() { - self.push_point(segment.ctrl.from(), PointFlags::CONTROL_POINT_0, update_bounds); + self.push_point( + segment.ctrl.from(), + PointFlags::CONTROL_POINT_0, + update_bounds, + ); if !segment.is_quadratic() { - self.push_point(segment.ctrl.to(), PointFlags::CONTROL_POINT_1, update_bounds); + self.push_point( + segment.ctrl.to(), + PointFlags::CONTROL_POINT_1, + update_bounds, + ); } } @@ -294,9 +322,17 @@ impl Contour { self.push_point(segment.baseline.from(), PointFlags::empty(), update_bounds); if !segment.is_line() { - self.push_point(segment.ctrl.from(), PointFlags::CONTROL_POINT_0, update_bounds); + self.push_point( + segment.ctrl.from(), + PointFlags::CONTROL_POINT_0, + update_bounds, + ); if !segment.is_quadratic() { - self.push_point(segment.ctrl.to(), PointFlags::CONTROL_POINT_1, update_bounds); + self.push_point( + segment.ctrl.to(), + PointFlags::CONTROL_POINT_1, + update_bounds, + ); } } @@ -336,14 +372,16 @@ impl Contour { #[inline] pub fn hull_segment_after(&self, prev_point_index: u32) -> LineSegmentF32 { let next_point_index = self.next_point_index_of(prev_point_index); - LineSegmentF32::new(&self.points[prev_point_index as usize], - &self.points[next_point_index as usize]) + LineSegmentF32::new( + &self.points[prev_point_index as usize], + &self.points[next_point_index as usize], + ) } #[inline] pub fn point_is_endpoint(&self, point_index: u32) -> bool { !self.flags[point_index as usize] - .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1) + .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1) } #[inline] @@ -427,8 +465,8 @@ impl Contour { if contour_is_monotonic { if self.point_is_endpoint(point_index) { if let Some(last_endpoint_index) = last_endpoint_index { - if !self.curve_with_endpoints_is_monotonic(last_endpoint_index, - point_index) { + if !self.curve_with_endpoints_is_monotonic(last_endpoint_index, point_index) + { contour_is_monotonic = false; } } @@ -443,7 +481,10 @@ impl Contour { } // Update bounds. - self.bounds = self.bounds.intersection(view_box).unwrap_or_else(|| RectF32::default()); + self.bounds = self + .bounds + .intersection(view_box) + .unwrap_or_else(|| RectF32::default()); } fn make_monotonic(&mut self) { @@ -458,15 +499,23 @@ impl Contour { } if let Some(last_endpoint_index) = last_endpoint_index { - let position_index = - if point_index == input_point_count { 0 } else { point_index }; - let baseline = LineSegmentF32::new(&contour.points[last_endpoint_index as usize], - &contour.points[position_index as usize]); + let position_index = if point_index == input_point_count { + 0 + } else { + point_index + }; + let baseline = LineSegmentF32::new( + &contour.points[last_endpoint_index as usize], + &contour.points[position_index as usize], + ); let point_count = point_index - last_endpoint_index + 1; if point_count == 3 { let ctrl_point_index = last_endpoint_index as usize + 1; let ctrl_position = &contour.points[ctrl_point_index]; - handle_cubic(self, Segment::quadratic(&baseline, &ctrl_position).to_cubic()); + handle_cubic( + self, + Segment::quadratic(&baseline, &ctrl_position).to_cubic(), + ); } else if point_count == 4 { let first_ctrl_point_index = last_endpoint_index as usize + 1; let ctrl_position_0 = &contour.points[first_ctrl_point_index + 0]; @@ -475,9 +524,11 @@ impl Contour { handle_cubic(self, Segment::cubic(&baseline, &ctrl)); } - self.push_point(contour.points[position_index as usize], - PointFlags::empty(), - false); + self.push_point( + contour.points[position_index as usize], + PointFlags::empty(), + false, + ); } last_endpoint_index = Some(point_index); @@ -502,22 +553,25 @@ impl Contour { } } - fn curve_with_endpoints_is_monotonic(&self, start_endpoint_index: u32, end_endpoint_index: u32) - -> bool { + fn curve_with_endpoints_is_monotonic( + &self, + start_endpoint_index: u32, + end_endpoint_index: u32, + ) -> bool { let start_position = self.points[start_endpoint_index as usize]; let end_position = self.points[end_endpoint_index as usize]; if start_position.x() <= end_position.x() { for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].x() > - self.points[point_index as usize + 1].x() { + if self.points[point_index as usize].x() > self.points[point_index as usize + 1].x() + { return false; } } } else { for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].x() < - self.points[point_index as usize + 1].x() { + if self.points[point_index as usize].x() < self.points[point_index as usize + 1].x() + { return false; } } @@ -525,15 +579,15 @@ impl Contour { if start_position.y() <= end_position.y() { for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].y() > - self.points[point_index as usize + 1].y() { + if self.points[point_index as usize].y() > self.points[point_index as usize + 1].y() + { return false; } } } else { for point_index in start_endpoint_index..end_endpoint_index { - if self.points[point_index as usize].y() < - self.points[point_index as usize + 1].y() { + if self.points[point_index as usize].y() < self.points[point_index as usize + 1].y() + { return false; } } @@ -554,37 +608,45 @@ impl Debug for Contour { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { for (segment_index, segment) in self.iter().enumerate() { if segment_index == 0 { - write!(formatter, - "M {} {}", - segment.baseline.from_x(), - segment.baseline.from_y())?; + write!( + formatter, + "M {} {}", + segment.baseline.from_x(), + segment.baseline.from_y() + )?; } match segment.kind { SegmentKind::None => {} SegmentKind::Line => { - write!(formatter, - " L {} {}", - segment.baseline.to_x(), - segment.baseline.to_y())?; + write!( + formatter, + " L {} {}", + segment.baseline.to_x(), + segment.baseline.to_y() + )?; } SegmentKind::Quadratic => { - write!(formatter, - " Q {} {} {} {}", - segment.ctrl.from_x(), - segment.ctrl.from_y(), - segment.baseline.to_x(), - segment.baseline.to_y())?; + write!( + formatter, + " Q {} {} {} {}", + segment.ctrl.from_x(), + segment.ctrl.from_y(), + segment.baseline.to_x(), + segment.baseline.to_y() + )?; } SegmentKind::Cubic => { - write!(formatter, - " C {} {} {} {} {} {}", - segment.ctrl.from_x(), - segment.ctrl.from_y(), - segment.ctrl.to_x(), - segment.ctrl.to_y(), - segment.baseline.to_x(), - segment.baseline.to_y())?; + write!( + formatter, + " C {} {} {} {} {} {}", + segment.ctrl.from_x(), + segment.ctrl.from_y(), + segment.ctrl.to_x(), + segment.ctrl.to_y(), + segment.baseline.to_x(), + segment.baseline.to_y() + )?; } } } @@ -630,8 +692,8 @@ impl<'a> Iterator for ContourIter<'a> { #[inline] fn next(&mut self) -> Option { let contour = self.contour; - if (self.index == contour.len() && !self.contour.closed) || - self.index == contour.len() + 1 { + if (self.index == contour.len() && !self.contour.closed) || self.index == contour.len() + 1 + { return None; } @@ -654,15 +716,20 @@ impl<'a> Iterator for ContourIter<'a> { let point2 = contour.position_of(point2_index); self.index += 1; if contour.point_is_endpoint(point2_index) { - return Some(Segment::quadratic(&LineSegmentF32::new(&point0, &point2), &point1)); + return Some(Segment::quadratic( + &LineSegmentF32::new(&point0, &point2), + &point1, + )); } let point3_index = self.index; let point3 = contour.position_of(point3_index); self.index += 1; debug_assert!(contour.point_is_endpoint(point3_index)); - return Some(Segment::cubic(&LineSegmentF32::new(&point0, &point3), - &LineSegmentF32::new(&point1, &point2))); + return Some(Segment::cubic( + &LineSegmentF32::new(&point0, &point3), + &LineSegmentF32::new(&point1, &point2), + )); } } diff --git a/geometry/src/segment.rs b/geometry/src/segment.rs index 4426d66a..5973b865 100644 --- a/geometry/src/segment.rs +++ b/geometry/src/segment.rs @@ -197,9 +197,10 @@ impl<'s> CubicSegment<'s> { // See Kaspar Fischer, "Piecewise Linear Approximation of Bézier Curves", 2000. #[inline] pub fn is_flat(self, tolerance: f32) -> bool { - let mut uv = F32x4::splat(3.0) * self.0.ctrl.0 - - self.0.baseline.0 - self.0.baseline.0 - - self.0.baseline.reversed().0; + let mut uv = F32x4::splat(3.0) * self.0.ctrl.0 + - self.0.baseline.0 + - self.0.baseline.0 + - self.0.baseline.reversed().0; uv = uv * uv; uv = uv.max(uv.zwxy()); uv[0] + uv[1] <= 16.0 * tolerance * tolerance @@ -244,17 +245,20 @@ impl<'s> CubicSegment<'s> { ctrl1 = LineSegmentF32(p012p123.concat_zw_zw(p12p23)); } - (Segment { - baseline: baseline0, - ctrl: ctrl0, - kind: SegmentKind::Cubic, - flags: self.0.flags & SegmentFlags::FIRST_IN_SUBPATH, - }, Segment { - baseline: baseline1, - ctrl: ctrl1, - kind: SegmentKind::Cubic, - flags: self.0.flags & SegmentFlags::CLOSES_SUBPATH, - }) + ( + Segment { + baseline: baseline0, + ctrl: ctrl0, + kind: SegmentKind::Cubic, + flags: self.0.flags & SegmentFlags::FIRST_IN_SUBPATH, + }, + Segment { + baseline: baseline1, + ctrl: ctrl1, + kind: SegmentKind::Cubic, + flags: self.0.flags & SegmentFlags::CLOSES_SUBPATH, + }, + ) } #[inline] @@ -284,13 +288,15 @@ impl<'s> CubicSegment<'s> { #[inline] pub fn y_extrema(self) -> (Option, Option) { if self.is_monotonic() { - return (None, None) + return (None, None); } - let p0p1p2p3 = F32x4::new(self.0.baseline.from_y(), - self.0.ctrl.from_y(), - self.0.ctrl.to_y(), - self.0.baseline.to_y()); + let p0p1p2p3 = F32x4::new( + self.0.baseline.from_y(), + self.0.ctrl.from_y(), + self.0.ctrl.to_y(), + self.0.baseline.to_y(), + ); let pxp0p1p2 = p0p1p2p3.wxyz(); let pxv0v1v2 = p0p1p2p3 - pxp0p1p2; @@ -317,11 +323,19 @@ impl<'s> CubicSegment<'s> { } #[inline] - pub fn min_x(&self) -> f32 { f32::min(self.0.baseline.min_x(), self.0.ctrl.min_x()) } + pub fn min_x(&self) -> f32 { + f32::min(self.0.baseline.min_x(), self.0.ctrl.min_x()) + } #[inline] - pub fn min_y(&self) -> f32 { f32::min(self.0.baseline.min_y(), self.0.ctrl.min_y()) } + pub fn min_y(&self) -> f32 { + f32::min(self.0.baseline.min_y(), self.0.ctrl.min_y()) + } #[inline] - pub fn max_x(&self) -> f32 { f32::max(self.0.baseline.max_x(), self.0.ctrl.max_x()) } + pub fn max_x(&self) -> f32 { + f32::max(self.0.baseline.max_x(), self.0.ctrl.max_x()) + } #[inline] - pub fn max_y(&self) -> f32 { f32::max(self.0.baseline.max_y(), self.0.ctrl.max_y()) } + pub fn max_y(&self) -> f32 { + f32::max(self.0.baseline.max_y(), self.0.ctrl.max_y()) + } } diff --git a/geometry/src/stroke.rs b/geometry/src/stroke.rs index 6c638070..fe891b65 100644 --- a/geometry/src/stroke.rs +++ b/geometry/src/stroke.rs @@ -26,7 +26,10 @@ pub struct OutlineStrokeToFill { impl OutlineStrokeToFill { #[inline] pub fn new(outline: Outline, stroke_width: f32) -> OutlineStrokeToFill { - OutlineStrokeToFill { outline, stroke_width } + OutlineStrokeToFill { + outline, + stroke_width, + } } #[inline] @@ -55,7 +58,11 @@ struct ContourStrokeToFill { impl ContourStrokeToFill { #[inline] fn new(input: Contour, output: Contour, radius: f32) -> ContourStrokeToFill { - ContourStrokeToFill { input, output, radius } + ContourStrokeToFill { + input, + output, + radius, + } } fn offset_forward(&mut self) { @@ -66,7 +73,11 @@ impl ContourStrokeToFill { fn offset_backward(&mut self) { // FIXME(pcwalton) - let mut segments: Vec<_> = self.input.iter().map(|segment| segment.reversed()).collect(); + let mut segments: Vec<_> = self + .input + .iter() + .map(|segment| segment.reversed()) + .collect(); segments.reverse(); for segment in &segments { segment.offset(self.radius, &mut self.output); @@ -108,7 +119,7 @@ impl Offset for SegmentPF3 { if self.is_quadratic() { let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from()); - let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to()); + let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to()); segment_0 = segment_0.offset(distance); segment_1 = segment_1.offset(distance); let ctrl = match segment_0.intersection_t(&segment_1) { @@ -123,7 +134,7 @@ impl Offset for SegmentPF3 { if self.baseline.from() == self.ctrl.from() { let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.to()); - let mut segment_1 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to()); + let mut segment_1 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to()); segment_0 = segment_0.offset(distance); segment_1 = segment_1.offset(distance); let ctrl = match segment_0.intersection_t(&segment_1) { @@ -137,7 +148,7 @@ impl Offset for SegmentPF3 { if self.ctrl.to() == self.baseline.to() { let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from()); - let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to()); + let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.baseline.to()); segment_0 = segment_0.offset(distance); segment_1 = segment_1.offset(distance); let ctrl = match segment_0.intersection_t(&segment_1) { @@ -150,18 +161,20 @@ impl Offset for SegmentPF3 { } let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from()); - let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.ctrl.to()); - let mut segment_2 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to()); + let mut segment_1 = LineSegmentF32::new(&self.ctrl.from(), &self.ctrl.to()); + let mut segment_2 = LineSegmentF32::new(&self.ctrl.to(), &self.baseline.to()); segment_0 = segment_0.offset(distance); segment_1 = segment_1.offset(distance); segment_2 = segment_2.offset(distance); - let (ctrl_0, ctrl_1) = match (segment_0.intersection_t(&segment_1), - segment_1.intersection_t(&segment_2)) { + let (ctrl_0, ctrl_1) = match ( + segment_0.intersection_t(&segment_1), + segment_1.intersection_t(&segment_2), + ) { (Some(t0), Some(t1)) => (segment_0.sample(t0), segment_1.sample(t1)), - _ => { - (segment_0.to().lerp(segment_1.from(), 0.5), - segment_1.to().lerp(segment_2.from(), 0.5)) - } + _ => ( + segment_0.to().lerp(segment_1.from(), 0.5), + segment_1.to().lerp(segment_2.from(), 0.5), + ), }; let baseline = LineSegmentF32::new(&segment_0.from(), &segment_2.to()); let ctrl = LineSegmentF32::new(&ctrl_0, &ctrl_1); @@ -169,7 +182,10 @@ impl Offset for SegmentPF3 { } fn error_is_within_tolerance(&self, other: &SegmentPF3, distance: f32) -> bool { - let (mut min, mut max) = (f32::abs(distance) - TOLERANCE, f32::abs(distance) + TOLERANCE); + let (mut min, mut max) = ( + f32::abs(distance) - TOLERANCE, + f32::abs(distance) + TOLERANCE, + ); min = if min <= 0.0 { 0.0 } else { min * min }; max = if max <= 0.0 { 0.0 } else { max * max }; @@ -179,8 +195,10 @@ impl Offset for SegmentPF3 { let (this_p, other_p) = (self.sample(t), other.sample(t)); let vector = this_p - other_p; let square_distance = vector.square_length(); - debug!("this_p={:?} other_p={:?} vector={:?} sqdist={:?} min={:?} max={:?}", - this_p, other_p, vector, square_distance, min, max); + debug!( + "this_p={:?} other_p={:?} vector={:?} sqdist={:?} min={:?} max={:?}", + this_p, other_p, vector, square_distance, min, max + ); if square_distance < min || square_distance > max { return false; }