iced_core/renderer.rs
1//! Write your own renderer.
2#[cfg(debug_assertions)]
3mod null;
4
5use crate::{
6 Background, Border, Color, Font, Pixels, Rectangle, Shadow, Size,
7 Transformation, Vector,
8};
9
10/// A component that can be used by widgets to draw themselves on a screen.
11pub trait Renderer {
12 /// Starts recording a new layer.
13 fn start_layer(&mut self, bounds: Rectangle);
14
15 /// Ends recording a new layer.
16 ///
17 /// The new layer will clip its contents to the provided `bounds`.
18 fn end_layer(&mut self);
19
20 /// Draws the primitives recorded in the given closure in a new layer.
21 ///
22 /// The layer will clip its contents to the provided `bounds`.
23 fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) {
24 self.start_layer(bounds);
25 f(self);
26 self.end_layer();
27 }
28
29 /// Starts recording with a new [`Transformation`].
30 fn start_transformation(&mut self, transformation: Transformation);
31
32 /// Ends recording a new layer.
33 ///
34 /// The new layer will clip its contents to the provided `bounds`.
35 fn end_transformation(&mut self);
36
37 /// Applies a [`Transformation`] to the primitives recorded in the given closure.
38 fn with_transformation(
39 &mut self,
40 transformation: Transformation,
41 f: impl FnOnce(&mut Self),
42 ) {
43 self.start_transformation(transformation);
44 f(self);
45 self.end_transformation();
46 }
47
48 /// Applies a translation to the primitives recorded in the given closure.
49 fn with_translation(
50 &mut self,
51 translation: Vector,
52 f: impl FnOnce(&mut Self),
53 ) {
54 self.with_transformation(
55 Transformation::translate(translation.x, translation.y),
56 f,
57 );
58 }
59
60 /// Fills a [`Quad`] with the provided [`Background`].
61 fn fill_quad(&mut self, quad: Quad, background: impl Into<Background>);
62
63 /// Clears all of the recorded primitives in the [`Renderer`].
64 fn clear(&mut self);
65}
66
67/// A polygon with four sides.
68#[derive(Debug, Clone, Copy, PartialEq)]
69pub struct Quad {
70 /// The bounds of the [`Quad`].
71 pub bounds: Rectangle,
72
73 /// The [`Border`] of the [`Quad`]. The border is drawn on the inside of the [`Quad`].
74 pub border: Border,
75
76 /// The [`Shadow`] of the [`Quad`].
77 pub shadow: Shadow,
78
79 /// Whether the [`Quad`] should be snapped to the pixel grid.
80 pub snap: bool,
81}
82
83impl Default for Quad {
84 fn default() -> Self {
85 Self {
86 bounds: Rectangle::with_size(Size::ZERO),
87 border: Border::default(),
88 shadow: Shadow::default(),
89 snap: cfg!(feature = "crisp"),
90 }
91 }
92}
93
94/// The styling attributes of a [`Renderer`].
95#[derive(Debug, Clone, Copy, PartialEq)]
96pub struct Style {
97 /// The text color
98 pub text_color: Color,
99}
100
101impl Default for Style {
102 fn default() -> Self {
103 Style {
104 text_color: Color::BLACK,
105 }
106 }
107}
108
109/// A headless renderer is a renderer that can render offscreen without
110/// a window nor a compositor.
111pub trait Headless {
112 /// Creates a new [`Headless`] renderer;
113 fn new(
114 default_font: Font,
115 default_text_size: Pixels,
116 backend: Option<&str>,
117 ) -> impl Future<Output = Option<Self>>
118 where
119 Self: Sized;
120
121 /// Returns the unique name of the renderer.
122 ///
123 /// This name may be used by testing libraries to uniquely identify
124 /// snapshots.
125 fn name(&self) -> String;
126
127 /// Draws offscreen into a screenshot, returning a collection of
128 /// bytes representing the rendered pixels in RGBA order.
129 fn screenshot(
130 &mut self,
131 size: Size<u32>,
132 scale_factor: f32,
133 background_color: Color,
134 ) -> Vec<u8>;
135}