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::mesh;
9use crate::graphics::text::{Editor, Paragraph};
10use crate::image::{self, Image};
11use crate::primitive::{self, Primitive};
12use crate::quad::{self, Quad};
13use crate::text::{self, Text};
14use crate::triangle;
15
16pub type Stack = layer::Stack<Layer>;
17
18#[derive(Debug)]
19pub struct Layer {
20 pub bounds: Rectangle,
21 pub quads: quad::Batch,
22 pub triangles: triangle::Batch,
23 pub primitives: primitive::Batch,
24 pub images: image::Batch,
25 pub text: text::Batch,
26 pending_meshes: Vec<Mesh>,
27 pending_text: Vec<Text>,
28}
29
30impl Layer {
31 pub fn is_empty(&self) -> bool {
32 self.quads.is_empty()
33 && self.triangles.is_empty()
34 && self.primitives.is_empty()
35 && self.images.is_empty()
36 && self.text.is_empty()
37 && self.pending_meshes.is_empty()
38 && self.pending_text.is_empty()
39 }
40
41 pub fn draw_quad(
42 &mut self,
43 quad: renderer::Quad,
44 background: Background,
45 transformation: Transformation,
46 ) {
47 let bounds = quad.bounds * transformation;
48
49 let quad = Quad {
50 position: [bounds.x, bounds.y],
51 size: [bounds.width, bounds.height],
52 border_color: color::pack(quad.border.color),
53 border_radius: (quad.border.radius * transformation.scale_factor())
54 .into(),
55 border_width: quad.border.width * transformation.scale_factor(),
56 shadow_color: color::pack(quad.shadow.color),
57 shadow_offset: (quad.shadow.offset * transformation.scale_factor())
58 .into(),
59 shadow_blur_radius: quad.shadow.blur_radius
60 * transformation.scale_factor(),
61 snap: quad.snap as u32,
62 };
63
64 self.quads.add(quad, &background);
65 }
66
67 pub fn draw_paragraph(
68 &mut self,
69 paragraph: &Paragraph,
70 position: Point,
71 color: Color,
72 clip_bounds: Rectangle,
73 transformation: Transformation,
74 ) {
75 let paragraph = Text::Paragraph {
76 paragraph: paragraph.downgrade(),
77 position,
78 color,
79 clip_bounds,
80 transformation,
81 };
82
83 self.pending_text.push(paragraph);
84 }
85
86 pub fn draw_editor(
87 &mut self,
88 editor: &Editor,
89 position: Point,
90 color: Color,
91 clip_bounds: Rectangle,
92 transformation: Transformation,
93 ) {
94 let editor = Text::Editor {
95 editor: editor.downgrade(),
96 position,
97 color,
98 clip_bounds,
99 transformation,
100 };
101
102 self.pending_text.push(editor);
103 }
104
105 pub fn draw_text(
106 &mut self,
107 text: crate::core::Text,
108 position: Point,
109 color: Color,
110 clip_bounds: Rectangle,
111 transformation: Transformation,
112 ) {
113 let text = Text::Cached {
114 content: text.content,
115 bounds: Rectangle::new(position, text.bounds) * transformation,
116 color,
117 size: text.size * transformation.scale_factor(),
118 line_height: text.line_height.to_absolute(text.size)
119 * transformation.scale_factor(),
120 font: text.font,
121 align_x: text.align_x,
122 align_y: text.align_y,
123 shaping: text.shaping,
124 clip_bounds: clip_bounds * transformation,
125 };
126
127 self.pending_text.push(text);
128 }
129
130 pub fn draw_text_raw(
131 &mut self,
132 raw: graphics::text::Raw,
133 transformation: Transformation,
134 ) {
135 let raw = Text::Raw {
136 raw,
137 transformation,
138 };
139
140 self.pending_text.push(raw);
141 }
142
143 pub fn draw_image(&mut self, image: Image, transformation: Transformation) {
144 match image {
145 Image::Raster {
146 image,
147 bounds,
148 clip_bounds,
149 } => {
150 self.draw_raster(image, bounds, clip_bounds, transformation);
151 }
152 Image::Vector {
153 svg,
154 bounds,
155 clip_bounds,
156 } => {
157 self.draw_svg(svg, bounds, clip_bounds, transformation);
158 }
159 }
160 }
161
162 pub fn draw_raster(
163 &mut self,
164 image: core::Image,
165 bounds: Rectangle,
166 clip_bounds: Rectangle,
167 transformation: Transformation,
168 ) {
169 let image = Image::Raster {
170 image: core::Image {
171 border_radius: image.border_radius
172 * transformation.scale_factor(),
173 ..image
174 },
175 bounds: bounds * transformation,
176 clip_bounds: clip_bounds * transformation,
177 };
178
179 self.images.push(image);
180 }
181
182 pub fn draw_svg(
183 &mut self,
184 svg: Svg,
185 bounds: Rectangle,
186 clip_bounds: Rectangle,
187 transformation: Transformation,
188 ) {
189 let svg = Image::Vector {
190 svg,
191 bounds: bounds * transformation,
192 clip_bounds: clip_bounds * transformation,
193 };
194
195 self.images.push(svg);
196 }
197
198 pub fn draw_mesh(
199 &mut self,
200 mut mesh: Mesh,
201 transformation: Transformation,
202 ) {
203 match &mut mesh {
204 Mesh::Solid {
205 transformation: local_transformation,
206 ..
207 }
208 | Mesh::Gradient {
209 transformation: local_transformation,
210 ..
211 } => {
212 *local_transformation = *local_transformation * transformation;
213 }
214 }
215
216 self.pending_meshes.push(mesh);
217 }
218
219 pub fn draw_mesh_group(
220 &mut self,
221 meshes: Vec<Mesh>,
222 transformation: Transformation,
223 ) {
224 self.flush_meshes();
225
226 self.triangles.push(triangle::Item::Group {
227 meshes,
228 transformation,
229 });
230 }
231
232 pub fn draw_mesh_cache(
233 &mut self,
234 cache: mesh::Cache,
235 transformation: Transformation,
236 ) {
237 self.flush_meshes();
238
239 self.triangles.push(triangle::Item::Cached {
240 cache,
241 transformation,
242 });
243 }
244
245 pub fn draw_text_group(
246 &mut self,
247 text: Vec<Text>,
248 transformation: Transformation,
249 ) {
250 self.flush_text();
251
252 self.text.push(text::Item::Group {
253 text,
254 transformation,
255 });
256 }
257
258 pub fn draw_text_cache(
259 &mut self,
260 cache: text::Cache,
261 transformation: Transformation,
262 ) {
263 self.flush_text();
264
265 self.text.push(text::Item::Cached {
266 cache,
267 transformation,
268 });
269 }
270
271 pub fn draw_primitive(
272 &mut self,
273 bounds: Rectangle,
274 primitive: impl Primitive,
275 transformation: Transformation,
276 ) {
277 let bounds = bounds * transformation;
278
279 self.primitives
280 .push(primitive::Instance::new(bounds, primitive));
281 }
282
283 fn flush_meshes(&mut self) {
284 if !self.pending_meshes.is_empty() {
285 self.triangles.push(triangle::Item::Group {
286 transformation: Transformation::IDENTITY,
287 meshes: self.pending_meshes.drain(..).collect(),
288 });
289 }
290 }
291
292 fn flush_text(&mut self) {
293 if !self.pending_text.is_empty() {
294 self.text.push(text::Item::Group {
295 transformation: Transformation::IDENTITY,
296 text: self.pending_text.drain(..).collect(),
297 });
298 }
299 }
300}
301
302impl graphics::Layer for Layer {
303 fn with_bounds(bounds: Rectangle) -> Self {
304 Self {
305 bounds,
306 ..Self::default()
307 }
308 }
309
310 fn bounds(&self) -> Rectangle {
311 self.bounds
312 }
313
314 fn flush(&mut self) {
315 self.flush_meshes();
316 self.flush_text();
317 }
318
319 fn resize(&mut self, bounds: Rectangle) {
320 self.bounds = bounds;
321 }
322
323 fn reset(&mut self) {
324 self.bounds = Rectangle::INFINITE;
325
326 self.quads.clear();
327 self.triangles.clear();
328 self.primitives.clear();
329 self.text.clear();
330 self.images.clear();
331 self.pending_meshes.clear();
332 self.pending_text.clear();
333 }
334
335 fn start(&self) -> usize {
336 if !self.quads.is_empty() {
337 return 1;
338 }
339
340 if !self.triangles.is_empty() {
341 return 2;
342 }
343
344 if !self.primitives.is_empty() {
345 return 3;
346 }
347
348 if !self.images.is_empty() {
349 return 4;
350 }
351
352 if !self.text.is_empty() {
353 return 5;
354 }
355
356 usize::MAX
357 }
358
359 fn end(&self) -> usize {
360 if !self.text.is_empty() {
361 return 5;
362 }
363
364 if !self.images.is_empty() {
365 return 4;
366 }
367
368 if !self.primitives.is_empty() {
369 return 3;
370 }
371
372 if !self.triangles.is_empty() {
373 return 2;
374 }
375
376 if !self.quads.is_empty() {
377 return 1;
378 }
379
380 0
381 }
382
383 fn merge(&mut self, layer: &mut Self) {
384 self.quads.append(&mut layer.quads);
385 self.triangles.append(&mut layer.triangles);
386 self.primitives.append(&mut layer.primitives);
387 self.images.append(&mut layer.images);
388 self.text.append(&mut layer.text);
389 }
390}
391
392impl Default for Layer {
393 fn default() -> Self {
394 Self {
395 bounds: Rectangle::INFINITE,
396 quads: quad::Batch::default(),
397 triangles: triangle::Batch::default(),
398 primitives: primitive::Batch::default(),
399 text: text::Batch::default(),
400 images: image::Batch::default(),
401 pending_meshes: Vec::new(),
402 pending_text: Vec::new(),
403 }
404 }
405}