Skip to main content

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}