Skip to main content

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