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