scene.rs

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