X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcolor.c;h=eb03f55f928a573b9a11d547e136b1efd5d0fbe4;hb=9f47008ae084fa7cf1168bde87c9e8abe31a4ded;hp=fa43483c954f5e8e73705b2bf318257d48800d81;hpb=9bad41adfe9d0623ae016ee99a528688a86c96e8;p=nothing.git diff --git a/src/color.c b/src/color.c index fa43483c..eb03f55f 100644 --- a/src/color.c +++ b/src/color.c @@ -1,5 +1,6 @@ #include #include +#include #include "color.h" @@ -15,6 +16,38 @@ Color rgba(float r, float g, float b, float a) return result; } +/* TODO(#928): Should the Hue in HSLA representation be in degrees? */ +Color hsla(float h, float s, float l, float a) +{ + h = fmodf(h, 360.0f); + + const float c = (1.0f - fabsf(2.0f * l - 1.0f)) * s; + const float x = c * (1 - fabsf(fmodf(h / 60.0f, 2.0f) - 1.0f)); + const float m = l - c / 2.0f; + + Color color = {0.0f, 0.0f, 0.0f, a}; + + if (0.0f <= h && h < 60.0f) { + color = rgba(c, x, 0.0f, a); + } else if (60.0f <= h && h < 120.0f) { + color = rgba(x, c, 0.0f, a); + } else if (120.0f <= h && h < 180.0f) { + color = rgba(0.0f, c, x, a); + } else if (180.0f <= h && h < 240.0f) { + color = rgba(0.0f, x, c, a); + } else if (240.0f <= h && h < 300.0f) { + color = rgba(x, 0.0f, c, a); + } else if (300.0f <= h && h < 360.0f) { + color = rgba(c, 0.0f, x, a); + } + + color.r += m; + color.g += m; + color.b += m; + + return color; +} + static Uint8 hex2dec_digit(char c) { if (c >= '0' && c <= '9') { @@ -50,6 +83,17 @@ Color hexstr(const char *hexstr) 1.0f); } +Color hexs(String input) +{ + if (input.count < 6) return COLOR_BLACK; + + return rgba( + parse_color_component(input.data) / 255.0f, + parse_color_component(input.data + 2) / 255.0f, + parse_color_component(input.data + 4) / 255.0f, + 1.0f); +} + SDL_Color color_for_sdl(Color color) { const SDL_Color result = { @@ -89,3 +133,41 @@ Color color_scale(Color c, Color fc) fmaxf(fminf(c.b * fc.b, 1.0f), 0.0f), fmaxf(fminf(c.a * fc.a, 1.0f), 0.0f)); } + +int color_hex_to_stream(Color color, FILE *stream) +{ + SDL_Color sdl = color_for_sdl(color); + return fprintf(stream, "%02x%02x%02x", sdl.r, sdl.g, sdl.b); +} + +int color_hex_to_string(Color color, char *buffer, size_t buffer_size) +{ + SDL_Color sdl = color_for_sdl(color); + return snprintf(buffer, buffer_size, "%02x%02x%02x", sdl.r, sdl.g, sdl.b); +} + +Color rgba_to_hsla(Color color) +{ + const float max = fmaxf(color.r, fmaxf(color.g, color.b)); + const float min = fminf(color.r, fminf(color.g, color.b)); + const float c = max - min; + float hue = 0.0f; + float saturation = 0.0f; + const float lightness = (max + min) * 0.5f; + + if (fabsf(c) > 1e-6) { + if (fabs(max - color.r) <= 1e-6) { + hue = 60.0f * fmodf((color.g - color.b) / c, 6.0f); + } else if (fabs(max - color.g) <= 1e-6) { + hue = 60.0f * ((color.b - color.r) / c + 2.0f); + } else { + hue = 60.0f * ((color.r - color.g) / c + 4.0f); + } + + saturation = c / (1.0f - fabsf(2.0f * lightness - 1.0f)); + } + + // TODO(#929): Color struct is used not only for RGBA + // But also for HSLA. We should make another similar struct but for HSLA + return rgba(hue, saturation, lightness, color.a); +}