iced_core/renderer.rs
1//! Write your own renderer.
2mod null;
3
4use crate::image;
5use crate::{
6 Background, Border, Color, Font, Pixels, Rectangle, Shadow, Size, Transformation, Vector,
7};
8
9/// Whether anti-aliasing should be avoided by snapping primitive coordinates to the
10/// pixel grid.
11pub const CRISP: bool = cfg!(feature = "crisp");
12
13/// A component that can be used by widgets to draw themselves on a screen.
14pub trait Renderer {
15 /// Starts recording a new layer.
16 fn start_layer(&mut self, bounds: Rectangle);
17
18 /// Ends recording a new layer.
19 ///
20 /// The new layer will clip its contents to the provided `bounds`.
21 fn end_layer(&mut self);
22
23 /// Draws the primitives recorded in the given closure in a new layer.
24 ///
25 /// The layer will clip its contents to the provided `bounds`.
26 fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) {
27 self.start_layer(bounds);
28 f(self);
29 self.end_layer();
30 }
31
32 /// Starts recording with a new [`Transformation`].
33 fn start_transformation(&mut self, transformation: Transformation);
34
35 /// Ends recording a new layer.
36 ///
37 /// The new layer will clip its contents to the provided `bounds`.
38 fn end_transformation(&mut self);
39
40 /// Applies a [`Transformation`] to the primitives recorded in the given closure.
41 fn with_transformation(&mut self, transformation: Transformation, f: impl FnOnce(&mut Self)) {
42 self.start_transformation(transformation);
43 f(self);
44 self.end_transformation();
45 }
46
47 /// Applies a translation to the primitives recorded in the given closure.
48 fn with_translation(&mut self, translation: Vector, f: impl FnOnce(&mut Self)) {
49 self.with_transformation(Transformation::translate(translation.x, translation.y), f);
50 }
51
52 /// Fills a [`Quad`] with the provided [`Background`].
53 fn fill_quad(&mut self, quad: Quad, background: impl Into<Background>);
54
55 /// Creates an [`image::Allocation`] for the given [`image::Handle`] and calls the given callback with it.
56 fn allocate_image(
57 &mut self,
58 handle: &image::Handle,
59 callback: impl FnOnce(Result<image::Allocation, image::Error>) + Send + 'static,
60 );
61
62 /// Provides hints to the [`Renderer`] about the rendering target.
63 ///
64 /// This may be used internally by the [`Renderer`] to perform optimizations
65 /// and/or improve rendering quality.
66 ///
67 /// For instance, providing a `scale_factor` may be used by some renderers to
68 /// perform metrics hinting internally in physical coordinates while keeping
69 /// layout coordinates logical and, therefore, maintain linearity.
70 fn hint(&mut self, scale_factor: f32);
71
72 /// Returns the last scale factor provided as a [`hint`](Self::hint).
73 fn scale_factor(&self) -> Option<f32>;
74
75 /// Resets the [`Renderer`] to start drawing in the `new_bounds` from scratch.
76 fn reset(&mut self, new_bounds: Rectangle);
77
78 /// Polls any concurrent computations that may be pending in the [`Renderer`].
79 ///
80 /// By default, it does nothing.
81 fn tick(&mut self) {}
82}
83
84/// A polygon with four sides.
85#[derive(Debug, Clone, Copy, PartialEq)]
86pub struct Quad {
87 /// The bounds of the [`Quad`].
88 pub bounds: Rectangle,
89
90 /// The [`Border`] of the [`Quad`]. The border is drawn on the inside of the [`Quad`].
91 pub border: Border,
92
93 /// The [`Shadow`] of the [`Quad`].
94 pub shadow: Shadow,
95
96 /// Whether the [`Quad`] should be snapped to the pixel grid.
97 pub snap: bool,
98}
99
100impl Default for Quad {
101 fn default() -> Self {
102 Self {
103 bounds: Rectangle::with_size(Size::ZERO),
104 border: Border::default(),
105 shadow: Shadow::default(),
106 snap: CRISP,
107 }
108 }
109}
110
111/// The styling attributes of a [`Renderer`].
112#[derive(Debug, Clone, Copy, PartialEq)]
113pub struct Style {
114 /// The text color
115 pub text_color: Color,
116}
117
118impl Default for Style {
119 fn default() -> Self {
120 Style {
121 text_color: Color::BLACK,
122 }
123 }
124}
125
126/// A headless renderer is a renderer that can render offscreen without
127/// a window nor a compositor.
128pub trait Headless {
129 /// Creates a new [`Headless`] renderer;
130 fn new(settings: Settings, backend: Option<&str>) -> impl Future<Output = Option<Self>>
131 where
132 Self: Sized;
133
134 /// Returns the unique name of the renderer.
135 ///
136 /// This name may be used by testing libraries to uniquely identify
137 /// snapshots.
138 fn name(&self) -> String;
139
140 /// Draws offscreen into a screenshot, returning a collection of
141 /// bytes representing the rendered pixels in RGBA order.
142 fn screenshot(
143 &mut self,
144 size: Size<u32>,
145 scale_factor: f32,
146 background_color: Color,
147 ) -> Vec<u8>;
148}
149
150/// The settings of a [`Renderer`].
151#[derive(Debug, Clone, Copy, PartialEq)]
152pub struct Settings {
153 /// The default [`Font`] to use.
154 pub default_font: Font,
155
156 /// The default size of text.
157 ///
158 /// By default, it will be set to `16.0`.
159 pub default_text_size: Pixels,
160}
161
162impl Default for Settings {
163 fn default() -> Self {
164 Self {
165 default_font: Font::DEFAULT,
166 default_text_size: Pixels(16.0),
167 }
168 }
169}