iced_core/
renderer.rs

1//! Write your own renderer.
2#[cfg(debug_assertions)]
3mod null;
4
5use crate::image;
6use crate::{
7    Background, Border, Color, Font, Pixels, Rectangle, Shadow, Size, 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(&mut self, transformation: Transformation, f: impl FnOnce(&mut Self)) {
39        self.start_transformation(transformation);
40        f(self);
41        self.end_transformation();
42    }
43
44    /// Applies a translation to the primitives recorded in the given closure.
45    fn with_translation(&mut self, translation: Vector, f: impl FnOnce(&mut Self)) {
46        self.with_transformation(Transformation::translate(translation.x, translation.y), f);
47    }
48
49    /// Fills a [`Quad`] with the provided [`Background`].
50    fn fill_quad(&mut self, quad: Quad, background: impl Into<Background>);
51
52    /// Resets the [`Renderer`] to start drawing in the `new_bounds` from scratch.
53    fn reset(&mut self, new_bounds: Rectangle);
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
63/// A polygon with four sides.
64#[derive(Debug, Clone, Copy, PartialEq)]
65pub struct Quad {
66    /// The bounds of the [`Quad`].
67    pub bounds: Rectangle,
68
69    /// The [`Border`] of the [`Quad`]. The border is drawn on the inside of the [`Quad`].
70    pub border: Border,
71
72    /// The [`Shadow`] of the [`Quad`].
73    pub shadow: Shadow,
74
75    /// Whether the [`Quad`] should be snapped to the pixel grid.
76    pub snap: bool,
77}
78
79impl Default for Quad {
80    fn default() -> Self {
81        Self {
82            bounds: Rectangle::with_size(Size::ZERO),
83            border: Border::default(),
84            shadow: Shadow::default(),
85            snap: cfg!(feature = "crisp"),
86        }
87    }
88}
89
90/// The styling attributes of a [`Renderer`].
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub struct Style {
93    /// The text color
94    pub text_color: Color,
95}
96
97impl Default for Style {
98    fn default() -> Self {
99        Style {
100            text_color: Color::BLACK,
101        }
102    }
103}
104
105/// A headless renderer is a renderer that can render offscreen without
106/// a window nor a compositor.
107pub trait Headless {
108    /// Creates a new [`Headless`] renderer;
109    fn new(
110        default_font: Font,
111        default_text_size: Pixels,
112        backend: Option<&str>,
113    ) -> impl Future<Output = Option<Self>>
114    where
115        Self: Sized;
116
117    /// Returns the unique name of the renderer.
118    ///
119    /// This name may be used by testing libraries to uniquely identify
120    /// snapshots.
121    fn name(&self) -> String;
122
123    /// Draws offscreen into a screenshot, returning a collection of
124    /// bytes representing the rendered pixels in RGBA order.
125    fn screenshot(
126        &mut self,
127        size: Size<u32>,
128        scale_factor: f32,
129        background_color: Color,
130    ) -> Vec<u8>;
131}