Skip to content

Commit 45f1279

Browse files
committed
Implemented some additional API functions related to crate::core_types::Color
Signed-off-by: Jacobsky <cael.jacobsen@gmail.com>
1 parent 37a35c5 commit 45f1279

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

gdnative-core/src/core_types/color.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::private::get_api;
22
use crate::sys;
33
use std::mem::transmute;
44

5+
use crate::core_types::GodotString;
56
/// RGBA color with 32 bits floating point components.
67
#[repr(C)]
78
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -47,6 +48,68 @@ impl Color {
4748
a: self.a + (weight * (other.a - self.a)),
4849
}
4950
}
51+
#[inline]
52+
pub fn blend(&self, other: &Color) -> Color {
53+
Color::from_sys(unsafe { (get_api().godot_color_blend)(self.sys(), other.sys()) })
54+
}
55+
56+
#[inline]
57+
pub fn contrasted(&self) -> Color {
58+
Color::from_sys(unsafe { (get_api().godot_color_contrasted)(self.sys()) })
59+
}
60+
#[inline]
61+
pub fn darkened(&self, amount: f32) -> Color {
62+
Color::from_sys(unsafe { (get_api().godot_color_darkened)(self.sys(), amount) })
63+
}
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+
}
69+
#[inline]
70+
pub fn gray(&self) -> f32 {
71+
// Implemented as described in godot docs
72+
(self.r + self.b + self.g) / 3.0
73+
}
74+
75+
#[inline]
76+
pub fn inverted(&self) -> Color {
77+
// Implementation as described in godot docs.
78+
Color {
79+
r: 1.0f32 - self.r,
80+
g: 1.0f32 - self.g,
81+
b: 1.0f32 - self.b,
82+
a: self.a,
83+
}
84+
}
85+
86+
pub fn to_abgr32(&self) -> i32 {
87+
unsafe { (get_api().godot_color_to_abgr32)(self.sys()) }
88+
}
89+
90+
pub fn to_abgr64(&self) -> i32 {
91+
unsafe { (get_api().godot_color_to_abgr64)(self.sys()) }
92+
}
93+
94+
pub fn to_argb32(&self) -> i32 {
95+
unsafe { (get_api().godot_color_to_argb32)(self.sys()) }
96+
}
97+
98+
pub fn to_argb64(&self) -> i32 {
99+
unsafe { (get_api().godot_color_to_argb64)(self.sys()) }
100+
}
101+
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) })
104+
}
105+
106+
pub fn to_rgba32(&self) -> i32 {
107+
unsafe { (get_api().godot_color_to_rgba32)(self.sys()) }
108+
}
109+
110+
pub fn to_rgba64(&self) -> i32 {
111+
unsafe { (get_api().godot_color_to_rgba64)(self.sys()) }
112+
}
50113

51114
#[doc(hidden)]
52115
#[inline]
@@ -72,3 +135,49 @@ fn color_repr() {
72135
use std::mem::size_of;
73136
assert_eq!(size_of::<Color>(), size_of::<sys::godot_color>());
74137
}
138+
139+
godot_test!(test_color {
140+
// 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());
147+
// Test Gray
148+
// String comparison due to non-trivial way to truncate floats
149+
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()));
154+
// Test invert
155+
let inverted = Color::rgb(1.0, 1.0,1.0).inverted();
156+
assert!(0f32.is_equal_approx(inverted.r));
157+
assert!(0f32.is_equal_approx(inverted.g));
158+
assert!(0f32.is_equal_approx(inverted.b));
159+
160+
let inverted = Color::rgb(0.95, 0.95,0.95).inverted();
161+
assert!(0.05f32.is_equal_approx(inverted.r));
162+
assert!(0.05f32.is_equal_approx(inverted.g));
163+
assert!(0.05f32.is_equal_approx(inverted.b));
164+
165+
let inverted = Color::rgb(0.05, 0.95,0.55).inverted();
166+
assert!(0.95f32.is_equal_approx(inverted.r));
167+
assert!(0.05f32.is_equal_approx(inverted.g));
168+
assert!(0.45f32.is_equal_approx(inverted.b));
169+
170+
// 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);
183+
});

test/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub extern "C" fn run_tests(
2222

2323
status &= gdnative::core_types::dictionary::test_dictionary();
2424
// status &= gdnative::test_dictionary_clone_clear();
25-
25+
status &= gdnative::core_types::test_color();
2626
status &= gdnative::core_types::test_array();
2727
status &= gdnative::core_types::test_array_debug();
2828
// status &= gdnative::test_array_clone_clear();

0 commit comments

Comments
 (0)