Skip to content

Commit ac2c789

Browse files
authored
Refactor Brush to use generic types for image and gradient data (#134)
As discussed in #133 (review) we can also generalize `Brush` over image data and gradient. This makes `BrushRef<'a> = Brush<ImageBrushRef<'a>, &'a Gradient>` which allows to share more From impls, most notably various color implementations (even owned version can now support conversion from &color because color is copy anyway). --------- Signed-off-by: sagudev <[email protected]>
1 parent 0b578d9 commit ac2c789

File tree

1 file changed

+31
-63
lines changed

1 file changed

+31
-63
lines changed

src/brush.rs

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,66 @@ use color::{AlphaColor, ColorSpace, DynamicColor, OpaqueColor, Srgb};
1010
/// Describes the color content of a filled or stroked shape.
1111
///
1212
/// See also [`BrushRef`] which can be used to avoid allocations.
13-
#[derive(Clone, Debug, PartialEq)]
13+
#[derive(Copy, Clone, Debug, PartialEq)]
1414
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15-
pub enum Brush {
15+
pub enum Brush<I = ImageBrush, G = Gradient> {
1616
/// Solid color brush.
1717
Solid(AlphaColor<Srgb>),
1818
/// Gradient brush.
19-
Gradient(Gradient),
19+
Gradient(G),
2020
/// Image brush.
21-
Image(ImageBrush),
21+
Image(I),
2222
}
2323

24-
impl<CS: ColorSpace> From<AlphaColor<CS>> for Brush {
24+
impl<CS: ColorSpace, I, G> From<AlphaColor<CS>> for Brush<I, G> {
2525
fn from(c: AlphaColor<CS>) -> Self {
2626
Self::Solid(c.convert())
2727
}
2828
}
2929

30-
impl From<DynamicColor> for Brush {
30+
impl<I, G> From<DynamicColor> for Brush<I, G> {
3131
fn from(c: DynamicColor) -> Self {
3232
Self::Solid(c.to_alpha_color::<Srgb>())
3333
}
3434
}
3535

36-
impl<CS: ColorSpace> From<OpaqueColor<CS>> for Brush {
36+
impl<CS: ColorSpace, I, G> From<OpaqueColor<CS>> for Brush<I, G> {
3737
fn from(c: OpaqueColor<CS>) -> Self {
3838
Self::Solid(c.with_alpha(1.).convert())
3939
}
4040
}
4141

42-
impl From<Gradient> for Brush {
42+
impl<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+
48+
impl<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+
54+
impl<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+
60+
impl<I> From<Gradient> for Brush<I, Gradient> {
4361
fn from(g: Gradient) -> Self {
4462
Self::Gradient(g)
4563
}
4664
}
4765

48-
impl From<ImageBrush> for Brush {
49-
fn from(value: ImageBrush) -> Self {
66+
impl<G, D> From<ImageBrush<D>> for Brush<ImageBrush<D>, G> {
67+
fn from(value: ImageBrush<D>) -> Self {
5068
Self::Image(value)
5169
}
5270
}
5371

54-
impl Default for Brush {
72+
impl<I, G> Default for Brush<I, G> {
5573
fn default() -> Self {
5674
Self::Solid(AlphaColor::<Srgb>::TRANSPARENT)
5775
}
@@ -95,17 +113,9 @@ impl Brush {
95113
/// Reference to a [brush](Brush).
96114
///
97115
/// This is useful for methods that would like to accept brushes by reference. Defining
98-
/// the type as `impl<Into<BrushRef>>` allows accepting types like `&LinearGradient`
116+
/// the type as `impl Into<BrushRef>` allows accepting types like `&Gradient`
99117
/// directly without cloning or allocating.
100-
#[derive(Copy, Clone, Debug, PartialEq)]
101-
pub enum BrushRef<'a> {
102-
/// Solid color brush.
103-
Solid(AlphaColor<Srgb>),
104-
/// Gradient brush.
105-
Gradient(&'a Gradient),
106-
/// Image brush.
107-
Image(ImageBrushRef<'a>),
108-
}
118+
pub type BrushRef<'a> = Brush<ImageBrushRef<'a>, &'a Gradient>;
109119

110120
impl BrushRef<'_> {
111121
/// Converts the reference to an owned brush.
@@ -119,54 +129,12 @@ impl BrushRef<'_> {
119129
}
120130
}
121131

122-
impl<CS: ColorSpace> From<AlphaColor<CS>> for BrushRef<'_> {
123-
fn from(color: AlphaColor<CS>) -> Self {
124-
Self::Solid(color.convert())
125-
}
126-
}
127-
128-
impl From<DynamicColor> for BrushRef<'_> {
129-
fn from(color: DynamicColor) -> Self {
130-
Self::Solid(color.to_alpha_color::<Srgb>())
131-
}
132-
}
133-
134-
impl<CS: ColorSpace> From<OpaqueColor<CS>> for BrushRef<'_> {
135-
fn from(color: OpaqueColor<CS>) -> Self {
136-
Self::Solid(color.with_alpha(1.).convert())
137-
}
138-
}
139-
140-
impl<'a, CS: ColorSpace> From<&'a AlphaColor<CS>> for BrushRef<'_> {
141-
fn from(color: &'a AlphaColor<CS>) -> Self {
142-
Self::Solid((*color).convert())
143-
}
144-
}
145-
146-
impl<'a> From<&'a DynamicColor> for BrushRef<'_> {
147-
fn from(color: &'a DynamicColor) -> Self {
148-
Self::Solid((*color).to_alpha_color::<Srgb>())
149-
}
150-
}
151-
152-
impl<'a, CS: ColorSpace> From<&'a OpaqueColor<CS>> for BrushRef<'_> {
153-
fn from(color: &'a OpaqueColor<CS>) -> Self {
154-
Self::Solid((*color).with_alpha(1.).convert())
155-
}
156-
}
157-
158132
impl<'a> From<&'a Gradient> for BrushRef<'a> {
159133
fn from(gradient: &'a Gradient) -> Self {
160134
Self::Gradient(gradient)
161135
}
162136
}
163137

164-
impl<'a> From<ImageBrushRef<'a>> for BrushRef<'a> {
165-
fn from(image: ImageBrushRef<'a>) -> Self {
166-
Self::Image(image)
167-
}
168-
}
169-
170138
impl<'a> From<&'a ImageBrush> for BrushRef<'a> {
171139
fn from(image: &'a ImageBrush) -> Self {
172140
Self::Image(image.as_ref())

0 commit comments

Comments
 (0)