Skip to content

Commit

Permalink
Add rounded_rectangle to geometry::Path
Browse files Browse the repository at this point in the history
  • Loading branch information
gintsgints authored and hecrj committed Sep 12, 2024
1 parent aed59ba commit 7e89015
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
13 changes: 12 additions & 1 deletion graphics/src/geometry/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ pub use builder::Builder;

pub use lyon_path;

use iced_core::{Point, Size};
use crate::core::border;
use crate::core::{Point, Size};

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

/// Creates a new [`Path`] representing a rounded rectangle given its top-left
/// corner coordinate, its [`Size`] and [`border::Radius`].
pub fn rounded_rectangle(
top_left: Point,
size: Size,
radius: border::Radius,
) -> Self {
Self::new(|p| p.rounded_rectangle(top_left, size, radius))
}

/// Creates a new [`Path`] representing a circle given its center
/// coordinate and its radius.
pub fn circle(center: Point, radius: f32) -> Self {
Expand Down
68 changes: 67 additions & 1 deletion graphics/src/geometry/path/builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::geometry::path::{arc, Arc, Path};

use iced_core::{Point, Radians, Size};
use crate::core::border;
use crate::core::{Point, Radians, Size};

use lyon_path::builder::{self, SvgPathBuilder};
use lyon_path::geom;
Expand Down Expand Up @@ -160,6 +161,71 @@ impl Builder {
self.close();
}

/// Adds a rounded rectangle to the [`Path`] given its top-left
/// corner coordinate its [`Size`] and [`border::Radius`].
#[inline]
pub fn rounded_rectangle(
&mut self,
top_left: Point,
size: Size,
radius: border::Radius,
) {
let min_size = (size.height / 2.0).min(size.width / 2.0);
let [top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner] =
radius.into();

self.move_to(Point::new(
top_left.x + min_size.min(top_left_corner),
top_left.y,
));
self.line_to(Point::new(
top_left.x + size.width - min_size.min(top_right_corner),
top_left.y,
));
self.arc_to(
Point::new(top_left.x + size.width, top_left.y),
Point::new(
top_left.x + size.width,
top_left.y + min_size.min(top_right_corner),
),
min_size.min(top_right_corner),
);
self.line_to(Point::new(
top_left.x + size.width,
top_left.y + size.height - min_size.min(bottom_right_corner),
));
self.arc_to(
Point::new(top_left.x + size.width, top_left.y + size.height),
Point::new(
top_left.x + size.width - min_size.min(bottom_right_corner),
top_left.y + size.height,
),
min_size.min(bottom_right_corner),
);
self.line_to(Point::new(
top_left.x + min_size.min(bottom_left_corner),
top_left.y + size.height,
));
self.arc_to(
Point::new(top_left.x, top_left.y + size.height),
Point::new(
top_left.x,
top_left.y + size.height - min_size.min(bottom_left_corner),
),
min_size.min(bottom_left_corner),
);
self.line_to(Point::new(
top_left.x,
top_left.y + min_size.min(top_left_corner),
));
self.arc_to(
Point::new(top_left.x, top_left.y),
Point::new(top_left.x + min_size.min(top_left_corner), top_left.y),
min_size.min(top_left_corner),
);
self.close();
}

/// Adds a circle to the [`Path`] given its center coordinate and its
/// radius.
#[inline]
Expand Down

0 comments on commit 7e89015

Please sign in to comment.