From eac5bcb64f17dfbb52b64ea4f95693462986bb69 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector@hecrj.dev>
Date: Fri, 3 May 2024 07:04:57 +0200
Subject: Fix `Image::bounds` when rotation present in `iced_graphics`

---
 core/src/rectangle.rs | 16 ++++++++++++++--
 core/src/rotation.rs  | 14 +++-----------
 core/src/size.rs      | 15 ++++++++++++++-
 3 files changed, 31 insertions(+), 14 deletions(-)

(limited to 'core/src')

diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs
index fb66131a..1556e072 100644
--- a/core/src/rectangle.rs
+++ b/core/src/rectangle.rs
@@ -1,6 +1,6 @@
-use crate::{Point, Size, Vector};
+use crate::{Point, Radians, Size, Vector};
 
-/// A rectangle.
+/// An axis-aligned rectangle.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
 pub struct Rectangle<T = f32> {
     /// X coordinate of the top-left corner.
@@ -172,6 +172,18 @@ impl Rectangle<f32> {
             height: self.height + amount * 2.0,
         }
     }
+
+    /// Rotates the [`Rectangle`] and returns the smallest [`Rectangle`]
+    /// containing it.
+    pub fn rotate(self, rotation: Radians) -> Self {
+        let size = self.size().rotate(rotation);
+        let position = Point::new(
+            self.center_x() - size.width / 2.0,
+            self.center_y() - size.height / 2.0,
+        );
+
+        Self::new(position, size)
+    }
 }
 
 impl std::ops::Mul<f32> for Rectangle<f32> {
diff --git a/core/src/rotation.rs b/core/src/rotation.rs
index f36ef089..00a8c302 100644
--- a/core/src/rotation.rs
+++ b/core/src/rotation.rs
@@ -36,20 +36,12 @@ impl Rotation {
         Degrees(self.radians().0.to_degrees())
     }
 
-    /// Rotates the given [`Size`].
+    /// Applies the [`Rotation`] to the given [`Size`], returning
+    /// the minimum [`Size`] containing the rotated one.
     pub fn apply(self, size: Size) -> Size {
         match self {
             Self::Floating(_) => size,
-            Self::Solid(rotation) => {
-                let radians = f32::from(rotation);
-
-                Size {
-                    width: (size.width * radians.cos()).abs()
-                        + (size.height * radians.sin()).abs(),
-                    height: (size.width * radians.sin()).abs()
-                        + (size.height * radians.cos()).abs(),
-                }
-            }
+            Self::Solid(rotation) => size.rotate(rotation),
         }
     }
 }
diff --git a/core/src/size.rs b/core/src/size.rs
index 66be2d85..d7459355 100644
--- a/core/src/size.rs
+++ b/core/src/size.rs
@@ -1,4 +1,4 @@
-use crate::Vector;
+use crate::{Radians, Vector};
 
 /// An amount of space in 2 dimensions.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
@@ -51,6 +51,19 @@ impl Size {
             height: self.height + other.height,
         }
     }
+
+    /// Rotates the given [`Size`] and returns the minimum [`Size`]
+    /// containing it.
+    pub fn rotate(self, rotation: Radians) -> Size {
+        let radians = f32::from(rotation);
+
+        Size {
+            width: (self.width * radians.cos()).abs()
+                + (self.height * radians.sin()).abs(),
+            height: (self.width * radians.sin()).abs()
+                + (self.height * radians.cos()).abs(),
+        }
+    }
 }
 
 impl<T> From<[T; 2]> for Size<T> {
-- 
cgit