1// LAF Gfx Library
2// Copyright (c) 2020-2022 Igara Studio S.A.
3// Copyright (c) 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#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "gfx/hsl.h"
13#include "gfx/rgb.h"
14
15#include <algorithm>
16#include <cmath>
17
18namespace gfx {
19
20using namespace std;
21
22Hsl::Hsl(double hue, double saturation, double lightness)
23 : m_hue(hue)
24 , m_saturation(std::clamp(saturation, 0.0, 1.0))
25 , m_lightness(std::clamp(lightness, 0.0, 1.0))
26{ }
27
28Hsl::Hsl(const Rgb& rgb)
29{
30 const int M = rgb.maxComponent();
31 const int m = rgb.minComponent();
32 const int c = M - m;
33 const double chroma = double(c) / 255.0;
34 const double l = double((M + m) / 255.0) / 2.0;
35 double hue_prime = 0.0;
36 double h, s;
37
38 if (c == 0) {
39 h = 0.0; // Undefined Hue because max == min
40 s = 0.0;
41 }
42 else {
43 const double r = double(rgb.red()) / 255.0;
44 const double g = double(rgb.green()) / 255.0;
45 const double b = double(rgb.blue()) / 255.0;
46
47 if (M == rgb.red()) {
48 hue_prime = (g - b) / chroma;
49
50 while (hue_prime < 0.0)
51 hue_prime += 6.0;
52 hue_prime = std::fmod(hue_prime, 6.0);
53 }
54 else if (M == rgb.green()) {
55 hue_prime = ((b - r) / chroma) + 2.0;
56 }
57 else if (M == rgb.blue()) {
58 hue_prime = ((r - g) / chroma) + 4.0;
59 }
60
61 h = hue_prime * 60.0;
62 s = chroma / (1-std::fabs(2.0*l-1.0));
63 }
64
65 m_hue = h;
66 m_saturation = s;
67 m_lightness = l;
68}
69
70int Hsl::hueInt() const
71{
72 return int(std::floor(m_hue + 0.5));
73}
74
75int Hsl::saturationInt() const
76{
77 return int(std::floor(m_saturation*100.0 + 0.5));
78}
79
80int Hsl::lightnessInt() const
81{
82 return int(std::floor(m_lightness*100.0 + 0.5));
83}
84
85} // namespace gfx
86