1use crate::font::FontHeight;
22use crate::formatted_text::{DrawValueLayer, GlyphDrawValues};
23use crate::style::resource::StyleResource;
24use crate::{
25 brush::Brush,
26 core::{
27 algebra::{Matrix3, Point2, Vector2},
28 color::Color,
29 log::Log,
30 math::{self, Rect, TriangleDefinition},
31 },
32 font::FontResource,
33 formatted_text::FormattedText,
34 Thickness,
35};
36use bytemuck::{Pod, Zeroable};
37use fyrox_core::math::{round_to_step, OptionRect};
38use fyrox_material::MaterialResource;
39use fyrox_texture::TextureResource;
40use std::fmt::{Display, Formatter};
41use std::ops::Range;
42
43#[derive(Clone, Copy, Debug, Pod, Zeroable)]
44#[repr(C)]
45pub struct Vertex {
46 pub pos: Vector2<f32>,
47 pub tex_coord: Vector2<f32>,
48 pub color: Color,
49}
50
51impl Vertex {
52 fn new(pos: Vector2<f32>, tex_coord: Vector2<f32>) -> Vertex {
53 Vertex {
54 pos,
55 tex_coord,
56 color: Color::WHITE,
57 }
58 }
59}
60
61#[derive(Clone, Debug)]
62pub enum CommandTexture {
63 None,
64 Texture(TextureResource),
65 Font {
66 font: FontResource,
67 height: FontHeight,
68 page_index: usize,
69 },
70}
71
72#[derive(Clone, Debug)]
74pub struct ClippingGeometry {
75 pub vertex_buffer: Vec<Vertex>,
76 pub triangle_buffer: Vec<TriangleDefinition>,
77 pub transform_stack: TransformStack,
78}
79
80impl Draw for ClippingGeometry {
81 #[inline(always)]
82 fn push_vertex_raw(&mut self, mut vertex: Vertex) {
83 vertex.pos = self
84 .transform_stack
85 .transform
86 .transform_point(&Point2::from(vertex.pos))
87 .coords;
88
89 self.vertex_buffer.push(vertex);
90 }
91
92 #[inline(always)]
93 fn push_triangle(&mut self, a: u32, b: u32, c: u32) {
94 self.triangle_buffer.push(TriangleDefinition([a, b, c]));
95 }
96
97 #[inline(always)]
98 fn last_vertex_index(&self) -> u32 {
99 self.vertex_buffer.len() as u32
100 }
101}
102
103impl ClippingGeometry {
104 #[inline]
105 pub fn is_contains_point(&self, pos: Vector2<f32>) -> bool {
106 for triangle in self.triangle_buffer.iter() {
107 if let Some((va, vb, vc)) = self.triangle_points(triangle) {
108 if math::is_point_inside_2d_triangle(pos, va.pos, vb.pos, vc.pos) {
109 return true;
110 }
111 }
112 }
113
114 false
115 }
116
117 #[inline]
118 pub fn triangle_points(
119 &self,
120 triangle: &TriangleDefinition,
121 ) -> Option<(&Vertex, &Vertex, &Vertex)> {
122 let a = self.vertex_buffer.get(triangle[0] as usize)?;
123 let b = self.vertex_buffer.get(triangle[1] as usize)?;
124 let c = self.vertex_buffer.get(triangle[2] as usize)?;
125 Some((a, b, c))
126 }
127}
128
129#[derive(Clone, Debug)]
130pub struct Command {
131 pub clip_bounds: Rect<f32>,
133 pub bounds: Rect<f32>,
135 pub brush: Brush,
137 pub texture: CommandTexture,
138 pub triangles: Range<usize>,
139 pub material: MaterialResource,
140 pub opacity: f32,
141 pub clipping_geometry: Option<ClippingGeometry>,
143 pub transform: Matrix3<f32>,
144}
145
146pub trait Draw {
147 #[inline]
148 fn push_vertex(&mut self, pos: Vector2<f32>, tex_coord: Vector2<f32>) {
149 self.push_vertex_raw(Vertex::new(pos, tex_coord))
150 }
151
152 fn push_vertex_raw(&mut self, vertex: Vertex);
153
154 fn push_triangle(&mut self, a: u32, b: u32, c: u32);
155
156 fn last_vertex_index(&self) -> u32;
157
158 #[inline]
159 fn push_triangle_multicolor(&mut self, vertices: [(Vector2<f32>, Color); 3]) {
160 let index = self.last_vertex_index();
161 for &(pos, color) in &vertices {
162 self.push_vertex_raw(Vertex {
163 pos,
164 tex_coord: Vector2::new(0.0, 0.0),
165 color,
166 });
167 }
168
169 self.push_triangle(index, index + 1, index + 2);
170 }
171
172 #[inline]
173 fn push_triangle_filled(&mut self, vertices: [Vector2<f32>; 3]) {
174 let index = self.last_vertex_index();
175
176 for &pos in &vertices {
177 self.push_vertex(pos, Default::default());
178 }
179
180 self.push_triangle(index, index + 1, index + 2);
181 }
182
183 #[inline]
184 fn push_line(&mut self, a: Vector2<f32>, b: Vector2<f32>, thickness: f32) {
185 let index = self.last_vertex_index();
186 let perp = get_line_thickness_vector(a, b, thickness);
187 self.push_vertex(a - perp, Vector2::new(0.0, 0.0));
188 self.push_vertex(b - perp, Vector2::new(1.0, 0.0));
189 self.push_vertex(a + perp, Vector2::new(1.0, 1.0));
190 self.push_vertex(b + perp, Vector2::new(0.0, 1.0));
191
192 self.push_triangle(index, index + 1, index + 2);
193 self.push_triangle(index + 2, index + 1, index + 3);
194 }
195
196 #[inline]
197 fn push_rect(&mut self, rect: &Rect<f32>, thickness: f32) {
198 let offset = thickness * 0.5;
199
200 let left_top = Vector2::new(rect.x() + offset, rect.y() + thickness);
201 let right_top = Vector2::new(rect.x() + rect.w() - offset, rect.y() + thickness);
202 let right_bottom = Vector2::new(
203 rect.x() + rect.w() - offset,
204 rect.y() + rect.h() - thickness,
205 );
206 let left_bottom = Vector2::new(rect.x() + offset, rect.y() + rect.h() - thickness);
207 let left_top_off = Vector2::new(rect.x(), rect.y() + offset);
208 let right_top_off = Vector2::new(rect.x() + rect.w(), rect.y() + offset);
209 let right_bottom_off = Vector2::new(rect.x() + rect.w(), rect.y() + rect.h() - offset);
210 let left_bottom_off = Vector2::new(rect.x(), rect.y() + rect.h() - offset);
211
212 self.push_line(left_top_off, right_top_off, thickness);
214 self.push_line(right_bottom_off, left_bottom_off, thickness);
215
216 self.push_line(right_top, right_bottom, thickness);
218 self.push_line(left_bottom, left_top, thickness);
219 }
220
221 #[inline]
222 fn push_rect_vary(&mut self, rect: &Rect<f32>, thickness: Thickness) {
223 let left_top = Vector2::new(rect.x() + thickness.left * 0.5, rect.y() + thickness.top);
224 let right_top = Vector2::new(
225 rect.x() + rect.w() - thickness.right * 0.5,
226 rect.y() + thickness.top,
227 );
228 let right_bottom = Vector2::new(
229 rect.x() + rect.w() - thickness.right * 0.5,
230 rect.y() + rect.h() - thickness.bottom,
231 );
232 let left_bottom = Vector2::new(
233 rect.x() + thickness.left * 0.5,
234 rect.y() + rect.h() - thickness.bottom,
235 );
236 let left_top_off = Vector2::new(rect.x(), rect.y() + thickness.top * 0.5);
237 let right_top_off = Vector2::new(rect.x() + rect.w(), rect.y() + thickness.top * 0.5);
238 let right_bottom_off = Vector2::new(
239 rect.x() + rect.w(),
240 rect.y() + rect.h() - thickness.bottom * 0.5,
241 );
242 let left_bottom_off = Vector2::new(rect.x(), rect.y() + rect.h() - thickness.bottom * 0.5);
243
244 self.push_line(left_top_off, right_top_off, thickness.top);
246 self.push_line(right_bottom_off, left_bottom_off, thickness.bottom);
247
248 self.push_line(right_top, right_bottom, thickness.right);
250 self.push_line(left_bottom, left_top, thickness.left);
251 }
252
253 #[inline]
254 fn push_rect_filled(&mut self, rect: &Rect<f32>, tex_coords: Option<&[Vector2<f32>; 4]>) {
255 let index = self.last_vertex_index();
256 self.push_vertex(
257 Vector2::new(rect.x(), rect.y()),
258 tex_coords.map_or(Vector2::new(0.0, 0.0), |t| t[0]),
259 );
260 self.push_vertex(
261 Vector2::new(rect.x() + rect.w(), rect.y()),
262 tex_coords.map_or(Vector2::new(1.0, 0.0), |t| t[1]),
263 );
264 self.push_vertex(
265 Vector2::new(rect.x() + rect.w(), rect.y() + rect.h()),
266 tex_coords.map_or(Vector2::new(1.0, 1.0), |t| t[2]),
267 );
268 self.push_vertex(
269 Vector2::new(rect.x(), rect.y() + rect.h()),
270 tex_coords.map_or(Vector2::new(0.0, 1.0), |t| t[3]),
271 );
272
273 self.push_triangle(index, index + 1, index + 2);
274 self.push_triangle(index, index + 2, index + 3);
275 }
276
277 #[inline]
278 fn push_rect_multicolor(&mut self, rect: &Rect<f32>, colors: [Color; 4]) {
279 let index = self.last_vertex_index();
280 self.push_vertex_raw(Vertex {
281 pos: rect.left_top_corner(),
282 tex_coord: Vector2::new(0.0, 0.0),
283 color: colors[0],
284 });
285 self.push_vertex_raw(Vertex {
286 pos: rect.right_top_corner(),
287 tex_coord: Vector2::new(1.0, 0.0),
288 color: colors[1],
289 });
290 self.push_vertex_raw(Vertex {
291 pos: rect.right_bottom_corner(),
292 tex_coord: Vector2::new(1.0, 1.0),
293 color: colors[2],
294 });
295 self.push_vertex_raw(Vertex {
296 pos: rect.left_bottom_corner(),
297 tex_coord: Vector2::new(0.0, 1.0),
298 color: colors[3],
299 });
300
301 self.push_triangle(index, index + 1, index + 2);
302 self.push_triangle(index, index + 2, index + 3);
303 }
304
305 #[inline]
306 fn push_circle_filled(
307 &mut self,
308 origin: Vector2<f32>,
309 radius: f32,
310 segments: usize,
311 color: Color,
312 ) {
313 if segments >= 3 {
314 let center_index = self.last_vertex_index();
315
316 self.push_vertex_raw(Vertex {
317 pos: origin,
318 tex_coord: Vector2::default(),
319 color,
320 });
321
322 let two_pi = 2.0 * std::f32::consts::PI;
323 let delta_angle = two_pi / (segments as f32);
324 let mut angle: f32 = 0.0;
325 for _ in 0..segments {
326 let x = origin.x + radius * angle.cos();
327 let y = origin.y + radius * angle.sin();
328 self.push_vertex_raw(Vertex {
329 pos: Vector2::new(x, y),
330 tex_coord: Vector2::default(),
331 color,
332 });
333 angle += delta_angle;
334 }
335
336 let first_vertex = center_index + 1;
337 for segment in 0..segments {
338 self.push_triangle(
339 center_index,
340 first_vertex + segment as u32,
341 first_vertex + (segment as u32 + 1) % segments as u32,
342 );
343 }
344 }
345 }
346
347 #[inline]
348 fn push_circle(
349 &mut self,
350 center: Vector2<f32>,
351 radius: f32,
352 subdivisions: usize,
353 thickness: f32,
354 ) {
355 let start_vertex = self.last_vertex_index();
356 let d = std::f32::consts::TAU / subdivisions as f32;
357
358 let half_thickness = thickness * 0.5;
359
360 let mut angle = 0.0;
361 while angle < std::f32::consts::TAU {
362 let r = Vector2::new(angle.cos(), angle.sin());
363
364 let p0 = center + r.scale(radius - half_thickness);
365 self.push_vertex(p0, Default::default());
366
367 let p1 = center + r.scale(radius + half_thickness);
368 self.push_vertex(p1, Default::default());
369
370 angle += d;
371 }
372 let last_vertex_index = self.last_vertex_index();
373
374 self.connect_as_line(start_vertex, last_vertex_index, true)
375 }
376
377 #[inline]
378 fn connect_as_line(&mut self, from: u32, to: u32, closed: bool) {
379 if closed {
380 let count = to - from;
381 for i in (0..count).step_by(2) {
382 let i0 = from + i % count;
383 let i1 = from + (i + 1) % count;
384 let i2 = from + (i + 2) % count;
385 let i3 = from + (i + 3) % count;
386 self.push_triangle(i0, i1, i2);
387 self.push_triangle(i1, i3, i2);
388 }
389 } else {
390 for i in (from..to.saturating_sub(4)).step_by(2) {
391 let i0 = i;
392 let i1 = i + 1;
393 let i2 = i + 2;
394 let i3 = i + 3;
395 self.push_triangle(i0, i1, i2);
396 self.push_triangle(i1, i3, i2);
397 }
398 }
399 }
400
401 #[inline]
402 fn push_arc(
403 &mut self,
404 center: Vector2<f32>,
405 radius: f32,
406 angles: Range<f32>,
407 subdivisions: usize,
408 thickness: f32,
409 ) {
410 let start_vertex = self.last_vertex_index();
411 self.push_arc_path_with_thickness(center, radius, angles, subdivisions, thickness);
412 let last_vertex_index = self.last_vertex_index();
413
414 self.connect_as_line(start_vertex, last_vertex_index, false)
415 }
416
417 #[inline]
418 fn push_arc_path_with_thickness(
419 &mut self,
420 center: Vector2<f32>,
421 radius: f32,
422 angles: Range<f32>,
423 subdivisions: usize,
424 thickness: f32,
425 ) {
426 let mut start_angle = math::wrap_angle(angles.start);
427 let mut end_angle = math::wrap_angle(angles.end);
428
429 if start_angle > end_angle {
430 std::mem::swap(&mut start_angle, &mut end_angle);
431 }
432
433 let d = (end_angle - start_angle) / subdivisions as f32;
434
435 let half_thickness = thickness * 0.5;
436
437 let mut angle = start_angle;
438 while angle <= end_angle {
439 let r = Vector2::new(angle.cos(), angle.sin());
440
441 let p0 = center + r.scale(radius - half_thickness);
442 self.push_vertex(p0, Default::default());
443
444 let p1 = center + r.scale(radius + half_thickness);
445 self.push_vertex(p1, Default::default());
446
447 angle += d;
448 }
449 }
450
451 #[inline]
452 fn push_arc_path(
453 &mut self,
454 center: Vector2<f32>,
455 radius: f32,
456 angles: Range<f32>,
457 subdivisions: usize,
458 ) {
459 let mut start_angle = math::wrap_angle(angles.start);
460 let mut end_angle = math::wrap_angle(angles.end);
461
462 if start_angle > end_angle {
463 std::mem::swap(&mut start_angle, &mut end_angle);
464 }
465
466 let d = (end_angle - start_angle) / subdivisions as f32;
467
468 let mut angle = start_angle;
469 while angle <= end_angle {
470 let p0 = center + Vector2::new(angle.cos() * radius, angle.sin() * radius);
471
472 self.push_vertex(p0, Default::default());
473
474 angle += d;
475 }
476 }
477
478 #[inline]
479 fn push_line_path(&mut self, a: Vector2<f32>, b: Vector2<f32>) {
480 self.push_vertex(a, Default::default());
481 self.push_vertex(b, Default::default());
482 }
483
484 #[inline]
485 fn push_line_path_with_thickness(&mut self, a: Vector2<f32>, b: Vector2<f32>, thickness: f32) {
486 let perp = get_line_thickness_vector(a, b, thickness);
487 self.push_vertex(a - perp, Vector2::new(0.0, 0.0));
488 self.push_vertex(a + perp, Vector2::new(1.0, 1.0));
489 self.push_vertex(b - perp, Vector2::new(1.0, 0.0));
490 self.push_vertex(b + perp, Vector2::new(0.0, 1.0));
491 }
492
493 #[inline]
494 fn push_rounded_rect_filled(
495 &mut self,
496 rect: &Rect<f32>,
497 mut corner_radius: f32,
498 corner_subdivisions: usize,
499 ) {
500 let min_axis = rect.w().min(rect.h());
502 corner_radius = corner_radius.min(min_axis * 0.5);
503
504 let center_index = self.last_vertex_index();
505 self.push_vertex(rect.center(), Default::default());
506
507 self.push_line_path(
508 Vector2::new(rect.x(), rect.y() + rect.h() - corner_radius),
509 Vector2::new(rect.x(), rect.y() + corner_radius),
510 );
511
512 self.push_arc_path(
513 rect.position + Vector2::repeat(corner_radius),
514 corner_radius,
515 180.0f32.to_radians()..270.0f32.to_radians(),
516 corner_subdivisions,
517 );
518
519 self.push_line_path(
520 Vector2::new(rect.x() + corner_radius, rect.y()),
521 Vector2::new(rect.x() + rect.w() - corner_radius, rect.y()),
522 );
523
524 self.push_arc_path(
525 Vector2::new(
526 rect.position.x + rect.w() - corner_radius,
527 rect.position.y + corner_radius,
528 ),
529 corner_radius,
530 270.0f32.to_radians()..359.9999f32.to_radians(),
531 corner_subdivisions,
532 );
533
534 self.push_line_path(
535 Vector2::new(rect.x() + rect.w(), rect.y() + corner_radius),
536 Vector2::new(rect.x() + rect.w(), rect.y() + rect.h() - corner_radius),
537 );
538
539 self.push_arc_path(
540 Vector2::new(
541 rect.position.x + rect.w() - corner_radius,
542 rect.position.y + rect.h() - corner_radius,
543 ),
544 corner_radius,
545 0.0f32.to_radians()..90.0f32.to_radians(),
546 corner_subdivisions,
547 );
548
549 self.push_line_path(
550 Vector2::new(rect.x() + rect.w() - corner_radius, rect.y() + rect.h()),
551 Vector2::new(rect.x() + corner_radius, rect.y() + rect.h()),
552 );
553
554 self.push_arc_path(
555 Vector2::new(
556 rect.position.x + corner_radius,
557 rect.position.y + rect.h() - corner_radius,
558 ),
559 corner_radius,
560 90.0f32.to_radians()..180.0f32.to_radians(),
561 corner_subdivisions,
562 );
563
564 let first_index = center_index + 1;
566 let last_vertex_index = self.last_vertex_index().saturating_sub(1);
567 for i in first_index..last_vertex_index {
568 let next = i + 1;
569 self.push_triangle(i, next, center_index)
570 }
571
572 self.push_triangle(last_vertex_index, first_index, center_index);
573 }
574
575 #[inline]
576 fn push_rounded_rect(
577 &mut self,
578 rect: &Rect<f32>,
579 thickness: f32,
580 mut corner_radius: f32,
581 corner_subdivisions: usize,
582 ) {
583 let min_axis = rect.w().min(rect.h());
585 corner_radius = corner_radius.min(min_axis * 0.5);
586
587 let half_thickness = thickness * 0.5;
588
589 let start_index = self.last_vertex_index();
590
591 self.push_line_path_with_thickness(
592 Vector2::new(
593 rect.x() + half_thickness,
594 rect.y() + rect.h() - thickness - corner_radius,
595 ),
596 Vector2::new(
597 rect.x() + half_thickness,
598 rect.y() + thickness + corner_radius,
599 ),
600 thickness,
601 );
602
603 self.push_arc_path_with_thickness(
604 rect.position + Vector2::repeat(corner_radius + half_thickness),
605 corner_radius,
606 180.0f32.to_radians()..270.0f32.to_radians(),
607 corner_subdivisions,
608 thickness,
609 );
610
611 self.push_line_path_with_thickness(
612 Vector2::new(
613 rect.x() + corner_radius + half_thickness,
614 rect.y() + half_thickness,
615 ),
616 Vector2::new(
617 rect.x() + rect.w() - corner_radius - half_thickness,
618 rect.y() + half_thickness,
619 ),
620 thickness,
621 );
622
623 self.push_arc_path_with_thickness(
624 Vector2::new(
625 rect.position.x + rect.w() - corner_radius - half_thickness,
626 rect.position.y + corner_radius + half_thickness,
627 ),
628 corner_radius,
629 270.0f32.to_radians()..359.9999f32.to_radians(),
630 corner_subdivisions,
631 thickness,
632 );
633
634 self.push_line_path_with_thickness(
635 Vector2::new(
636 rect.x() + rect.w() - half_thickness,
637 rect.y() + thickness + corner_radius,
638 ),
639 Vector2::new(
640 rect.x() + rect.w() - half_thickness,
641 rect.y() + rect.h() - thickness - corner_radius,
642 ),
643 thickness,
644 );
645
646 self.push_arc_path_with_thickness(
647 Vector2::new(
648 rect.position.x + rect.w() - corner_radius - half_thickness,
649 rect.position.y + rect.h() - corner_radius - half_thickness,
650 ),
651 corner_radius,
652 0.0f32.to_radians()..90.0f32.to_radians(),
653 corner_subdivisions,
654 thickness,
655 );
656
657 self.push_line_path_with_thickness(
658 Vector2::new(
659 rect.x() + rect.w() - corner_radius - half_thickness,
660 rect.y() + rect.h() - half_thickness,
661 ),
662 Vector2::new(
663 rect.x() + corner_radius + half_thickness,
664 rect.y() + rect.h() - half_thickness,
665 ),
666 thickness,
667 );
668
669 self.push_arc_path_with_thickness(
670 Vector2::new(
671 rect.position.x + corner_radius + half_thickness,
672 rect.position.y + rect.h() - corner_radius - half_thickness,
673 ),
674 corner_radius,
675 90.0f32.to_radians()..180.0f32.to_radians(),
676 corner_subdivisions,
677 thickness,
678 );
679
680 let last_vertex_index = self.last_vertex_index();
681 self.connect_as_line(start_index, last_vertex_index, true);
682 }
683
684 #[inline]
685 fn push_bezier(
686 &mut self,
687 p0: Vector2<f32>,
688 p1: Vector2<f32>,
689 p2: Vector2<f32>,
690 p3: Vector2<f32>,
691 subdivisions: usize,
692 thickness: f32,
693 ) {
694 fn cubic_bezier(
695 p0: Vector2<f32>,
696 p1: Vector2<f32>,
697 p2: Vector2<f32>,
698 p3: Vector2<f32>,
699 t: f32,
700 ) -> Vector2<f32> {
701 p0.scale((1.0 - t).powi(3))
702 + p1.scale(3.0 * t * (1.0 - t).powi(2))
703 + p2.scale(3.0 * t.powi(2) * (1.0 - t))
704 + p3.scale(t.powi(3))
705 }
706
707 let mut prev = cubic_bezier(p0, p1, p2, p3, 0.0);
708 for i in 0..subdivisions {
709 let t = (i + 1) as f32 / subdivisions as f32;
710 let next = cubic_bezier(p0, p1, p2, p3, t);
711 self.push_line(prev, next, thickness);
714 prev = next;
715 }
716 }
717
718 #[inline]
719 fn push_grid(&mut self, zoom: f32, cell_size: Vector2<f32>, grid_bounds: Rect<f32>) {
720 let mut local_left_bottom = grid_bounds.left_top_corner();
721 local_left_bottom.x = round_to_step(local_left_bottom.x, cell_size.x);
722 local_left_bottom.y = round_to_step(local_left_bottom.y, cell_size.y);
723
724 let mut local_right_top = grid_bounds.right_bottom_corner();
725 local_right_top.x = round_to_step(local_right_top.x, cell_size.x);
726 local_right_top.y = round_to_step(local_right_top.y, cell_size.y);
727
728 let w = (local_right_top.x - local_left_bottom.x).abs();
729 let h = (local_right_top.y - local_left_bottom.y).abs();
730
731 let nw = ((w / cell_size.x).ceil()) as usize;
732 let nh = ((h / cell_size.y).ceil()) as usize;
733
734 for ny in 0..=nh {
735 let k = ny as f32 / (nh) as f32;
736 let y = local_left_bottom.y + k * h;
737 self.push_line(
738 Vector2::new(local_left_bottom.x - cell_size.x, y),
739 Vector2::new(local_right_top.x + cell_size.x, y),
740 1.0 / zoom,
741 );
742 }
743
744 for nx in 0..=nw {
745 let k = nx as f32 / (nw) as f32;
746 let x = local_left_bottom.x + k * w;
747 self.push_line(
748 Vector2::new(x, local_left_bottom.y - cell_size.y),
749 Vector2::new(x, local_right_top.y + cell_size.y),
750 1.0 / zoom,
751 );
752 }
753 }
754}
755
756#[derive(Clone, Debug)]
757pub struct TransformStack {
758 transform: Matrix3<f32>,
759 stack: Vec<Matrix3<f32>>,
760}
761
762impl Default for TransformStack {
763 fn default() -> Self {
764 Self {
765 transform: Matrix3::identity(),
766 stack: vec![],
767 }
768 }
769}
770
771impl TransformStack {
772 #[inline]
773 pub fn push(&mut self, matrix: Matrix3<f32>) {
774 self.stack
775 .push(std::mem::replace(&mut self.transform, matrix));
776 }
777
778 #[inline]
780 pub fn transform(&self) -> &Matrix3<f32> {
781 &self.transform
782 }
783
784 #[inline]
785 pub fn len(&self) -> usize {
786 self.stack.len()
787 }
788
789 #[inline]
790 pub fn is_empty(&self) -> bool {
791 self.stack.is_empty()
792 }
793
794 #[inline]
795 pub fn content(&self) -> Vec<Matrix3<f32>> {
796 self.stack.clone()
797 }
798
799 #[inline]
800 pub fn pop(&mut self) {
801 if let Some(top) = self.stack.pop() {
802 self.transform = top;
803 } else {
804 Log::err("TransformStack pop failure.")
805 }
806 }
807}
808
809#[derive(Debug, Clone, Default)]
810pub struct RenderData {
811 pub vertex_buffer: Vec<Vertex>,
812 pub triangle_buffer: Vec<TriangleDefinition>,
813 pub command_buffer: Vec<Command>,
814}
815
816impl Display for RenderData {
817 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
818 f.debug_struct("RenderData")
819 .field("Vertices Count: ", &self.vertex_buffer.len())
820 .field("Triangles Count: ", &self.triangle_buffer.len())
821 .field("Commands Count: ", &self.command_buffer.len())
822 .finish()
823 }
824}
825
826impl RenderData {
827 pub fn clear(&mut self) {
828 self.vertex_buffer.clear();
829 self.triangle_buffer.clear();
830 self.command_buffer.clear();
831 }
832
833 pub fn append(&mut self, other: &Self) {
834 let vertex_index_offset = self.vertex_buffer.len();
835 let triangle_index_offset = self.triangle_buffer.len();
836 self.vertex_buffer.extend_from_slice(&other.vertex_buffer);
837 for cmd in other.command_buffer.iter() {
838 let mut cmd_copy = cmd.clone();
839 cmd_copy.triangles.start += triangle_index_offset;
840 cmd_copy.triangles.end += triangle_index_offset;
841 self.command_buffer.push(cmd_copy);
842 }
843 for triangle in other.triangle_buffer.iter() {
844 self.triangle_buffer
845 .push(triangle.add(vertex_index_offset as u32));
846 }
847 }
848
849 #[inline]
850 pub fn triangle_points(
851 &self,
852 triangle: &TriangleDefinition,
853 ) -> Option<(&Vertex, &Vertex, &Vertex)> {
854 let a = self.vertex_buffer.get(triangle[0] as usize)?;
855 let b = self.vertex_buffer.get(triangle[1] as usize)?;
856 let c = self.vertex_buffer.get(triangle[2] as usize)?;
857 Some((a, b, c))
858 }
859
860 #[inline]
861 pub fn is_command_contains_point(&self, command: &Command, pos: Vector2<f32>) -> bool {
862 for i in command.triangles.clone() {
863 if let Some(triangle) = self.triangle_buffer.get(i) {
864 if let Some((va, vb, vc)) = self.triangle_points(triangle) {
865 if math::is_point_inside_2d_triangle(pos, va.pos, vb.pos, vc.pos) {
866 return true;
867 }
868 }
869 }
870 }
871
872 false
873 }
874}
875
876#[derive(Debug, Clone)]
877pub struct DrawingContext {
878 pub render_data: RenderData,
879 pub transform_stack: TransformStack,
880 opacity_stack: Vec<f32>,
881 triangles_to_commit: usize,
882 pub style: StyleResource,
883 pub elapsed_time: f32,
887}
888
889fn get_line_thickness_vector(a: Vector2<f32>, b: Vector2<f32>, thickness: f32) -> Vector2<f32> {
890 if let Some(dir) = (b - a).try_normalize(f32::EPSILON) {
891 Vector2::new(dir.y, -dir.x).scale(thickness * 0.5)
892 } else {
893 Vector2::default()
894 }
895}
896
897impl Draw for DrawingContext {
898 #[inline(always)]
899 fn push_vertex_raw(&mut self, vertex: Vertex) {
900 self.render_data.vertex_buffer.push(vertex);
901 }
902
903 #[inline(always)]
904 fn push_triangle(&mut self, a: u32, b: u32, c: u32) {
905 self.render_data
906 .triangle_buffer
907 .push(TriangleDefinition([a, b, c]));
908 self.triangles_to_commit += 1;
909 }
910
911 #[inline(always)]
912 fn last_vertex_index(&self) -> u32 {
913 self.render_data.vertex_buffer.len() as u32
914 }
915}
916
917impl DrawingContext {
918 #[inline]
919 pub fn new(style: StyleResource) -> DrawingContext {
920 DrawingContext {
921 render_data: RenderData::default(),
922 triangles_to_commit: 0,
923 opacity_stack: vec![1.0],
924 transform_stack: Default::default(),
925 style,
926 elapsed_time: 0.0,
927 }
928 }
929
930 #[inline]
931 pub fn clear(&mut self) {
932 self.render_data.clear();
933 self.opacity_stack.clear();
934 self.opacity_stack.push(1.0);
935 self.triangles_to_commit = 0;
936 }
937
938 #[inline]
939 pub fn copy_render_data_and_clear(&mut self, dest: &mut RenderData) {
940 dest.command_buffer.clear();
941 dest.command_buffer
942 .append(&mut self.render_data.command_buffer);
943
944 dest.vertex_buffer.clear();
945 dest.vertex_buffer
946 .append(&mut self.render_data.vertex_buffer);
947
948 dest.triangle_buffer.clear();
949 dest.triangle_buffer
950 .append(&mut self.render_data.triangle_buffer);
951
952 self.triangles_to_commit = 0;
953 }
954
955 pub fn append(&mut self, render_data: &RenderData) {
956 self.render_data.append(render_data);
957 }
958
959 #[inline]
960 pub fn get_vertices(&self) -> &[Vertex] {
961 self.render_data.vertex_buffer.as_slice()
962 }
963
964 #[inline]
965 pub fn get_triangles(&self) -> &[TriangleDefinition] {
966 self.render_data.triangle_buffer.as_slice()
967 }
968
969 #[inline]
970 pub fn get_commands(&self) -> &Vec<Command> {
971 &self.render_data.command_buffer
972 }
973
974 #[inline]
975 pub fn push_opacity(&mut self, opacity: f32) {
976 self.opacity_stack.push(opacity);
977 }
978
979 #[inline]
980 pub fn pop_opacity(&mut self) {
981 self.opacity_stack.pop().unwrap();
982 }
983
984 #[inline]
985 pub fn triangle_points(
986 &self,
987 triangle: &TriangleDefinition,
988 ) -> Option<(&Vertex, &Vertex, &Vertex)> {
989 self.render_data.triangle_points(triangle)
990 }
991
992 #[inline]
993 pub fn is_command_contains_point(&self, command: &Command, pos: Vector2<f32>) -> bool {
994 self.render_data.is_command_contains_point(command, pos)
995 }
996
997 #[inline]
998 fn pending_range(&self) -> Range<usize> {
999 if self.render_data.triangle_buffer.is_empty() {
1000 0..self.triangles_to_commit
1001 } else {
1002 (self.render_data.triangle_buffer.len() - self.triangles_to_commit)
1003 ..self.render_data.triangle_buffer.len()
1004 }
1005 }
1006
1007 #[inline]
1008 fn bounds_of(&self, range: Range<usize>) -> Rect<f32> {
1009 let mut bounds = OptionRect::default();
1010 for i in range {
1011 for &k in self.render_data.triangle_buffer[i].as_ref() {
1012 bounds.push(self.render_data.vertex_buffer[k as usize].pos);
1013 }
1014 }
1015 bounds.unwrap_or_default()
1016 }
1017
1018 #[inline]
1019 pub fn commit(
1020 &mut self,
1021 clip_bounds: Rect<f32>,
1022 brush: Brush,
1023 texture: CommandTexture,
1024 material: &MaterialResource,
1025 clipping_geometry: Option<ClippingGeometry>,
1026 ) {
1027 if self.triangles_to_commit > 0 {
1028 let triangles = self.pending_range();
1029 let bounds = self.bounds_of(triangles.clone());
1030
1031 let opacity = *self.opacity_stack.last().unwrap();
1032 self.render_data.command_buffer.push(Command {
1033 clip_bounds,
1034 bounds,
1035 brush,
1036 texture,
1037 triangles,
1038 material: material.clone(),
1039 opacity,
1040 clipping_geometry,
1041 transform: *self.transform_stack.transform(),
1042 });
1043 self.triangles_to_commit = 0;
1044 }
1045 }
1046
1047 #[inline]
1048 pub fn draw_text(
1049 &mut self,
1050 clip_bounds: Rect<f32>,
1051 position: Vector2<f32>,
1052 material: &MaterialResource,
1053 formatted_text: &FormattedText,
1054 ) {
1055 #[inline(always)]
1056 fn draw(
1057 formatted_text: &FormattedText,
1058 layer: DrawValueLayer,
1059 ctx: &mut DrawingContext,
1060 clip_bounds: Rect<f32>,
1061 position: Vector2<f32>,
1062 material: &MaterialResource,
1063 ) {
1064 let mut current_draw_values = None;
1065 for element in formatted_text.get_glyphs() {
1066 if let DrawValueLayer::Shadow = layer {
1067 if !formatted_text.shadow_at(element.source_char_index) {
1068 continue;
1069 }
1070 }
1071 let draw_values = formatted_text.get_glyph_draw_values(layer, element);
1072 if current_draw_values.is_none() {
1073 current_draw_values = Some(draw_values)
1074 } else if current_draw_values.as_ref() != Some(&draw_values) {
1075 let GlyphDrawValues {
1077 atlas_page_index: page_index,
1078 font,
1079 brush,
1080 height,
1081 } = current_draw_values.unwrap();
1082 let texture = CommandTexture::Font {
1083 font,
1084 page_index,
1085 height,
1086 };
1087 ctx.commit(clip_bounds, brush, texture, material, None);
1088 current_draw_values = Some(draw_values);
1089 }
1090
1091 let bounds = element.bounds;
1092 let dilation = match layer {
1093 DrawValueLayer::Main => 0.0,
1094 DrawValueLayer::Shadow => {
1095 formatted_text.shadow_dilation_at(element.source_char_index)
1096 }
1097 };
1098 let offset = match layer {
1099 DrawValueLayer::Main => Vector2::default(),
1100 DrawValueLayer::Shadow => {
1101 formatted_text.shadow_offset_at(element.source_char_index)
1102 }
1103 };
1104
1105 let final_bounds = Rect::new(
1106 position.x + bounds.x() + offset.x,
1107 position.y + bounds.y() + offset.y,
1108 bounds.w(),
1109 bounds.h(),
1110 )
1111 .inflate(dilation, dilation);
1112
1113 ctx.push_rect_filled(&final_bounds, Some(&element.tex_coords));
1114 }
1115
1116 if let Some(GlyphDrawValues {
1117 atlas_page_index: page_index,
1118 font,
1119 brush,
1120 height,
1121 }) = current_draw_values
1122 {
1123 let texture = CommandTexture::Font {
1124 font,
1125 page_index,
1126 height,
1127 };
1128 ctx.commit(clip_bounds, brush, texture, material, None);
1130 }
1131 }
1132
1133 if *formatted_text.shadow || !formatted_text.runs.is_empty() {
1135 draw(
1136 formatted_text,
1137 DrawValueLayer::Shadow,
1138 self,
1139 clip_bounds,
1140 position,
1141 material,
1142 );
1143 }
1144
1145 draw(
1146 formatted_text,
1147 DrawValueLayer::Main,
1148 self,
1149 clip_bounds,
1150 position,
1151 material,
1152 );
1153 }
1154}