#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; float chroma = (1 - fabs(2 * (src -> l) - 1)) * (src -> s); float x = chroma * (1 - fabs((int)(hue/60) % 2 - 1)); float m = (src -> l) - (chroma/2); if (0 <= hue && hue < 60) { r = chroma; g = x; b = 0; } else if (60 <= hue && hue < 120) { r = x; g = chroma; b = 0; } else if (120 <= hue && hue < 180) { r = 0; g = chroma; b = x; } else if (180 <= hue && hue < 240) { r = 0; g = x; b = chroma; } else if (240 <= hue && hue < 300) { r = x; g = 0; b = chroma; } else if (300 <= hue && hue < 360) { 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); dest -> l = (max + min)/2; //bi-hexcone model. if (max == min) { // neutral color. dest -> h = 0; // undefined. dest -> s = 0.0f; } else { float chroma = max - min; 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; nrgb.r = strtol(h1, NULL, 16); nrgb.g = strtol(h2, NULL, 16); nrgb.b = strtol(h3, NULL, 16); 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 - ASCII_ZERO); if (strlen(token) > 1) { printf("%s", token + 1); } } else if (c == 'x' && strlen(token) > 3) { if (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); }