Repository navigation
Expand file tree
/
Copy pathPrintColors.java
More file actions
executable file
·209 lines (181 loc) · 8.62 KB
/
Copy pathPrintColors.java
File metadata and controls
executable file
·209 lines (181 loc) · 8.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS org.codejive.miniterm:miniterm${miniterm.ffm:}:${miniterm.version:0.2.0}
//DEPS org.codejive.miniterm:colors:${miniterm.version:0.2.0}
package examples;
import java.io.IOException;
import org.codejive.miniterm.Terminal;
import org.codejive.miniterm.colors.Color;
import org.codejive.miniterm.colors.TermColors;
public class PrintColors {
// The standard ANSI colors (red, green, yellow, blue, magenta, cyan) live at palette
// indices 1-6 and are also reachable through the classic SGR 31-36 escape codes.
private static final int[] SAMPLE_INDICES = {1, 2, 3, 4, 5, 6};
public static void main(String[] args) {
try (Terminal terminal = Terminal.create()) {
terminal.enableRawMode();
printColorKinds();
printBaseColors(terminal);
Color.RgbColor[] palette = printPalette(terminal);
demoTruecolor();
demoPaletteChange(terminal, palette);
} catch (IOException e) {
e.printStackTrace();
}
}
// Demonstrates the three Color implementations that don't require querying the terminal:
// BasicColor (the 8 classic ANSI colors, in normal/dark/bright intensities), IndexedColor
// (the 256-color palette by index) and DefaultColor (resets to the terminal's own color).
private static void printColorKinds() {
System.out.println("BasicColor - classic ANSI colors (normal / dark / bright):");
printBasicColorRow(Color.BasicColor.normalColors);
printBasicColorRow(Color.BasicColor.darkColors);
printBasicColorRow(Color.BasicColor.brightColors);
System.out.println();
System.out.println("IndexedColor - selected entries from the 256-color palette:");
StringBuilder line = new StringBuilder(" ");
for (int index : new int[] {16, 82, 94, 129, 160, 196, 214, 226}) {
line.append(colored(Color.indexed(index), String.format("%3d", index)));
}
System.out.println(line);
System.out.println();
System.out.println("DefaultColor - resets foreground/background to the terminal default:");
System.out.println(
" "
+ colored(Color.BasicColor.green, "colored")
+ " "
+ colored(Color.DEFAULT, "default")
+ " text");
System.out.println();
}
private static void printBasicColorRow(Color.BasicColor[] colors) {
StringBuilder line = new StringBuilder(" ");
for (Color.BasicColor color : colors) {
line.append(colored(color, color.toString()));
}
System.out.println(line);
}
// Wraps text in the CSI sequence for the given color's foreground style, followed by a reset.
private static String colored(Color color, String text) {
return "\u001b[" + color.toForegroundStyle() + "m" + text + "\u001b[0m ";
}
private static void printBaseColors(Terminal terminal) throws IOException {
Color fg = TermColors.queryForeground(terminal, () -> terminal.read(500));
Color bg = TermColors.queryBackground(terminal, () -> terminal.read(500));
Color cursor = TermColors.queryCursor(terminal, () -> terminal.read(500));
System.out.println("Terminal colors (queried via OSC):");
System.out.println(" foreground : " + (fg != null ? fg : "not reported"));
System.out.println(" background : " + (bg != null ? bg : "not reported"));
System.out.println(" cursor : " + (cursor != null ? cursor : "not reported"));
System.out.println();
}
private static Color.RgbColor[] printPalette(Terminal terminal) throws IOException {
System.out.println("Full 256-color palette (queried via OSC 4):");
Color.RgbColor[] palette = TermColors.queryPalette(terminal, () -> terminal.read(500));
for (int row = 0; row < 16; row++) {
StringBuilder line = new StringBuilder(" ");
for (int col = 0; col < 16; col++) {
int index = row * 16 + col;
line.append(swatch(index, palette[index]));
}
System.out.println(line);
}
System.out.println();
return palette;
}
private static String swatch(int index, Color.RgbColor color) {
if (color == null) {
return String.format("%4d? ", index);
}
// Use indexed color (48;5;N) instead of RGB (48;2;R;G;B) to display the actual
// palette entry as the terminal interprets it, not our queried RGB approximation.
return String.format("\u001b[48;5;%dm%4d\u001b[0m ", index, index);
}
private static void demoPaletteChange(Terminal terminal, Color.RgbColor[] original) throws IOException {
System.out.println("Before: standard ANSI colors 1-6 using their current palette entries");
printSample();
System.out.println();
System.out.println("Press Enter to swap those palette entries for a custom color scheme...");
waitForEnter(terminal);
Color.RgbColor[] custom = new Color.RgbColor[256];
custom[1] = Color.rgb8(0xE0, 0x60, 0x60); // red -> soft red
custom[2] = Color.rgb8(0x60, 0xC0, 0x80); // green -> mint
custom[3] = Color.rgb8(0xE0, 0xC0, 0x60); // yellow -> gold
custom[4] = Color.rgb8(0x60, 0x90, 0xE0); // blue -> sky blue
custom[5] = Color.rgb8(0xC0, 0x70, 0xE0); // magenta -> lavender
custom[6] = Color.rgb8(0x50, 0xC0, 0xC0); // cyan -> teal
TermColors.setPalette(terminal, custom);
System.out.println("After: same text, new palette entries");
printSample();
System.out.println();
System.out.println("Press Enter to restore the original palette entries...");
waitForEnter(terminal);
restoreSample(terminal, original);
System.out.println("Palette restored.");
}
private static void printSample() {
// Deliberately not bold: many terminals (e.g. mintty) render bold + color 1-6 using the
// *bright* palette entries (9-14) instead, which would hide the palette change we made.
StringBuilder line = new StringBuilder(" ");
for (int index : SAMPLE_INDICES) {
line.append(
String.format("\u001b[3%dm\u2588\u2588 color %d \u2588\u2588\u001b[0m ", index, index));
}
System.out.println(line);
}
private static void restoreSample(Terminal terminal, Color.RgbColor[] original) throws IOException {
for (int index : SAMPLE_INDICES) {
if (original[index] != null) {
TermColors.setColor(terminal, index, original[index]);
} else {
TermColors.resetColor(terminal, index);
}
}
}
private static void waitForEnter(Terminal terminal) throws IOException {
int c;
do {
c = terminal.read(-1);
} while (c != '\r' && c != '\n' && c != -1);
}
private static void demoTruecolor() {
System.out.println("Truecolor (24-bit RGB) - direct color specification:");
System.out.println(" Gradient from red to blue:");
StringBuilder gradient = new StringBuilder(" ");
for (int i = 0; i < 40; i++) {
int r = 255 - (i * 255 / 39);
int g = 0;
int b = (i * 255 / 39);
Color.RgbColor color = Color.rgb8(r, g, b);
gradient.append(String.format("\u001b[48;2;%d;%d;%dm ", r, g, b));
}
gradient.append("\u001b[0m");
System.out.println(gradient);
System.out.println(" Rainbow spectrum:");
StringBuilder rainbow = new StringBuilder(" ");
for (int i = 0; i < 40; i++) {
float hue = i / 40.0f;
int[] rgb = hsvToRgb(hue, 1.0f, 1.0f);
rainbow.append(String.format("\u001b[48;2;%d;%d;%dm ", rgb[0], rgb[1], rgb[2]));
}
rainbow.append("\u001b[0m");
System.out.println(rainbow);
System.out.println();
}
private static int[] hsvToRgb(float h, float s, float v) {
int hi = (int) (h * 6);
float f = h * 6 - hi;
float p = v * (1 - s);
float q = v * (1 - f * s);
float t = v * (1 - (1 - f) * s);
float r, g, b;
switch (hi % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
default: r = v; g = p; b = q; break;
}
return new int[] {(int)(r * 255), (int)(g * 255), (int)(b * 255)};
}
}