use crate::renderer::{DrawCallHandle, Renderer};
use crate::types::*;
pub struct Sprite<'a, 'b> {
renderer: &'a mut Renderer,
call: &'b DrawCallHandle,
z: f32,
coords: (f32, f32, f32, f32),
texcoords: (f32, f32, f32, f32),
color: (f32, f32, f32, f32),
rotation: (f32, f32, f32),
clip_area: Option<(f32, f32, f32, f32)>,
}
impl<'a, 'b> Sprite<'a, 'b> {
pub(crate) fn new(renderer: &'a mut Renderer, call: &'b DrawCallHandle) -> Sprite<'a, 'b> {
Sprite {
renderer,
call,
z: 0.0,
coords: (0.0, 0.0, 0.0, 0.0),
texcoords: (-1.0, -1.0, -1.0, -1.0),
color: (1.0, 1.0, 1.0, 1.0),
rotation: (0.0, 0.0, 0.0),
clip_area: None,
}
}
pub fn finish(&mut self) {
if let Some(area) = self.clip_area {
self.renderer.draw_quad_clipped(
area,
self.coords,
self.texcoords,
self.color,
self.rotation,
self.z,
self.call,
);
} else {
self.renderer.draw_quad(
self.coords,
self.texcoords,
self.color,
self.rotation,
self.z,
self.call,
);
}
}
pub fn z(&mut self, z: f32) -> &mut Self {
self.z = z;
self
}
pub fn coordinates<R: Into<Rect>>(&mut self, rect: R) -> &mut Self {
self.coords = rect.into().into_corners();
self
}
pub fn physical_coordinates<R: Into<Rect>>(&mut self, rect: R) -> &mut Self {
let (x0, y0, x1, y1) = rect.into().into_corners();
let df = self.renderer.dpi_factor;
self.coords = (x0 / df, y0 / df, x1 / df, y1 / df);
self
}
pub fn texture_coordinates<R: Into<Rect>>(&mut self, rect: R) -> &mut Self {
let (tw, th) = self.renderer.get_texture_size(self.call);
let (tw, th) = (tw as f32, th as f32);
let (x0, y0, x1, y1) = rect.into().into_corners();
self.texcoords = (x0 / tw, y0 / th, x1 / tw, y1 / th);
self
}
pub fn pixel_alignment(&mut self) -> &mut Self {
let (x0, y0, x1, y1) = self.coords;
let dpi_factor = self.renderer.dpi_factor;
let round_px = |x: f32| (x * dpi_factor).round() / dpi_factor;
let (w, h) = (round_px(x1 - x0), round_px(y1 - y0));
let (x0, y0) = (round_px(x0), round_px(y0));
let (x1, y1) = (x0 + w, y0 + h);
self.coords = (x0, y0, x1, y1);
self
}
pub fn uvs<R: Into<Rect>>(&mut self, rect: R) -> &mut Self {
self.texcoords = rect.into().into_corners();
self
}
pub fn clip_area<R: Into<Rect>>(&mut self, rect: R) -> &mut Self {
self.clip_area = Some(rect.into().into_corners());
self
}
pub fn color(&mut self, (red, green, blue, alpha): (f32, f32, f32, f32)) -> &mut Self {
self.color = (red, green, blue, alpha);
self
}
pub fn rotation(&mut self, rotation: f32, pivot_x: f32, pivot_y: f32) -> &mut Self {
self.rotation = (rotation, pivot_x, pivot_y);
self
}
}