TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
gui_style_gradient.h
Go to the documentation of this file.
1#pragma once
2
4
5#include <span>
6#include <cmath>
7#include <array>
8
9namespace tachyon
10{
13
14 // ------------------------------------------------------------------------
15 // Color and Gradient Types
16 // ------------------------------------------------------------------------
17
19 struct ColorStop
20 {
21 private:
22 color4b color = {};
23 uint16_t offset = 0;
24
25 public:
26 bool operator==(const ColorStop& other) const noexcept = default;
27
28 ColorStop& SetColor(color4b newColor) { color = newColor; return *this; }
29
32 {
33 newColor.r = (newColor.r < 0) ? 0 : (newColor.r > 1) ? 1 : newColor.r;
34 newColor.g = (newColor.g < 0) ? 0 : (newColor.g > 1) ? 1 : newColor.g;
35 newColor.b = (newColor.b < 0) ? 0 : (newColor.b > 1) ? 1 : newColor.b;
36 newColor.a = (newColor.a < 0) ? 0 : (newColor.a > 1) ? 1 : newColor.a;
37 auto pack = [](float value) -> byte
38 {
39 int iv = static_cast<int>(std::lround(value * 255.0f));
40 iv = std::clamp(iv, 0, 255);
41 return static_cast<byte>(iv);
42 };
43 color = color4b{
44 .r = pack(newColor.r),
45 .g = pack(newColor.g),
46 .b = pack(newColor.b),
47 .a = pack(newColor.a)
48 };
49 return *this;
50 }
51
53 ColorStop& SetOffset(float newOffset)
54 {
55 if (newOffset < 0.0f) newOffset = 0.0f;
56 if (newOffset >= 1.0f) newOffset = 1.0f;
57 offset = static_cast<uint16_t>(newOffset * 65535.0f);
58 return *this;
59 }
60
62 float GetOffset() const { return (offset / 65535.0f); }
64 color4f GetColor4f() const { return color4f { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f }; }
65 color4b GetColor4b() const { return color; }
66 };
67
70 enum class GradientType : uint8_t
71 {
73 Linear,
75 };
76
78 enum class ColorSpace : uint8_t
79 {
86 };
87
90 struct Gradient
91 {
92 static constexpr int kMaxStops = 8;
93
94 std::array<ColorStop, kMaxStops> stops{};
95 uint16_t value = 0;
96 uint8_t stopCount = 0;
99
101 float GetValue() const
102 {
103 // multiply it by even number so that 90 degrees is exactly 0.25, 180 is 0.5, etc.
104 return float(value) / 65534.0f;
105 }
106
108 static Gradient Solid(const color4f& color)
109 {
110 Gradient g;
112 g.AddStop(color, 0.0f);
113 g.AddStop(color, 1.0f);
114 return g;
115 }
116
118 static Gradient Solid(const color4b& color)
119 {
120 Gradient g;
122 g.AddStop(color, 0.0f);
123 g.AddStop(color, 1.0f);
124 return g;
125 }
126
128 static Gradient Linear(const color4f& c0, const color4f& c1)
129 {
130 Gradient g;
132 g.AddStop(c0, 0.0f);
133 g.AddStop(c1, 1.0f);
134 return g;
135 }
136
138 static Gradient Linear(const color4b& c0, const color4b& c1)
139 {
140 Gradient g;
142 g.AddStop(c0, 0.0f);
143 g.AddStop(c1, 1.0f);
144 return g;
145 }
146
148 static Gradient Linear(const color4f& c0, const color4f& c1, const color4f& c2)
149 {
150 Gradient g;
152 g.AddStop(c0, 0.0f);
153 g.AddStop(c1, 0.5f);
154 g.AddStop(c2, 1.0f);
155 return g;
156 }
157
159 static Gradient Linear(const color4b& c0, const color4b& c1, const color4b& c2)
160 {
161 Gradient g;
163 g.AddStop(c0, 0.0f);
164 g.AddStop(c1, 0.5f);
165 g.AddStop(c2, 1.0f);
166 return g;
167 }
168
170 static Gradient Linear(const color4f& c0, const color4f& c1, const color4f& c2, const color4f& c3)
171 {
172 Gradient g;
174 g.AddStop(c0, 0.00f);
175 g.AddStop(c1, 0.25f);
176 g.AddStop(c2, 0.50f);
177 g.AddStop(c3, 1.00f);
178 return g;
179 }
180
182 static Gradient Linear(const color4b& c0, const color4b& c1, const color4b& c2, const color4b& c3)
183 {
184 Gradient g;
186 g.AddStop(c0, 0.00f);
187 g.AddStop(c1, 0.25f);
188 g.AddStop(c2, 0.50f);
189 g.AddStop(c3, 1.00f);
190 return g;
191 }
192
196 static uint16_t EncodeAngle(float angleDegrees)
197 {
198 double whole;
199 double turn = std::modf(double(angleDegrees) / 360.0, &whole);
200 if (turn < 0.0) turn += 1.0;
201 return static_cast<uint16_t>(turn * 65534.0);
202 }
203
205 static Gradient Linear(float angleDegrees = 0.0f)
206 {
207 Gradient g;
209 g.value = EncodeAngle(angleDegrees);
210 return g;
211 }
212
215 static Gradient Radial(float angleDegrees = 1.0f)
216 {
217 Gradient g;
219 g.value = EncodeAngle(angleDegrees);
220 return g;
221 }
222
224 inline Gradient& WithColorSpace(ColorSpace cs) { colorSpace = cs; return *this; }
226 inline ColorSpace GetColorSpace() const { return colorSpace; }
227
229 inline bool AddStop(const color4f& color, float offset)
230 {
231 if (stopCount >= kMaxStops)
232 return false;
233 stops[stopCount++] = ColorStop {}.SetColor(color).SetOffset(offset);
234 return true;
235 }
236
238 inline bool AddStop(const color4b& color, float offset)
239 {
240 if (stopCount >= kMaxStops)
241 return false;
242 stops[stopCount++] = ColorStop{}.SetColor(color).SetOffset(offset);
243 return true;
244 }
245
247 inline void ClearStops() { stopCount = 0; }
248
251 inline uint8_t StopCount() const { return stopCount < kMaxStops ? stopCount : uint8_t(kMaxStops); }
252
254 inline bool IsEmpty() const { return type == GradientType::None || stopCount == 0; }
255
257 void WriteTo(std::span<color4b> out) const;
258
259 bool operator==(const Gradient& other) const noexcept
260 {
261 if (type != other.type || stopCount != other.stopCount ||
262 value != other.value || colorSpace != other.colorSpace)
263 return false;
264
265 for (uint8_t i = 0; i < StopCount(); ++i)
266 if (stops[i] != other.stops[i])
267 return false;
268
269 return true;
270 }
271 };
272
274}//namespace tachyon
@ None
Definition gui_element_flags.h:19
GradientType
Kind of Gradient.
Definition gui_style_gradient.h:71
ColorSpace
The space gradient stops are interpolated in.
Definition gui_style_gradient.h:79
@ Linear
Definition gui_style_gradient.h:73
@ None
Definition gui_style_gradient.h:72
@ Radial
Definition gui_style_gradient.h:74
@ HSV
Definition gui_style_gradient.h:83
@ HSL
Definition gui_style_gradient.h:82
@ Oklab
perceptual
Definition gui_style_gradient.h:85
@ sRGB
the default, as CSS
Definition gui_style_gradient.h:80
@ LinearRGB
Definition gui_style_gradient.h:81
@ Lab
CIE Lab, perceptual.
Definition gui_style_gradient.h:84
Definition gui_logging.h:24
Color stops for gradients.
Definition gui_style_gradient.h:20
bool operator==(const ColorStop &other) const noexcept=default
float GetOffset() const
Position along the gradient, 0..1.
Definition gui_style_gradient.h:62
ColorStop & SetColor(color4b newColor)
Definition gui_style_gradient.h:28
color4f GetColor4f() const
The color as 0..1 floats.
Definition gui_style_gradient.h:64
color4b GetColor4b() const
Definition gui_style_gradient.h:65
ColorStop & SetOffset(float newOffset)
Position along the gradient, 0..1 (clamped); stored as 16 bits.
Definition gui_style_gradient.h:53
ColorStop & SetColor(color4f newColor)
Clamps each channel to 0..1 and stores it as 8 bits.
Definition gui_style_gradient.h:31
Up to kMaxStops color stops plus an angle and interpolation color space.
Definition gui_style_gradient.h:91
uint8_t StopCount() const
The stops in use: stopCount, but never past the stop array (a gradient built in code can set stopCoun...
Definition gui_style_gradient.h:251
static Gradient Linear(const color4f &c0, const color4f &c1)
Two stops at 0 and 1.
Definition gui_style_gradient.h:128
static Gradient Linear(float angleDegrees=0.0f)
An empty linear gradient at an angle in degrees; add stops with AddStop.
Definition gui_style_gradient.h:205
std::array< ColorStop, kMaxStops > stops
the first stopCount are in use
Definition gui_style_gradient.h:94
static constexpr int kMaxStops
capacity of stops
Definition gui_style_gradient.h:92
bool IsEmpty() const
No stops, or type None: nothing to draw.
Definition gui_style_gradient.h:254
ColorSpace colorSpace
space the stops are interpolated in
Definition gui_style_gradient.h:98
bool operator==(const Gradient &other) const noexcept
Definition gui_style_gradient.h:259
float GetValue() const
value as a fraction of a full turn (see EncodeAngle).
Definition gui_style_gradient.h:101
bool AddStop(const color4f &color, float offset)
Adds a stop at offset (0..1); false when all kMaxStops are in use.
Definition gui_style_gradient.h:229
uint8_t stopCount
stops in use
Definition gui_style_gradient.h:96
static uint16_t EncodeAngle(float angleDegrees)
Angle as a fraction of a full turn in [0, 1), wrapping negative angles (-90deg == 270deg).
Definition gui_style_gradient.h:196
bool AddStop(const color4b &color, float offset)
Adds a stop at offset (0..1); false when all kMaxStops are in use.
Definition gui_style_gradient.h:238
static Gradient Linear(const color4b &c0, const color4b &c1, const color4b &c2, const color4b &c3)
Four stops at 0, 0.25, 0.5 and 1.
Definition gui_style_gradient.h:182
uint16_t value
the angle, encoded by EncodeAngle
Definition gui_style_gradient.h:95
void ClearStops()
Removes all stops.
Definition gui_style_gradient.h:247
static Gradient Linear(const color4b &c0, const color4b &c1, const color4b &c2)
Three stops at 0, 0.5 and 1.
Definition gui_style_gradient.h:159
static Gradient Solid(const color4f &color)
One color: two equal stops at 0 and 1.
Definition gui_style_gradient.h:108
GradientType type
Definition gui_style_gradient.h:97
Gradient & WithColorSpace(ColorSpace cs)
Sets the space the stops are interpolated in; returns *this.
Definition gui_style_gradient.h:224
static Gradient Solid(const color4b &color)
One color: two equal stops at 0 and 1.
Definition gui_style_gradient.h:118
static Gradient Radial(float angleDegrees=1.0f)
An empty radial gradient; add stops with AddStop.
Definition gui_style_gradient.h:215
static Gradient Linear(const color4b &c0, const color4b &c1)
Two stops at 0 and 1.
Definition gui_style_gradient.h:138
void WriteTo(std::span< color4b > out) const
Samples the gradient evenly across out, sRGB encoded.
ColorSpace GetColorSpace() const
Space the stops are interpolated in.
Definition gui_style_gradient.h:226
static Gradient Linear(const color4f &c0, const color4f &c1, const color4f &c2)
Three stops at 0, 0.5 and 1.
Definition gui_style_gradient.h:148
static Gradient Linear(const color4f &c0, const color4f &c1, const color4f &c2, const color4f &c3)
Four stops at 0, 0.25, 0.5 and 1.
Definition gui_style_gradient.h:170
Definition gui_base_types.h:384
Definition gui_base_types.h:395
float b
Definition gui_base_types.h:396
float r
Definition gui_base_types.h:396
float a
Definition gui_base_types.h:396
float g
Definition gui_base_types.h:396