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}