diff options
author | 2023-10-23 03:13:28 +0200 | |
---|---|---|
committer | 2024-02-02 01:53:23 +0100 | |
commit | 5467c19c80c992f03890264ed58156305a26b19a (patch) | |
tree | 141f48d4329ccb518d85fb121f51c22835744a11 /graphics | |
parent | 759f0e922598504705b543185bc7140a652b726a (diff) | |
download | iced-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.rs | 18 | ||||
-rw-r--r-- | graphics/src/primitive.rs | 32 | ||||
-rw-r--r-- | graphics/src/transformation.rs | 80 |
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() |