This repository has been archived by the owner on Apr 16, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Colors.cpp
111 lines (89 loc) · 3.21 KB
/
Colors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/////////////////////////////////////////////////////////////////////////////////
//
// Thor C++ Library
// Copyright (c) 2011-2012 Jan Haller
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////
#include <Thor/Graphics/Colors.hpp>
#include <Aurora/Tools/ForEach.hpp>
#include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/Drawable.hpp>
#include <numeric>
#include <cassert>
namespace thor
{
sf::Color blendColors(const sf::Color& firstColor, const sf::Color& secondColor, float interpolation)
{
assert(interpolation >= 0.f && interpolation <= 1.f);
float firstPart = 1.f - interpolation;
return sf::Color(
static_cast<sf::Uint8>(firstPart * firstColor.r + interpolation * secondColor.r),
static_cast<sf::Uint8>(firstPart * firstColor.g + interpolation * secondColor.g),
static_cast<sf::Uint8>(firstPart * firstColor.b + interpolation * secondColor.b),
static_cast<sf::Uint8>(firstPart * firstColor.a + interpolation * secondColor.a));
}
detail::ColorGradientConvertible createGradient(const sf::Color& color)
{
return detail::ColorGradientConvertible(color);
}
// ---------------------------------------------------------------------------------------------------------------------------
ColorGradient::ColorGradient(const sf::Color& color)
: mColors(1, color)
, mTransitionTimes()
{
}
ColorGradient::ColorGradient(detail::ColorGradientConvertible origin)
: mColors()
, mTransitionTimes()
{
mColors.swap(origin.mColors);
mTransitionTimes.swap(origin.mTransitionTimes);
normalize();
}
sf::Color ColorGradient::getColor(float interpolation) const
{
assert(interpolation >= 0.f && interpolation <= 1.f);
// If the gradient consists of a single color, return it independently of when
if (mColors.size() == 1)
return mColors[0];
// Find out to which transition the parameter belongs
std::size_t index = 0;
float sum = 0.f;
AURORA_CITR_FOREACH(itr, mTransitionTimes)
{
sum += *itr;
if (sum >= interpolation)
{
sum -= *itr;
break;
}
++index;
}
// Return interpolation of colors at each end of the transition
return blendColors(mColors[index], mColors[index+1], (interpolation - sum) / mTransitionTimes[index]);
}
void ColorGradient::normalize()
{
float sum = std::accumulate(mTransitionTimes.begin(), mTransitionTimes.end(), 0.f);
AURORA_ITR_FOREACH(itr, mTransitionTimes)
*itr /= sum;
}
} // namespace thor