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