1pub use {
2 crate::{
3 makepad_derive_live::*,
4 makepad_platform::*,
5 }
7};
8
9live_design!{
10 link shaders;
11
12 pub PI = 3.141592653589793
13 pub E = 2.718281828459045
14 pub LN2 = 0.6931471805599453
15 pub LN10 = 2.302585092994046
16 pub LOG2E = 1.4426950408889634
17 pub LOG10E = 0.4342944819032518
18 pub SQRT1_2 = 0.70710678118654757
19 pub TORAD = 0.017453292519943295
20 pub GOLDEN = 1.618033988749895
21
22 pub GaussShadow = {
23 fn gaussian(x:float, sigma:float )->float{
26 let pi = 3.141592653589793;
27 return exp(-(x * x) / (2.0 * sigma * sigma)) / (sqrt(2.0 * pi) * sigma);
28 }
29
30 fn erf_vec2(x0:vec2)->vec2 {
32 let s = sign(x0);
33 let a = abs(x0);
34 let x1 = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
35 x1 *= x1;
36 return s - s / (x1 * x1);
37 }
38
39 fn erf_vec4(x0:vec4)->vec4 {
40 let s = sign(x0);
41 let a = abs(x0);
42 let x1 = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
43 x1 *= x1;
44 return s - s / (x1 * x1);
45 }
46
47 fn rounded_box_shadow_x(x:float, y:float, sigma:float, corner:float, half_size:vec2)->float{
49 let delta = min(half_size.y - corner - abs(y), 0.0);
50 let curved = half_size.x - corner + sqrt(max(0.0, corner * corner - delta * delta));
51 let integral = 0.5 + 0.5 * erf_vec2((x + vec2(-curved, curved)) * (sqrt(0.5) / sigma));
52 return integral.y - integral.x;
53 }
54
55 fn rounded_box_shadow(lower:vec2, upper:vec2, point:vec2, sigma:float, corner:float)->float{
57 let center = (lower + upper) * 0.5;
59 let half_size = (upper - lower) * 0.5;
60 point -= center;
61
62 let low = point.y - half_size.y;
64 let high = point.y + half_size.y;
65 let start = clamp(-3.0 * sigma, low, high);
66 let end = clamp(3.0 * sigma, low, high);
67
68 let step = (end - start) / 4.0;
70 let y = start + step * 0.5;
71 let value = 0.0;
72 for i in 0..4{
73 value += rounded_box_shadow_x(point.x, point.y - y, sigma, corner, half_size) * gaussian(y, sigma) * step;
74 y += step;
75 }
76
77 return value;
78 }
79
80 fn box_shadow(lower:vec2, upper:vec2, point:vec2, sigma:float)->float {
81 let query = vec4(point - lower, point - upper);
82 let integral = 0.5 + 0.5 * erf_vec4(query * (sqrt(0.5) / sigma));
83 return (integral.z - integral.x) * (integral.w - integral.y);
84 }
85 }
86
87 pub Math = {
88 fn rotate_2d(v: vec2, a: float) -> vec2 {
89 let ca = cos(a);
90 let sa = sin(a);
91 return vec2(v.x * ca - v.y * sa, v.x * sa + v.y * ca);
92 }
93
94 fn random_2d(v: vec2)->float {
95 return fract(sin(dot(v.xy, vec2(12.9898,78.233))) * 43758.5453);
96 }
97 }
98
99 pub Pal = {
100
101 fn premul(v: vec4) -> vec4 {
102 return vec4(v.x * v.w, v.y * v.w, v.z * v.w, v.w);
103 }
104
105 fn iq(t: float, a: vec3, b: vec3, c: vec3, d: vec3) -> vec3 {
106 return a + b * cos(6.28318 * (c * t + d));
107 }
108
109 fn iq0(t: float) -> vec3 {
110 return mix(vec3(0., 0., 0.), vec3(1., 1., 1.), cos(t * PI) * 0.5 + 0.5);
111 }
112
113 fn iq1(t: float) -> vec3 {
114 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0., 0.33, 0.67));
115 }
116
117 fn iq2(t: float) -> vec3 {
118 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0., 0.1, 0.2));
119 }
120
121 fn iq3(t: float) -> vec3 {
122 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0.3, 0.2, 0.2));
123 }
124
125 fn iq4(t: float) -> vec3 {
126 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 0.5), vec3(0.8, 0.9, 0.3));
127 }
128
129 fn iq5(t: float) -> vec3 {
130 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 0.7, 0.4), vec3(0, 0.15, 0.20));
131 }
132
133 fn iq6(t: float) -> vec3 {
134 return Pal::iq(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(2., 1.0, 0.), vec3(0.5, 0.2, 0.25));
135 }
136
137 fn iq7(t: float) -> vec3 {
138 return Pal::iq(t, vec3(0.8, 0.5, 0.4), vec3(0.2, 0.4, 0.2), vec3(2., 1.0, 1.0), vec3(0., 0.25, 0.25));
139 }
140
141 fn hsv2rgb(c: vec4) -> vec4 { let K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
143 let p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
144 return vec4(c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y), c.w);
145 }
146
147 fn rgb2hsv(c: vec4) -> vec4 {
148 let K: vec4 = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
149 let p: vec4 = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
150 let q: vec4 = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
151
152 let d: float = q.x - min(q.w, q.y);
153 let e: float = 1.0e-10;
154 return vec4(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x, c.w);
155 }
156 }
157
158 pub Sdf2d = struct {
159 field pos: vec2
160 field result: vec4
161 field last_pos: vec2
162 field start_pos: vec2
163 field shape: float
164 field clip: float
165 field has_clip: float
166 field old_shape: float
167 field blur: float
168 field aa: float
169 field scale_factor: float
170 field dist: float
171
172 fn antialias(p: vec2) -> float {
173 return 1.0 / length(vec2(length(dFdx(p)), length(dFdy(p))));
174 }
175
176 fn viewport(pos: vec2) -> Self {
177 return Self {
178 pos: pos
179 result: vec4(0.)
180 last_pos: vec2(0.)
181 start_pos: vec2(0.)
182 shape: 1e+20
183 clip: -1e+20
184 has_clip: 0.0
185 old_shape: 1e+20
186 blur: 0.00001
187 aa: antialias(pos)
188 scale_factor: 1.0
189 dist: 0.0
190 };
191 }
192
193 fn translate(inout self, x: float, y: float) -> vec2 {
194 self.pos -= vec2(x, y);
195 return self.pos;
196 }
197
198 fn rotate(inout self, a: float, x: float, y: float) {
199 let ca = cos(-a);
200 let sa = sin(-a);
201 let p = self.pos - vec2(x, y);
202 self.pos = vec2(p.x * ca - p.y * sa, p.x * sa + p.y * ca) + vec2(x, y);
203 }
204
205 fn scale(inout self, f: float, x: float, y: float) {
206 self.scale_factor *= f;
207 self.pos = (self.pos - vec2(x, y)) * f + vec2(x, y);
208 }
209
210 fn clear(inout self, color: vec4) {
211 self.result = vec4(color.rgb * color.a + self.result.rgb * (1.0 - color.a), color.a);
212 }
213
214 fn calc_blur(inout self, w: float) -> float {
215 let wa = clamp(-w * self.aa, 0.0, 1.0);
216 let wb = 1.0;
217 if self.blur > 0.001 {
218 wb = clamp(-w / self.blur, 0.0, 1.0);
219 }
220 return wa * wb;
221 }
222
223 fn fill_keep_premul(inout self, source: vec4) -> vec4 {
224 let f = self.calc_blur(self.shape);
225 self.result = source * f + self.result * (1. - source.a * f);
226 if self.has_clip > 0.5 {
227 let f2 = 1.0 - self.calc_blur(-self.clip);
228 self.result = source * f2 + self.result * (1. - source.a * f2);
229 }
230 return self.result;
231 }
232
233 fn fill_premul(inout self, color: vec4) -> vec4 {
234 self.fill_keep_premul(color);
235 self.old_shape = self.shape = 1e+20;
236 self.clip = -1e+20;
237 self.has_clip = 0.;
238 return self.result;
239 }
240
241 fn fill_keep(inout self, color: vec4) -> vec4 {
242 return self.fill_keep_premul(vec4(color.rgb * color.a, color.a))
243 }
244
245 fn fill(inout self, color: vec4) -> vec4 {
246 return self.fill_premul(vec4(color.rgb * color.a, color.a))
247 }
248
249 fn stroke_keep(inout self, color: vec4, width: float) -> vec4 {
250 let f = self.calc_blur(abs(self.shape) - width / self.scale_factor);
251 let source = vec4(color.rgb * color.a, color.a);
252 let dest = self.result;
253 self.result = source * f + dest * (1.0 - source.a * f);
254 return self.result;
255 }
256
257 fn stroke(inout self, color: vec4, width: float) -> vec4 {
258 self.stroke_keep(color, width);
259 self.old_shape = self.shape = 1e+20;
260 self.clip = -1e+20;
261 self.has_clip = 0.;
262 return self.result;
263 }
264
265 fn glow_keep(inout self, color: vec4, width: float) -> vec4 {
266 let f = self.calc_blur(abs(self.shape) - width / self.scale_factor);
267 let source = vec4(color.rgb * color.a, color.a);
268 let dest = self.result;
269 self.result = vec4(source.rgb * f, 0.) + dest;
270 return self.result;
271 }
272
273 fn glow(inout self, color: vec4, width: float) -> vec4 {
274 self.glow_keep(color, width);
275 self.old_shape = self.shape = 1e+20;
276 self.clip = -1e+20;
277 self.has_clip = 0.;
278 return self.result;
279 }
280
281 fn union(inout self) {
282 self.old_shape = self.shape = min(self.dist, self.old_shape);
283 }
284
285 fn intersect(inout self) {
286 self.old_shape = self.shape = max(self.dist, self.old_shape);
287 }
288
289 fn subtract(inout self) {
290 self.old_shape = self.shape = max(-self.dist, self.old_shape);
291 }
292
293 fn gloop(inout self, k: float) {
294 let h = clamp(0.5 + 0.5 * (self.old_shape - self.dist) / k, 0.0, 1.0);
295 self.old_shape = self.shape = mix(self.old_shape, self.dist, h) - k * h * (1.0 - h);
296 }
297
298 fn blend(inout self, k: float) {
299 self.old_shape = self.shape = mix(self.old_shape, self.dist, k);
300 }
301
302 fn circle(inout self, x: float, y: float, r: float) {
303 let c = self.pos - vec2(x, y);
304 let len = sqrt(c.x * c.x + c.y * c.y);
305 self.dist = (len - r) / self.scale_factor;
306 self.old_shape = self.shape;
307 self.shape = min(self.shape, self.dist);
308 }
309
310 fn arc_round_caps(
312 inout self,
313 x: float,
315 y: float,
317 radius: float,
319 start_angle: float,
321 end_angle: float,
323 thickness: float
325 ) {
326 let p = self.pos - vec2(x, y);
327 let half_angle = (end_angle - start_angle) / 2.0;
328 let p = Math::rotate_2d(p, -start_angle - half_angle);
329 p.x = abs(p.x);
330 let sin_half_angle = sin(half_angle);
331 let cos_half_angle = cos(half_angle);
332 let dist_to_arc = abs(length(p) - radius) - 0.5 * thickness;
333 let cap_center = vec2(sin_half_angle, cos_half_angle) * radius;
334 let dist_to_cap = length(p - cap_center) - 0.5 * thickness;
335 if cos_half_angle * p.x < sin_half_angle * p.y {
336 self.dist = dist_to_arc;
337 } else {
338 self.dist = dist_to_cap;
339 }
340 self.old_shape = self.shape;
341 self.shape = min(self.shape, self.dist);
342 }
343
344 fn arc_flat_caps(
346 inout self,
347 x: float,
349 y: float,
351 radius: float,
353 start_angle: float,
355 end_angle: float,
357 thickness: float
359 ) {
360 let p = self.pos - vec2(x, y);
361 let half_angle = (end_angle - start_angle) / 2.0;
362 let p = Math::rotate_2d(p, -start_angle - half_angle);
363 p.x = abs(p.x);
364 let p = Math::rotate_2d(p, half_angle);
365 let dist_to_arc = abs(length(p) - radius) - thickness * 0.5;
366 let dist_y_to_cap = max(0.0, abs(radius - p.y) - thickness * 0.5);
367 let dist_to_cap = sign(p.x) * length(vec2(p.x, dist_y_to_cap));
368 self.dist = max(dist_to_arc, dist_to_cap);
369 self.old_shape = self.shape;
370 self.shape = min(self.shape, self.dist);
371 }
372
373 fn arc2(inout self, x: float, y: float, r: float, s:float, e:float)->vec4{
374 let c = self.pos - vec2(x, y);
375 let pi = 3.141592653589793; let ang = (atan(c.y,c.x)+pi)/(2.0*pi);
381 let ces = (e-s)*0.5;
382 let ang2 = 1.0 - abs(ang - ces)+ces
383 return mix(vec4(0.,0.,0.,1.0),vec4(1.0),ang2);
384 }
385
386
387 fn hline(inout self, y: float, h:float) {
388 let c = self.pos.y - y;
389 self.dist = -h+abs(c) / self.scale_factor;
390 self.old_shape = self.shape;
391 self.shape = min(self.shape, self.dist);
392 }
393
394 fn box(inout self, x: float, y: float, w: float, h: float, r: float) {
395 let p = self.pos - vec2(x, y);
396 let size = vec2(0.5 * w, 0.5 * h);
397 let bp = max(abs(p - size.xy) - (size.xy - vec2(2. * r, 2. * r).xy), vec2(0., 0.));
398 self.dist = (length(bp) - 2. * r) / self.scale_factor;
399 self.old_shape = self.shape;
400 self.shape = min(self.shape, self.dist);
401 }
402
403 fn box_y(inout self, x: float, y: float, w: float, h: float, r_top: float, r_bottom: float) {
404 let size = vec2(0.5 * w, 0.5 * h);
405 let p_r = self.pos - vec2(x, y);
406 let p = abs(p_r - size.xy) - size.xy;
407
408 let bp_top = max(p + vec2(2. * r_top, 2. * r_top).xy, vec2(0., 0.));
409 let bp_bottom = max(p + vec2(2. * r_bottom, 2. * r_bottom).xy, vec2(0., 0.));
410
411 self.dist = mix(
412 (length(bp_top) - 2. * r_top),
413 (length(bp_bottom) - 2. * r_bottom),
414 step(0.5 * h, p_r.y)
415 ) / self.scale_factor;
416
417 self.old_shape = self.shape;
418 self.shape = min(self.shape, self.dist);
419 }
420
421 fn box_x(inout self, x: float, y: float, w: float, h: float, r_left: float, r_right: float) {
422 let size = vec2(0.5 * w, 0.5 * h);
423 let p_r = self.pos - vec2(x, y);
424 let p = abs(p_r - size.xy) - size.xy;
425
426 let bp_left = max(p + vec2(2. * r_left, 2. * r_left).xy, vec2(0., 0.));
427 let bp_right = max(p + vec2(2. * r_right, 2. * r_right).xy, vec2(0., 0.));
428
429 self.dist = mix(
430 (length(bp_left) - 2. * r_left),
431 (length(bp_right) - 2. * r_right),
432 step(0.5 * w, p_r.x)
433 ) / self.scale_factor;
434
435 self.old_shape = self.shape;
436 self.shape = min(self.shape, self.dist);
437 }
438
439 fn box_all(
440 inout self,
441 x: float,
442 y: float,
443 w: float,
444 h: float,
445 r_left_top: float,
446 r_right_top: float,
447 r_right_bottom: float,
448 r_left_bottom: float
449 ) {
450 let size = vec2(0.5 * w, 0.5 * h);
451 let p_r = self.pos - vec2(x, y);
452 let p = abs(p_r - size.xy) - size.xy;
453
454 let bp_lt = max(p + vec2(2. * r_left_top, 2. * r_left_top).xy, vec2(0., 0.));
455 let bp_rt = max(p + vec2(2. * r_right_top, 2. * r_right_top).xy, vec2(0., 0.));
456 let bp_rb = max(p + vec2(2. * r_right_bottom, 2. * r_right_bottom).xy, vec2(0., 0.));
457 let bp_lb = max(p + vec2(2. * r_left_bottom, 2. * r_left_bottom).xy, vec2(0., 0.));
458
459 self.dist = mix(
460 mix(
461 (length(bp_lt) - 2. * r_left_top),
462 (length(bp_lb) - 2. * r_left_bottom),
463 step(0.5 * h, p_r.y)
464 ),
465 mix(
466 (length(bp_rt) - 2. * r_right_top),
467 (length(bp_rb) - 2. * r_right_bottom),
468 step(0.5 * h, p_r.y)
469 ),
470 step(0.5 * w, p_r.x)
471 ) / self.scale_factor;
472
473 self.old_shape = self.shape;
474 self.shape = min(self.shape, self.dist);
475 }
476
477
478 fn rect(inout self, x: float, y: float, w: float, h: float) {
479 let s = vec2(w, h) * 0.5;
480 let d = abs(vec2(x, y) - self.pos + s) - s;
481 let dm = min(d, vec2(0., 0.));
482 self.dist = max(dm.x, dm.y) + length(max(d, vec2(0., 0.)));
483 self.old_shape = self.shape;
484 self.shape = min(self.shape, self.dist);
485 }
486
487 fn hexagon(inout self, x: float, y: float, r: float) {
488 let dx = abs(x - self.pos.x) * 1.15;
489 let dy = abs(y - self.pos.y);
490 self.dist = max(dy + cos(60.0 * TORAD) * dx - r, dx - r);
491 self.old_shape = self.shape;
492 self.shape = min(self.shape, self.dist);
493 }
494
495 fn move_to(inout self, x: float, y: float) {
496 self.last_pos =
497 self.start_pos = vec2(x, y);
498 }
499
500 fn line_to(inout self, x: float, y: float) {
501 let p = vec2(x, y);
502
503 let pa = self.pos - self.last_pos;
504 let ba = p - self.last_pos;
505 let h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
506 let s = sign(pa.x * ba.y - pa.y * ba.x);
507 self.dist = length(pa - ba * h) / self.scale_factor;
508 self.old_shape = self.shape;
509 self.shape = min(self.shape, self.dist);
510 self.clip = max(self.clip, self.dist * s);
511 self.has_clip = 1.0;
512 self.last_pos = p;
513 }
514
515 fn close_path(inout self) {
516 self.line_to(self.start_pos.x, self.start_pos.y);
517 }
518 }
519}