swf/types/
color_transform.rs

1use crate::{Color, Fixed8};
2use std::ops::{Mul, MulAssign};
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub struct ColorTransform {
6    pub r_multiply: Fixed8,
7    pub g_multiply: Fixed8,
8    pub b_multiply: Fixed8,
9    pub a_multiply: Fixed8,
10    pub r_add: i16,
11    pub g_add: i16,
12    pub b_add: i16,
13    pub a_add: i16,
14}
15
16impl ColorTransform {
17    pub const IDENTITY: Self = Self {
18        r_multiply: Fixed8::ONE,
19        b_multiply: Fixed8::ONE,
20        g_multiply: Fixed8::ONE,
21        a_multiply: Fixed8::ONE,
22        r_add: 0,
23        b_add: 0,
24        g_add: 0,
25        a_add: 0,
26    };
27
28    pub fn multiply_from(color: Color) -> Self {
29        Self {
30            r_multiply: Fixed8::from_f32(f32::from(color.r) / 255.0),
31            g_multiply: Fixed8::from_f32(f32::from(color.g) / 255.0),
32            b_multiply: Fixed8::from_f32(f32::from(color.b) / 255.0),
33            a_multiply: Fixed8::from_f32(f32::from(color.a) / 255.0),
34            ..Default::default()
35        }
36    }
37
38    /// Returns the multiplicative component of this color transform in RGBA order
39    /// with the values normalized [0.0, 1.0].
40    pub fn mult_rgba_normalized(&self) -> [f32; 4] {
41        [
42            self.r_multiply.into(),
43            self.g_multiply.into(),
44            self.b_multiply.into(),
45            self.a_multiply.into(),
46        ]
47    }
48
49    /// Returns the additive component of this color transform in RGBA order
50    /// with the values normalized [-1.0, 1.0].
51    pub fn add_rgba_normalized(&self) -> [f32; 4] {
52        [
53            f32::from(self.r_add) / 255.0,
54            f32::from(self.g_add) / 255.0,
55            f32::from(self.b_add) / 255.0,
56            f32::from(self.a_add) / 255.0,
57        ]
58    }
59
60    /// Sets the multiplicate component of this color transform.
61    pub fn set_mult_color(&mut self, color: &Color) {
62        self.r_multiply = Fixed8::from_f32(f32::from(color.r) / 255.0);
63        self.g_multiply = Fixed8::from_f32(f32::from(color.g) / 255.0);
64        self.b_multiply = Fixed8::from_f32(f32::from(color.b) / 255.0);
65        self.a_multiply = Fixed8::from_f32(f32::from(color.a) / 255.0);
66    }
67}
68
69impl Default for ColorTransform {
70    fn default() -> Self {
71        Self::IDENTITY
72    }
73}
74
75impl Mul for ColorTransform {
76    type Output = ColorTransform;
77
78    fn mul(self, rhs: Self) -> Self::Output {
79        ColorTransform {
80            r_multiply: self.r_multiply.wrapping_mul(rhs.r_multiply),
81            g_multiply: self.g_multiply.wrapping_mul(rhs.g_multiply),
82            b_multiply: self.b_multiply.wrapping_mul(rhs.b_multiply),
83            a_multiply: self.a_multiply.wrapping_mul(rhs.a_multiply),
84            r_add: self
85                .r_add
86                .wrapping_add(self.r_multiply.wrapping_mul_int(rhs.r_add)),
87            g_add: self
88                .g_add
89                .wrapping_add(self.g_multiply.wrapping_mul_int(rhs.g_add)),
90            b_add: self
91                .b_add
92                .wrapping_add(self.b_multiply.wrapping_mul_int(rhs.b_add)),
93            a_add: self
94                .a_add
95                .wrapping_add(self.a_multiply.wrapping_mul_int(rhs.a_add)),
96        }
97    }
98}
99
100impl MulAssign for ColorTransform {
101    fn mul_assign(&mut self, rhs: Self) {
102        *self = *self * rhs;
103    }
104}
105
106impl Mul<Color> for &ColorTransform {
107    type Output = Color;
108
109    fn mul(self, mut color: Color) -> Color {
110        if color.a > 0 {
111            color.r = self
112                .r_multiply
113                .mul_int(i16::from(color.r))
114                .saturating_add(self.r_add)
115                .clamp(0, 255) as u8;
116            color.g = self
117                .g_multiply
118                .mul_int(i16::from(color.g))
119                .saturating_add(self.g_add)
120                .clamp(0, 255) as u8;
121            color.b = self
122                .b_multiply
123                .mul_int(i16::from(color.b))
124                .saturating_add(self.b_add)
125                .clamp(0, 255) as u8;
126            color.a = self
127                .a_multiply
128                .mul_int(i16::from(color.a))
129                .saturating_add(self.a_add)
130                .clamp(0, 255) as u8;
131        }
132        color
133    }
134}