diff --git a/coresdk/src/coresdk/color.cpp b/coresdk/src/coresdk/color.cpp index 9cb79de1..c3dd9348 100644 --- a/coresdk/src/coresdk/color.cpp +++ b/coresdk/src/coresdk/color.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "utility_functions.h" @@ -38,9 +39,6 @@ namespace splashkit_lib return rgba_color(red / 255.0f, green / 255.0f, blue / 255.0f, alpha / 255.0f); } - /// _gets a color given its color components. Each of the components has - /// a value between 0 and 1 - /// color rgba_color(double red, double green, double blue, double alpha) { color result; @@ -52,32 +50,33 @@ namespace splashkit_lib return result; } - /// _gets a color given its _r_g_b components. Each of the components has - /// a value between 0 and 1.0f. - /// color rgb_color(int red, int green, int blue) { return rgba_color(red / 255.0f, green / 255.0f, blue / 255.0f, 1.0f); } - /// _gets a color given its _r_g_b components. Each of the components has - /// a value between 0 and 1. - /// color rgb_color(double red, double green, double blue) { return rgba_color(red, green, blue, 1.0f); } - /// _returs a color from a combination of hue, saturation, and brightness. - /// - /// @param hue, saturation, brightness: _values between 0 and 1 - /// @returns _the matching color - /// color hsb_color(double hue, double saturation, double brightness) { double domain_offset; double red, green, blue; + double original_hue = hue; + double original_saturation = saturation; + double original_brightness = brightness; + + hue = std::clamp(hue, 0.0, 1.0); + saturation = std::clamp(saturation, 0.0, 1.0); + brightness = std::clamp(brightness, 0.0, 1.0); + + if (hue != original_hue || saturation != original_saturation || brightness != original_brightness) { + LOG(WARNING) << "Attempting to create a color from out-of-bounds HSB components. Values should be between 0 and 1."; + } + if (brightness == 0) return COLOR_BLACK; diff --git a/coresdk/src/test/unit_tests/unit_test_color.cpp b/coresdk/src/test/unit_tests/unit_test_color.cpp index 3388cc52..1eb3f573 100644 --- a/coresdk/src/test/unit_tests/unit_test_color.cpp +++ b/coresdk/src/test/unit_tests/unit_test_color.cpp @@ -74,3 +74,97 @@ TEST_CASE("can convert a color to a hex string", "[color_to_string][color_green] REQUIRE(alpha_of(result) == 200); } } + +TEST_CASE("hsb_color converts HSB to RGB correctly", "[hsb_color]") +{ + SECTION("black when brightness is 0") + { + color black = hsb_color(0.5, 1.0, 0.0); + REQUIRE(red_of(black) == 0); + REQUIRE(green_of(black) == 0); + REQUIRE(blue_of(black) == 0); + REQUIRE(alpha_of(black) == 255); + } + + SECTION("gray when saturation is 0") + { + color gray = hsb_color(0.3, 0.0, 0.5); + REQUIRE(red_of(gray) == 127); + REQUIRE(green_of(gray) == 127); + REQUIRE(blue_of(gray) == 127); + REQUIRE(alpha_of(gray) == 255); + } + + SECTION("pure red from HSB") + { + color red = hsb_color(0.0, 1.0, 1.0); + REQUIRE(red_of(red) == 255); + REQUIRE(green_of(red) == 0); + REQUIRE(blue_of(red) == 0); + REQUIRE(alpha_of(red) == 255); + } + + SECTION("pure green from HSB") + { + color green = hsb_color(1.0 / 3.0, 1.0, 1.0); + REQUIRE(red_of(green) == 0); + REQUIRE(green_of(green) == 255); + REQUIRE(blue_of(green) == 0); + REQUIRE(alpha_of(green) == 255); + } + + SECTION("pure blue from HSB") + { + color blue = hsb_color(2.0 / 3.0, 1.0, 1.0); + REQUIRE(red_of(blue) == 0); + REQUIRE(green_of(blue) == 0); + REQUIRE(blue_of(blue) == 255); + REQUIRE(alpha_of(blue) == 255); + } + + SECTION("pure yellow from HSB") + { + color yellow = hsb_color(1.0 / 6.0, 1.0, 1.0); + REQUIRE(red_of(yellow) == 255); + REQUIRE(green_of(yellow) == 255); + REQUIRE(blue_of(yellow) == 0); + REQUIRE(alpha_of(yellow) == 255); + } + + SECTION("pure cyan from HSB") + { + color cyan = hsb_color(0.5, 1.0, 1.0); + REQUIRE(red_of(cyan) == 0); + REQUIRE(green_of(cyan) == 255); + REQUIRE(blue_of(cyan) == 255); + REQUIRE(alpha_of(cyan) == 255); + } + + SECTION("pure magenta from HSB") + { + color magenta = hsb_color(5.0 / 6.0, 1.0, 1.0); + REQUIRE(red_of(magenta) == 255); + REQUIRE(green_of(magenta) == 0); + REQUIRE(blue_of(magenta) == 255); + REQUIRE(alpha_of(magenta) == 255); + } + + SECTION("Out-of-bounds values still return valid colors") + { + color low_hue = hsb_color(-0.5, 1.0, 1.0); + color high_hue = hsb_color(1.5, 1.0, 1.0); + color low_saturation = hsb_color(0.5, -0.5, 1.0); + color high_saturation = hsb_color(0.5, 1.5, 1.0); + color low_brightness = hsb_color(0.5, 1.0, -0.5); + color high_brightness = hsb_color(0.5, 1.0, 1.5); + + REQUIRE(red_of(low_hue) >= 0); + REQUIRE(red_of(high_hue) <= 255); + + REQUIRE(green_of(low_saturation) >= 0); + REQUIRE(green_of(high_saturation) <= 255); + + REQUIRE(blue_of(low_brightness) >= 0); + REQUIRE(blue_of(high_brightness) <= 255); + } +}