1#![allow(dead_code)]
2
3use std::{
4 fmt::Display,
5 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign},
6};
7
8use super::{RGBf, RGB, RGB24, RGBA, RGBA32};
9
10fn convert_f32_to_u8(v: f32) -> u8 {
11 let v = (v * 255.0 + 0.5) as i32;
12 v.max(0).min(255) as u8
13}
14
15#[derive(Clone, Copy, PartialEq, Debug)]
16pub struct RGBAf {
17 r: f32,
18 g: f32,
19 b: f32,
20 a: f32,
21}
22
23impl Display for RGBAf {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(
26 f,
27 "RGBAf(r: {}, g: {}, b: {}, a: {})",
28 self.r, self.g, self.b, self.a
29 )
30 }
31}
32
33impl Default for RGBAf {
34 fn default() -> Self {
35 Self {
36 r: 0.0,
37 g: 0.0,
38 b: 0.0,
39 a: 0.0,
40 }
41 }
42}
43
44impl Add<RGBAf> for RGBAf {
45 type Output = RGBAf;
46
47 fn add(self, rhs: RGBAf) -> Self::Output {
48 RGBAf::new(
49 self.r + rhs.r,
50 self.g + rhs.g,
51 self.b + rhs.b,
52 self.a + rhs.a,
53 )
54 }
55}
56
57impl Add<f32> for RGBAf {
58 type Output = RGBAf;
59
60 fn add(self, rhs: f32) -> Self::Output {
61 RGBAf::new(self.r + rhs, self.g + rhs, self.b + rhs, self.a + rhs)
62 }
63}
64
65impl Add<RGBAf> for f32 {
66 type Output = RGBAf;
67
68 fn add(self, rhs: RGBAf) -> Self::Output {
69 RGBAf::new(self + rhs.r, self + rhs.g, self + rhs.b, self + rhs.a)
70 }
71}
72
73impl AddAssign<RGBAf> for RGBAf {
74 fn add_assign(&mut self, rhs: RGBAf) {
75 *self = *self + rhs;
76 }
77}
78
79impl AddAssign<f32> for RGBAf {
80 fn add_assign(&mut self, rhs: f32) {
81 *self = *self + rhs;
82 }
83}
84
85impl Sub<RGBAf> for RGBAf {
86 type Output = RGBAf;
87
88 fn sub(self, rhs: RGBAf) -> Self::Output {
89 RGBAf::new(
90 self.r - rhs.r,
91 self.g - rhs.g,
92 self.b - rhs.b,
93 self.a - rhs.a,
94 )
95 }
96}
97
98impl Sub<f32> for RGBAf {
99 type Output = RGBAf;
100
101 fn sub(self, rhs: f32) -> Self::Output {
102 RGBAf::new(self.r - rhs, self.g - rhs, self.b - rhs, self.a - rhs)
103 }
104}
105
106impl Sub<RGBAf> for f32 {
107 type Output = RGBAf;
108
109 fn sub(self, rhs: RGBAf) -> Self::Output {
110 RGBAf::new(self - rhs.r, self - rhs.g, self - rhs.b, self - rhs.a)
111 }
112}
113
114impl SubAssign<RGBAf> for RGBAf {
115 fn sub_assign(&mut self, rhs: RGBAf) {
116 *self = *self - rhs;
117 }
118}
119
120impl SubAssign<f32> for RGBAf {
121 fn sub_assign(&mut self, rhs: f32) {
122 *self = *self - rhs;
123 }
124}
125
126impl Mul<RGBAf> for RGBAf {
127 type Output = RGBAf;
128
129 fn mul(self, rhs: RGBAf) -> Self::Output {
130 RGBAf::new(
131 self.r * rhs.r,
132 self.g * rhs.g,
133 self.b * rhs.b,
134 self.a * rhs.a,
135 )
136 }
137}
138
139impl Mul<f32> for RGBAf {
140 type Output = RGBAf;
141
142 fn mul(self, rhs: f32) -> Self::Output {
143 RGBAf::new(self.r * rhs, self.g * rhs, self.b * rhs, self.a * rhs)
144 }
145}
146
147impl Mul<RGBAf> for f32 {
148 type Output = RGBAf;
149
150 fn mul(self, rhs: RGBAf) -> Self::Output {
151 RGBAf::new(self * rhs.r, self * rhs.g, self * rhs.b, self * rhs.a)
152 }
153}
154
155impl MulAssign<RGBAf> for RGBAf {
156 fn mul_assign(&mut self, rhs: RGBAf) {
157 *self = *self * rhs;
158 }
159}
160
161impl MulAssign<f32> for RGBAf {
162 fn mul_assign(&mut self, rhs: f32) {
163 *self = *self * rhs;
164 }
165}
166
167impl Div<RGBAf> for RGBAf {
168 type Output = RGBAf;
169
170 fn div(self, rhs: RGBAf) -> Self::Output {
171 RGBAf::new(
172 self.r / rhs.r,
173 self.g / rhs.g,
174 self.b / rhs.b,
175 self.a / rhs.a,
176 )
177 }
178}
179
180impl Div<f32> for RGBAf {
181 type Output = RGBAf;
182
183 fn div(self, rhs: f32) -> Self::Output {
184 RGBAf::new(self.r / rhs, self.g / rhs, self.b / rhs, self.a / rhs)
185 }
186}
187
188impl Div<RGBAf> for f32 {
189 type Output = RGBAf;
190
191 fn div(self, rhs: RGBAf) -> Self::Output {
192 RGBAf::new(self / rhs.r, self / rhs.g, self / rhs.b, self / rhs.a)
193 }
194}
195
196impl DivAssign<RGBAf> for RGBAf {
197 fn div_assign(&mut self, rhs: RGBAf) {
198 *self = *self / rhs;
199 }
200}
201
202impl DivAssign<f32> for RGBAf {
203 fn div_assign(&mut self, rhs: f32) {
204 *self = *self / rhs;
205 }
206}
207
208impl Neg for RGBAf {
209 type Output = RGBAf;
210
211 fn neg(self) -> Self::Output {
212 RGBAf::new(-self.r, -self.g, -self.b, -self.a)
213 }
214}
215
216impl Index<usize> for RGBAf {
217 type Output = f32;
218
219 fn index(&self, index: usize) -> &Self::Output {
220 match index {
221 0 => &self.r,
222 1 => &self.g,
223 2 => &self.b,
224 3 => &self.a,
225 _ => panic!("`rmath::color::RGBAf::index`: index out of bounds."),
226 }
227 }
228}
229
230impl IndexMut<usize> for RGBAf {
231 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
232 match index {
233 0 => &mut self.r,
234 1 => &mut self.g,
235 2 => &mut self.b,
236 3 => &mut self.a,
237 _ => panic!("`rmath::color::RGBAf::index_mut`: index out of bounds."),
238 }
239 }
240}
241
242impl From<f32> for RGBAf {
243 fn from(rgb: f32) -> Self {
244 Self::new(rgb, rgb, rgb, 1.0)
245 }
246}
247
248impl From<(f32, f32, f32)> for RGBAf {
249 fn from(rgb: (f32, f32, f32)) -> Self {
250 Self::new(rgb.0, rgb.1, rgb.2, 1.0)
251 }
252}
253
254impl From<(f32, f32, f32, f32)> for RGBAf {
255 fn from(rgbaf: (f32, f32, f32, f32)) -> Self {
256 Self::new(rgbaf.0, rgbaf.1, rgbaf.2, rgbaf.3)
257 }
258}
259
260impl From<[f32; 3]> for RGBAf {
261 fn from(rgb: [f32; 3]) -> Self {
262 Self::new(rgb[0], rgb[1], rgb[2], 1.0)
263 }
264}
265
266impl From<[f32; 4]> for RGBAf {
267 fn from(rgbaf: [f32; 4]) -> Self {
268 Self::new(rgbaf[0], rgbaf[1], rgbaf[2], rgbaf[3])
269 }
270}
271
272impl From<u32> for RGBAf {
273 fn from(rgba: u32) -> Self {
274 let r = ((rgba >> 24) & 0xff) as f32 / 255.0;
275 let g = ((rgba >> 16) & 0xff) as f32 / 255.0;
276 let b = ((rgba >> 8) & 0xff) as f32 / 255.0;
277 let a = (rgba & 0xff) as f32 / 255.0;
278 Self::new(r, g, b, a)
279 }
280}
281
282impl From<u8> for RGBAf {
283 fn from(rgba: u8) -> Self {
284 let rgba = rgba as f32 / 255.0;
285 Self::new(rgba, rgba, rgba, rgba)
286 }
287}
288
289impl From<(u8, u8, u8)> for RGBAf {
290 fn from(rgb: (u8, u8, u8)) -> Self {
291 let (r, g, b) = rgb;
292 let r = r as f32 / 255.0;
293 let g = g as f32 / 255.0;
294 let b = b as f32 / 255.0;
295 Self::new(r, g, b, 1.0)
296 }
297}
298
299impl From<(u8, u8, u8, u8)> for RGBAf {
300 fn from(rgba: (u8, u8, u8, u8)) -> Self {
301 let (r, g, b, a) = rgba;
302 let r = r as f32 / 255.0;
303 let g = g as f32 / 255.0;
304 let b = b as f32 / 255.0;
305 let a = a as f32 / 255.0;
306 Self::new(r, g, b, a)
307 }
308}
309
310impl From<[u8; 3]> for RGBAf {
311 fn from(rgb: [u8; 3]) -> Self {
312 let r = rgb[0] as f32 / 255.0;
313 let g = rgb[1] as f32 / 255.0;
314 let b = rgb[2] as f32 / 255.0;
315 Self::new(r, g, b, 1.0)
316 }
317}
318
319impl From<[u8; 4]> for RGBAf {
320 fn from(rgba: [u8; 4]) -> Self {
321 let r = rgba[0] as f32 / 255.0;
322 let g = rgba[1] as f32 / 255.0;
323 let b = rgba[2] as f32 / 255.0;
324 let a = rgba[3] as f32 / 255.0;
325 Self::new(r, g, b, a)
326 }
327}
328
329impl From<RGB> for RGBAf {
330 fn from(color: RGB) -> Self {
331 color.to_rgbaf()
332 }
333}
334
335impl From<(RGB, f32)> for RGBAf {
336 fn from(color: (RGB, f32)) -> Self {
337 color.0.to_rgbaf_alpha(color.1)
338 }
339}
340
341impl From<RGBf> for RGBAf {
342 fn from(color: RGBf) -> Self {
343 color.to_rgbaf()
344 }
345}
346
347impl From<(RGBf, f32)> for RGBAf {
348 fn from(color: (RGBf, f32)) -> Self {
349 color.0.to_rgbaf_alpha(color.1)
350 }
351}
352
353impl From<RGBA> for RGBAf {
354 fn from(color: RGBA) -> Self {
355 color.to_rgbaf()
356 }
357}
358
359impl From<RGB24> for RGBAf {
360 fn from(color: RGB24) -> Self {
361 color.to_rgbaf()
362 }
363}
364
365impl From<(RGB24, f32)> for RGBAf {
366 fn from(color: (RGB24, f32)) -> Self {
367 color.0.to_rgbaf_alpha(color.1)
368 }
369}
370
371impl From<RGBA32> for RGBAf {
372 fn from(color: RGBA32) -> Self {
373 color.to_rgbaf()
374 }
375}
376
377impl RGBAf {
378 pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
379 Self { r, g, b, a }
380 }
381
382 pub fn black() -> Self {
383 Self::new(0.0, 0.0, 0.0, 1.0)
384 }
385
386 pub fn white() -> Self {
387 Self::new(1.0, 1.0, 1.0, 1.0)
388 }
389
390 pub fn red() -> Self {
391 Self::new(1.0, 0.0, 0.0, 1.0)
392 }
393
394 pub fn green() -> Self {
395 Self::new(0.0, 1.0, 0.0, 1.0)
396 }
397
398 pub fn blue() -> Self {
399 Self::new(0.0, 0.0, 1.0, 1.0)
400 }
401
402 pub fn black_alpha(alpha: f32) -> Self {
403 Self::new(0.0, 0.0, 0.0, alpha)
404 }
405
406 pub fn white_alpha(alpha: f32) -> Self {
407 Self::new(1.0, 1.0, 1.0, alpha)
408 }
409
410 pub fn red_alpha(alpha: f32) -> Self {
411 Self::new(1.0, 0.0, 0.0, alpha)
412 }
413
414 pub fn green_alpha(alpha: f32) -> Self {
415 Self::new(0.0, 1.0, 0.0, alpha)
416 }
417
418 pub fn blue_alpha(alpha: f32) -> Self {
419 Self::new(0.0, 0.0, 1.0, alpha)
420 }
421
422 pub fn r(self) -> f32 {
423 self.r
424 }
425
426 pub fn g(self) -> f32 {
427 self.g
428 }
429
430 pub fn b(self) -> f32 {
431 self.b
432 }
433
434 pub fn a(self) -> f32 {
435 self.a
436 }
437}
438
439impl RGBAf {
440 pub fn sum(self) -> f32 {
441 self.r + self.g + self.b
442 }
443
444 pub fn gray(self) -> f32 {
445 self.sum() / 3.0
446 }
447
448 pub fn luma1(self) -> f32 {
449 0.299 * self.r + 0.587 * self.g + 0.144 * self.b
450 }
451
452 pub fn luma2(self) -> f32 {
453 0.2126 * self.r + 0.7152 * self.g + 0.0722 * self.b
454 }
455
456 pub fn min_element(self) -> f32 {
457 self.r.min(self.g).min(self.b).min(self.a)
458 }
459
460 pub fn max_element(self) -> f32 {
461 self.r.max(self.g).max(self.b).max(self.a)
462 }
463
464 pub fn is_finite(self) -> bool {
465 self.r.is_finite() && self.g.is_finite() && self.b.is_finite() && self.a.is_finite()
466 }
467
468 pub fn is_nan(self) -> bool {
469 self.r.is_nan() || self.g.is_nan() || self.b.is_nan() || self.a.is_nan()
470 }
471
472 pub fn is_infinite(self) -> bool {
473 self.r.is_infinite() || self.g.is_infinite() || self.b.is_infinite() || self.a.is_infinite()
474 }
475
476 pub fn clamp(self, min: Self, max: Self) -> Self {
477 ruby_assert!(min.r <= max.r);
478 ruby_assert!(min.g <= max.g);
479 ruby_assert!(min.b <= max.b);
480 ruby_assert!(min.a <= max.a);
481
482 self.min(max).max(min)
483 }
484
485 pub fn min(self, rhs: Self) -> Self {
486 Self::new(
487 self.r.min(rhs.r),
488 self.g.min(rhs.g),
489 self.b.min(rhs.b),
490 self.a.min(rhs.a),
491 )
492 }
493
494 pub fn max(self, rhs: Self) -> Self {
495 Self::new(
496 self.r.max(rhs.r),
497 self.g.max(rhs.g),
498 self.b.max(rhs.b),
499 self.a.max(rhs.a),
500 )
501 }
502
503 pub fn abs(self) -> Self {
504 Self::new(self.r.abs(), self.g.abs(), self.b.abs(), self.a.abs())
505 }
506
507 pub fn round(self) -> Self {
508 Self::new(
509 self.r.round(),
510 self.g.round(),
511 self.b.round(),
512 self.a.round(),
513 )
514 }
515
516 pub fn floor(self) -> Self {
517 Self::new(
518 self.r.floor(),
519 self.g.floor(),
520 self.b.floor(),
521 self.a.floor(),
522 )
523 }
524
525 pub fn ceil(self) -> Self {
526 Self::new(self.r.ceil(), self.g.ceil(), self.b.ceil(), self.a.ceil())
527 }
528
529 pub fn trunc(self) -> Self {
530 Self::new(
531 self.r.trunc(),
532 self.g.trunc(),
533 self.b.trunc(),
534 self.a.trunc(),
535 )
536 }
537
538 pub fn fract(self) -> Self {
539 Self::new(
540 self.r.fract(),
541 self.g.fract(),
542 self.b.fract(),
543 self.a.fract(),
544 )
545 }
546
547 pub fn sqrt(self) -> Self {
548 Self::new(self.r.sqrt(), self.g.sqrt(), self.b.sqrt(), self.a.sqrt())
549 }
550
551 pub fn exp(self) -> Self {
552 Self::new(self.r.exp(), self.g.exp(), self.b.exp(), self.a.exp())
553 }
554
555 pub fn exp2(self) -> Self {
556 Self::new(self.r.exp2(), self.g.exp2(), self.b.exp2(), self.a.exp2())
557 }
558
559 pub fn ln(self) -> Self {
560 Self::new(self.r.ln(), self.g.ln(), self.b.ln(), self.a.ln())
561 }
562
563 pub fn log(self, base: f32) -> Self {
564 Self::new(
565 self.r.log(base),
566 self.g.log(base),
567 self.b.log(base),
568 self.a.log(base),
569 )
570 }
571
572 pub fn log2(self) -> Self {
573 Self::new(self.r.log2(), self.g.log2(), self.b.log2(), self.a.log2())
574 }
575
576 pub fn log10(self) -> Self {
577 Self::new(
578 self.r.log10(),
579 self.g.log10(),
580 self.b.log10(),
581 self.a.log10(),
582 )
583 }
584
585 pub fn cbrt(self) -> Self {
586 Self::new(self.r.cbrt(), self.g.cbrt(), self.b.cbrt(), self.a.cbrt())
587 }
588
589 pub fn powf(self, n: f32) -> Self {
590 Self::new(
591 self.r.powf(n),
592 self.g.powf(n),
593 self.b.powf(n),
594 self.a.powf(n),
595 )
596 }
597
598 pub fn sin(self) -> Self {
599 Self::new(self.r.sin(), self.g.sin(), self.b.sin(), self.a.sin())
600 }
601
602 pub fn cos(self) -> Self {
603 Self::new(self.r.cos(), self.g.cos(), self.b.cos(), self.a.cos())
604 }
605
606 pub fn tan(self) -> Self {
607 Self::new(self.r.tan(), self.g.tan(), self.b.tan(), self.a.tan())
608 }
609
610 pub fn sin_cos(self) -> (Self, Self) {
611 (self.sin(), self.cos())
612 }
613
614 pub fn recip(self) -> Self {
615 Self::new(
616 self.r.recip(),
617 self.g.recip(),
618 self.b.recip(),
619 self.a.recip(),
620 )
621 }
622
623 pub fn saturate(self) -> Self {
624 self.clamp(Self::black_alpha(0.0), Self::white_alpha(1.0))
625 }
626
627 pub fn lerp(self, rhs: Self, s: f32) -> Self {
628 (rhs - self) * s + self
629 }
630
631 pub fn gamma_correct(self) -> Self {
632 let inv = 1.0 / 2.2;
633 Self::new(self.r.powf(inv), self.g.powf(inv), self.b.powf(inv), self.a)
634 }
635}
636
637impl RGBAf {
638 pub fn to_array(self) -> [f32; 4] {
639 [self.r, self.g, self.b, self.a]
640 }
641
642 pub fn to_tuple(self) -> (f32, f32, f32, f32) {
643 (self.r, self.g, self.b, self.a)
644 }
645
646 pub fn to_rgbf(self) -> RGBf {
647 RGBf::new(self.r, self.g, self.b)
648 }
649
650 pub fn to_rgb(self) -> RGB {
651 RGB::new(self.r as f64, self.g as f64, self.b as f64)
652 }
653
654 pub fn to_rgba(self) -> RGBA {
655 RGBA::new(self.r as f64, self.g as f64, self.b as f64, self.a as f64)
656 }
657
658 pub fn to_rgb24(self) -> RGB24 {
659 RGB24::new(
660 convert_f32_to_u8(self.r),
661 convert_f32_to_u8(self.g),
662 convert_f32_to_u8(self.b),
663 )
664 }
665
666 pub fn to_rgba32(self) -> RGBA32 {
667 RGBA32::new(
668 convert_f32_to_u8(self.r),
669 convert_f32_to_u8(self.g),
670 convert_f32_to_u8(self.b),
671 convert_f32_to_u8(self.a),
672 )
673 }
674}