summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-10-23 03:13:28 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-02-02 01:53:23 +0100
commit5467c19c80c992f03890264ed58156305a26b19a (patch)
tree141f48d4329ccb518d85fb121f51c22835744a11 /graphics
parent759f0e922598504705b543185bc7140a652b726a (diff)
downloadiced-5467c19c80c992f03890264ed58156305a26b19a.tar.gz
iced-5467c19c80c992f03890264ed58156305a26b19a.tar.bz2
iced-5467c19c80c992f03890264ed58156305a26b19a.zip
Replace `Primitive::Translate` with `Transform`
Diffstat (limited to 'graphics')
-rw-r--r--graphics/src/damage.rs18
-rw-r--r--graphics/src/primitive.rs32
-rw-r--r--graphics/src/transformation.rs80
3 files changed, 106 insertions, 24 deletions
diff --git a/graphics/src/damage.rs b/graphics/src/damage.rs
index ba9192ef..8edf69d7 100644
--- a/graphics/src/damage.rs
+++ b/graphics/src/damage.rs
@@ -102,10 +102,10 @@ impl<T: Damage> Damage for Primitive<T> {
.fold(Rectangle::with_size(Size::ZERO), |a, b| {
Rectangle::union(&a, &b)
}),
- Self::Translate {
- translation,
+ Self::Transform {
+ transformation,
content,
- } => content.bounds() + *translation,
+ } => content.bounds() * *transformation,
Self::Cache { content } => content.bounds(),
Self::Custom(custom) => custom.bounds(),
}
@@ -144,19 +144,19 @@ fn regions<T: Damage>(a: &Primitive<T>, b: &Primitive<T>) -> Vec<Rectangle> {
}
}
(
- Primitive::Translate {
- translation: translation_a,
+ Primitive::Transform {
+ transformation: transformation_a,
content: content_a,
},
- Primitive::Translate {
- translation: translation_b,
+ Primitive::Transform {
+ transformation: transformation_b,
content: content_b,
},
) => {
- if translation_a == translation_b {
+ if transformation_a == transformation_b {
return regions(content_a, content_b)
.into_iter()
- .map(|r| r + *translation_a)
+ .map(|r| r * *transformation_a)
.collect();
}
}
diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs
index aed59e1a..32008698 100644
--- a/graphics/src/primitive.rs
+++ b/graphics/src/primitive.rs
@@ -8,6 +8,7 @@ use crate::core::{
};
use crate::text::editor;
use crate::text::paragraph;
+use crate::Transformation;
use std::sync::Arc;
@@ -104,12 +105,12 @@ pub enum Primitive<T> {
/// The content of the clip
content: Box<Primitive<T>>,
},
- /// A primitive that applies a translation
- Translate {
- /// The translation vector
- translation: Vector,
+ /// A primitive that applies a [`Transformation`]
+ Transform {
+ /// The [`Transformation`]
+ transformation: Transformation,
- /// The primitive to translate
+ /// The primitive to transform
content: Box<Primitive<T>>,
},
/// A cached primitive.
@@ -125,12 +126,12 @@ pub enum Primitive<T> {
}
impl<T> Primitive<T> {
- /// Creates a [`Primitive::Group`].
+ /// Groups the current [`Primitive`].
pub fn group(primitives: Vec<Self>) -> Self {
Self::Group { primitives }
}
- /// Creates a [`Primitive::Clip`].
+ /// Clips the current [`Primitive`].
pub fn clip(self, bounds: Rectangle) -> Self {
Self::Clip {
bounds,
@@ -138,10 +139,21 @@ impl<T> Primitive<T> {
}
}
- /// Creates a [`Primitive::Translate`].
+ /// Translates the current [`Primitive`].
pub fn translate(self, translation: Vector) -> Self {
- Self::Translate {
- translation,
+ Self::Transform {
+ transformation: Transformation::translate(
+ translation.x,
+ translation.y,
+ ),
+ content: Box::new(self),
+ }
+ }
+
+ /// Transforms the current [`Primitive`].
+ pub fn transform(self, transformation: Transformation) -> Self {
+ Self::Transform {
+ transformation,
content: Box::new(self),
}
}
diff --git a/graphics/src/transformation.rs b/graphics/src/transformation.rs
index cf0457a4..1aeb691e 100644
--- a/graphics/src/transformation.rs
+++ b/graphics/src/transformation.rs
@@ -1,4 +1,6 @@
-use glam::{Mat4, Vec3};
+use crate::core::{Point, Rectangle, Size, Vector};
+
+use glam::{Mat4, Vec3, Vec4};
use std::ops::Mul;
/// A 2D transformation matrix.
@@ -6,10 +8,8 @@ use std::ops::Mul;
pub struct Transformation(Mat4);
impl Transformation {
- /// Get the identity transformation.
- pub fn identity() -> Transformation {
- Transformation(Mat4::IDENTITY)
- }
+ /// A [`Transformation`] that preserves whatever is transformed.
+ pub const IDENTITY: Self = Self(Mat4::IDENTITY);
/// Creates an orthographic projection.
#[rustfmt::skip]
@@ -30,6 +30,26 @@ impl Transformation {
pub fn scale(x: f32, y: f32) -> Transformation {
Transformation(Mat4::from_scale(Vec3::new(x, y, 1.0)))
}
+
+ /// The scale factor on the X axis.
+ pub fn scale_x(&self) -> f32 {
+ self.0.x_axis.x
+ }
+
+ /// The scale factor on the Y axis.
+ pub fn scale_y(&self) -> f32 {
+ self.0.y_axis.y
+ }
+
+ /// The translation on the X axis.
+ pub fn translation_x(&self) -> f32 {
+ self.0.w_axis.x
+ }
+
+ /// The translation on the Y axis.
+ pub fn translation_y(&self) -> f32 {
+ self.0.w_axis.y
+ }
}
impl Mul for Transformation {
@@ -40,6 +60,56 @@ impl Mul for Transformation {
}
}
+impl Mul<Transformation> for Point {
+ type Output = Self;
+
+ fn mul(self, transformation: Transformation) -> Self {
+ let point = transformation
+ .0
+ .mul_vec4(Vec4::new(self.x, self.y, 1.0, 1.0));
+
+ Point::new(point.x, point.y)
+ }
+}
+
+impl Mul<Transformation> for Vector {
+ type Output = Self;
+
+ fn mul(self, transformation: Transformation) -> Self {
+ let new_vector = transformation
+ .0
+ .mul_vec4(Vec4::new(self.x, self.y, 1.0, 0.0));
+
+ Vector::new(new_vector.x, new_vector.y)
+ }
+}
+
+impl Mul<Transformation> for Size {
+ type Output = Self;
+
+ fn mul(self, transformation: Transformation) -> Self {
+ let new_size = transformation.0.mul_vec4(Vec4::new(
+ self.width,
+ self.height,
+ 1.0,
+ 0.0,
+ ));
+
+ Size::new(new_size.x, new_size.y)
+ }
+}
+
+impl Mul<Transformation> for Rectangle {
+ type Output = Self;
+
+ fn mul(self, transformation: Transformation) -> Self {
+ let position = self.position();
+ let size = self.size();
+
+ Self::new(position * transformation, size * transformation)
+ }
+}
+
impl AsRef<[f32; 16]> for Transformation {
fn as_ref(&self) -> &[f32; 16] {
self.0.as_ref()