Skip to content

Commit 8399a63

Browse files
committed
Common.h further split up. Formatting rules changed to (almost) LLVM standard.
1 parent 06f2bf5 commit 8399a63

17 files changed

+1009
-916
lines changed

.clang-format

+11-81
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,15 @@
1-
BasedOnStyle: Google
1+
---
2+
BasedOnStyle: LLVM
3+
ColumnLimit: 130
4+
---
25
Language: Cpp
3-
Standard: Cpp11
4-
5-
ColumnLimit: 0
6-
IndentWidth: 2
7-
ContinuationIndentWidth: 2
8-
UseTab: Never
9-
10-
MaxEmptyLinesToKeep: 2
11-
KeepEmptyLinesAtTheStartOfBlocks: false
12-
13-
BinPackArguments: true
14-
BinPackParameters: true
15-
16-
AlignConsecutiveAssignments: false
17-
AlignConsecutiveDeclarations: false
18-
AlignOperands: true
19-
AlignTrailingComments: true
20-
AlignEscapedNewlinesLeft: true
21-
22-
ConstructorInitializerAllOnOneLineOrOnePerLine: false
23-
ConstructorInitializerIndentWidth: 0
24-
25-
BraceWrapping:
26-
AfterClass: false
27-
AfterStruct: false
28-
AfterUnion: false
29-
AfterEnum: false
30-
AfterFunction: false
31-
AfterControlStatement: false
32-
AfterNamespace: false
33-
AfterObjCDeclaration: false
34-
BeforeCatch: false
35-
BeforeElse: false
36-
IndentBraces: false
37-
38-
BreakBeforeBraces: Custom
39-
BreakBeforeBinaryOperators: None
40-
BreakBeforeTernaryOperators: false
41-
BreakConstructorInitializersBeforeComma: false
426
AlwaysBreakBeforeMultilineStrings: true
43-
AlwaysBreakTemplateDeclarations: true
44-
Cpp11BracedListStyle: true
45-
46-
IndentCaseLabels: false
47-
IndentWrappedFunctionNames: true
48-
IndentFunctionDeclarationAfterType: true
49-
50-
AlignAfterOpenBracket: true
51-
AccessModifierOffset: -2
7+
AlwaysBreakTemplateDeclarations: Yes
8+
CompactNamespaces: true
9+
ConstructorInitializerIndentWidth: 4
10+
ContinuationIndentWidth: 2
5211
DerivePointerAlignment: false
12+
MaxEmptyLinesToKeep: 2
5313
PointerAlignment: Left
54-
55-
NamespaceIndentation: Inner
56-
SpaceBeforeAssignmentOperators: true
57-
SpacesInSquareBrackets: false
58-
SpaceBeforeParens: ControlStatements
59-
SpacesInParentheses: false
60-
SpaceInEmptyParentheses: false
61-
SpaceAfterCStyleCast: false
62-
SpacesInCStyleCastParentheses: false
63-
SpacesBeforeTrailingComments: 1
64-
SpacesInAngles: false
65-
SpacesInContainerLiterals: false
66-
67-
AllowShortBlocksOnASingleLine: true
68-
AllowShortIfStatementsOnASingleLine: true
69-
AllowShortLoopsOnASingleLine: true
70-
AllowShortCaseLabelsOnASingleLine: true
71-
AllowShortFunctionsOnASingleLine: Inline
72-
73-
# SortIncludes: false
74-
# SpaceAfterTemplateKeyword: true
75-
76-
# MacroBlockBegin: "*_MACRO_START"
77-
# MacroBlockEnd: "*_MACRO_END"
78-
79-
# Allow putting all parameters of a function declaration onto the next line
80-
# even if BinPackParameters is false.
81-
# AllowAllParametersOfDeclarationOnNextLine: true
82-
83-
# A regular expression that describes comments with special meaning, which
84-
# should not be split into lines or otherwise changed.
85-
# CommentPragmas: ""
14+
SortIncludes: false
15+
...

.vscode/settings.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@
7979
"vector": "cpp",
8080
"any": "cpp",
8181
"list": "cpp",
82-
"unordered_map": "cpp"
82+
"unordered_map": "cpp",
83+
"csignal": "cpp",
84+
"deque": "cpp",
85+
"random": "cpp",
86+
"regex": "cpp",
87+
"stack": "cpp",
88+
"variant": "cpp"
8389
}
8490
}

src/Color.h

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// color types and functions
2+
//
3+
// david lindecrantz <[email protected]>
4+
5+
#pragma once
6+
7+
#include "Common.h"
8+
9+
namespace sfc {
10+
11+
const rgba_t transparent_color = 0x00000000;
12+
13+
// vector<channel_t> to vector<rgba_t>
14+
inline rgba_vec_t to_rgba(const channel_vec_t& data) {
15+
if (data.size() % 4 != 0)
16+
throw std::runtime_error("RGBA vector size not a multiple of 4");
17+
rgba_vec_t v(data.size() >> 2);
18+
for (unsigned i = 0; i < v.size(); ++i) {
19+
v[i] = (data[i * 4]) + (data[(i * 4) + 1] << 8) + (data[(i * 4) + 2] << 16) + (data[(i * 4) + 3] << 24);
20+
}
21+
return v;
22+
}
23+
24+
// swap bytes between network order and little endian
25+
constexpr rgba_t reverse_bytes(rgba_t v) {
26+
return ((v >> 24) & 0xff) | ((v << 8) & 0xff0000) | ((v >> 8) & 0xff00) | ((v << 24) & 0xff000000);
27+
}
28+
29+
// rgba value to css style hex string
30+
inline std::string to_hexstring(rgba_t value, bool pound = true, bool alpha = false) {
31+
return fmt::format("{1}{0:0{2}x}", reverse_bytes(value) >> (alpha ? 0 : 8), pound ? "#" : "", alpha ? 8 : 6);
32+
}
33+
34+
// css style hex string to rgba value
35+
inline rgba_t from_hexstring(const std::string& str) {
36+
std::string s = str;
37+
if (s.at(0) == '#')
38+
s.erase(0, 1);
39+
if (s.size() == 6)
40+
s.insert(6, 2, 'f');
41+
if (s.size() != 8)
42+
throw std::runtime_error("Argument color-zero not a 6 or 8 character hex-string");
43+
uint32_t i;
44+
if (sscanf(s.c_str(), "%x", &i) == 1) {
45+
return reverse_bytes(i);
46+
} else {
47+
throw std::runtime_error("Failed to interpret argument color-zero");
48+
};
49+
}
50+
51+
// scale up value using left bit replication
52+
constexpr channel_t scale_up(channel_t value, unsigned shift) {
53+
switch (shift) {
54+
case 7:
55+
return value ? 0xff : 0;
56+
case 6:
57+
return (value << 6) | ((value << 4) & 0x30) | ((value << 2) & 0xc) | (value & 0x3);
58+
case 5:
59+
return (value << 5) | ((value << 2) & 0x1c) | ((value >> 1) & 0x3);
60+
case 4:
61+
return (value << 4) | (value & 0xf);
62+
case 3:
63+
return (value << 3) | ((value >> 2) & 0x7);
64+
case 2:
65+
return (value << 2) | ((value >> 4) & 0x3);
66+
case 1:
67+
return (value << 1) | ((value >> 6) & 0x1);
68+
default:
69+
return (value << shift);
70+
}
71+
}
72+
73+
//
74+
// rgba_color / hsva_color
75+
//
76+
77+
struct rgba_color final {
78+
channel_t r = {};
79+
channel_t g = {};
80+
channel_t b = {};
81+
channel_t a = {};
82+
83+
rgba_color(){};
84+
rgba_color(rgba_t c) : r(c & 0x000000ff), g((c & 0x0000ff00) >> 8), b((c & 0x00ff0000) >> 16), a((c & 0xff000000) >> 24){};
85+
86+
operator rgba_t() {
87+
rgba_t i = r;
88+
i += g << 8;
89+
i += b << 16;
90+
i += a << 24;
91+
return i;
92+
}
93+
94+
bool operator>(const rgba_color& other) const;
95+
};
96+
97+
struct hsva_color final {
98+
float h = {};
99+
float s = {};
100+
float v = {};
101+
float a = {};
102+
103+
hsva_color(){};
104+
hsva_color(const rgba_color& rgba);
105+
operator rgba_color();
106+
};
107+
108+
// rgba to hsva
109+
inline hsva_color::hsva_color(const rgba_color& rgba) {
110+
float rgb_max = (float)fmax(fmax(rgba.r, rgba.g), rgba.b);
111+
float rgb_min = (float)fmin(fmin(rgba.r, rgba.g), rgba.b);
112+
float rgb_delta = rgb_max - rgb_min;
113+
114+
if (rgb_delta > 0) {
115+
if (rgb_max == rgba.r) {
116+
h = 60.0f * (fmod(((rgba.g - rgba.b) / rgb_delta), 6.0f));
117+
} else if (rgb_max == rgba.g) {
118+
h = 60.0f * (((rgba.b - rgba.r) / rgb_delta) + 2.0f);
119+
} else if (rgb_max == rgba.b) {
120+
h = 60.0f * (((rgba.r - rgba.g) / rgb_delta) + 4.0f);
121+
}
122+
s = (rgb_max > 0) ? rgb_delta / rgb_max : 0;
123+
v = rgb_max;
124+
} else {
125+
h = 0;
126+
s = 0;
127+
v = rgb_max;
128+
}
129+
130+
if (h < 0)
131+
h = 360 + h;
132+
a = rgba.a / 255.0f;
133+
}
134+
135+
// hsva to rgba
136+
inline hsva_color::operator rgba_color() {
137+
rgba_color rgba;
138+
float c = v * s;
139+
float p = fmod(h / 60.0f, 6.0f);
140+
float x = c * (1.0f - fabs(fmod(p, 2.0f) - 1.0f));
141+
float m = v - c;
142+
143+
if (0.0f <= p && p < 1.0f) {
144+
rgba.r = (channel_t)c;
145+
rgba.g = (channel_t)x;
146+
rgba.b = 0;
147+
} else if (1.0f <= p && p < 2.0f) {
148+
rgba.r = (channel_t)x;
149+
rgba.g = (channel_t)c;
150+
rgba.b = 0;
151+
} else if (2.0f <= p && p < 3.0f) {
152+
rgba.r = 0;
153+
rgba.g = (channel_t)c;
154+
rgba.b = (channel_t)x;
155+
} else if (3.0f <= p && p < 4.0f) {
156+
rgba.r = 0;
157+
rgba.g = (channel_t)x;
158+
rgba.b = (channel_t)c;
159+
} else if (4.0f <= p && p < 5.0f) {
160+
rgba.r = (channel_t)x;
161+
rgba.g = 0;
162+
rgba.b = (channel_t)c;
163+
} else if (5.0f <= p && p < 6.0f) {
164+
rgba.r = (channel_t)c;
165+
rgba.g = 0;
166+
rgba.b = (channel_t)x;
167+
} else {
168+
rgba.r = 0;
169+
rgba.g = 0;
170+
rgba.b = 0;
171+
}
172+
173+
rgba.r += (channel_t)m;
174+
rgba.g += (channel_t)m;
175+
rgba.b += (channel_t)m;
176+
rgba.a = (channel_t)(a * 255.0f);
177+
return rgba;
178+
}
179+
180+
// aesthetically pleasing color sorting
181+
inline bool rgba_color::operator>(const rgba_color& o) const {
182+
const int segments = 8;
183+
hsva_color hsva = hsva_color(*this);
184+
hsva_color hsva_o = hsva_color(o);
185+
186+
int h = (int)(segments * hsva.h);
187+
// int l = (int)(segments * hsva.s);
188+
int l = (int)(segments * sqrt(0.241f * r + 0.691f * g + 0.068f * b));
189+
int v = (int)(segments * hsva.v);
190+
191+
int ho = (int)(segments * hsva_o.h);
192+
// int lo = (int)(segments * hsva_o.s);
193+
int lo = (int)(segments * sqrt(0.241f * o.r + 0.691f * o.g + 0.068f * o.b));
194+
int vo = (int)(segments * hsva_o.v);
195+
196+
return std::tie(h, l, v) > std::tie(ho, lo, vo);
197+
}
198+
199+
inline void sort_colors(rgba_vec_t& colors) {
200+
std::sort(colors.begin(), colors.end(), [](const rgba_t& a, const rgba_t& b) -> bool { return rgba_color(a) > rgba_color(b); });
201+
}
202+
203+
} /* namespace sfc */

0 commit comments

Comments
 (0)