1use super::*;
4
5#[derive(Clone, Debug)]
8pub struct AlphaMaskPaint {
9 pub path: kurbo::BezPath,
10 pub transform: kurbo::Affine,
11 pub fill: Fill,
12 pub opacity: f64,
13}
14
15#[derive(Clone, Debug)]
17pub struct ReplayCanvasLayerUpdate {
18 pub layer: usize,
19 pub node_ids: Option<Vec<u32>>,
21}
22
23pub trait RenderContext {
25 fn fill(&mut self, layer: usize, path: kurbo::BezPath, fill: &Fill) {
28 self.fill_with_opacity(layer, path, fill, 1.0);
29 }
30 fn fill_with_opacity(&mut self, layer: usize, path: kurbo::BezPath, fill: &Fill, opacity: f64);
32 fn fill_with_material_and_opacity(
34 &mut self,
35 layer: usize,
36 path: kurbo::BezPath,
37 fill: &Fill,
38 _material: &Material,
39 opacity: f64,
40 ) {
41 self.fill_with_opacity(layer, path, fill, opacity);
42 }
43 fn fill_with_material_and_opacity_and_smoothing(
45 &mut self,
46 layer: usize,
47 path: kurbo::BezPath,
48 fill: &Fill,
49 material: &Material,
50 opacity: f64,
51 smoothing: PathSmoothing,
52 ) {
53 let path = crate::drawing::path_smoothing::smooth_bez_path(&path, smoothing);
54 self.fill_with_material_and_opacity(layer, path, fill, material, opacity);
55 }
56 fn stroke(&mut self, layer: usize, path: kurbo::BezPath, stroke: &Stroke) {
58 self.stroke_with_opacity(layer, path, stroke, 1.0);
59 }
60 fn stroke_with_opacity(
62 &mut self,
63 layer: usize,
64 path: kurbo::BezPath,
65 stroke: &Stroke,
66 opacity: f64,
67 );
68 fn stroke_with_material_and_opacity(
70 &mut self,
71 layer: usize,
72 path: kurbo::BezPath,
73 stroke: &Stroke,
74 _material: &Material,
75 opacity: f64,
76 ) {
77 self.stroke_with_opacity(layer, path, stroke, opacity);
78 }
79 fn stroke_with_material_and_opacity_and_smoothing(
81 &mut self,
82 layer: usize,
83 path: kurbo::BezPath,
84 stroke: &Stroke,
85 material: &Material,
86 opacity: f64,
87 smoothing: PathSmoothing,
88 ) {
89 let path = crate::drawing::path_smoothing::smooth_bez_path(&path, smoothing);
90 self.stroke_with_material_and_opacity(layer, path, stroke, material, opacity);
91 }
92 fn stroke_with_draw_range_and_material_and_opacity(
94 &mut self,
95 layer: usize,
96 path: kurbo::BezPath,
97 stroke: &Stroke,
98 material: &Material,
99 opacity: f64,
100 draw_start: f64,
101 draw_end: f64,
102 );
103 fn stroke_with_draw_range_and_material_and_opacity_and_smoothing(
105 &mut self,
106 layer: usize,
107 path: kurbo::BezPath,
108 stroke: &Stroke,
109 material: &Material,
110 opacity: f64,
111 draw_start: f64,
112 draw_end: f64,
113 smoothing: PathSmoothing,
114 ) {
115 let path = crate::drawing::path_smoothing::smooth_bez_path(&path, smoothing);
116 self.stroke_with_draw_range_and_material_and_opacity(
117 layer, path, stroke, material, opacity, draw_start, draw_end,
118 );
119 }
120
121 fn save(&mut self, layer: usize);
124 fn restore(&mut self, layer: usize);
126 fn clip(&mut self, layer: usize, path: BezPath);
128 fn clip_alpha(&mut self, _layer: usize, _paints: &[AlphaMaskPaint], _feather: f64) {
131 panic!("this rendering backend does not implement alpha masks");
132 }
133 fn transform(&mut self, layer: usize, affine: kurbo::Affine);
135
136 fn load_image(&mut self, identifier: &str, image: &[u8], width: usize, height: usize);
139 fn draw_image(&mut self, layer: usize, image_path: &str, rect: kurbo::Rect);
141 fn get_image_size(&mut self, image_path: &str) -> Option<(usize, usize)>;
143 fn image_loaded(&self, image_path: &str) -> bool;
145
146 fn layers(&self) -> usize;
149 fn resize_layers_to(&mut self, layer_count: usize, dirty_canvases: Rc<RefCell<Vec<bool>>>);
151 fn clear(&mut self, layer: usize);
153 fn flush(&mut self, layer: usize, dirty_canvases: Rc<RefCell<Vec<bool>>>);
155 fn resize(&mut self, width: usize, height: usize);
157 fn refresh_layers(&mut self, layers: &[usize]);
159 fn set_scene_lighting(&mut self, _layer: usize, _lighting: &SceneLighting) {}
161 fn clear_targeted_replay(&mut self, _layer: usize) {}
163 fn take_ready_canvas_layers(&mut self) -> Vec<usize> {
165 vec![]
166 }
167
168 fn take_replay_canvas_layers(&mut self) -> Vec<usize> {
170 vec![]
171 }
172
173 fn take_replay_canvas_layer_updates(&mut self) -> Vec<ReplayCanvasLayerUpdate> {
175 self.take_replay_canvas_layers()
176 .into_iter()
177 .map(|layer| ReplayCanvasLayerUpdate {
178 layer,
179 node_ids: None,
180 })
181 .collect()
182 }
183
184 fn request_layer_screenshot(&mut self, _layer: usize, _request_id: u32) {}
186
187 fn take_layer_screenshot(&mut self, _layer: usize, _request_id: u32) -> Option<ScreenshotData> {
189 None
190 }
191
192 fn take_layer_surface_screenshots(
194 &mut self,
195 layer: usize,
196 request_id: u32,
197 ) -> Vec<LayerSurfaceScreenshotData> {
198 self.take_layer_screenshot(layer, request_id)
199 .map(|screenshot| {
200 vec![LayerSurfaceScreenshotData {
201 id: screenshot.id,
202 key: "single".to_string(),
203 data: screenshot.data,
204 width: screenshot.width,
205 height: screenshot.height,
206 origin_x: 0.0,
207 origin_y: 0.0,
208 logical_width: screenshot.width as f32,
209 logical_height: screenshot.height as f32,
210 }]
211 })
212 .unwrap_or_default()
213 }
214
215 fn retains_canvas_nodes(&self) -> bool {
217 true
218 }
219
220 fn begin_node(
222 &mut self,
223 _layer: usize,
224 _node_id: u32,
225 _z_index: i32,
226 _light_mask: u32,
227 ) -> bool {
228 true
229 }
230
231 fn begin_node_with_bounds(
233 &mut self,
234 layer: usize,
235 node_id: u32,
236 z_index: i32,
237 _coverage_bounds: kurbo::Rect,
238 light_mask: u32,
239 ) -> bool {
240 self.begin_node(layer, node_id, z_index, light_mask)
241 }
242
243 fn take_clean_skipped_node(&mut self, _layer: usize, _node_id: u32) -> bool {
245 false
246 }
247
248 fn end_node(&mut self, _layer: usize, _node_id: u32) -> bool {
250 true
251 }
252
253 fn remove_node(&mut self, _layer: usize, _node_id: u32) -> bool {
255 true
256 }
257}
258
259pub fn bez_path_to_svg_path_data(path: &BezPath) -> String {
261 use kurbo::PathEl;
262
263 let mut data = String::new();
264 for element in path.elements() {
265 match element {
266 PathEl::MoveTo(point) => data.push_str(&format!("M{:.3},{:.3}", point.x, point.y)),
267 PathEl::LineTo(point) => data.push_str(&format!("L{:.3},{:.3}", point.x, point.y)),
268 PathEl::QuadTo(ctrl, point) => data.push_str(&format!(
269 "Q{:.3},{:.3} {:.3},{:.3}",
270 ctrl.x, ctrl.y, point.x, point.y
271 )),
272 PathEl::CurveTo(ctrl1, ctrl2, point) => data.push_str(&format!(
273 "C{:.3},{:.3} {:.3},{:.3} {:.3},{:.3}",
274 ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, point.x, point.y
275 )),
276 PathEl::ClosePath => data.push('Z'),
277 }
278 }
279 data
280}
281
282#[derive(Debug, Clone, Copy, PartialEq)]
284pub enum Layer {
285 Native,
287 NativeNonOccluding,
289 Canvas,
291 DontCare,
293}