summaryrefslogtreecommitdiffstats
path: root/servo/components/style/values/distance.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /servo/components/style/values/distance.rs
parentInitial commit. (diff)
downloadfirefox-e51783d008170d9ab27d25da98ca3a38b0a41b67.tar.xz
firefox-e51783d008170d9ab27d25da98ca3a38b0a41b67.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'servo/components/style/values/distance.rs')
-rw-r--r--servo/components/style/values/distance.rs138
1 files changed, 138 insertions, 0 deletions
diff --git a/servo/components/style/values/distance.rs b/servo/components/style/values/distance.rs
new file mode 100644
index 0000000000..fef376cf5f
--- /dev/null
+++ b/servo/components/style/values/distance.rs
@@ -0,0 +1,138 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+//! Machinery to compute distances between animatable values.
+
+use app_units::Au;
+use euclid::default::Size2D;
+use std::iter::Sum;
+use std::ops::Add;
+
+/// A trait to compute squared distances between two animatable values.
+///
+/// This trait is derivable with `#[derive(ComputeSquaredDistance)]`. The derived
+/// implementation uses a `match` expression with identical patterns for both
+/// `self` and `other`, calling `ComputeSquaredDistance::compute_squared_distance`
+/// on each fields of the values.
+///
+/// If a variant is annotated with `#[animation(error)]`, the corresponding
+/// `match` arm returns an error.
+///
+/// Trait bounds for type parameter `Foo` can be opted out of with
+/// `#[animation(no_bound(Foo))]` on the type definition, trait bounds for
+/// fields can be opted into with `#[distance(field_bound)]` on the field.
+pub trait ComputeSquaredDistance {
+ /// Computes the squared distance between two animatable values.
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;
+}
+
+/// A distance between two animatable values.
+#[derive(Add, Clone, Copy, Debug, From)]
+pub struct SquaredDistance {
+ value: f64,
+}
+
+impl SquaredDistance {
+ /// Returns a squared distance from its square root.
+ #[inline]
+ pub fn from_sqrt(sqrt: f64) -> Self {
+ Self { value: sqrt * sqrt }
+ }
+}
+
+impl ComputeSquaredDistance for u16 {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(SquaredDistance::from_sqrt(
+ ((*self as f64) - (*other as f64)).abs(),
+ ))
+ }
+}
+
+impl ComputeSquaredDistance for i16 {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
+ }
+}
+
+impl ComputeSquaredDistance for i32 {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
+ }
+}
+
+impl ComputeSquaredDistance for f32 {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
+ }
+}
+
+impl ComputeSquaredDistance for f64 {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(SquaredDistance::from_sqrt((*self - *other).abs()))
+ }
+}
+
+impl ComputeSquaredDistance for Au {
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ self.0.compute_squared_distance(&other.0)
+ }
+}
+
+impl<T> ComputeSquaredDistance for Box<T>
+where
+ T: ComputeSquaredDistance,
+{
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ (**self).compute_squared_distance(&**other)
+ }
+}
+
+impl<T> ComputeSquaredDistance for Option<T>
+where
+ T: ComputeSquaredDistance,
+{
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ match (self.as_ref(), other.as_ref()) {
+ (Some(this), Some(other)) => this.compute_squared_distance(other),
+ (None, None) => Ok(SquaredDistance::from_sqrt(0.)),
+ _ => Err(()),
+ }
+ }
+}
+
+impl<T> ComputeSquaredDistance for Size2D<T>
+where
+ T: ComputeSquaredDistance,
+{
+ #[inline]
+ fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
+ Ok(self.width.compute_squared_distance(&other.width)? +
+ self.height.compute_squared_distance(&other.height)?)
+ }
+}
+
+impl SquaredDistance {
+ /// Returns the square root of this squared distance.
+ #[inline]
+ pub fn sqrt(self) -> f64 {
+ self.value.sqrt()
+ }
+}
+
+impl Sum for SquaredDistance {
+ fn sum<I>(iter: I) -> Self
+ where
+ I: Iterator<Item = Self>,
+ {
+ iter.fold(SquaredDistance::from_sqrt(0.), Add::add)
+ }
+}