1use crate::ImageBrushRef;
5
6use super::{Gradient, ImageBrush};
7
8use color::{AlphaColor, ColorSpace, DynamicColor, OpaqueColor, Srgb};
9
10#[derive(Copy, Clone, Debug, PartialEq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub enum Brush<I = ImageBrush, G = Gradient> {
16 Solid(AlphaColor<Srgb>),
18 Gradient(G),
20 Image(I),
22}
23
24impl<CS: ColorSpace, I, G> From<AlphaColor<CS>> for Brush<I, G> {
25 fn from(c: AlphaColor<CS>) -> Self {
26 Self::Solid(c.convert())
27 }
28}
29
30impl<I, G> From<DynamicColor> for Brush<I, G> {
31 fn from(c: DynamicColor) -> Self {
32 Self::Solid(c.to_alpha_color::<Srgb>())
33 }
34}
35
36impl<CS: ColorSpace, I, G> From<OpaqueColor<CS>> for Brush<I, G> {
37 fn from(c: OpaqueColor<CS>) -> Self {
38 Self::Solid(c.with_alpha(1.).convert())
39 }
40}
41
42impl<CS: ColorSpace, I, G> From<&AlphaColor<CS>> for Brush<I, G> {
43 fn from(c: &AlphaColor<CS>) -> Self {
44 Self::Solid((*c).convert())
45 }
46}
47
48impl<I, G> From<&DynamicColor> for Brush<I, G> {
49 fn from(c: &DynamicColor) -> Self {
50 Self::Solid((*c).to_alpha_color::<Srgb>())
51 }
52}
53
54impl<CS: ColorSpace, I, G> From<&OpaqueColor<CS>> for Brush<I, G> {
55 fn from(c: &OpaqueColor<CS>) -> Self {
56 Self::Solid((*c).with_alpha(1.).convert())
57 }
58}
59
60impl<I> From<Gradient> for Brush<I, Gradient> {
61 fn from(g: Gradient) -> Self {
62 Self::Gradient(g)
63 }
64}
65
66impl<G, D> From<ImageBrush<D>> for Brush<ImageBrush<D>, G> {
67 fn from(value: ImageBrush<D>) -> Self {
68 Self::Image(value)
69 }
70}
71
72impl<I, G> Default for Brush<I, G> {
73 fn default() -> Self {
74 Self::Solid(AlphaColor::<Srgb>::TRANSPARENT)
75 }
76}
77
78impl Brush {
79 #[must_use]
81 pub fn with_alpha(self, alpha: f32) -> Self {
82 match self {
83 Self::Solid(color) => color.with_alpha(alpha).into(),
84 Self::Gradient(gradient) => gradient.with_alpha(alpha).into(),
85 Self::Image(image) => image.with_alpha(alpha).into(),
86 }
87 }
88
89 #[must_use]
94 #[doc(alias = "with_alpha_factor")]
95 #[track_caller]
96 pub fn multiply_alpha(self, alpha: f32) -> Self {
97 debug_assert!(
98 alpha.is_finite() && alpha >= 0.0,
99 "A non-finite or negative alpha ({alpha}) is meaningless."
100 );
101 if alpha == 1.0 {
102 self
103 } else {
104 match self {
105 Self::Solid(color) => color.multiply_alpha(alpha).into(),
106 Self::Gradient(gradient) => gradient.multiply_alpha(alpha).into(),
107 Self::Image(image) => image.multiply_alpha(alpha).into(),
108 }
109 }
110 }
111}
112
113pub type BrushRef<'a> = Brush<ImageBrushRef<'a>, &'a Gradient>;
119
120impl BrushRef<'_> {
121 #[must_use]
123 pub fn to_owned(&self) -> Brush {
124 match self {
125 Self::Solid(color) => Brush::Solid(*color),
126 Self::Gradient(gradient) => Brush::Gradient((*gradient).clone()),
127 Self::Image(image) => Brush::Image(image.to_owned()),
128 }
129 }
130}
131
132impl<'a> From<&'a Gradient> for BrushRef<'a> {
133 fn from(gradient: &'a Gradient) -> Self {
134 Self::Gradient(gradient)
135 }
136}
137
138impl<'a> From<&'a ImageBrush> for BrushRef<'a> {
139 fn from(image: &'a ImageBrush) -> Self {
140 Self::Image(image.as_ref())
141 }
142}
143
144impl<'a> From<&'a Brush> for BrushRef<'a> {
145 fn from(brush: &'a Brush) -> Self {
146 match brush {
147 Brush::Solid(color) => Self::Solid(*color),
148 Brush::Gradient(gradient) => Self::Gradient(gradient),
149 Brush::Image(image) => Self::Image(image.as_ref()),
150 }
151 }
152}
153
154#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158#[repr(u8)]
159pub enum Extend {
160 #[default]
162 Pad = 0,
163 Repeat = 1,
165 Reflect = 2,
167}