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