1use crate::core::{
2 self, Background, Color, Point, Rectangle, Svg, Transformation, renderer,
3};
4use crate::graphics;
5use crate::graphics::Mesh;
6use crate::graphics::color;
7use crate::graphics::layer;
8use crate::graphics::text::{Editor, Paragraph};
9use crate::image::{self, Image};
10use crate::primitive::{self, Primitive};
11use crate::quad::{self, Quad};
12use crate::text::{self, Text};
13use crate::triangle;
14
15pub type Stack = layer::Stack<Layer>;
16
17#[derive(Debug)]
18pub struct Layer {
19 pub bounds: Rectangle,
20 pub quads: quad::Batch,
21 pub triangles: triangle::Batch,
22 pub primitives: primitive::Batch,
23 pub images: image::Batch,
24 pub text: text::Batch,
25 pending_meshes: Vec<Mesh>,
26 pending_text: Vec<Text>,
27}
28
29impl Layer {
30 pub fn is_empty(&self) -> bool {
31 self.quads.is_empty()
32 && self.triangles.is_empty()
33 && self.primitives.is_empty()
34 && self.images.is_empty()
35 && self.text.is_empty()
36 && self.pending_meshes.is_empty()
37 && self.pending_text.is_empty()
38 }
39
40 pub fn draw_quad(
41 &mut self,
42 quad: renderer::Quad,
43 background: Background,
44 transformation: Transformation,
45 ) {
46 let bounds = quad.bounds * transformation;
47
48 let quad = Quad {
49 position: [bounds.x, bounds.y],
50 size: [bounds.width, bounds.height],
51 border_color: color::pack(quad.border.color),
52 border_radius: quad.border.radius.into(),
53 border_width: quad.border.width,
54 shadow_color: color::pack(quad.shadow.color),
55 shadow_offset: quad.shadow.offset.into(),
56 shadow_blur_radius: quad.shadow.blur_radius,
57 };
58
59 self.quads.add(quad, &background);
60 }
61
62 pub fn draw_paragraph(
63 &mut self,
64 paragraph: &Paragraph,
65 position: Point,
66 color: Color,
67 clip_bounds: Rectangle,
68 transformation: Transformation,
69 ) {
70 let paragraph = Text::Paragraph {
71 paragraph: paragraph.downgrade(),
72 position,
73 color,
74 clip_bounds,
75 transformation,
76 };
77
78 self.pending_text.push(paragraph);
79 }
80
81 pub fn draw_editor(
82 &mut self,
83 editor: &Editor,
84 position: Point,
85 color: Color,
86 clip_bounds: Rectangle,
87 transformation: Transformation,
88 ) {
89 let editor = Text::Editor {
90 editor: editor.downgrade(),
91 position,
92 color,
93 clip_bounds,
94 transformation,
95 };
96
97 self.pending_text.push(editor);
98 }
99
100 pub fn draw_text(
101 &mut self,
102 text: crate::core::Text,
103 position: Point,
104 color: Color,
105 clip_bounds: Rectangle,
106 transformation: Transformation,
107 ) {
108 let text = Text::Cached {
109 content: text.content,
110 bounds: Rectangle::new(position, text.bounds) * transformation,
111 color,
112 size: text.size * transformation.scale_factor(),
113 line_height: text.line_height.to_absolute(text.size)
114 * transformation.scale_factor(),
115 font: text.font,
116 align_x: text.align_x,
117 align_y: text.align_y,
118 shaping: text.shaping,
119 clip_bounds: clip_bounds * transformation,
120 };
121
122 self.pending_text.push(text);
123 }
124
125 pub fn draw_image(&mut self, image: Image, transformation: Transformation) {
126 match image {
127 Image::Raster(image, bounds) => {
128 self.draw_raster(image, bounds, transformation);
129 }
130 Image::Vector(svg, bounds) => {
131 self.draw_svg(svg, bounds, transformation);
132 }
133 }
134 }
135
136 pub fn draw_raster(
137 &mut self,
138 image: core::Image,
139 bounds: Rectangle,
140 transformation: Transformation,
141 ) {
142 let image = Image::Raster(image, bounds * transformation);
143
144 self.images.push(image);
145 }
146
147 pub fn draw_svg(
148 &mut self,
149 svg: Svg,
150 bounds: Rectangle,
151 transformation: Transformation,
152 ) {
153 let svg = Image::Vector(svg, bounds * transformation);
154
155 self.images.push(svg);
156 }
157
158 pub fn draw_mesh(
159 &mut self,
160 mut mesh: Mesh,
161 transformation: Transformation,
162 ) {
163 match &mut mesh {
164 Mesh::Solid {
165 transformation: local_transformation,
166 ..
167 }
168 | Mesh::Gradient {
169 transformation: local_transformation,
170 ..
171 } => {
172 *local_transformation = *local_transformation * transformation;
173 }
174 }
175
176 self.pending_meshes.push(mesh);
177 }
178
179 pub fn draw_mesh_group(
180 &mut self,
181 meshes: Vec<Mesh>,
182 transformation: Transformation,
183 ) {
184 self.flush_meshes();
185
186 self.triangles.push(triangle::Item::Group {
187 meshes,
188 transformation,
189 });
190 }
191
192 pub fn draw_mesh_cache(
193 &mut self,
194 cache: triangle::Cache,
195 transformation: Transformation,
196 ) {
197 self.flush_meshes();
198
199 self.triangles.push(triangle::Item::Cached {
200 cache,
201 transformation,
202 });
203 }
204
205 pub fn draw_text_group(
206 &mut self,
207 text: Vec<Text>,
208 transformation: Transformation,
209 ) {
210 self.flush_text();
211
212 self.text.push(text::Item::Group {
213 text,
214 transformation,
215 });
216 }
217
218 pub fn draw_text_cache(
219 &mut self,
220 cache: text::Cache,
221 transformation: Transformation,
222 ) {
223 self.flush_text();
224
225 self.text.push(text::Item::Cached {
226 cache,
227 transformation,
228 });
229 }
230
231 pub fn draw_primitive(
232 &mut self,
233 bounds: Rectangle,
234 primitive: Box<dyn Primitive>,
235 transformation: Transformation,
236 ) {
237 let bounds = bounds * transformation;
238
239 self.primitives
240 .push(primitive::Instance { bounds, primitive });
241 }
242
243 fn flush_meshes(&mut self) {
244 if !self.pending_meshes.is_empty() {
245 self.triangles.push(triangle::Item::Group {
246 transformation: Transformation::IDENTITY,
247 meshes: self.pending_meshes.drain(..).collect(),
248 });
249 }
250 }
251
252 fn flush_text(&mut self) {
253 if !self.pending_text.is_empty() {
254 self.text.push(text::Item::Group {
255 transformation: Transformation::IDENTITY,
256 text: self.pending_text.drain(..).collect(),
257 });
258 }
259 }
260}
261
262impl graphics::Layer for Layer {
263 fn with_bounds(bounds: Rectangle) -> Self {
264 Self {
265 bounds,
266 ..Self::default()
267 }
268 }
269
270 fn flush(&mut self) {
271 self.flush_meshes();
272 self.flush_text();
273 }
274
275 fn resize(&mut self, bounds: Rectangle) {
276 self.bounds = bounds;
277 }
278
279 fn reset(&mut self) {
280 self.bounds = Rectangle::INFINITE;
281
282 self.quads.clear();
283 self.triangles.clear();
284 self.primitives.clear();
285 self.text.clear();
286 self.images.clear();
287 self.pending_meshes.clear();
288 self.pending_text.clear();
289 }
290}
291
292impl Default for Layer {
293 fn default() -> Self {
294 Self {
295 bounds: Rectangle::INFINITE,
296 quads: quad::Batch::default(),
297 triangles: triangle::Batch::default(),
298 primitives: primitive::Batch::default(),
299 text: text::Batch::default(),
300 images: image::Batch::default(),
301 pending_meshes: Vec::new(),
302 pending_text: Vec::new(),
303 }
304 }
305}