ferroui_base/media/immutable/
immutable_pen.rs1use crate::media::immutable::{ImmutableDashStyle, ImmutableSolidColorBrush};
2use crate::media::{IBrush, IDashStyle, IImmutableBrush, IPen, PenLineCap, PenLineJoin};
3use std::any::Any;
4use std::rc::Rc;
5
6#[derive(Clone, Debug)]
8pub struct ImmutablePen {
9 brush: Option<Rc<dyn IBrush>>,
10 thickness: f64,
11 dash_style: Option<Rc<dyn IDashStyle>>,
12 line_cap: PenLineCap,
13 line_join: PenLineJoin,
14 miter_limit: f64,
15 shared: std::sync::OnceLock<Option<crate::media::SharedPen>>,
17}
18
19impl ImmutablePen {
20 pub fn new(
22 brush: Option<Rc<dyn IImmutableBrush>>,
23 thickness: f64,
24 dash_style: Option<Rc<ImmutableDashStyle>>,
25 line_cap: PenLineCap,
26 line_join: PenLineJoin,
27 miter_limit: f64,
28 ) -> Self {
29 Self {
30 brush: brush.map(|b| b as Rc<dyn IBrush>),
31 thickness,
32 line_cap,
33 line_join,
34 miter_limit,
35 dash_style: dash_style.map(|d| d as Rc<dyn IDashStyle>),
36 shared: std::sync::OnceLock::new(),
37 }
38 }
39
40 pub fn with_brush(brush: Option<Rc<dyn IImmutableBrush>>, thickness: f64) -> Self {
43 Self::new(brush, thickness, None, PenLineCap::Flat, PenLineJoin::Miter, 10.0)
44 }
45
46 pub fn from_uint32(color: u32, thickness: f64) -> Self {
48 Self::with_brush(Some(Rc::new(ImmutableSolidColorBrush::from_uint32(color))), thickness)
49 }
50
51 #[inline]
53 pub fn brush(&self) -> Option<Rc<dyn IBrush>> {
54 self.brush.clone()
55 }
56
57 #[inline]
59 pub fn thickness(&self) -> f64 {
60 self.thickness
61 }
62
63 #[inline]
65 pub fn dash_style(&self) -> Option<Rc<dyn IDashStyle>> {
66 self.dash_style.clone()
67 }
68
69 #[inline]
71 pub fn line_cap(&self) -> PenLineCap {
72 self.line_cap
73 }
74
75 #[inline]
77 pub fn line_join(&self) -> PenLineJoin {
78 self.line_join
79 }
80
81 #[inline]
84 pub fn miter_limit(&self) -> f64 {
85 self.miter_limit
86 }
87}
88
89impl IPen for ImmutablePen {
90 fn brush(&self) -> Option<Rc<dyn IBrush>> {
91 self.brush.clone()
92 }
93
94 fn dash_style(&self) -> Option<Rc<dyn IDashStyle>> {
95 self.dash_style.clone()
96 }
97
98 #[inline]
99 fn line_cap(&self) -> PenLineCap {
100 self.line_cap
101 }
102
103 #[inline]
104 fn line_join(&self) -> PenLineJoin {
105 self.line_join
106 }
107
108 #[inline]
109 fn miter_limit(&self) -> f64 {
110 self.miter_limit
111 }
112
113 #[inline]
114 fn thickness(&self) -> f64 {
115 self.thickness
116 }
117
118 fn as_any(&self) -> &dyn Any {
119 self
120 }
121
122 fn into_immutable_pen(self: Rc<Self>) -> Rc<ImmutablePen> {
123 self
124 }
125
126 fn to_shared(&self) -> Option<crate::media::SharedPen> {
127 self.shared.get_or_init(|| crate::media::SharedPen::from_pen(self)).clone()
128 }
129
130 fn equals(&self, other: &dyn IPen) -> bool {
131 if self.reference_id() == other.reference_id() {
132 return true;
133 }
134
135 self.brush == other.brush()
136 && self.thickness == other.thickness()
137 && self.dash_style == other.dash_style()
138 && self.line_cap == other.line_cap()
139 && self.line_join == other.line_join()
140 && self.miter_limit == other.miter_limit()
141 }
142}
143
144impl PartialEq for ImmutablePen {
145 fn eq(&self, other: &Self) -> bool {
146 IPen::equals(self, other)
147 }
148}