scene.rs

  1use std::mem;
  2
  3use super::{Bounds, Hsla, Pixels, Point};
  4use crate::{Corners, Edges};
  5use bytemuck::{Pod, Zeroable};
  6use collections::BTreeMap;
  7
  8// Exported to metal
  9pub type PointF = Point<f32>;
 10
 11#[derive(Debug)]
 12pub struct Scene {
 13    layers: BTreeMap<u32, SceneLayer>,
 14    pub(crate) scale_factor: f32,
 15}
 16
 17#[derive(Default, Debug)]
 18pub struct SceneLayer {
 19    pub quads: Vec<Quad>,
 20}
 21
 22impl Scene {
 23    pub fn new(scale_factor: f32) -> Scene {
 24        Scene {
 25            layers: Default::default(),
 26            scale_factor,
 27        }
 28    }
 29
 30    pub fn take(&mut self) -> Scene {
 31        Scene {
 32            layers: mem::take(&mut self.layers),
 33            scale_factor: self.scale_factor,
 34        }
 35    }
 36
 37    pub fn insert(&mut self, primitive: impl Into<Primitive>) {
 38        let mut primitive = primitive.into();
 39        primitive.scale(self.scale_factor);
 40        let layer = self.layers.entry(primitive.order()).or_default();
 41        match primitive {
 42            Primitive::Quad(quad) => layer.quads.push(quad),
 43        }
 44    }
 45
 46    pub fn layers(&self) -> impl Iterator<Item = &SceneLayer> {
 47        self.layers.values()
 48    }
 49}
 50
 51#[derive(Clone, Debug)]
 52pub enum Primitive {
 53    Quad(Quad),
 54}
 55
 56impl Primitive {
 57    pub fn order(&self) -> u32 {
 58        match self {
 59            Primitive::Quad(quad) => quad.order,
 60        }
 61    }
 62
 63    pub fn is_transparent(&self) -> bool {
 64        match self {
 65            Primitive::Quad(quad) => {
 66                quad.background.is_transparent() && quad.border_color.is_transparent()
 67            }
 68        }
 69    }
 70
 71    pub fn scale(&mut self, factor: f32) {
 72        match self {
 73            Primitive::Quad(quad) => {
 74                quad.scale(factor);
 75            }
 76        }
 77    }
 78}
 79
 80#[derive(Debug, Clone, Copy, Zeroable, Pod)]
 81#[repr(C)]
 82pub struct Quad {
 83    pub order: u32,
 84    pub bounds: Bounds<Pixels>,
 85    pub clip_bounds: Bounds<Pixels>,
 86    pub clip_corner_radii: Corners<Pixels>,
 87    pub background: Hsla,
 88    pub border_color: Hsla,
 89    pub corner_radii: Corners<Pixels>,
 90    pub border_widths: Edges<Pixels>,
 91}
 92
 93impl Quad {
 94    pub fn vertices(&self) -> impl Iterator<Item = Point<Pixels>> {
 95        let x1 = self.bounds.origin.x;
 96        let y1 = self.bounds.origin.y;
 97        let x2 = x1 + self.bounds.size.width;
 98        let y2 = y1 + self.bounds.size.height;
 99        [
100            Point::new(x1, y1),
101            Point::new(x2, y1),
102            Point::new(x2, y2),
103            Point::new(x1, y2),
104        ]
105        .into_iter()
106    }
107
108    pub fn scale(&mut self, factor: f32) {
109        self.bounds *= factor;
110        self.clip_bounds *= factor;
111        self.clip_corner_radii *= factor;
112        self.corner_radii *= factor;
113        self.border_widths *= factor;
114    }
115}
116
117impl From<Quad> for Primitive {
118    fn from(quad: Quad) -> Self {
119        Primitive::Quad(quad)
120    }
121}