pix_engine/
renderer.rs

1//! Graphics renderer functions.
2
3use crate::{error::Result, image::Icon, prelude::*};
4use std::num::NonZeroUsize;
5
6pub(crate) use crate::{texture::TextureRenderer, window::WindowRenderer};
7
8#[cfg(not(target_arch = "wasm32"))]
9pub mod sdl;
10#[cfg(not(target_arch = "wasm32"))]
11pub(crate) use sdl::Renderer;
12
13#[cfg(target_arch = "wasm32")]
14pub mod wasm;
15#[cfg(target_arch = "wasm32")]
16pub(crate) use wasm::Renderer;
17
18const TEXTURE_CACHE_SIZE: usize = 256;
19const TEXT_CACHE_SIZE: usize = 512;
20
21/// Settings used to set up the renderer.
22#[derive(Debug, Clone)]
23pub(crate) struct RendererSettings {
24    /// Base window title.
25    pub(crate) title: String,
26    /// Application icon.
27    pub(crate) icon: Option<Icon>,
28    /// Starting window X coordinate.
29    pub(crate) x: Position,
30    /// Starting window Y coordinate.
31    pub(crate) y: Position,
32    /// Starting window width.
33    pub(crate) width: u32,
34    /// Starting window height.
35    pub(crate) height: u32,
36    /// Rendering scale for x-coordinates.
37    pub(crate) scale_x: f32,
38    /// Rendering scale for y-coordinates.
39    pub(crate) scale_y: f32,
40    /// Audio queue sample rate. `None` uses device default.
41    pub(crate) audio_sample_rate: Option<i32>,
42    /// Audio queue channel count. 1 for mono, 2 for stereo, etc. `None` uses device default.
43    pub(crate) audio_channels: Option<u8>,
44    /// Audio queue buffer size. `None` uses devide default.
45    pub(crate) audio_buffer_size: Option<u16>,
46    /// Window fullscreen mode.
47    pub(crate) fullscreen: bool,
48    /// Sync [`Engine::on_update`] rate with monitor refresh rate.
49    pub(crate) vsync: bool,
50    /// Enable window resizing.
51    pub(crate) resizable: bool,
52    /// Disable window borders.
53    pub(crate) borderless: bool,
54    /// Enable high resolution mode, if supported.
55    pub(crate) allow_highdpi: bool,
56    /// Hide window.
57    pub(crate) hidden: bool,
58    /// Show frame rate per second in title bar.
59    pub(crate) show_frame_rate: bool,
60    /// Limit [`Engine::on_update`] to target frame frate per second.
61    pub(crate) target_frame_rate: Option<usize>,
62    /// Size of allowed texture cache before least-used entries are evicted.
63    pub(crate) texture_cache_size: NonZeroUsize,
64    /// Size of allowed font cache before least-used entries are evicted.
65    pub(crate) text_cache_size: NonZeroUsize,
66}
67
68impl Default for RendererSettings {
69    #[allow(clippy::expect_used)]
70    fn default() -> Self {
71        Self {
72            title: String::new(),
73            icon: None,
74            x: Position::default(),
75            y: Position::default(),
76            width: 640,
77            height: 480,
78            scale_x: 1.0,
79            scale_y: 1.0,
80            audio_sample_rate: None,
81            audio_channels: None,
82            audio_buffer_size: None,
83            fullscreen: false,
84            vsync: false,
85            resizable: false,
86            borderless: false,
87            allow_highdpi: false,
88            hidden: false,
89            show_frame_rate: false,
90            target_frame_rate: None,
91            texture_cache_size: TEXTURE_CACHE_SIZE.try_into().expect("valid cache size"),
92            text_cache_size: TEXT_CACHE_SIZE.try_into().expect("valid cache size"),
93        }
94    }
95}
96
97/// Trait for operations on the underlying `Renderer`.
98pub(crate) trait Rendering: Sized {
99    /// Creates a new Renderer instance.
100    fn new(settings: RendererSettings) -> Result<Self>;
101
102    /// Clears the current canvas to the given clear color
103    fn clear(&mut self) -> Result<()>;
104
105    /// Sets the color used by the renderer to draw the current canvas.
106    fn set_draw_color(&mut self, color: Color) -> Result<()>;
107
108    /// Sets the clip rect used by the renderer to draw to the current canvas.
109    fn clip(&mut self, rect: Option<Rect<i32>>) -> Result<()>;
110
111    /// Sets the blend mode used by the renderer to drawing.
112    fn blend_mode(&mut self, mode: BlendMode);
113
114    /// Updates the canvas from the current back buffer.
115    fn present(&mut self);
116
117    /// Set the rendering scale of the current canvas. Drawing coordinates are scaled by x/y
118    /// factors before being drawn to the canvas.
119    fn scale(&mut self, x: f32, y: f32) -> Result<()>;
120
121    /// Set the font size for drawing text to the current canvas.
122    fn font_size(&mut self, size: u32) -> Result<()>;
123
124    /// Set the font style for drawing text to the current canvas.
125    fn font_style(&mut self, style: FontStyle);
126
127    /// Set the font family for drawing text to the current canvas.
128    fn font_family(&mut self, font: &Font) -> Result<()>;
129
130    /// Get clipboard text from the system clipboard.
131    fn clipboard_text(&self) -> String;
132
133    /// Set clipboard text to the system clipboard.
134    fn set_clipboard_text(&self, value: &str) -> Result<()>;
135
136    /// Open a URL in the default system browser.
137    fn open_url(&self, url: &str) -> Result<()>;
138
139    /// Draw text to the current canvas. `angle` must be in degrees.
140    #[allow(clippy::too_many_arguments)]
141    fn text(
142        &mut self,
143        position: Point<i32>,
144        text: &str,
145        wrap_width: Option<u32>,
146        angle: Option<f64>,
147        center: Option<Point<i32>>,
148        flipped: Option<Flipped>,
149        fill: Option<Color>,
150        outline: u16,
151    ) -> Result<(u32, u32)>;
152
153    /// Returns the rendered dimensions of the given text using the current font
154    /// as `(width, height)`.
155    fn size_of(&self, text: &str, wrap_width: Option<u32>) -> Result<(u32, u32)>;
156
157    /// Draw a pixel to the current canvas.
158    fn point(&mut self, p: Point<i32>, color: Color) -> Result<()>;
159
160    /// Draw a line to the current canvas.
161    fn line(&mut self, line: Line<i32>, smooth: bool, width: u8, color: Color) -> Result<()>;
162
163    /// Draw a cubic Bezier curve to the current canvas.
164    fn bezier<I>(&mut self, ps: I, detail: i32, stroke: Option<Color>) -> Result<()>
165    where
166        I: Iterator<Item = Point<i32>>;
167
168    /// Draw a triangle to the current canvas.
169    fn triangle(
170        &mut self,
171        tri: Tri<i32>,
172        smooth: bool,
173        fill: Option<Color>,
174        stroke: Option<Color>,
175    ) -> Result<()>;
176
177    /// Draw a rectangle to the current canvas.
178    fn rect(
179        &mut self,
180        rect: Rect<i32>,
181        radius: Option<i32>,
182        fill: Option<Color>,
183        stroke: Option<Color>,
184    ) -> Result<()>;
185
186    /// Draw a quadrilateral to the current canvas.
187    fn quad(
188        &mut self,
189        quad: Quad<i32>,
190        smooth: bool,
191        fill: Option<Color>,
192        stroke: Option<Color>,
193    ) -> Result<()>;
194
195    /// Draw a polygon to the current canvas.
196    fn polygon<I>(
197        &mut self,
198        ps: I,
199        smooth: bool,
200        fill: Option<Color>,
201        stroke: Option<Color>,
202    ) -> Result<()>
203    where
204        I: Iterator<Item = Point<i32>>;
205
206    /// Draw a ellipse to the current canvas.
207    fn ellipse(
208        &mut self,
209        ellipse: Ellipse<i32>,
210        smooth: bool,
211        fill: Option<Color>,
212        stroke: Option<Color>,
213    ) -> Result<()>;
214
215    /// Draw an arc to the current canvas.
216    #[allow(clippy::too_many_arguments)]
217    fn arc(
218        &mut self,
219        p: Point<i32>,
220        radius: i32,
221        start: i32,
222        end: i32,
223        mode: ArcMode,
224        fill: Option<Color>,
225        stroke: Option<Color>,
226    ) -> Result<()>;
227
228    /// Draw an image to the current canvas, optionally rotated about a `center`, flipped or
229    /// tinted. `angle` must be in degrees.
230    #[allow(clippy::too_many_arguments)]
231    fn image(
232        &mut self,
233        img: &Image,
234        src: Option<Rect<i32>>,
235        dst: Option<Rect<i32>>,
236        angle: f64,
237        center: Option<Point<i32>>,
238        flipped: Option<Flipped>,
239        tint: Option<Color>,
240    ) -> Result<()>;
241
242    /// Return the current rendered target pixels as an array of bytes.
243    fn to_bytes(&mut self) -> Result<Vec<u8>>;
244
245    /// Connect a controller with the given joystick index to start receiving events.
246    fn open_controller(&mut self, controller_id: ControllerId) -> Result<()>;
247
248    /// Disconnect a controller with the given joystick index to stop receiving events.
249    fn close_controller(&mut self, controller_id: ControllerId);
250}