1pub use {
2 std::{
3 rc::Rc,
4 cell::RefCell,
5 io::prelude::*,
6 fs::File,
7 collections::HashMap,
8 },
9 crate::{
10 makepad_platform::*,
11 cx_2d::Cx2d,
12 turtle::{Walk, Layout},
13 draw_list_2d::{ManyInstances, DrawList2d, RedrawingApi},
14 geometry::GeometryQuad2D,
15 makepad_vector::font::Glyph,
16 makepad_vector::trapezoidator::Trapezoidator,
17 makepad_vector::geometry::{AffineTransformation, Transform, Vector},
18 makepad_vector::internal_iter::*,
19 makepad_vector::path::PathIterator,
20 }
21};
22
23live_design!{
24 pub DrawTrapezoidVector= {{DrawTrapezoidVector}} {
25 varying v_p0: vec2;
26 varying v_p1: vec2;
27 varying v_p2: vec2;
28 varying v_p3: vec2;
29 varying v_pixel: vec2;
30
31 fn intersect_line_segment_with_vertical_line(p0: vec2, p1: vec2, x: float) -> vec2 {
32 return vec2(
33 x,
34 mix(p0.y, p1.y, (x - p0.x) / (p1.x - p0.x))
35 );
36 }
37
38 fn intersect_line_segment_with_horizontal_line(p0: vec2, p1: vec2, y: float) -> vec2 {
39 return vec2(
40 mix(p0.x, p1.x, (y - p0.y) / (p1.y - p0.y)),
41 y
42 );
43 }
44
45 fn compute_clamped_right_trapezoid_area(p0: vec2, p1: vec2, p_min: vec2, p_max: vec2) -> float {
46 let x0 = clamp(p0.x, p_min.x, p_max.x);
47 let x1 = clamp(p1.x, p_min.x, p_max.x);
48 if (p0.x < p_min.x && p_min.x < p1.x) {
49 p0 = intersect_line_segment_with_vertical_line(p0, p1, p_min.x);
50 }
51 if (p0.x < p_max.x && p_max.x < p1.x) {
52 p1 = intersect_line_segment_with_vertical_line(p0, p1, p_max.x);
53 }
54 if (p0.y < p_min.y && p_min.y < p1.y) {
55 p0 = intersect_line_segment_with_horizontal_line(p0, p1, p_min.y);
56 }
57 if (p1.y < p_min.y && p_min.y < p0.y) {
58 p1 = intersect_line_segment_with_horizontal_line(p1, p0, p_min.y);
59 }
60 if (p0.y < p_max.y && p_max.y < p1.y) {
61 p1 = intersect_line_segment_with_horizontal_line(p0, p1, p_max.y);
62 }
63 if (p1.y < p_max.y && p_max.y < p0.y) {
64 p0 = intersect_line_segment_with_horizontal_line(p1, p0, p_max.y);
65 }
66 p0 = clamp(p0, p_min, p_max);
67 p1 = clamp(p1, p_min, p_max);
68 let h0 = p_max.y - p0.y;
69 let h1 = p_max.y - p1.y;
70 let a0 = (p0.x - x0) * h0;
71 let a1 = (p1.x - p0.x) * (h0 + h1) * 0.5;
72 let a2 = (x1 - p1.x) * h1;
73 return a0 + a1 + a2;
74 }
75
76 fn compute_clamped_trapezoid_area(self, p_min: vec2, p_max: vec2) -> float {
77 let a0 = compute_clamped_right_trapezoid_area(self.v_p0, self.v_p1, p_min, p_max);
78 let a1 = compute_clamped_right_trapezoid_area(self.v_p2, self.v_p3, p_min, p_max);
79 return a0 - a1;
80 }
81
82 fn fragment(self) -> vec4 {
83 let p_min = self.v_pixel.xy - 0.5;
84 let p_max = self.v_pixel.xy + 0.5;
85 let t_area = self.compute_clamped_trapezoid_area(p_min, p_max);
86 if self.chan < 0.5 {
87 return vec4(t_area, 0., 0., 0.);
88 }
89 if self.chan < 1.5 {
90 return vec4(0., t_area, 0., 0.);
91 }
92 if self.chan < 2.5 {
93 return vec4(0., 0., t_area, 0.);
94 }
95 return vec4(t_area, t_area, t_area, 0.);
96 }
97
98 fn vertex(self) -> vec4 {
99 let pos_min = vec2(self.a_xs.x, min(self.a_ys.x, self.a_ys.y));
100 let pos_max = vec2(self.a_xs.y, max(self.a_ys.z, self.a_ys.w));
101 let pos = mix(pos_min - 1.0, pos_max + 1.0, self.geom_pos);
102
103 self.v_p0 = vec2(self.a_xs.x, self.a_ys.x);
105 self.v_p1 = vec2(self.a_xs.y, self.a_ys.y);
106 self.v_p2 = vec2(self.a_xs.x, self.a_ys.z);
107 self.v_p3 = vec2(self.a_xs.y, self.a_ys.w);
108 self.v_pixel = pos;
109 return self.camera_projection * vec4(pos, 0.0, 1.0);
110 }
111 }
112}
113
114
115#[derive(Live, LiveRegister)]
116#[repr(C)]
117pub struct DrawTrapezoidVector {
118 #[rust] pub trapezoidator: Trapezoidator,
119 #[live] pub geometry: GeometryQuad2D,
120 #[deref] pub draw_vars: DrawVars,
121 #[calc] pub a_xs: Vec2,
122 #[calc] pub a_ys: Vec4,
123 #[calc] pub chan: f32,
124}
125
126impl LiveHook for DrawTrapezoidVector{
127 fn before_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]){
128 self.draw_vars.before_apply_init_shader(cx, apply, index, nodes, &self.geometry);
129 }
130 fn after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) {
131 self.draw_vars.after_apply_update_self(cx, apply, index, nodes, &self.geometry);
132 }
133}
134