maycoon_core/vgi/mod.rs
1use nalgebra::Vector2;
2use std::any::Any;
3use std::error::Error;
4use std::fmt::Debug;
5use std::sync::Arc;
6use winit::event_loop::ActiveEventLoop;
7use winit::window::Window;
8
9use crate::vgi::kurbo::{
10 Affine, Circle, CircleSegment, CubicBez, Ellipse, QuadBez, Rect, RoundedRect, Stroke, Triangle,
11};
12pub use peniko::*;
13
14#[cfg(feature = "svg")]
15pub use usvg as svg;
16
17/// Contains the [vello::VectorGraphicsInterface] which uses [vello] as the backend.
18///
19/// This is the recommended graphics backend.
20///
21/// Requires the `vello-vg` feature (enabled by default).
22#[cfg(feature = "vello-vg")]
23pub mod vello;
24
25/// Contains the [dummy::DummyGraphics] & [dummy::DummyGraphics] structs.
26///
27/// Useful for testing.
28pub mod dummy;
29
30/// The default graphics backend for maycoon.
31///
32/// See [vello::VectorGraphicsInterface] for more.
33///
34/// Requires the `vello-vg` feature (enabled by default).
35#[cfg(feature = "vello-vg")]
36pub type DefaultGraphics = vello::VectorGraphicsInterface;
37
38/// A trait describing ways to render vector graphics.
39///
40/// This is a universal interface for 2D vector graphics rendering.
41pub trait VectorGraphicsInterface: Debug + 'static {
42 /// The error used by most graphics operations.
43 type Error: Error;
44 /// A direct interface for drawing vector graphics using this interface.
45 type Scene: Scene;
46 /// A configuration struct for initializing the interface.
47 type Config: Debug + Default + Clone;
48
49 /// Creates a new vector graphics interface using the given configuration.
50 ///
51 /// Returns an [Err] if the interface could not be created.
52 fn new(config: Self::Config) -> Result<Self, Self::Error>
53 where
54 Self: Sized;
55
56 /// Initializes the interface.
57 ///
58 /// This will be called on [winit::event::Event::Resumed] to initialize the graphics interface.
59 ///
60 /// Returns an [Err] if the interface could not be initialized.
61 fn init(
62 &mut self,
63 window: Arc<Window>,
64 event_loop: &ActiveEventLoop,
65 ) -> Result<(), Self::Error>;
66
67 /// Renders the scene to the window.
68 ///
69 /// This method should render the scene on a window surface and **present** the surface too.
70 ///
71 /// Returns an [Err] if the scene could not be rendered.
72 fn render(
73 &mut self,
74 window: Arc<Window>,
75 event_loop: &ActiveEventLoop,
76 scene: &Self::Scene,
77 bg_color: Color,
78 ) -> Result<(), Self::Error>;
79
80 /// Resizes the window.
81 ///
82 /// This method should resize the window surface to the given size.
83 ///
84 /// **NOTE**: Do not resize the window itself. This is already done automatically.
85 ///
86 /// Returns an [Err] if the window could not be resized.
87 fn resize(
88 &mut self,
89 window: Arc<Window>,
90 event_loop: &ActiveEventLoop,
91 size: Vector2<u32>,
92 ) -> Result<(), Self::Error>;
93
94 /// Uninitializes the interface.
95 ///
96 /// This will be called on [winit::event::Event::Suspended] to uninitialize the graphics interface.
97 ///
98 /// Returns an [Err] if the interface could not be uninitialized.
99 fn uninit(
100 &mut self,
101 window: Arc<Window>,
102 event_loop: &ActiveEventLoop,
103 ) -> Result<(), Self::Error>;
104
105 /// Destroys the interface.
106 ///
107 /// This will be called on [winit::event::WindowEvent::Destroyed] to destroy the graphics interface.
108 ///
109 /// Returns an [Err] if the interface could not be destroyed.
110 fn destroy(
111 &mut self,
112 window: Arc<Window>,
113 event_loop: &ActiveEventLoop,
114 ) -> Result<(), Self::Error>;
115}
116
117/// An interface for drawing vector graphics onto a canvas.
118///
119/// Must be provided by the [VectorGraphicsInterface].
120pub trait Scene: 'static {
121 /// Creates a new empty scene.
122 fn new() -> Self
123 where
124 Self: Sized;
125
126 /// Returns this [Scene] as an [Any] reference.
127 fn as_any(&self) -> &dyn Any;
128
129 /// Returns this [Scene] as a mutable [Any] reference.
130 fn as_any_mut(&mut self) -> &mut dyn Any;
131
132 /// Clones this [Scene] and returns it boxed.
133 ///
134 /// Used to keep object safety while allowing the scene to be cloned.
135 fn dyn_clone(&self) -> Box<dyn Scene>;
136
137 /// Resets the [Scene] to its initial state.
138 ///
139 /// This scene should be equal to [Scene::new] after this call.
140 fn reset(&mut self);
141
142 /// Appends the given [Scene] to this [Scene].
143 ///
144 /// Apply an optional transform to the scene.
145 fn append(&mut self, other: &dyn Scene, transform: Option<Affine>);
146
147 /// Draws a rectangle onto the [Scene] with the given brush.
148 ///
149 /// Apply an optional transform to the rectangle.
150 ///
151 /// Optionally, strokes and does not fill the rectangle.
152 fn draw_rect(
153 &mut self,
154 brush: &Brush,
155 transform: Option<Affine>,
156 stroke: Option<&Stroke>,
157 rect: &Rect,
158 );
159
160 /// Draws a rounded rectangle onto the [Scene] with the given brush.
161 ///
162 /// Apply an optional transform to the rectangle.
163 ///
164 /// Optionally, strokes and does not fill the rectangle.
165 fn draw_rounded_rect(
166 &mut self,
167 brush: &Brush,
168 transform: Option<Affine>,
169 stroke: Option<&Stroke>,
170 rect: &RoundedRect,
171 );
172
173 /// Draws a circle onto the [Scene] with the given brush.
174 ///
175 /// Apply an optional transform to the circle.
176 ///
177 /// Optionally, strokes and does not fill the circle.
178 fn draw_circle(
179 &mut self,
180 brush: &Brush,
181 transform: Option<Affine>,
182 stroke: Option<&Stroke>,
183 circle: &Circle,
184 );
185
186 /// Draws a circle segment onto the [Scene] with the given brush.
187 ///
188 /// Apply an optional transform to the circle segment.
189 ///
190 /// Optionally, strokes and does not fill the circle segment.
191 fn draw_circle_segment(
192 &mut self,
193 brush: &Brush,
194 transform: Option<Affine>,
195 stroke: Option<&Stroke>,
196 circle_segment: &CircleSegment,
197 );
198
199 /// Draws an ellipse onto the [Scene] with the given brush.
200 ///
201 /// Apply an optional transform to the ellipse.
202 ///
203 /// Optionally, strokes and does not fill the ellipse.
204 fn draw_ellipse(
205 &mut self,
206 brush: &Brush,
207 transform: Option<Affine>,
208 stroke: Option<&Stroke>,
209 ellipse: &Ellipse,
210 );
211
212 /// Draws a cubic bezier onto the [Scene] with the given brush.
213 ///
214 /// Apply an optional transform to the cubic bezier.
215 ///
216 /// Optionally, strokes and does not fill the cubic bezier.
217 fn draw_cubic_bezier(
218 &mut self,
219 brush: &Brush,
220 transform: Option<Affine>,
221 stroke: Option<&Stroke>,
222 cubic_bez: &CubicBez,
223 );
224
225 /// Draws a quadratic bezier onto the [Scene] with the given brush.
226 ///
227 /// Apply an optional transform to the quadratic bezier.
228 ///
229 /// Optionally, strokes and does not fill the quadratic bezier.
230 fn draw_quadratic_bezier(
231 &mut self,
232 brush: &Brush,
233 transform: Option<Affine>,
234 stroke: Option<&Stroke>,
235 quad_bez: &QuadBez,
236 );
237
238 /// Draws a triangle onto the [Scene] with the given brush.
239 ///
240 /// Apply an optional transform to the triangle.
241 ///
242 /// Optionally, strokes and does not fill the triangle.
243 fn draw_triangle(
244 &mut self,
245 brush: &Brush,
246 transform: Option<Affine>,
247 stroke: Option<&Stroke>,
248 triangle: &Triangle,
249 );
250
251 /// Draws an image onto the [Scene] with the given brush.
252 ///
253 /// Apply an optional transform to the image (after the position is inserted).
254 fn draw_image(&mut self, img: &ImageBrush, transform: Option<Affine>, position: Vector2<f32>);
255
256 /// Draws text onto the [Scene] with the given brush.
257 ///
258 /// Apply an optional transform to the text (after the position is inserted).
259 ///
260 /// You can also specify hinting, size, and the line gap.
261 ///
262 /// Furthermore, you can choose if the text should be wrapped by passing `max_width`.
263 fn draw_text(
264 &mut self,
265 brush: &Brush,
266 transform: Option<Affine>,
267 position: Vector2<f32>,
268 text: &str,
269 hinting: bool,
270 font: &FontData,
271 size: f32,
272 line_gap: f32,
273 max_width: f32,
274 );
275
276 // TODO: add `Affine` transform arg as soon as vello_svg supports it
277 /// Draws an SVG onto the [Scene] with an optional transform.
278 ///
279 /// Only enabled if the [svg] feature is enabled.
280 #[cfg(feature = "svg")]
281 fn draw_svg(&mut self, svg: &usvg::Tree, transform: Option<Affine>);
282}