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