drawing_impeller/common/display_list/
paint.rs1use 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(¢er),
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(¢er),
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}