Skip to main content

drawing_impeller/common/display_list/
paint.rs

1use std::sync::{Arc, Mutex};
2
3use crate::ImpellerTexture;
4
5use super::{
6    convert_blend_mode, convert_color, convert_color_matrix, convert_image_filter, convert_matrix,
7    convert_point, convert_texture_sampling, convert_tile_mode, ColorSourceFragment,
8    ImageFilterFragment,
9};
10
11#[derive(Clone)]
12pub struct Paint {
13    pub(crate) paint: Arc<Mutex<impellers::Paint>>,
14}
15
16impl Default for Paint {
17    fn default() -> Self {
18        Self {
19            paint: Arc::new(Mutex::new(impellers::Paint::default())),
20        }
21    }
22}
23
24impl drawing_api::Paint for Paint {
25    type ColorSourceFragment = crate::ColorSourceFragment;
26    type ImageFilterFragment = crate::ImageFilterFragment;
27    type Texture = ImpellerTexture;
28
29    fn set_color(&mut self, color: impl Into<drawing_api::Color>) {
30        let color = color.into();
31        self.paint.lock().unwrap().set_color(convert_color(&color));
32    }
33
34    fn set_blend_mode(&mut self, blend_mode: drawing_api::BlendMode) {
35        self.paint
36            .lock()
37            .unwrap()
38            .set_blend_mode(convert_blend_mode(blend_mode));
39    }
40
41    fn set_draw_style(&mut self, draw_style: drawing_api::DrawStyle) {
42        self.paint.lock().unwrap().set_draw_style(match draw_style {
43            drawing_api::DrawStyle::Fill => impellers::DrawStyle::Fill,
44            drawing_api::DrawStyle::Stroke => impellers::DrawStyle::Stroke,
45            drawing_api::DrawStyle::StrokeAndFill => impellers::DrawStyle::StrokeAndFill,
46        });
47    }
48
49    fn set_stroke_cap(&mut self, cap: drawing_api::StrokeCap) {
50        self.paint.lock().unwrap().set_stroke_cap(match cap {
51            drawing_api::StrokeCap::Butt => impellers::StrokeCap::Butt,
52            drawing_api::StrokeCap::Round => impellers::StrokeCap::Round,
53            drawing_api::StrokeCap::Square => impellers::StrokeCap::Square,
54        });
55    }
56
57    fn set_stroke_join(&mut self, join: drawing_api::StrokeJoin) {
58        self.paint.lock().unwrap().set_stroke_join(match join {
59            drawing_api::StrokeJoin::Miter => impellers::StrokeJoin::Miter,
60            drawing_api::StrokeJoin::Round => impellers::StrokeJoin::Round,
61            drawing_api::StrokeJoin::Bevel => impellers::StrokeJoin::Bevel,
62        });
63    }
64
65    fn set_stroke_width(&mut self, width: f32) {
66        self.paint.lock().unwrap().set_stroke_width(width);
67    }
68
69    fn set_stroke_miter(&mut self, miter: f32) {
70        self.paint.lock().unwrap().set_stroke_miter(miter);
71    }
72
73    fn set_color_source(
74        &mut self,
75        color_source: drawing_api::ColorSource<Self::Texture, ColorSourceFragment>,
76    ) {
77        let color_source = match color_source {
78            drawing_api::ColorSource::LinearGradient {
79                start,
80                end,
81                colors,
82                stops,
83                tile_mode,
84                transformation,
85            } => impellers::ColorSource::new_linear_gradient(
86                convert_point(&start),
87                convert_point(&end),
88                &colors
89                    .into_iter()
90                    .map(|c| convert_color(&c))
91                    .collect::<Vec<_>>(),
92                &stops,
93                convert_tile_mode(tile_mode),
94                transformation.map(|t| convert_matrix(&t)).as_ref(),
95            ),
96            drawing_api::ColorSource::RadialGradient {
97                center,
98                radius,
99                colors,
100                stops,
101                tile_mode,
102                transformation,
103            } => impellers::ColorSource::new_radial_gradient(
104                convert_point(&center),
105                radius,
106                &colors
107                    .into_iter()
108                    .map(|c| convert_color(&c))
109                    .collect::<Vec<_>>(),
110                &stops,
111                convert_tile_mode(tile_mode),
112                transformation.map(|t| convert_matrix(&t)).as_ref(),
113            ),
114            drawing_api::ColorSource::ConicalGradient {
115                start_center,
116                start_radius,
117                end_center,
118                end_radius,
119                colors,
120                stops,
121                tile_mode,
122                transformation,
123            } => impellers::ColorSource::new_conical_gradient(
124                convert_point(&start_center),
125                start_radius,
126                convert_point(&end_center),
127                end_radius,
128                &colors
129                    .into_iter()
130                    .map(|c| convert_color(&c))
131                    .collect::<Vec<_>>(),
132                &stops,
133                convert_tile_mode(tile_mode),
134                transformation.map(|t| convert_matrix(&t)).as_ref(),
135            ),
136            drawing_api::ColorSource::SweepGradient {
137                center,
138                start,
139                end,
140                colors,
141                stops,
142                tile_mode,
143                transformation,
144            } => impellers::ColorSource::new_sweep_gradient(
145                convert_point(&center),
146                start,
147                end,
148                &colors
149                    .into_iter()
150                    .map(|c| convert_color(&c))
151                    .collect::<Vec<_>>(),
152                &stops,
153                convert_tile_mode(tile_mode),
154                transformation.map(|t| convert_matrix(&t)).as_ref(),
155            ),
156            drawing_api::ColorSource::Image {
157                image,
158                horizontal_tile_mode,
159                vertical_tile_mode,
160                sampling,
161                transformation,
162            } => impellers::ColorSource::new_image(
163                &image.texture,
164                convert_tile_mode(horizontal_tile_mode),
165                convert_tile_mode(vertical_tile_mode),
166                convert_texture_sampling(sampling),
167                transformation.map(|t| convert_matrix(&t)).as_ref(),
168            ),
169            drawing_api::ColorSource::Fragment { color_source } => color_source.color_source,
170        };
171        self.paint.lock().unwrap().set_color_source(&color_source);
172    }
173
174    fn set_color_filter(&mut self, color_filter: drawing_api::ColorFilter) {
175        let color_filter = match color_filter {
176            drawing_api::ColorFilter::Blend(color, blend_mode) => {
177                impellers::ColorFilter::new_blend(
178                    convert_color(&color),
179                    convert_blend_mode(blend_mode),
180                )
181            }
182            drawing_api::ColorFilter::Matrix(color_matrix) => {
183                impellers::ColorFilter::new_matrix(convert_color_matrix(&color_matrix))
184            }
185        };
186        self.paint.lock().unwrap().set_color_filter(&color_filter);
187    }
188
189    fn set_image_filter(&mut self, image_filter: drawing_api::ImageFilter<ImageFilterFragment>) {
190        let image_filter = convert_image_filter(image_filter);
191        self.paint.lock().unwrap().set_image_filter(&image_filter);
192    }
193
194    fn set_mask_filter(&mut self, mask_filter: drawing_api::MaskFilter) {
195        let mask_filter = match mask_filter {
196            drawing_api::MaskFilter::Blur { style, sigma } => impellers::MaskFilter::new_blur(
197                match style {
198                    drawing_api::BlurStyle::Normal => impellers::BlurStyle::Normal,
199                    drawing_api::BlurStyle::Solid => impellers::BlurStyle::Solid,
200                    drawing_api::BlurStyle::Outer => impellers::BlurStyle::Outer,
201                    drawing_api::BlurStyle::Inner => impellers::BlurStyle::Inner,
202                },
203                sigma,
204            ),
205        };
206        self.paint.lock().unwrap().set_mask_filter(&mask_filter);
207    }
208}