Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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