@@ -14,16 +14,44 @@ pub struct Color {
14
14
}
15
15
16
16
impl Color {
17
+ #[ deprecated]
17
18
#[ inline]
18
19
pub fn rgba ( r : f32 , g : f32 , b : f32 , a : f32 ) -> Color {
19
20
Color { r, g, b, a }
20
21
}
21
22
23
+ #[ deprecated]
22
24
#[ inline]
23
25
pub fn rgb ( r : f32 , g : f32 , b : f32 ) -> Color {
24
26
Color { r, g, b, a : 1.0 }
25
27
}
26
28
29
+ #[ inline]
30
+ pub fn from_rgba ( r : f32 , g : f32 , b : f32 , a : f32 ) -> Color {
31
+ Color { r, g, b, a }
32
+ }
33
+
34
+ #[ inline]
35
+ pub fn from_rgb ( r : f32 , g : f32 , b : f32 ) -> Color {
36
+ Color { r, g, b, a : 1.0 }
37
+ }
38
+
39
+ #[ inline]
40
+ pub fn from_hsv ( h : f32 , s : f32 , v : f32 ) -> Color {
41
+ Color :: from_hsva ( h, s, v, 1.0 )
42
+ }
43
+
44
+ #[ inline]
45
+ pub fn from_hsva ( h : f32 , s : f32 , v : f32 , a : f32 ) -> Color {
46
+ let color = Color {
47
+ r : 0.0 ,
48
+ g : 0.0 ,
49
+ b : 0.0 ,
50
+ a : 0.0 ,
51
+ } ;
52
+ Color :: from_sys ( unsafe { ( get_api ( ) . godot_color_from_hsv ) ( color. sys ( ) , h, s, v, a) } )
53
+ }
54
+
27
55
#[ inline]
28
56
pub fn h ( & self ) -> f32 {
29
57
unsafe { ( get_api ( ) . godot_color_get_h ) ( self . sys ( ) ) }
@@ -48,6 +76,7 @@ impl Color {
48
76
a : self . a + ( weight * ( other. a - self . a ) ) ,
49
77
}
50
78
}
79
+
51
80
#[ inline]
52
81
pub fn blend ( & self , other : & Color ) -> Color {
53
82
Color :: from_sys ( unsafe { ( get_api ( ) . godot_color_blend ) ( self . sys ( ) , other. sys ( ) ) } )
@@ -57,15 +86,12 @@ impl Color {
57
86
pub fn contrasted ( & self ) -> Color {
58
87
Color :: from_sys ( unsafe { ( get_api ( ) . godot_color_contrasted ) ( self . sys ( ) ) } )
59
88
}
89
+
60
90
#[ inline]
61
91
pub fn darkened ( & self , amount : f32 ) -> Color {
62
92
Color :: from_sys ( unsafe { ( get_api ( ) . godot_color_darkened ) ( self . sys ( ) , amount) } )
63
93
}
64
- #[ inline]
65
- pub fn from_hsv ( h : f32 , s : f32 , v : f32 , a : f32 ) -> Color {
66
- let color = Color :: rgba ( 0.0 , 0.0 , 0.0 , 0.0 ) ;
67
- Color :: from_sys ( unsafe { ( get_api ( ) . godot_color_from_hsv ) ( color. sys ( ) , h, s, v, a) } )
68
- }
94
+
69
95
#[ inline]
70
96
pub fn gray ( & self ) -> f32 {
71
97
// Implemented as described in godot docs
@@ -76,39 +102,105 @@ impl Color {
76
102
pub fn inverted ( & self ) -> Color {
77
103
// Implementation as described in godot docs.
78
104
Color {
79
- r : 1.0f32 - self . r ,
80
- g : 1.0f32 - self . g ,
81
- b : 1.0f32 - self . b ,
105
+ r : 1.0 - self . r ,
106
+ g : 1.0 - self . g ,
107
+ b : 1.0 - self . b ,
82
108
a : self . a ,
83
109
}
84
110
}
85
111
86
- pub fn to_abgr32 ( & self ) -> i32 {
87
- unsafe { ( get_api ( ) . godot_color_to_abgr32 ) ( self . sys ( ) ) }
112
+ #[ inline]
113
+ pub fn to_html ( & self , with_alpha : bool ) -> GodotString {
114
+ GodotString :: from_sys ( unsafe { ( get_api ( ) . godot_color_to_html ) ( self . sys ( ) , with_alpha) } )
88
115
}
89
116
90
- pub fn to_abgr64 ( & self ) -> i32 {
91
- unsafe { ( get_api ( ) . godot_color_to_abgr64 ) ( self . sys ( ) ) }
117
+ /// Returns the reverse of the RGBA32 byte representation for this color where each byte represents a component of the ABGR profile.
118
+ /// This is the byte information used when storing this color as a part of a texture.
119
+ /// # Endianness
120
+ /// On big endian architecture this is stored in ABGR byte order
121
+ /// On little endian machines this is stored in RGBA byte order
122
+ /// # Example
123
+ /// `0x00FF7FFF` would be the equivalent to `Color::from_rgba(1.0, 0.5, 1.0, 0.0)`
124
+ #[ inline]
125
+ pub fn to_abgr32 ( & self ) -> u32 {
126
+ ( ( self . a * 255.0 ) as u32 ) << 24
127
+ | ( ( self . b * 255.0 ) as u32 ) << 16
128
+ | ( ( self . g * 255.0 ) as u32 ) << 8
129
+ | ( self . r * 255.0 ) as u32
92
130
}
93
131
94
- pub fn to_argb32 ( & self ) -> i32 {
95
- unsafe { ( get_api ( ) . godot_color_to_argb32 ) ( self . sys ( ) ) }
132
+ /// Returns the reverse of the RGBA64 byte representation for this color where each word represents represents a component of the ABGR profile.
133
+ /// This is the byte information used when storing this color as a part of a texture.
134
+ /// # Endianness
135
+ /// On big endian architecture this is stored in ABGR word order
136
+ /// On little endian machines this is stored in RGBA word order
137
+ /// # Example
138
+ /// `0x0000FFFF7FFFFFFF` would be the equivalent to `Color::from_rgba(0.0, 1.0, 0.5, 1.0)`
139
+ #[ inline]
140
+ pub fn to_abgr64 ( & self ) -> u64 {
141
+ ( ( self . a * 65535.0 ) as u64 ) << 48
142
+ | ( ( self . b * 65535.0 ) as u64 ) << 32
143
+ | ( ( self . g * 65535.0 ) as u64 ) << 16
144
+ | ( ( self . r * 65535.0 ) as u64 )
96
145
}
97
146
98
- pub fn to_argb64 ( & self ) -> i32 {
99
- unsafe { ( get_api ( ) . godot_color_to_argb64 ) ( self . sys ( ) ) }
147
+ /// Returns the ARGB32 format representation representation for this color where each byte represents a component of the ARGB profile.
148
+ /// This is the byte information used when storing this color as a part of a texture.
149
+ /// # Endianness
150
+ /// On big endian architecture this is stored in the order ARGB byte order
151
+ /// On little endian machines this is stored in the order BGRA byte order
152
+ /// `0x0000FFFF7FFFFFFF` would be the equivalent to `Color::from_rgba(1.0, 0.5, 1.0, 0.0)`
153
+ #[ inline]
154
+ pub fn to_argb32 ( & self ) -> u32 {
155
+ ( ( self . a * 255.0 ) as u32 ) << 24
156
+ | ( ( self . r * 255.0 ) as u32 ) << 16
157
+ | ( ( self . g * 255.0 ) as u32 ) << 8
158
+ | ( self . b * 255.0 ) as u32
100
159
}
101
160
102
- pub fn to_html ( & self , with_alpha : bool ) -> GodotString {
103
- GodotString :: from_sys ( unsafe { ( get_api ( ) . godot_color_to_html ) ( self . sys ( ) , with_alpha) } )
161
+ /// Returns the ARGB64 format representation for this color where each word represents a component of the ARGB profile.
162
+ /// This is the byte information used when storing this color as a part of a texture.
163
+ /// # Endianness
164
+ /// On big endian architecture this is stored in the order ARGB word order
165
+ /// On little endian machines this is stored in the order BGRA word order
166
+ /// # Example
167
+ /// `0x0000FFFF7FFFFFFF` would be the equivalent to `Color::from_rgba(1.0, 0.5, 1.0, 0.0)`
168
+ #[ inline]
169
+ pub fn to_argb64 ( & self ) -> u64 {
170
+ ( ( self . a * 65535.0 ) as u64 ) << 48
171
+ | ( ( self . r * 65535.0 ) as u64 ) << 32
172
+ | ( ( self . g * 65535.0 ) as u64 ) << 16
173
+ | ( ( self . b * 65535.0 ) as u64 )
104
174
}
105
175
106
- pub fn to_rgba32 ( & self ) -> i32 {
107
- unsafe { ( get_api ( ) . godot_color_to_rgba32 ) ( self . sys ( ) ) }
176
+ /// Returns the OpenGL Texture format byte representation for this color where each byte represents a component of the RGBA profile.
177
+ /// This is the byte information used when storing this color as a part of a texture.
178
+ /// # Endianness
179
+ /// On big endian architecture this is stored in RGBA byte order
180
+ /// On little endian machines this is stored in ABGR byte order
181
+ /// # Example
182
+ /// `0x00FF7FFF` would be the equivalent to `Color::from_rgba(0.0, 1.0, 0.5, 1.0)`
183
+ #[ inline]
184
+ pub fn to_rgba32 ( & self ) -> u32 {
185
+ ( ( self . r * 255.0 ) as u32 ) << 24
186
+ | ( ( self . g * 255.0 ) as u32 ) << 16
187
+ | ( ( self . b * 255.0 ) as u32 ) << 8
188
+ | ( self . a * 255.0 ) as u32
108
189
}
109
190
110
- pub fn to_rgba64 ( & self ) -> i32 {
111
- unsafe { ( get_api ( ) . godot_color_to_rgba64 ) ( self . sys ( ) ) }
191
+ /// Returns the OpenGL Texture format byte representation for this color where each byte represents a component of the RGBA profile.
192
+ /// This is the byte information used when storing this color as a part of a texture.
193
+ /// # Endianness
194
+ /// On big endian architecture this is stored in RGBA word order
195
+ /// On little endian machines this is stored in ABGR word order
196
+ /// # Example
197
+ /// `0x0000FFFF7FFFFFFF` would be the equivalent to `Color::from_rgba(0.0, 1.0, 0.5, 1.0)`
198
+ #[ inline]
199
+ pub fn to_rgba64 ( & self ) -> u64 {
200
+ ( ( self . r * 65535.0 ) as u64 ) << 48
201
+ | ( ( self . g * 65535.0 ) as u64 ) << 32
202
+ | ( ( self . b * 65535.0 ) as u64 ) << 16
203
+ | ( ( self . a * 65535.0 ) as u64 )
112
204
}
113
205
114
206
#[ doc( hidden) ]
@@ -136,48 +228,59 @@ fn color_repr() {
136
228
assert_eq ! ( size_of:: <Color >( ) , size_of:: <sys:: godot_color>( ) ) ;
137
229
}
138
230
231
+ #[ test]
232
+ fn color_to_pixel_color_formats ( ) {
233
+ let color = Color :: from_rgba ( 1.0 , 0.5 , 1.0 , 0.0 ) ;
234
+ assert_eq ! ( 0xFF7FFF00 , color. to_rgba32( ) ) ;
235
+ assert_eq ! ( 0xFFFF7FFFFFFF0000 , color. to_rgba64( ) ) ;
236
+ assert_eq ! ( 0x00FF7FFF , color. to_abgr32( ) ) ;
237
+ assert_eq ! ( 0x0000FFFF7FFFFFFF , color. to_abgr64( ) ) ;
238
+ assert_eq ! ( 0x00FF7FFF , color. to_argb32( ) ) ;
239
+ assert_eq ! ( 0x0000FFFF7FFFFFFF , color. to_argb64( ) ) ;
240
+ }
241
+
139
242
godot_test ! ( test_color {
140
243
// Test to_html
141
- assert_eq!( "ffffffff" , Color :: rgba ( 1.0 , 1.0 , 1.0 , 1.0 ) . to_html( true ) . to_string( ) ) ;
142
- assert_eq!( "ffffff" , Color :: rgba ( 1.0 , 1.0 , 1.0 , 1.0 ) . to_html( false ) . to_string( ) ) ;
143
- assert_eq!( "80ffffff" , Color :: rgba ( 1.0 , 1.0 , 1.0 , 0.5 ) . to_html( true ) . to_string( ) ) ;
144
- assert_eq!( "ffffff" , Color :: rgba ( 1.0 , 1.0 , 1.0 , 0.5 ) . to_html( false ) . to_string( ) ) ;
145
- assert_eq!( "ff8000" , Color :: rgb ( 1.0 , 0.5 , 0.0 ) . to_html( false ) . to_string( ) ) ;
146
- assert_eq!( "ff0080ff" , Color :: rgb ( 0.0 , 0.5 , 1.0 ) . to_html( true ) . to_string( ) ) ;
244
+ assert_eq!( "ffffffff" , Color :: from_rgba ( 1.0 , 1.0 , 1.0 , 1.0 ) . to_html( true ) . to_string( ) ) ;
245
+ assert_eq!( "ffffff" , Color :: from_rgba ( 1.0 , 1.0 , 1.0 , 1.0 ) . to_html( false ) . to_string( ) ) ;
246
+ assert_eq!( "80ffffff" , Color :: from_rgba ( 1.0 , 1.0 , 1.0 , 0.5 ) . to_html( true ) . to_string( ) ) ;
247
+ assert_eq!( "ffffff" , Color :: from_rgba ( 1.0 , 1.0 , 1.0 , 0.5 ) . to_html( false ) . to_string( ) ) ;
248
+ assert_eq!( "ff8000" , Color :: from_rgb ( 1.0 , 0.5 , 0.0 ) . to_html( false ) . to_string( ) ) ;
249
+ assert_eq!( "ff0080ff" , Color :: from_rgb ( 0.0 , 0.5 , 1.0 ) . to_html( true ) . to_string( ) ) ;
147
250
// Test Gray
148
251
// String comparison due to non-trivial way to truncate floats
149
252
use crate :: core_types:: IsEqualApprox ;
150
- assert!( 0.4f32 . is_equal_approx( Color :: rgb ( 0.2 , 0.4 , 0.6 ) . gray( ) ) ) ;
151
- assert!( 0.5f32 . is_equal_approx( Color :: rgb ( 0.1 , 0.5 , 0.9 ) . gray( ) ) ) ;
152
- assert!( 0.9f32 . is_equal_approx( Color :: rgb ( 1.0 , 1.0 , 0.7 ) . gray( ) ) ) ;
153
- assert!( 0.42f32 . is_equal_approx( Color :: rgb ( 0.6 , 0.6 , 0.06 ) . gray( ) ) ) ;
253
+ assert!( 0.4f32 . is_equal_approx( Color :: from_rgb ( 0.2 , 0.4 , 0.6 ) . gray( ) ) ) ;
254
+ assert!( 0.5f32 . is_equal_approx( Color :: from_rgb ( 0.1 , 0.5 , 0.9 ) . gray( ) ) ) ;
255
+ assert!( 0.9f32 . is_equal_approx( Color :: from_rgb ( 1.0 , 1.0 , 0.7 ) . gray( ) ) ) ;
256
+ assert!( 0.42f32 . is_equal_approx( Color :: from_rgb ( 0.6 , 0.6 , 0.06 ) . gray( ) ) ) ;
154
257
// Test invert
155
- let inverted = Color :: rgb ( 1.0 , 1.0 , 1.0 ) . inverted( ) ;
258
+ let inverted = Color :: from_rgb ( 1.0 , 1.0 , 1.0 ) . inverted( ) ;
156
259
assert!( 0f32 . is_equal_approx( inverted. r) ) ;
157
260
assert!( 0f32 . is_equal_approx( inverted. g) ) ;
158
261
assert!( 0f32 . is_equal_approx( inverted. b) ) ;
159
262
160
- let inverted = Color :: rgb ( 0.95 , 0.95 , 0.95 ) . inverted( ) ;
263
+ let inverted = Color :: from_rgb ( 0.95 , 0.95 , 0.95 ) . inverted( ) ;
161
264
assert!( 0.05f32 . is_equal_approx( inverted. r) ) ;
162
265
assert!( 0.05f32 . is_equal_approx( inverted. g) ) ;
163
266
assert!( 0.05f32 . is_equal_approx( inverted. b) ) ;
164
267
165
- let inverted = Color :: rgb ( 0.05 , 0.95 , 0.55 ) . inverted( ) ;
268
+ let inverted = Color :: from_rgb ( 0.05 , 0.95 , 0.55 ) . inverted( ) ;
166
269
assert!( 0.95f32 . is_equal_approx( inverted. r) ) ;
167
270
assert!( 0.05f32 . is_equal_approx( inverted. g) ) ;
168
271
assert!( 0.45f32 . is_equal_approx( inverted. b) ) ;
169
272
170
273
// This is a series of sanity checks to test that the API bounds work properly.
171
- let color = Color :: from_hsv( 1.0 , 1.0 , 1.0 , 1.0 ) ;
172
- color. darkened ( 0.20 ) ;
173
- color . contrasted ( ) ;
174
- color. inverted ( ) ;
175
- color. to_rgba32 ( ) ;
176
- color . to_rgba64 ( ) ;
177
- color. to_abgr32 ( ) ;
178
- color. to_abgr64 ( ) ;
179
- color . to_argb32 ( ) ;
180
- color. to_argb64 ( ) ;
181
- let other_color = Color :: rgba ( 1.0 , 1 .0, 1.0 , 1.0 ) ;
182
- color. blend( & other_color) ;
274
+ let hsv_color = Color :: from_hsv( 0.75 , 0.5 , 0.25 ) ;
275
+ let color = Color :: from_hsva ( 0.75 , 0.5 , 0.25 , 1.0 ) ;
276
+ assert_eq! ( hsv_color , color ) ;
277
+ let color = Color :: from_rgb ( 0.75 , 0.5 , 0.25 ) ;
278
+ assert_eq! ( Color :: from_rgb ( 0.25 , 0.5 , 0.75 ) , color. inverted ( ) ) ;
279
+ // Following results were derived from the godot engine code based on the RGB values of 0.75, 0.5, 0.25 respectively.
280
+ assert_eq! ( Color :: from_rgb ( 0.25 , 0.00 , 0.75 ) , color. contrasted ( ) ) ;
281
+ assert_eq! ( Color :: from_rgba ( 0.60 , 0.40 , 0.20 , 1.0 ) , color. darkened ( 0.20 ) ) ;
282
+ // Check that the blend values are correct.
283
+ let color = Color :: from_rgba ( 0.0 , 1.0 , 0.5 , 1.0 ) ;
284
+ let other_color = Color :: from_rgba ( 1.0 , 0 .0, 0.5 , 1.0 ) ;
285
+ assert_eq! ( Color :: from_rgba ( 1.0 , 0.0 , 0.5 , 1.0 ) , color. blend( & other_color) ) ;
183
286
} ) ;
0 commit comments