diff options
-rw-r--r-- | bin/README | 1 | ||||
-rw-r--r-- | bin/bin.7 | 3 | ||||
-rw-r--r-- | bin/man1/scheme.1 | 35 | ||||
-rw-r--r-- | bin/scheme.c | 280 |
4 files changed, 143 insertions, 176 deletions
diff --git a/bin/README b/bin/README index 74de8a52..bd12df94 100644 --- a/bin/README +++ b/bin/README @@ -23,6 +23,7 @@ DESCRIPTION pngo(1) PNG optimizer psf2png(1) PSF2 to PNG renderer psfed(1) PSF2 font editor + scheme(1) color scheme ttpre(1) man output to HTML up(1) upload file wake(1) wake-on-LAN diff --git a/bin/bin.7 b/bin/bin.7 index 8d5239c1..e6ab3cc0 100644 --- a/bin/bin.7 +++ b/bin/bin.7 @@ -64,6 +64,9 @@ PSF2 to PNG renderer .It Xr psfed 1 PSF2 font editor . +.It Xr scheme 1 +color scheme +. .It Xr ttpre 1 man output to HTML . diff --git a/bin/man1/scheme.1 b/bin/man1/scheme.1 index fe13b367..738d9cd7 100644 --- a/bin/man1/scheme.1 +++ b/bin/man1/scheme.1 @@ -1,10 +1,10 @@ -.Dd September 7, 2018 +.Dd February 12, 2019 .Dt SCHEME 1 .Os . .Sh NAME .Nm scheme -.Nd terminal color scheme +.Nd color scheme . .Sh SYNOPSIS .Nm @@ -13,51 +13,38 @@ . .Sh DESCRIPTION .Nm -generates a terminal color scheme +generates a color scheme and outputs it in a number of formats. . .Pp The arguments are as follows: .Bl -tag -width Ds .It Fl a -Output only the 16 ANSI colors. +Generate the 16 ANSI colors. This is the default. -. .It Fl c Output a C enum. -. .It Fl g Output a swatch PNG. -. .It Fl h -Output HSV. -. +Output floating point HSV. .It Fl i -Swap white and black. -. +Swap black and white. .It Fl l Output Linux console OSC sequences. -. .It Fl m Output a .Xr mintty 1 theme. -Should be used with +Use with .Fl t . -. .It Fl p Ar n -Only output the color +Generate only the color .Ar n . -. .It Fl t -Additionally output terminal -background, -foreground, -bold, -selection -and cursor -colors. -. +Generate the 16 ANSI colors as well as +background, foreground, bold, selection and cursor colors. .It Fl x Output hexadecimal RGB. +This is the default. .El diff --git a/bin/scheme.c b/bin/scheme.c index 1bd1cea0..43fc26fc 100644 --- a/bin/scheme.c +++ b/bin/scheme.c @@ -31,23 +31,15 @@ struct HSV { double h, s, v; }; -static const struct HSV - R = { 0.0, 1.0, 1.0 }, - Y = { 60.0, 1.0, 1.0 }, - G = { 120.0, 1.0, 1.0 }, - C = { 180.0, 1.0, 1.0 }, - B = { 240.0, 1.0, 1.0 }, - M = { 300.0, 1.0, 1.0 }; - struct RGB { byte r, g, b; }; -static struct RGB rgb(struct HSV hsv) { - double c = hsv.v * hsv.s; - double h = hsv.h / 60.0; +static struct RGB convert(struct HSV o) { + double c = o.v * o.s; + double h = o.h / 60.0; double x = c * (1.0 - fabs(fmod(h, 2.0) - 1.0)); - double m = hsv.v - c; + double m = o.v - c; double r = m, g = m, b = m; if (h <= 1.0) { r += c; g += x; } else if (h <= 2.0) { r += x; g += c; } @@ -58,6 +50,14 @@ static struct RGB rgb(struct HSV hsv) { return (struct RGB) { r * 255.0, g * 255.0, b * 255.0 }; } +static const struct HSV +R = { 0.0, 1.0, 1.0 }, +Y = { 60.0, 1.0, 1.0 }, +G = { 120.0, 1.0, 1.0 }, +C = { 180.0, 1.0, 1.0 }, +B = { 240.0, 1.0, 1.0 }, +M = { 300.0, 1.0, 1.0 }; + static struct HSV x(struct HSV o, double hd, double sf, double vf) { return (struct HSV) { fmod(o.h + hd, 360.0), @@ -68,196 +68,172 @@ static struct HSV x(struct HSV o, double hd, double sf, double vf) { enum { Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, - Dark = 0, Light = 8, - Background = 16, Foreground, Bold, Selection, Cursor, + Dark = 0, + Light = 8, + Background = 16, + Foreground, + Bold, + Selection, + Cursor, SchemeLen, }; static struct HSV scheme[SchemeLen]; +static struct HSV *dark = &scheme[Dark]; +static struct HSV *light = &scheme[Light]; 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); + light[Black] = x(R, +45.0, 0.3, 0.3); + light[Red] = x(R, +10.0, 0.9, 0.8); + light[Green] = x(G, -55.0, 0.8, 0.6); + light[Yellow] = x(Y, -20.0, 0.8, 0.8); + light[Blue] = x(B, -55.0, 0.4, 0.5); + light[Magenta] = x(M, +45.0, 0.4, 0.6); + light[Cyan] = x(C, -60.0, 0.3, 0.6); + light[White] = x(R, +45.0, 0.3, 0.8); + + dark[Black] = x(light[Black], 0.0, 1.0, 0.3); + dark[White] = x(light[White], 0.0, 1.0, 0.6); for (uint i = Red; i < White; ++i) { - scheme[Dark + i] = x(scheme[Light + i], 0.0, 1.0, 0.8); + dark[i] = x(light[i], 0.0, 1.0, 0.8); } - scheme[Background] = x(scheme[Dark + Black], 0.0, 1.0, 0.9); - scheme[Foreground] = 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); + scheme[Background] = x(dark[Black], 0.0, 1.0, 0.9); + scheme[Foreground] = x(light[White], 0.0, 1.0, 0.9); + scheme[Bold] = x(light[White], 0.0, 1.0, 1.0); + scheme[Selection] = x(light[Red], +10.0, 1.0, 0.8); + scheme[Cursor] = x(dark[White], 0.0, 1.0, 0.8); } -static void swap(uint a, uint b) { - struct HSV t = scheme[a]; - scheme[a] = scheme[b]; - scheme[b] = t; +static void swap(struct HSV *a, struct HSV *b) { + struct HSV c = *a; + *a = *b; + *b = c; } static void invert(void) { - swap(Dark + Black, Light + White); - swap(Light + Black, Dark + White); + swap(&dark[Black], &light[White]); + swap(&dark[White], &light[Black]); +} + +typedef void OutputFn(const struct HSV *hsv, uint len); + +static void outputHSV(const struct HSV *hsv, uint len) { + for (uint i = 0; i < len; ++i) { + printf("%g,%g,%g\n", hsv[i].h, hsv[i].s, hsv[i].v); + } } -static void printHSV(uint n) { - printf("%g,%g,%g\n", scheme[n].h, scheme[n].s, scheme[n].v); +#define FORMAT_RGB "%02hhX%02hhX%02hhX" + +static void outputRGB(const struct HSV *hsv, uint len) { + for (uint i = 0; i < len; ++i) { + struct RGB rgb = convert(hsv[i]); + printf(FORMAT_RGB "\n", rgb.r, rgb.g, rgb.b); + } } -static void printRGB(uint n) { - printf( - "%02hhX%02hhX%02hhX\n", - rgb(scheme[n]).r, rgb(scheme[n]).g, rgb(scheme[n]).b - ); +static void outputLinux(const struct HSV *hsv, uint len) { + for (uint i = 0; i < len; ++i) { + struct RGB rgb = convert(hsv[i]); + printf("\x1B]P%X" FORMAT_RGB, i, rgb.r, rgb.g, rgb.b); + } } -static const char *CNames[SchemeLen] = { - [Dark + Black] = "DarkBlack", - [Dark + Red] = "DarkRed", - [Dark + Green] = "DarkGreen", - [Dark + Yellow] = "DarkYellow", - [Dark + Blue] = "DarkBlue", - [Dark + Magenta] = "DarkMagenta", - [Dark + Cyan] = "DarkCyan", - [Dark + White] = "DarkWhite", - [Light + Black] = "LightBlack", - [Light + Red] = "LightRed", - [Light + Green] = "LightGreen", - [Light + Yellow] = "LightYellow", - [Light + Blue] = "LightBlue", - [Light + Magenta] = "LightMagenta", - [Light + Cyan] = "LightCyan", - [Light + White] = "LightWhite", - [Background] = "Background", - [Foreground] = "Foreground", - [Bold] = "Bold", - [Selection] = "Selection", - [Cursor] = "Cursor", +static const char *Enum[SchemeLen] = { + "DarkBlack", "DarkRed", "DarkGreen", "DarkYellow", + "DarkBlue", "DarkMagenta", "DarkCyan", "DarkWhite", + "LightBlack", "LightRed", "LightGreen", "LightYellow", + "LightBlue", "LightMagenta", "LightCyan", "LightWhite", + "Background", "Foreground", "Bold", "Selection", "Cursor", }; -static void printCHead(void) { + +static void outputEnum(const struct HSV *hsv, uint len) { printf("enum {\n"); -} -static void printC(uint n) { - printf( - "\t%s = 0x%02hhX%02hhX%02hhX,\n", - CNames[n], rgb(scheme[n]).r, rgb(scheme[n]).g, rgb(scheme[n]).b - ); -} -static void printCTail(void) { + for (uint i = 0; i < len; ++i) { + struct RGB rgb = convert(hsv[i]); + printf("\t%s = 0x" FORMAT_RGB ",\n", Enum[i], rgb.r, rgb.g, rgb.b); + } printf("};\n"); } -static void printLinux(uint n) { - printf( - "\x1B]P%X%02hhX%02hhX%02hhX", - n, rgb(scheme[n]).r, rgb(scheme[n]).g, rgb(scheme[n]).b - ); -} - -static const char *MinttyNames[SchemeLen] = { - [Dark + Black] = "Black", - [Dark + Red] = "Red", - [Dark + Green] = "Green", - [Dark + Yellow] = "Yellow", - [Dark + Blue] = "Blue", - [Dark + Magenta] = "Magenta", - [Dark + Cyan] = "Cyan", - [Dark + White] = "White", - [Light + Black] = "BoldBlack", - [Light + Red] = "BoldRed", - [Light + Green] = "BoldGreen", - [Light + Yellow] = "BoldYellow", - [Light + Blue] = "BoldBlue", - [Light + Magenta] = "BoldMagenta", - [Light + Cyan] = "BoldCyan", - [Light + White] = "BoldWhite", - [Background] = "BackgroundColour", - [Foreground] = "ForegroundColour", - [Cursor] = "CursorColour", +static const char *Mintty[SchemeLen] = { + "Black", "Red", "Green", "Yellow", + "Blue", "Magenta", "Cyan", "White", + "BoldBlack", "BoldRed", "BoldGreen", "BoldYellow", + "BoldBlue", "BoldMagenta", "BoldCyan", "BoldWhite", + [Background] = "BackgroundColour", + [Foreground] = "ForegroundColour", + [Cursor] = "CursorColour", }; -static void printMintty(uint n) { - if (!MinttyNames[n]) return; - printf( - "%s=%hhu,%hhu,%hhu\n", - MinttyNames[n], rgb(scheme[n]).r, rgb(scheme[n]).g, rgb(scheme[n]).b - ); -} -static void png(uint at, uint to) { - if (to - at > 256) to = at + 256; +static void outputMintty(const struct HSV *hsv, uint len) { + for (uint i = 0; i < len; ++i) { + if (!Mintty[i]) continue; + struct RGB rgb = convert(hsv[i]); + printf("%s=%hhu,%hhu,%hhu\n", Mintty[i], rgb.r, rgb.g, rgb.b); + } +} - uint len = to - at; - uint swatchWidth = 64; - uint swatchHeight = 64; - uint cols = 8; - uint rows = (len + cols - 1) / cols; - uint width = swatchWidth * cols; - uint height = swatchHeight * rows; +enum { + SwatchWidth = 64, + SwatchHeight = 64, + SwatchCols = 8, +}; +static void outputPNG(const struct HSV *hsv, uint len) { + uint rows = (len + SwatchCols - 1) / SwatchCols; + uint width = SwatchWidth * SwatchCols; + uint height = SwatchHeight * rows; pngHead(stdout, width, height, 8, PNGIndexed); struct RGB pal[len]; for (uint i = 0; i < len; ++i) { - pal[i] = rgb(scheme[at + i]); + pal[i] = convert(hsv[i]); } pngPalette(stdout, (byte *)pal, sizeof(pal)); - uint8_t data[height][1 + width]; + byte data[height][1 + width]; memset(data, 0, sizeof(data)); - for (uint32_t y = 0; y < height; ++y) { - data[y][0] = (y % swatchHeight) ? PNGUp : PNGSub; + for (uint y = 0; y < height; ++y) { + data[y][0] = (y % SwatchHeight ? PNGUp : PNGSub); } - for (uint i = at; i < to; ++i) { - uint p = i - at; - uint32_t y = swatchHeight * (p / cols); - uint32_t x = swatchWidth * (p % cols); - data[y][1 + x] = x ? 1 : p; + for (uint i = 0; i < len; ++i) { + uint y = SwatchHeight * (i / SwatchCols); + uint x = SwatchWidth * (i % SwatchCols); + data[y][1 + x] = (x ? 1 : i); } - pngData(stdout, (byte *)data, sizeof(data)); pngTail(stdout); } -static void print(void fn(uint), uint at, uint to) { - for (uint i = at; i < to; ++i) { - fn(i); - } -} - int main(int argc, char *argv[]) { generate(); - uint at = 0; - uint to = Background; - char out = 'x'; + + OutputFn *output = outputRGB; + const struct HSV *hsv = scheme; + uint len = 16; int opt; while (0 < (opt = getopt(argc, argv, "acghilmp:tx"))) { switch (opt) { - break; case 'a': to = Background; + break; case 'a': len = 16; + break; case 'c': output = outputEnum; + break; case 'g': output = outputPNG; + break; case 'h': output = outputHSV; break; case 'i': invert(); - break; case 'p': at = strtoul(optarg, NULL, 0); to = at + 1; - break; case 't': to = SchemeLen; - break; case '?': return EX_USAGE; - break; default: out = opt; + break; case 'l': output = outputLinux; + break; case 'm': output = outputMintty; + break; case 'p': { + uint p = strtoul(optarg, NULL, 0); + if (p >= SchemeLen) return EX_USAGE; + hsv = &scheme[p]; + len = 1; + } + break; case 't': len = SchemeLen; + break; case 'x': output = outputRGB; + break; default: return EX_USAGE; } } - switch (out) { - break; case 'c': printCHead(); print(printC, at, to); printCTail(); - break; case 'g': png(at, to); - break; case 'h': print(printHSV, at, to); - break; case 'l': print(printLinux, at, to); - break; case 'm': print(printMintty, at, to); - break; case 'x': print(printRGB, at, to); - } - - return EX_OK; + output(hsv, len); } |