epaint/shapes/
path_shape.rs

1use crate::*;
2
3/// A path which can be stroked and/or filled (if closed).
4#[derive(Clone, Debug, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6pub struct PathShape {
7    /// Filled paths should prefer clockwise order.
8    pub points: Vec<Pos2>,
9
10    /// If true, connect the first and last of the points together.
11    /// This is required if `fill != TRANSPARENT`.
12    pub closed: bool,
13
14    /// Fill is only supported for convex polygons.
15    pub fill: Color32,
16
17    /// Color and thickness of the line.
18    pub stroke: PathStroke,
19    // TODO(emilk): Add texture support either by supplying uv for each point,
20    // or by some transform from points to uv (e.g. a callback or a linear transform matrix).
21}
22
23impl PathShape {
24    /// A line through many points.
25    ///
26    /// Use [`Shape::line_segment`] instead if your line only connects two points.
27    #[inline]
28    pub fn line(points: Vec<Pos2>, stroke: impl Into<PathStroke>) -> Self {
29        Self {
30            points,
31            closed: false,
32            fill: Default::default(),
33            stroke: stroke.into(),
34        }
35    }
36
37    /// A line that closes back to the start point again.
38    #[inline]
39    pub fn closed_line(points: Vec<Pos2>, stroke: impl Into<PathStroke>) -> Self {
40        Self {
41            points,
42            closed: true,
43            fill: Default::default(),
44            stroke: stroke.into(),
45        }
46    }
47
48    /// A convex polygon with a fill and optional stroke.
49    ///
50    /// The most performant winding order is clockwise.
51    #[inline]
52    pub fn convex_polygon(
53        points: Vec<Pos2>,
54        fill: impl Into<Color32>,
55        stroke: impl Into<PathStroke>,
56    ) -> Self {
57        Self {
58            points,
59            closed: true,
60            fill: fill.into(),
61            stroke: stroke.into(),
62        }
63    }
64
65    /// The visual bounding rectangle (includes stroke width)
66    #[inline]
67    pub fn visual_bounding_rect(&self) -> Rect {
68        if self.fill == Color32::TRANSPARENT && self.stroke.is_empty() {
69            Rect::NOTHING
70        } else {
71            Rect::from_points(&self.points).expand(self.stroke.width / 2.0)
72        }
73    }
74}
75
76impl From<PathShape> for Shape {
77    #[inline(always)]
78    fn from(shape: PathShape) -> Self {
79        Self::Path(shape)
80    }
81}