summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-09-07 19:30:51 -0400
committerpommicket <pommicket@gmail.com>2023-09-07 22:50:11 -0400
commitc7f323bf733160016247368883a58a9d467468b4 (patch)
tree6807738d64f94b9e0b5c136e6eb31f941fe7928d
parent5cad1bee9b72610d9d97b5f97e7f1a245a2d2ba5 (diff)
move color-related functions from util.c to color.c
-rw-r--r--buffer.c4
-rw-r--r--colors.c101
-rw-r--r--config.c2
-rw-r--r--gl.c2
-rw-r--r--ide-autocomplete.c6
-rw-r--r--main.c4
-rw-r--r--ted.h4
-rw-r--r--text.c2
-rw-r--r--util.c98
-rw-r--r--util.h4
10 files changed, 113 insertions, 114 deletions
diff --git a/buffer.c b/buffer.c
index 8d48c6d..39d28ac 100644
--- a/buffer.c
+++ b/buffer.c
@@ -3372,7 +3372,7 @@ void buffer_render(TextBuffer *buffer, Rect r) {
}
}
// set color
- rgba_u32_to_floats(line_number_color, text_state.color);
+ color_u32_to_floats(line_number_color, text_state.color);
text_state.x = x; text_state.y = y;
text_state_break_kerning(&text_state);
text_utf8_with_state(font, &text_state, str);
@@ -3532,7 +3532,7 @@ void buffer_render(TextBuffer *buffer, Rect r) {
if (syntax_highlighting) {
SyntaxCharType type = char_types[i];
ColorSetting color = syntax_char_type_to_color_setting(type);
- rgba_u32_to_floats(settings_color(settings, color), text_state.color);
+ color_u32_to_floats(settings_color(settings, color), text_state.color);
}
buffer_render_char(buffer, font, &text_state, c);
}
diff --git a/colors.c b/colors.c
index d9ef7aa..289d286 100644
--- a/colors.c
+++ b/colors.c
@@ -195,7 +195,104 @@ float color_contrast_ratio(const float rgb1[3], const float rgb2[3]) {
float color_contrast_ratio_u32(u32 color1, u32 color2) {
float rgb1[4], rgb2[4];
- rgba_u32_to_floats(color1, rgb1);
- rgba_u32_to_floats(color2, rgb2);
+ color_u32_to_floats(color1, rgb1);
+ color_u32_to_floats(color2, rgb2);
return color_contrast_ratio(rgb1, rgb2);
}
+
+void color_u32_to_floats(u32 rgba, float floats[4]) {
+ floats[0] = (float)((rgba >> 24) & 0xff) / 255.f;
+ floats[1] = (float)((rgba >> 16) & 0xff) / 255.f;
+ floats[2] = (float)((rgba >> 8) & 0xff) / 255.f;
+ floats[3] = (float)((rgba >> 0) & 0xff) / 255.f;
+}
+
+vec4 color_u32_to_vec4(u32 rgba) {
+ float c[4];
+ color_u32_to_floats(rgba, c);
+ return (vec4){c[0], c[1], c[2], c[3]};
+}
+
+u32 color_vec4_to_u32(vec4 color) {
+ return (u32)(color.x * 255) << 24
+ | (u32)(color.y * 255) << 16
+ | (u32)(color.z * 255) << 8
+ | (u32)(color.w * 255);
+}
+
+static vec4 color_rgba_to_hsva(vec4 rgba) {
+ float R = rgba.x, G = rgba.y, B = rgba.z, A = rgba.w;
+ float M = maxf(R, maxf(G, B));
+ float m = minf(R, minf(G, B));
+ float C = M - m;
+ float H = 0;
+ if (C == 0)
+ H = 0;
+ else if (M == R)
+ H = fmodf((G - B) / C, 6);
+ else if (M == G)
+ H = (B - R) / C + 2;
+ else if (M == B)
+ H = (R - G) / C + 4;
+ H *= 60;
+ float V = M;
+ float S = V == 0 ? 0 : C / V;
+ return (vec4){H, S, V, A};
+}
+
+static vec4 color_hsva_to_rgba(vec4 hsva) {
+ float H = hsva.x, S = hsva.y, V = hsva.z, A = hsva.w;
+ H /= 60;
+ float C = S * V;
+ float X = C * (1 - fabsf(fmodf(H, 2) - 1));
+ float R, G, B;
+ if (H <= 1)
+ R=C, G=X, B=0;
+ else if (H <= 2)
+ R=X, G=C, B=0;
+ else if (H <= 3)
+ R=0, G=C, B=X;
+ else if (H <= 4)
+ R=0, G=X, B=C;
+ else if (H <= 5)
+ R=X, G=0, B=C;
+ else
+ R=C, G=0, B=X;
+
+ float m = V-C;
+ R += m;
+ G += m;
+ B += m;
+ return (vec4){R, G, B, A};
+}
+
+u32 color_interpolate(float x, u32 color1, u32 color2) {
+ x = x * x * (3 - 2*x); // hermite interpolation
+
+ vec4 c1 = color_u32_to_vec4(color1), c2 = color_u32_to_vec4(color2);
+ // to make it interpolate more nicely, convert to hsv, interpolate in that space, then convert back
+ c1 = color_rgba_to_hsva(c1);
+ c2 = color_rgba_to_hsva(c2);
+ // v_1/2 named differently to avoid shadowing
+ float h1 = c1.x, s1 = c1.y, v_1 = c1.z, a1 = c1.w;
+ float h2 = c2.x, s2 = c2.y, v_2 = c2.z, a2 = c2.w;
+
+ float s_out = lerpf(x, s1, s2);
+ float v_out = lerpf(x, v_1, v_2);
+ float a_out = lerpf(x, a1, a2);
+
+ float h_out;
+ // because hue is on a circle, we need to make sure we take the shorter route around the circle
+ if (fabsf(h1 - h2) < 180) {
+ h_out = lerpf(x, h1, h2);
+ } else if (h1 > h2) {
+ h_out = lerpf(x, h1, h2 + 360);
+ } else {
+ h_out = lerpf(x, h1 + 360, h2);
+ }
+ h_out = fmodf(h_out, 360);
+
+ vec4 c_out = (vec4){h_out, s_out, v_out, a_out};
+ c_out = color_hsva_to_rgba(c_out);
+ return color_vec4_to_u32(c_out);
+}
diff --git a/config.c b/config.c
index 6dce3bc..e575803 100644
--- a/config.c
+++ b/config.c
@@ -1310,7 +1310,7 @@ u32 settings_color(const Settings *settings, ColorSetting color) {
}
void settings_color_floats(const Settings *settings, ColorSetting color, float f[4]) {
- rgba_u32_to_floats(settings_color(settings, color), f);
+ color_u32_to_floats(settings_color(settings, color), f);
}
diff --git a/gl.c b/gl.c
index bf03250..52902e6 100644
--- a/gl.c
+++ b/gl.c
@@ -232,7 +232,7 @@ void gl_geometry_init(void) {
void gl_geometry_rect(Rect r, u32 color_rgba) {
if (r.size.x <= 0 || r.size.y <= 0)
return;
- vec4 color = rgba_u32_to_vec4(color_rgba);
+ vec4 color = color_u32_to_vec4(color_rgba);
vec2 p1 = {rect_x1(r), rect_y1(r)};
vec2 p2 = {rect_x1(r), rect_y2(r)};
diff --git a/ide-autocomplete.c b/ide-autocomplete.c
index 295dcda..0ad78ed 100644
--- a/ide-autocomplete.c
+++ b/ide-autocomplete.c
@@ -668,7 +668,7 @@ void autocomplete_frame(Ted *ted) {
text_state.x = doc_x + padding;
text_state.y = doc_y + padding;
text_state.wrap = true;
- rgba_u32_to_floats(colors[COLOR_TEXT], text_state.color);
+ color_u32_to_floats(colors[COLOR_TEXT], text_state.color);
text_utf8_with_state(font, &text_state, document->documentation);
}
}
@@ -688,7 +688,7 @@ void autocomplete_frame(Ted *ted) {
float y = start_y;
TextRenderState state = text_render_state_default;
state.min_x = x + padding; state.min_y = y; state.max_x = x + menu_width - padding; state.max_y = y + menu_height;
- rgba_u32_to_floats(colors[COLOR_TEXT], state.color);
+ color_u32_to_floats(colors[COLOR_TEXT], state.color);
if (waiting_for_lsp && ncompletions == 0) {
state.x = x + padding; state.y = y;
@@ -708,7 +708,7 @@ void autocomplete_frame(Ted *ted) {
if (!settings->syntax_highlighting)
label_color = COLOR_TEXT;
- rgba_u32_to_floats(colors[label_color], state.color);
+ color_u32_to_floats(colors[label_color], state.color);
// draw icon
char icon_text[2] = {symbol_kind_icon(completion->kind), 0};
diff --git a/main.c b/main.c
index dbfb6a1..5791ad2 100644
--- a/main.c
+++ b/main.c
@@ -922,7 +922,7 @@ int main(int argc, char **argv) {
glViewport(0, 0, (GLsizei)window_width, (GLsizei)window_height);
{ // clear (background)
float bg_color[4];
- rgba_u32_to_floats(ted_active_color(ted, COLOR_BG), bg_color);
+ color_u32_to_floats(ted_active_color(ted, COLOR_BG), bg_color);
glClearColor(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
}
glClear(GL_COLOR_BUFFER_BIT);
@@ -1090,7 +1090,7 @@ int main(int argc, char **argv) {
text_state.x = text_x1;
text_state.y = text_y1;
text_state.wrap = true;
- rgba_u32_to_floats(ted_active_color(ted, COLOR_TEXT), text_state.color);
+ color_u32_to_floats(ted_active_color(ted, COLOR_TEXT), text_state.color);
text_utf8_with_state(font, &text_state, ted->message_shown);
gl_geometry_draw();
text_render(font);
diff --git a/ted.h b/ted.h
index 8de7fc4..2cc7d3a 100644
--- a/ted.h
+++ b/ted.h
@@ -807,6 +807,10 @@ float color_contrast_ratio(const float rgb1[3], const float rgb2[3]);
///
/// the "alpha" components (i.e. lowest 8 bits) of `color1`, `color2` are ignored
float color_contrast_ratio_u32(u32 color1, u32 color2);
+void color_u32_to_floats(u32 rgba, float floats[4]);
+vec4 color_u32_to_vec4(u32 rgba);
+u32 color_vec4_to_u32(vec4 color);
+u32 color_interpolate(float x, u32 color1, u32 color2);
// === command.c ===
/// parse command
diff --git a/text.c b/text.c
index 4e21143..8b4e38f 100644
--- a/text.c
+++ b/text.c
@@ -493,7 +493,7 @@ static vec2 text_render_utf8_internal(Font *font, const char *text, double x, do
render_state.render = render;
render_state.x = x;
render_state.y = y;
- rgba_u32_to_floats(color, render_state.color);
+ color_u32_to_floats(color, render_state.color);
text_utf8_with_state(font, &render_state, text);
return (vec2){
maxf(0.0f, (float)(render_state.x_largest - x)),
diff --git a/util.c b/util.c
index 1b9b9f3..bdeb687 100644
--- a/util.c
+++ b/util.c
@@ -720,26 +720,6 @@ vec2 vec2_polar(float r, float theta) {
return (vec2){r * cosf(theta), r * sinf(theta)};
}
-void rgba_u32_to_floats(u32 rgba, float floats[4]) {
- floats[0] = (float)((rgba >> 24) & 0xFF) / 255.f;
- floats[1] = (float)((rgba >> 16) & 0xFF) / 255.f;
- floats[2] = (float)((rgba >> 8) & 0xFF) / 255.f;
- floats[3] = (float)((rgba >> 0) & 0xFF) / 255.f;
-}
-
-vec4 rgba_u32_to_vec4(u32 rgba) {
- float c[4];
- rgba_u32_to_floats(rgba, c);
- return (vec4){c[0], c[1], c[2], c[3]};
-}
-
-u32 rgba_vec4_to_u32(vec4 color) {
- return (u32)(color.x * 255) << 24
- | (u32)(color.y * 255) << 16
- | (u32)(color.z * 255) << 8
- | (u32)(color.w * 255);
-}
-
bool rect_contains_point_v2(vec2 pos, vec2 size, vec2 point) {
float x1 = pos.x, y1 = pos.y, x2 = pos.x + size.x, y2 = pos.y + size.y,
x = point.x, y = point.y;
@@ -868,84 +848,6 @@ void rect_grow(Rect *r, float amount) {
r->size.y += 2 * amount;
}
-static vec4 color_rgba_to_hsva(vec4 rgba) {
- float R = rgba.x, G = rgba.y, B = rgba.z, A = rgba.w;
- float M = maxf(R, maxf(G, B));
- float m = minf(R, minf(G, B));
- float C = M - m;
- float H = 0;
- if (C == 0)
- H = 0;
- else if (M == R)
- H = fmodf((G - B) / C, 6);
- else if (M == G)
- H = (B - R) / C + 2;
- else if (M == B)
- H = (R - G) / C + 4;
- H *= 60;
- float V = M;
- float S = V == 0 ? 0 : C / V;
- return (vec4){H, S, V, A};
-}
-
-static vec4 color_hsva_to_rgba(vec4 hsva) {
- float H = hsva.x, S = hsva.y, V = hsva.z, A = hsva.w;
- H /= 60;
- float C = S * V;
- float X = C * (1 - fabsf(fmodf(H, 2) - 1));
- float R, G, B;
- if (H <= 1)
- R=C, G=X, B=0;
- else if (H <= 2)
- R=X, G=C, B=0;
- else if (H <= 3)
- R=0, G=C, B=X;
- else if (H <= 4)
- R=0, G=X, B=C;
- else if (H <= 5)
- R=X, G=0, B=C;
- else
- R=C, G=0, B=X;
-
- float m = V-C;
- R += m;
- G += m;
- B += m;
- return (vec4){R, G, B, A};
-}
-
-u32 color_interpolate(float x, u32 color1, u32 color2) {
- x = x * x * (3 - 2*x); // hermite interpolation
-
- vec4 c1 = rgba_u32_to_vec4(color1), c2 = rgba_u32_to_vec4(color2);
- // to make it interpolate more nicely, convert to hsv, interpolate in that space, then convert back
- c1 = color_rgba_to_hsva(c1);
- c2 = color_rgba_to_hsva(c2);
- // v_1/2 named differently to avoid shadowing
- float h1 = c1.x, s1 = c1.y, v_1 = c1.z, a1 = c1.w;
- float h2 = c2.x, s2 = c2.y, v_2 = c2.z, a2 = c2.w;
-
- float s_out = lerpf(x, s1, s2);
- float v_out = lerpf(x, v_1, v_2);
- float a_out = lerpf(x, a1, a2);
-
- float h_out;
- // because hue is on a circle, we need to make sure we take the shorter route around the circle
- if (fabsf(h1 - h2) < 180) {
- h_out = lerpf(x, h1, h2);
- } else if (h1 > h2) {
- h_out = lerpf(x, h1, h2 + 360);
- } else {
- h_out = lerpf(x, h1 + 360, h2);
- }
- h_out = fmodf(h_out, 360);
-
- vec4 c_out = (vec4){h_out, s_out, v_out, a_out};
- c_out = color_hsva_to_rgba(c_out);
- return rgba_vec4_to_u32(c_out);
-}
-
-
int timespec_cmp(struct timespec a, struct timespec b) {
if (a.tv_sec > b.tv_sec) return 1;
if (a.tv_sec < b.tv_sec) return -1;
diff --git a/util.h b/util.h
index 25ff72b..97db6fd 100644
--- a/util.h
+++ b/util.h
@@ -216,9 +216,6 @@ vec2 vec2_normalize(vec2 v);
float vec2_distance(vec2 a, vec2 b);
void vec2_print(vec2 v);
vec2 vec2_polar(float r, float theta);
-void rgba_u32_to_floats(u32 rgba, float floats[4]);
-vec4 rgba_u32_to_vec4(u32 rgba);
-u32 rgba_vec4_to_u32(vec4 color);
bool rect_contains_point_v2(vec2 pos, vec2 size, vec2 point);
bool centered_rect_contains_point(vec2 center, vec2 size, vec2 point);
Rect rect(vec2 pos, vec2 size);
@@ -250,7 +247,6 @@ void rect_shrink_right(Rect *r, float amount);
void rect_shrink_bottom(Rect *r, float amount);
/// adds `amount` to all sides of r
void rect_grow(Rect *r, float amount);
-u32 color_interpolate(float x, u32 color1, u32 color2);
int timespec_cmp(struct timespec a, struct timespec b);
bool timespec_eq(struct timespec a, struct timespec b);
struct timespec timespec_max(struct timespec a, struct timespec b);