commit 99a0e38e6ebb839a987ab4438d28f4d091fdc499 Author: JDierkse Date: Mon May 4 21:24:48 2020 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..851ef09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o.* +*.d.* +*.a.* +.*.swp +.AppleDouble +lib diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7da2786 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Makefiles"] + path = Makefiles + url = https://gogs.dierkse.nl/JDierkse/Makefiles.git diff --git a/Color/Color.cpp b/Color/Color.cpp new file mode 100644 index 0000000..bcfbbd7 --- /dev/null +++ b/Color/Color.cpp @@ -0,0 +1,338 @@ +#include "Color.h" +#include +#include +#include + + +namespace Color { + +Color::Color(const Color::HSL& hsl) : + m_hsl(hsl) +{ +} + +Color::Color(const Color::RGB& rgb) : + m_hsl(rgbToHSL(rgb)) +{ +} + +Color Color::FromHSL(int hue, int saturation, int luminance) +{ + return Color(HSL{Conversion::Hue(hue), Conversion::Saturation(saturation), Conversion::Luminance(luminance)}); +} + +Color Color::FromHSLString(const std::string& hslString) +{ + std::vector tokens = StringAlgorithm::split(hslString, '-'); + return Color(HSL{Conversion::Hue(Conversion::Hue(tokens[0])), Conversion::Saturation(Conversion::Saturation(tokens[1])), Conversion::Luminance(Conversion::Luminance(tokens[2]))}); +} + +Color Color::FromRGB(int red, int green, int blue) +{ + return Color(RGB{Conversion::Red(red), Conversion::Green(green), Conversion::Blue(blue)}); +} + +Color Color::FromRGBString(const std::string& rgbString) +{ + std::vector tokens = StringAlgorithm::split(rgbString, '-'); + return Color(RGB{Conversion::Red(Conversion::Red(tokens[0])), Conversion::Green(Conversion::Green(tokens[1])), Conversion::Blue(Conversion::Blue(tokens[2]))}); +} + +int Color::Hue() const +{ + return Conversion::Hue(m_hsl.hue); +} + +void Color::Hue(int hue) +{ + Hue(Conversion::Hue(hue)); +} + +void Color::Hue(double hue) +{ + m_hsl.hue = hue; +} + +int Color::Saturation() const +{ + return Conversion::Saturation(m_hsl.saturation); +} + +void Color::Saturation(int saturation) +{ + Saturation(Conversion::Saturation(saturation)); +} + +void Color::Saturation(double saturation) +{ + m_hsl.saturation = saturation; +} + +int Color::Luminance() const +{ + return Conversion::Luminance(m_hsl.luminance); +} + +void Color::Luminance(int luminance) +{ + Luminance(Conversion::Luminance(luminance)); +} + +void Color::Luminance(double luminance) +{ + m_hsl.luminance = luminance; +} + +std::string Color::HSLString() const +{ + std::stringstream ss; + ss << std::setw(3) << std::setfill('0') << Hue(); + ss << "-"; + ss << std::setw(3) << std::setfill('0') << Saturation(); + ss << "-"; + ss << std::setw(3) << std::setfill('0') << Luminance(); + return ss.str(); +} + +int Color::Red() const +{ + RGB rgb = hslToRGB(m_hsl); + return Conversion::Red(rgb.red); +} + +void Color::Red(int red) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.red = Conversion::Red(red); + m_hsl = rgbToHSL(rgb); +} + +void Color::Red(double red) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.red = red; + m_hsl = rgbToHSL(rgb); +} + +int Color::Green() const +{ + RGB rgb = hslToRGB(m_hsl); + return Conversion::Green(rgb.green); +} + +void Color::Green(int green) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.green = Conversion::Green(green); + m_hsl = rgbToHSL(rgb); +} + +void Color::Green(double green) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.green = green; + m_hsl = rgbToHSL(rgb); +} + +int Color::Blue() const +{ + RGB rgb = hslToRGB(m_hsl); + return Conversion::Blue(rgb.blue); +} + +void Color::Blue(int blue) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.blue = Conversion::Blue(blue); + m_hsl = rgbToHSL(rgb); +} + +void Color::Blue(double blue) +{ + RGB rgb = hslToRGB(m_hsl); + rgb.blue = blue; + m_hsl = rgbToHSL(rgb); +} + +std::string Color::RGBString() const +{ + std::stringstream ss; + ss << std::setw(3) << std::setfill('0') << Red(); + ss << "-"; + ss << std::setw(3) << std::setfill('0') << Green(); + ss << "-"; + ss << std::setw(3) << std::setfill('0') << Blue(); + return ss.str(); +} + +double Color::Conversion::Hue(int hue) +{ + return static_cast(hue) / m_hueFactor; +} + +int Color::Conversion::Hue(double hue) +{ + return static_cast(hue * m_hueFactor); +} + +int Color::Conversion::Hue(const std::string& hue) +{ + return std::stoi(hue); +} + +double Color::Conversion::Saturation(int saturation) +{ + return static_cast(saturation) / m_saturationFactor; +} + +int Color::Conversion::Saturation(double saturation) +{ + return static_cast(saturation * m_saturationFactor); +} + +int Color::Conversion::Saturation(const std::string& saturation) +{ + return std::stoi(saturation); +} + +double Color::Conversion::Luminance(int luminance) +{ + return static_cast(luminance) / m_luminanceFactor; +} + +int Color::Conversion::Luminance(double luminance) +{ + return static_cast(luminance * m_luminanceFactor); +} + +int Color::Conversion::Luminance(const std::string& luminance) +{ + return std::stoi(luminance); +} + +double Color::Conversion::Red(int red) +{ + return static_cast(red) / m_redFactor; +} + +int Color::Conversion::Red(double red) +{ + return static_cast(red * m_redFactor); +} + +int Color::Conversion::Red(const std::string& red) +{ + return std::stoi(red); +} + +double Color::Conversion::Green(int green) +{ + return static_cast(green) / m_greenFactor; +} + +int Color::Conversion::Green(double green) +{ + return static_cast(green * m_greenFactor); +} + +int Color::Conversion::Green(const std::string& green) +{ + return std::stoi(green); +} + +double Color::Conversion::Blue(int blue) +{ + return static_cast(blue) / m_blueFactor; +} + +int Color::Conversion::Blue(double blue) +{ + return static_cast(blue * m_blueFactor); +} + +int Color::Conversion::Blue(const std::string& blue) +{ + return std::stoi(blue); +} + +Color::HSL Color::rgbToHSL(const Color::RGB& rgb) +{ + double min = rgb.red < rgb.green? rgb.red: rgb.green; + min = min < rgb.blue? min: rgb.blue; + + double max = rgb.red > rgb.green? rgb.red: rgb.green; + max = max > rgb.blue? max: rgb.blue; + + double luminance = max; + double delta = max - min; + if (delta < 0.00001) + return HSL{0, 0, 0}; + + if (max <= 0.0) + return HSL{0, 0, 0}; + + double saturation = (delta / max); + double hue; + + if (rgb.red >= max) + { + hue = (rgb.green - rgb.blue) / delta; + } + else + { + if (rgb.green >= max) + hue = 2.0 + (rgb.blue - rgb.red) / delta; + else + hue = 4.0 + (rgb.red - rgb.green) / delta; + } + + hue *= 60.0; + + if (hue < 0.0) + hue += 360.0; + + hue /= 360; + + return Color::HSL{hue, saturation, luminance}; +} + +Color::RGB Color::hslToRGB(const Color::HSL& hsl) +{ + double red, green, blue; + + if (hsl.saturation <= 0.0) + return Color::RGB{hsl.luminance, hsl.luminance, hsl.luminance}; + + double hue = hsl.hue * 360; + if (hue >= 360.0) + hue = 0.0; + + hue /= 60.0; + + long i = static_cast(hue); + double ff = hue - i; + double p = hsl.luminance * (1.0 - hsl.saturation); + double q = hsl.luminance * (1.0 - (hsl.saturation * ff)); + double t = hsl.luminance * (1.0 - (hsl.saturation * (1.0 - ff))); + + switch(i) + { + case 0: + return Color::RGB{hsl.luminance, t, p}; + case 1: + return Color::RGB{q, hsl.luminance, p}; + case 2: + return Color::RGB{p, hsl.luminance, t}; + case 3: + return Color::RGB{p, q, hsl.luminance}; + case 4: + return Color::RGB{t, p, hsl.luminance}; + case 5: + default: + return Color::RGB{hsl.luminance, p, q}; + } + + return Color::RGB{0, 0, 0}; +} + +} // namespace Color diff --git a/Color/Makefile b/Color/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/Color/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/Libraries/Utilities b/Libraries/Utilities new file mode 120000 index 0000000..4a6b454 --- /dev/null +++ b/Libraries/Utilities @@ -0,0 +1 @@ +../../Utilities \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 120000 index 0000000..6aa5187 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +Makefiles/Makefile \ No newline at end of file diff --git a/Makefile.conf b/Makefile.conf new file mode 100644 index 0000000..f7319ed --- /dev/null +++ b/Makefile.conf @@ -0,0 +1,13 @@ +# +# Makefile.conf +# + +LFLAGS += -lUtilities +LFLAGS += -L$(ROOTPATH)/Libraries/Utilities/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/Utilities/include + +LFLAGS += -lColor +LFLAGS += -L$(ROOTPATH)/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/include + +DEBUGDIR := .debug diff --git a/Makefile.target b/Makefile.target new file mode 100644 index 0000000..bc48683 --- /dev/null +++ b/Makefile.target @@ -0,0 +1,13 @@ +# +# Makefile.target +# + +Color.a.$(ARCH) : $(OBJECTS) + $(call build_target_library_arch,$@,$^) + +Color.a: + $(call build_target,$@) + +.DEFAULT_GOAL := Color.a + +TARGETS += Color.a diff --git a/Makefiles b/Makefiles new file mode 160000 index 0000000..cd9ef1a --- /dev/null +++ b/Makefiles @@ -0,0 +1 @@ +Subproject commit cd9ef1a1b0f7b88f36b0c51b4209d1859aca83aa diff --git a/include/Color.h b/include/Color.h new file mode 100644 index 0000000..347742a --- /dev/null +++ b/include/Color.h @@ -0,0 +1,108 @@ +#ifndef COLOR_H +#define COLOR_H + +#include + + +namespace Color { + +class Color +{ +public: + Color() = default; + +public: + static Color FromHSL(int hue, int saturation, int luminance); + static Color FromHSLString(const std::string& hslString); + static Color FromRGB(int red, int green, int blue); + static Color FromRGBString(const std::string& rgbString); + +public: + int Hue() const; + void Hue(int hue); + void Hue(double hue); + int Saturation() const; + void Saturation(int saturation); + void Saturation(double saturation); + int Luminance() const; + void Luminance(int luminance); + void Luminance(double luminance); + std::string HSLString() const; + + int Red() const; + void Red(int red); + void Red(double red); + int Green() const; + void Green(int green); + void Green(double green); + int Blue() const; + void Blue(int blue); + void Blue(double blue); + std::string RGBString() const; + +private: + struct HSL + { + double hue; + double saturation; + double luminance; + }; + + struct RGB + { + double red; + double green; + double blue; + }; + + class Conversion + { + public: + Conversion() = delete; + ~Conversion() = delete; + + public: + static double Hue(int hue); + static int Hue(double hue); + static int Hue(const std::string& hue); + static double Saturation(int saturation); + static int Saturation(double saturation); + static int Saturation(const std::string& saturation); + static double Luminance(int luminance); + static int Luminance(double luminance); + static int Luminance(const std::string& luminance); + + static double Red(int red); + static int Red(double red); + static int Red(const std::string& red); + static double Green(int green); + static int Green(double green); + static int Green(const std::string& green); + static double Blue(int blue); + static int Blue(double blue); + static int Blue(const std::string& blue); + + private: + static const int m_hueFactor = 255; + static const int m_saturationFactor = 255; + static const int m_luminanceFactor = 255; + static const int m_redFactor = 255; + static const int m_greenFactor = 255; + static const int m_blueFactor = 255; + }; + +private: + Color(const Color::HSL& hsl); + Color(const Color::RGB& rgb); + +private: + static Color::HSL rgbToHSL(const Color::RGB& rgb); + static Color::RGB hslToRGB(const Color::HSL& hsl); + +private: + HSL m_hsl; +}; + +} // namespace Color + +#endif // COLOR_H