summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bin/scheme.c203
1 files changed, 119 insertions, 84 deletions
diff --git a/bin/scheme.c b/bin/scheme.c
index ba05f14e..db4ff88f 100644
--- a/bin/scheme.c
+++ b/bin/scheme.c
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 #include <sysexits.h>
 #include <unistd.h>
 #include <zlib.h>
@@ -41,69 +42,9 @@ static struct Hsv x(struct Hsv o, double hd, double sf, double vf) {
 	};
 }
 
-enum { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
-struct Ansi {
-	struct Hsv dark[8];
-	struct Hsv light[8];
-};
-
-struct Terminal {
-	struct Ansi ansi;
-	struct Hsv background, text, bold, selection, cursor;
-};
-
-#define HSV_LEN(x) (sizeof(x) / sizeof(struct Hsv))
-struct Scheme {
-	size_t len;
-	union {
-		struct Hsv hsv;
-		struct Ansi ansi;
-		struct Terminal terminal;
-	};
-};
-
-static struct Scheme ansi(void) {
-	struct Ansi a = {
-		.light = {
-			[BLACK]   = x(R, +45.0, 0.3, 0.3),
-			[RED]     = x(R, +10.0, 0.9, 0.8),
-			[GREEN]   = x(G, -55.0, 0.8, 0.6),
-			[YELLOW]  = x(Y, -20.0, 0.8, 0.8),
-			[BLUE]    = x(B, -55.0, 0.4, 0.5),
-			[MAGENTA] = x(M, +45.0, 0.4, 0.6),
-			[CYAN]    = x(C, -60.0, 0.3, 0.6),
-			[WHITE]   = x(R, +45.0, 0.3, 0.8),
-		},
-	};
-	a.dark[BLACK] = x(a.light[BLACK], 0.0, 1.0, 0.3);
-	a.dark[WHITE] = x(a.light[WHITE], 0.0, 1.0, 0.6);
-	for (int i = RED; i < WHITE; ++i) {
-		a.dark[i] = x(a.light[i], 0.0, 1.0, 0.8);
-	}
-	return (struct Scheme) { .len = HSV_LEN(a), .ansi = a };
-}
-
-static struct Scheme terminal(void) {
-	struct Ansi a = ansi().ansi;
-	struct Terminal t = {
-		.ansi       = a,
-		.background = x(a.dark[BLACK],    0.0, 1.0, 0.9),
-		.text       = x(a.light[WHITE],   0.0, 1.0, 0.9),
-		.bold       = x(a.light[WHITE],   0.0, 1.0, 1.0),
-		.selection  = x(a.light[RED],   +10.0, 1.0, 0.8),
-		.cursor     = x(a.dark[WHITE],    0.0, 1.0, 0.8),
-	};
-	return (struct Scheme) { .len = HSV_LEN(t), .terminal = t };
-}
-
-static void hsv(const struct Hsv *hsv, size_t len) {
-	for (size_t i = 0; i < len; ++i) {
-		printf("%g,%g,%g\n", hsv[i].h, hsv[i].s, hsv[i].v);
-	}
-}
-
-struct Rgb { uint8_t r, g, b; };
-static struct Rgb toRgb(struct Hsv hsv) {
+static struct Rgb {
+	uint8_t r, g, b;
+} toRgb(struct Hsv hsv) {
 	double c = hsv.v * hsv.s;
 	double h = hsv.h / 60.0;
 	double x = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
@@ -118,19 +59,110 @@ static struct Rgb toRgb(struct Hsv hsv) {
 	return (struct Rgb) { r * 255.0, g * 255.0, b * 255.0 };
 }
 
-static void hex(const struct Hsv *hsv, size_t len) {
-	for (size_t i = 0; i < len; ++i) {
-		struct Rgb rgb = toRgb(hsv[i]);
-		printf("%02X%02X%02X\n", rgb.r, rgb.g, rgb.b);
+enum { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
+static struct {
+	struct Hsv dark[8];
+	struct Hsv light[8];
+	struct Hsv background, text, bold, selection, cursor;
+} scheme;
+
+static void generate(void) {
+	scheme.light[BLACK]   = x(R, +45.0, 0.3, 0.3);
+	scheme.light[RED]     = x(R, +10.0, 0.9, 0.8);
+	scheme.light[GREEN]   = x(G, -55.0, 0.8, 0.6);
+	scheme.light[YELLOW]  = x(Y, -20.0, 0.8, 0.8);
+	scheme.light[BLUE]    = x(B, -55.0, 0.4, 0.5);
+	scheme.light[MAGENTA] = x(M, +45.0, 0.4, 0.6);
+	scheme.light[CYAN]    = x(C, -60.0, 0.3, 0.6);
+	scheme.light[WHITE]   = x(R, +45.0, 0.3, 0.8);
+
+	scheme.dark[BLACK] = x(scheme.light[BLACK], 0.0, 1.0, 0.3);
+	scheme.dark[WHITE] = x(scheme.light[WHITE], 0.0, 1.0, 0.6);
+	for (int i = RED; i < WHITE; ++i) {
+		scheme.dark[i] = x(scheme.light[i], 0.0, 1.0, 0.8);
 	}
+
+	scheme.background = x(scheme.dark[BLACK],    0.0, 1.0, 0.9);
+	scheme.text       = x(scheme.light[WHITE],   0.0, 1.0, 0.9);
+	scheme.bold       = x(scheme.light[WHITE],   0.0, 1.0, 1.0);
+	scheme.selection  = x(scheme.light[RED],   +10.0, 1.0, 0.8);
+	scheme.cursor     = x(scheme.dark[WHITE],    0.0, 1.0, 0.8);
 }
 
-static void console(const struct Hsv *hsv, size_t len) {
-	if (len > 16) len = 16;
-	for (size_t i = 0; i < len; ++i) {
-		struct Rgb rgb = toRgb(hsv[i]);
-		printf("\x1B]P%zX%02X%02X%02X", i, rgb.r, rgb.g, rgb.b);
+static void printHsv(struct Hsv hsv) {
+	printf("%g,%g,%g\n", hsv.h, hsv.s, hsv.v);
+}
+static void hsv(bool ansi) {
+	for (int i = BLACK; i <= WHITE; ++i) {
+		printHsv(scheme.dark[i]);
+	}
+	for (int i = BLACK; i <= WHITE; ++i) {
+		printHsv(scheme.light[i]);
 	}
+	if (ansi) return;
+	printHsv(scheme.background);
+	printHsv(scheme.text);
+	printHsv(scheme.bold);
+	printHsv(scheme.selection);
+	printHsv(scheme.cursor);
+}
+
+static void printHex(struct Hsv hsv) {
+	struct Rgb rgb = toRgb(hsv);
+	printf("%02X%02X%02X\n", rgb.r, rgb.g, rgb.b);
+}
+static void hex(bool ansi) {
+	for (int i = BLACK; i <= WHITE; ++i) {
+		printHex(scheme.dark[i]);
+	}
+	for (int i = BLACK; i <= WHITE; ++i) {
+		printHex(scheme.light[i]);
+	}
+	if (ansi) return;
+	printHex(scheme.background);
+	printHex(scheme.text);
+	printHex(scheme.bold);
+	printHex(scheme.selection);
+	printHex(scheme.cursor);
+}
+
+static void console(void) {
+	for (int i = BLACK; i <= WHITE; ++i) {
+		struct Rgb rgb = toRgb(scheme.dark[i]);
+		printf("\x1B]P%X%02X%02X%02X", i, rgb.r, rgb.g, rgb.b);
+	}
+	for (int i = BLACK; i <= WHITE; ++i) {
+		struct Rgb rgb = toRgb(scheme.dark[i]);
+		printf("\x1B]P%X%02X%02X%02X", 8 + i, rgb.r, rgb.g, rgb.b);
+	}
+}
+
+static void printMintty(const char *key, struct Hsv hsv) {
+	struct Rgb rgb = toRgb(hsv);
+	printf("%s=%d,%d,%d\n", key, rgb.r, rgb.g, rgb.b);
+}
+static void mintty(void) {
+	printMintty("Black", scheme.dark[BLACK]);
+	printMintty("Red", scheme.dark[RED]);
+	printMintty("Green", scheme.dark[GREEN]);
+	printMintty("Yellow", scheme.dark[YELLOW]);
+	printMintty("Blue", scheme.dark[BLUE]);
+	printMintty("Magenta", scheme.dark[MAGENTA]);
+	printMintty("Cyan", scheme.dark[CYAN]);
+	printMintty("White", scheme.dark[WHITE]);
+
+	printMintty("BoldBlack", scheme.light[BLACK]);
+	printMintty("BoldRed", scheme.light[RED]);
+	printMintty("BoldGreen", scheme.light[GREEN]);
+	printMintty("BoldYellow", scheme.light[YELLOW]);
+	printMintty("BoldBlue", scheme.light[BLUE]);
+	printMintty("BoldMagenta", scheme.light[MAGENTA]);
+	printMintty("BoldCyan", scheme.light[CYAN]);
+	printMintty("BoldWhite", scheme.light[WHITE]);
+
+	printMintty("BackgroundColour", scheme.background);
+	printMintty("ForegroundColour", scheme.text);
+	printMintty("CursorColour", scheme.cursor);
 }
 
 static uint32_t crc;
@@ -199,21 +231,24 @@ static void png(const struct Hsv *hsv, size_t len) {
 }
 
 int main(int argc, char *argv[]) {
-	struct Scheme (*gen)(void) = ansi;
-	void (*out)(const struct Hsv *, size_t len) = hex;
+	generate();
+	bool ansi = true;
+	char out = 'x';
 	int opt;
-	while (0 < (opt = getopt(argc, argv, "aghltx"))) {
+	while (0 < (opt = getopt(argc, argv, "aghlmtx"))) {
 		switch (opt) {
-			break; case 'a': gen = ansi;
-			break; case 'g': out = png;
-			break; case 'h': out = hsv;
-			break; case 'l': out = console;
-			break; case 't': gen = terminal;
-			break; case 'x': out = hex;
-			break; default: return EX_USAGE;
+			break; case 'a': ansi = true;
+			break; case 't': ansi = false;
+			break; case '?': return EX_USAGE;
+			break; default: out = opt;
 		}
 	}
-	struct Scheme scheme = gen();
-	out(&scheme.hsv, scheme.len);
+	switch (out) {
+		break; case 'g': png((struct Hsv *)&scheme, (ansi ? 16 : 21));
+		break; case 'h': hsv(ansi);
+		break; case 'l': console();
+		break; case 'm': mintty();
+		break; case 'x': hex(ansi);
+	}
 	return EX_OK;
 }