1// LAF Gfx Library
2// Copyright (c) 2020-2022 Igara Studio S.A.
3// Copyright (c) 2001-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef GFX_HSV_H_INCLUDED
9#define GFX_HSV_H_INCLUDED
10#pragma once
11
12#include <algorithm>
13#include <cmath>
14
15namespace gfx {
16
17class Rgb;
18
19class Hsv {
20public:
21 Hsv()
22 : m_hue(0.0)
23 , m_saturation(0.0)
24 , m_value(0.0)
25 { }
26
27 Hsv(double hue, double saturation, double value);
28
29 Hsv(const Hsv& hsv)
30 : m_hue(hsv.hue())
31 , m_saturation(hsv.saturation())
32 , m_value(hsv.value())
33 { }
34
35 // RGB to HSV conversion
36 explicit Hsv(const Rgb& rgb);
37
38 // Returns color's hue, a value from 0 to 360
39 double hue() const { return m_hue; }
40
41 // Returns color's saturation, a value from 0 to 100
42 double saturation() const { return m_saturation; }
43
44 // Returns color's brightness, a value from 0 to 100
45 double value() const { return m_value; }
46
47 // Integer getters, hue=[0,360), saturation=[0,100], value=[0,100]
48 int hueInt() const;
49 int saturationInt() const;
50 int valueInt() const;
51
52 void hue(double hue) {
53 while (hue < 0.0) hue += 360.0;
54 m_hue = std::fmod(hue, 360.0);
55 }
56
57 void saturation(double saturation) {
58 m_saturation = std::clamp(saturation, 0.0, 1.0);
59 }
60
61 void value(double value) {
62 m_value = std::clamp(value, 0.0, 1.0);
63 }
64
65 // The comparison is done through the integer value of each component.
66 bool operator==(const Hsv& other) const {
67 return (hueInt() == other.hueInt() &&
68 saturationInt() == other.saturationInt() &&
69 valueInt() == other.valueInt());
70 }
71
72 bool operator!=(const Hsv& other) const {
73 return !operator==(other);
74 }
75
76private:
77 double m_hue;
78 double m_saturation;
79 double m_value;
80};
81
82} // namespace gfx
83
84#endif
85