#include #include #include #include #include #include "colors.h" #define MIN_CONTRAST 0.5 void hsl2rgb(struct Rgb *dest, const struct Hls const *src) { if ((src -> h < 0 || 360 < src -> h) || (src -> s < 0 && 1 < src -> s) || (src -> l < 0 && 1 < src -> l)) { return; } float r, g, b; float hue = (src -> h)/60.0f; const float chroma = (1 - fabs((2 * (src -> l)) - 1)) * (src -> s); float x = chroma * (1 - fabs(fmod(hue, 2) - 1)); float m = (src -> l) - (chroma/2); if (0 <= hue && hue < 1) { r = chroma; g = x; b = 0; } else if (1 <= hue && hue < 2) { r = x; g = chroma; b = 0; } else if (2 <= hue && hue < 3) { r = 0; g = chroma; b = x; } else if (3 <= hue && hue < 4) { r = 0; g = x; b = chroma; } else if (4 <= hue && hue < 5) { r = x; g = 0; b = chroma; } else if (5 <= hue && hue < 6) { r = chroma; g = 0; b = x; } else { r = 0; g = 0; b = 0; } dest -> r = ceil((r + m) * 255); dest -> g = ceil((g + m) * 255); dest -> b = ceil((b + m) * 255); } void rgb2hsl(struct Hls *dest, const struct Rgb const *src) { if (src == NULL || dest == NULL) { return; } float r = (src -> r) / 255.0f; float g = (src -> g) / 255.0f; float b = (src -> b) / 255.0f; float min = fmin(fmin(r, g), b); float max = fmax(fmax(r, g), b); float chroma = max - min; dest -> l = (max + min)/2; //bi-hexcone model. if (chroma == 0) { // neutral color. dest -> h = 0; // undefined. dest -> s = 0.0f; } else { dest -> s = (dest -> l > 0.5) ? (chroma/(2 - max - min)) : (chroma/(max + min)); //piecewise function.. float hue; if (max == r) { hue = (int)((g - b)/chroma) + (g < b ? 6 : 0); // % 6 will break magenta (255, 0, 255) } else if (max == g) { hue = ((b - r)/chroma) + 2.0f; } else { hue = ((r - g)/chroma) + 4.0f; } dest -> h = (int)(hue * 60); } } static void decspan(const int d) { switch(d) { case 0: printf(""); break; case 1: printf(""); break; case 2: printf(""); break; case 3: printf(""); break; case 4: printf(""); break; case 5: printf(""); break; case 6: printf(""); break; case 7: printf(""); break; case 8: printf(""); break; case 9: printf(""); break; } } static void hexspan(const char *str) { const char h1[2] = {str[0], '\0'}; const char h2[2] = {str[1], '\0'}; const char h3[2] = {str[2], '\0'}; struct Rgb nrgb; // max value for a color code in darkplaces = 0xF // 0xF * 0xF = 255, max value for rgb nrgb.r = strtol(h1, NULL, 16) * 0xF; nrgb.g = strtol(h2, NULL, 16) * 0xF; nrgb.b = strtol(h3, NULL, 16) * 0xF; struct Hls nhls; rgb2hsl(&nhls, &nrgb); if (nhls.l < MIN_CONTRAST) { nhls.l = MIN_CONTRAST; hsl2rgb(&nrgb, &nhls); } printf("", nrgb.r, nrgb.g, nrgb.b); } static void b(char * const str) { char *token = strtok(str, "^"); char c; printf(""); while (token) { c = token[0]; if (isdigit(c)) { decspan(c - '0'); if (strlen(token) > 1) { printf("%s", token + 1); } printf(""); } else if ((c == 'x' && strlen(token) > 3) && (isxdigit(token[1]) && isxdigit(token[2]) && isxdigit(token[3]))) { hexspan(token + 1); //exclude x if (strlen(token) > 4){ printf("%s", token + 4); } printf(""); } else { printf("%s", token); } token = strtok(NULL, "^"); } printf(""); } void print_plname(const char* str) { //find instance of ^^ //replace with ^ //concatenate with rest of the string char *copy; copy = calloc(strlen(str) + 1, sizeof(char)); strcpy(copy, str); char *pos = copy; while (pos = strstr(pos, "^^")) { strcpy(pos, (pos + 1)); } b(copy); free(copy); }