Skip to content

Commit f392f4a

Browse files
authored
Merge pull request #2491 from gintsgints/master
rounded rectangle graphics
2 parents aed59ba + 7e89015 commit f392f4a

2 files changed

Lines changed: 79 additions & 2 deletions

File tree

graphics/src/geometry/path.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ pub use builder::Builder;
99

1010
pub use lyon_path;
1111

12-
use iced_core::{Point, Size};
12+
use crate::core::border;
13+
use crate::core::{Point, Size};
1314

1415
/// An immutable set of points that may or may not be connected.
1516
///
@@ -47,6 +48,16 @@ impl Path {
4748
Self::new(|p| p.rectangle(top_left, size))
4849
}
4950

51+
/// Creates a new [`Path`] representing a rounded rectangle given its top-left
52+
/// corner coordinate, its [`Size`] and [`border::Radius`].
53+
pub fn rounded_rectangle(
54+
top_left: Point,
55+
size: Size,
56+
radius: border::Radius,
57+
) -> Self {
58+
Self::new(|p| p.rounded_rectangle(top_left, size, radius))
59+
}
60+
5061
/// Creates a new [`Path`] representing a circle given its center
5162
/// coordinate and its radius.
5263
pub fn circle(center: Point, radius: f32) -> Self {

graphics/src/geometry/path/builder.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::geometry::path::{arc, Arc, Path};
22

3-
use iced_core::{Point, Radians, Size};
3+
use crate::core::border;
4+
use crate::core::{Point, Radians, Size};
45

56
use lyon_path::builder::{self, SvgPathBuilder};
67
use lyon_path::geom;
@@ -160,6 +161,71 @@ impl Builder {
160161
self.close();
161162
}
162163

164+
/// Adds a rounded rectangle to the [`Path`] given its top-left
165+
/// corner coordinate its [`Size`] and [`border::Radius`].
166+
#[inline]
167+
pub fn rounded_rectangle(
168+
&mut self,
169+
top_left: Point,
170+
size: Size,
171+
radius: border::Radius,
172+
) {
173+
let min_size = (size.height / 2.0).min(size.width / 2.0);
174+
let [top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner] =
175+
radius.into();
176+
177+
self.move_to(Point::new(
178+
top_left.x + min_size.min(top_left_corner),
179+
top_left.y,
180+
));
181+
self.line_to(Point::new(
182+
top_left.x + size.width - min_size.min(top_right_corner),
183+
top_left.y,
184+
));
185+
self.arc_to(
186+
Point::new(top_left.x + size.width, top_left.y),
187+
Point::new(
188+
top_left.x + size.width,
189+
top_left.y + min_size.min(top_right_corner),
190+
),
191+
min_size.min(top_right_corner),
192+
);
193+
self.line_to(Point::new(
194+
top_left.x + size.width,
195+
top_left.y + size.height - min_size.min(bottom_right_corner),
196+
));
197+
self.arc_to(
198+
Point::new(top_left.x + size.width, top_left.y + size.height),
199+
Point::new(
200+
top_left.x + size.width - min_size.min(bottom_right_corner),
201+
top_left.y + size.height,
202+
),
203+
min_size.min(bottom_right_corner),
204+
);
205+
self.line_to(Point::new(
206+
top_left.x + min_size.min(bottom_left_corner),
207+
top_left.y + size.height,
208+
));
209+
self.arc_to(
210+
Point::new(top_left.x, top_left.y + size.height),
211+
Point::new(
212+
top_left.x,
213+
top_left.y + size.height - min_size.min(bottom_left_corner),
214+
),
215+
min_size.min(bottom_left_corner),
216+
);
217+
self.line_to(Point::new(
218+
top_left.x,
219+
top_left.y + min_size.min(top_left_corner),
220+
));
221+
self.arc_to(
222+
Point::new(top_left.x, top_left.y),
223+
Point::new(top_left.x + min_size.min(top_left_corner), top_left.y),
224+
min_size.min(top_left_corner),
225+
);
226+
self.close();
227+
}
228+
163229
/// Adds a circle to the [`Path`] given its center coordinate and its
164230
/// radius.
165231
#[inline]

0 commit comments

Comments
 (0)