How to use toHSV method of formatter Package

Best Ginkgo code snippet using formatter.toHSV

Run Ginkgo automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

colorable_windows.go

Source: colorable_windows.go Github

copy
1/*
2These packages are used for colorize on Windows and contributed by [email protected]
3
4  * go-colorable: <https://github.com/mattn/go-colorable>
5  * go-isatty: <https://github.com/mattn/go-isatty>
6
7The MIT License (MIT)
8
9Copyright (c) 2016 Yasuhiro Matsumoto
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30package formatter
31
32import (
33	"bytes"
34	"fmt"
35	"io"
36	"math"
37	"os"
38	"strconv"
39	"strings"
40	"syscall"
41	"unsafe"
42)
43
44var (
45	kernel32                       = syscall.NewLazyDLL("kernel32.dll")
46	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
47	procSetConsoleTextAttribute    = kernel32.NewProc("SetConsoleTextAttribute")
48	procSetConsoleCursorPosition   = kernel32.NewProc("SetConsoleCursorPosition")
49	procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
50	procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
51	procGetConsoleMode             = kernel32.NewProc("GetConsoleMode")
52)
53
54func isTerminal(fd uintptr) bool {
55	var st uint32
56	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
57	return r != 0 && e == 0
58}
59
60const (
61	foregroundBlue      = 0x1
62	foregroundGreen     = 0x2
63	foregroundRed       = 0x4
64	foregroundIntensity = 0x8
65	foregroundMask      = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
66	backgroundBlue      = 0x10
67	backgroundGreen     = 0x20
68	backgroundRed       = 0x40
69	backgroundIntensity = 0x80
70	backgroundMask      = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
71)
72
73type wchar uint16
74type short int16
75type dword uint32
76type word uint16
77
78type coord struct {
79	x short
80	y short
81}
82
83type smallRect struct {
84	left   short
85	top    short
86	right  short
87	bottom short
88}
89
90type consoleScreenBufferInfo struct {
91	size              coord
92	cursorPosition    coord
93	attributes        word
94	window            smallRect
95	maximumWindowSize coord
96}
97
98type writer struct {
99	out     io.Writer
100	handle  syscall.Handle
101	lastbuf bytes.Buffer
102	oldattr word
103}
104
105func newColorable(file *os.File) io.Writer {
106	if file == nil {
107		panic("nil passed instead of *os.File to NewColorable()")
108	}
109
110	if isTerminal(file.Fd()) {
111		var csbi consoleScreenBufferInfo
112		handle := syscall.Handle(file.Fd())
113		procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
114		return &writer{out: file, handle: handle, oldattr: csbi.attributes}
115	} else {
116		return file
117	}
118}
119
120var color256 = map[int]int{
121	0:   0x000000,
122	1:   0x800000,
123	2:   0x008000,
124	3:   0x808000,
125	4:   0x000080,
126	5:   0x800080,
127	6:   0x008080,
128	7:   0xc0c0c0,
129	8:   0x808080,
130	9:   0xff0000,
131	10:  0x00ff00,
132	11:  0xffff00,
133	12:  0x0000ff,
134	13:  0xff00ff,
135	14:  0x00ffff,
136	15:  0xffffff,
137	16:  0x000000,
138	17:  0x00005f,
139	18:  0x000087,
140	19:  0x0000af,
141	20:  0x0000d7,
142	21:  0x0000ff,
143	22:  0x005f00,
144	23:  0x005f5f,
145	24:  0x005f87,
146	25:  0x005faf,
147	26:  0x005fd7,
148	27:  0x005fff,
149	28:  0x008700,
150	29:  0x00875f,
151	30:  0x008787,
152	31:  0x0087af,
153	32:  0x0087d7,
154	33:  0x0087ff,
155	34:  0x00af00,
156	35:  0x00af5f,
157	36:  0x00af87,
158	37:  0x00afaf,
159	38:  0x00afd7,
160	39:  0x00afff,
161	40:  0x00d700,
162	41:  0x00d75f,
163	42:  0x00d787,
164	43:  0x00d7af,
165	44:  0x00d7d7,
166	45:  0x00d7ff,
167	46:  0x00ff00,
168	47:  0x00ff5f,
169	48:  0x00ff87,
170	49:  0x00ffaf,
171	50:  0x00ffd7,
172	51:  0x00ffff,
173	52:  0x5f0000,
174	53:  0x5f005f,
175	54:  0x5f0087,
176	55:  0x5f00af,
177	56:  0x5f00d7,
178	57:  0x5f00ff,
179	58:  0x5f5f00,
180	59:  0x5f5f5f,
181	60:  0x5f5f87,
182	61:  0x5f5faf,
183	62:  0x5f5fd7,
184	63:  0x5f5fff,
185	64:  0x5f8700,
186	65:  0x5f875f,
187	66:  0x5f8787,
188	67:  0x5f87af,
189	68:  0x5f87d7,
190	69:  0x5f87ff,
191	70:  0x5faf00,
192	71:  0x5faf5f,
193	72:  0x5faf87,
194	73:  0x5fafaf,
195	74:  0x5fafd7,
196	75:  0x5fafff,
197	76:  0x5fd700,
198	77:  0x5fd75f,
199	78:  0x5fd787,
200	79:  0x5fd7af,
201	80:  0x5fd7d7,
202	81:  0x5fd7ff,
203	82:  0x5fff00,
204	83:  0x5fff5f,
205	84:  0x5fff87,
206	85:  0x5fffaf,
207	86:  0x5fffd7,
208	87:  0x5fffff,
209	88:  0x870000,
210	89:  0x87005f,
211	90:  0x870087,
212	91:  0x8700af,
213	92:  0x8700d7,
214	93:  0x8700ff,
215	94:  0x875f00,
216	95:  0x875f5f,
217	96:  0x875f87,
218	97:  0x875faf,
219	98:  0x875fd7,
220	99:  0x875fff,
221	100: 0x878700,
222	101: 0x87875f,
223	102: 0x878787,
224	103: 0x8787af,
225	104: 0x8787d7,
226	105: 0x8787ff,
227	106: 0x87af00,
228	107: 0x87af5f,
229	108: 0x87af87,
230	109: 0x87afaf,
231	110: 0x87afd7,
232	111: 0x87afff,
233	112: 0x87d700,
234	113: 0x87d75f,
235	114: 0x87d787,
236	115: 0x87d7af,
237	116: 0x87d7d7,
238	117: 0x87d7ff,
239	118: 0x87ff00,
240	119: 0x87ff5f,
241	120: 0x87ff87,
242	121: 0x87ffaf,
243	122: 0x87ffd7,
244	123: 0x87ffff,
245	124: 0xaf0000,
246	125: 0xaf005f,
247	126: 0xaf0087,
248	127: 0xaf00af,
249	128: 0xaf00d7,
250	129: 0xaf00ff,
251	130: 0xaf5f00,
252	131: 0xaf5f5f,
253	132: 0xaf5f87,
254	133: 0xaf5faf,
255	134: 0xaf5fd7,
256	135: 0xaf5fff,
257	136: 0xaf8700,
258	137: 0xaf875f,
259	138: 0xaf8787,
260	139: 0xaf87af,
261	140: 0xaf87d7,
262	141: 0xaf87ff,
263	142: 0xafaf00,
264	143: 0xafaf5f,
265	144: 0xafaf87,
266	145: 0xafafaf,
267	146: 0xafafd7,
268	147: 0xafafff,
269	148: 0xafd700,
270	149: 0xafd75f,
271	150: 0xafd787,
272	151: 0xafd7af,
273	152: 0xafd7d7,
274	153: 0xafd7ff,
275	154: 0xafff00,
276	155: 0xafff5f,
277	156: 0xafff87,
278	157: 0xafffaf,
279	158: 0xafffd7,
280	159: 0xafffff,
281	160: 0xd70000,
282	161: 0xd7005f,
283	162: 0xd70087,
284	163: 0xd700af,
285	164: 0xd700d7,
286	165: 0xd700ff,
287	166: 0xd75f00,
288	167: 0xd75f5f,
289	168: 0xd75f87,
290	169: 0xd75faf,
291	170: 0xd75fd7,
292	171: 0xd75fff,
293	172: 0xd78700,
294	173: 0xd7875f,
295	174: 0xd78787,
296	175: 0xd787af,
297	176: 0xd787d7,
298	177: 0xd787ff,
299	178: 0xd7af00,
300	179: 0xd7af5f,
301	180: 0xd7af87,
302	181: 0xd7afaf,
303	182: 0xd7afd7,
304	183: 0xd7afff,
305	184: 0xd7d700,
306	185: 0xd7d75f,
307	186: 0xd7d787,
308	187: 0xd7d7af,
309	188: 0xd7d7d7,
310	189: 0xd7d7ff,
311	190: 0xd7ff00,
312	191: 0xd7ff5f,
313	192: 0xd7ff87,
314	193: 0xd7ffaf,
315	194: 0xd7ffd7,
316	195: 0xd7ffff,
317	196: 0xff0000,
318	197: 0xff005f,
319	198: 0xff0087,
320	199: 0xff00af,
321	200: 0xff00d7,
322	201: 0xff00ff,
323	202: 0xff5f00,
324	203: 0xff5f5f,
325	204: 0xff5f87,
326	205: 0xff5faf,
327	206: 0xff5fd7,
328	207: 0xff5fff,
329	208: 0xff8700,
330	209: 0xff875f,
331	210: 0xff8787,
332	211: 0xff87af,
333	212: 0xff87d7,
334	213: 0xff87ff,
335	214: 0xffaf00,
336	215: 0xffaf5f,
337	216: 0xffaf87,
338	217: 0xffafaf,
339	218: 0xffafd7,
340	219: 0xffafff,
341	220: 0xffd700,
342	221: 0xffd75f,
343	222: 0xffd787,
344	223: 0xffd7af,
345	224: 0xffd7d7,
346	225: 0xffd7ff,
347	226: 0xffff00,
348	227: 0xffff5f,
349	228: 0xffff87,
350	229: 0xffffaf,
351	230: 0xffffd7,
352	231: 0xffffff,
353	232: 0x080808,
354	233: 0x121212,
355	234: 0x1c1c1c,
356	235: 0x262626,
357	236: 0x303030,
358	237: 0x3a3a3a,
359	238: 0x444444,
360	239: 0x4e4e4e,
361	240: 0x585858,
362	241: 0x626262,
363	242: 0x6c6c6c,
364	243: 0x767676,
365	244: 0x808080,
366	245: 0x8a8a8a,
367	246: 0x949494,
368	247: 0x9e9e9e,
369	248: 0xa8a8a8,
370	249: 0xb2b2b2,
371	250: 0xbcbcbc,
372	251: 0xc6c6c6,
373	252: 0xd0d0d0,
374	253: 0xdadada,
375	254: 0xe4e4e4,
376	255: 0xeeeeee,
377}
378
379func (w *writer) Write(data []byte) (n int, err error) {
380	var csbi consoleScreenBufferInfo
381	procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
382
383	er := bytes.NewBuffer(data)
384loop:
385	for {
386		r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
387		if r1 == 0 {
388			break loop
389		}
390
391		c1, _, err := er.ReadRune()
392		if err != nil {
393			break loop
394		}
395		if c1 != 0x1b {
396			fmt.Fprint(w.out, string(c1))
397			continue
398		}
399		c2, _, err := er.ReadRune()
400		if err != nil {
401			w.lastbuf.WriteRune(c1)
402			break loop
403		}
404		if c2 != 0x5b {
405			w.lastbuf.WriteRune(c1)
406			w.lastbuf.WriteRune(c2)
407			continue
408		}
409
410		var buf bytes.Buffer
411		var m rune
412		for {
413			c, _, err := er.ReadRune()
414			if err != nil {
415				w.lastbuf.WriteRune(c1)
416				w.lastbuf.WriteRune(c2)
417				w.lastbuf.Write(buf.Bytes())
418				break loop
419			}
420			if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
421				m = c
422				break
423			}
424			buf.Write([]byte(string(c)))
425		}
426
427		var csbi consoleScreenBufferInfo
428		switch m {
429		case 'A':
430			n, err = strconv.Atoi(buf.String())
431			if err != nil {
432				continue
433			}
434			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
435			csbi.cursorPosition.y -= short(n)
436			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
437		case 'B':
438			n, err = strconv.Atoi(buf.String())
439			if err != nil {
440				continue
441			}
442			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
443			csbi.cursorPosition.y += short(n)
444			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
445		case 'C':
446			n, err = strconv.Atoi(buf.String())
447			if err != nil {
448				continue
449			}
450			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
451			csbi.cursorPosition.x -= short(n)
452			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
453		case 'D':
454			n, err = strconv.Atoi(buf.String())
455			if err != nil {
456				continue
457			}
458			if n, err = strconv.Atoi(buf.String()); err == nil {
459				var csbi consoleScreenBufferInfo
460				procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
461				csbi.cursorPosition.x += short(n)
462				procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
463			}
464		case 'E':
465			n, err = strconv.Atoi(buf.String())
466			if err != nil {
467				continue
468			}
469			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
470			csbi.cursorPosition.x = 0
471			csbi.cursorPosition.y += short(n)
472			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
473		case 'F':
474			n, err = strconv.Atoi(buf.String())
475			if err != nil {
476				continue
477			}
478			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
479			csbi.cursorPosition.x = 0
480			csbi.cursorPosition.y -= short(n)
481			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
482		case 'G':
483			n, err = strconv.Atoi(buf.String())
484			if err != nil {
485				continue
486			}
487			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
488			csbi.cursorPosition.x = short(n)
489			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
490		case 'H':
491			token := strings.Split(buf.String(), ";")
492			if len(token) != 2 {
493				continue
494			}
495			n1, err := strconv.Atoi(token[0])
496			if err != nil {
497				continue
498			}
499			n2, err := strconv.Atoi(token[1])
500			if err != nil {
501				continue
502			}
503			csbi.cursorPosition.x = short(n2)
504			csbi.cursorPosition.x = short(n1)
505			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
506		case 'J':
507			n, err := strconv.Atoi(buf.String())
508			if err != nil {
509				continue
510			}
511			var cursor coord
512			switch n {
513			case 0:
514				cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
515			case 1:
516				cursor = coord{x: csbi.window.left, y: csbi.window.top}
517			case 2:
518				cursor = coord{x: csbi.window.left, y: csbi.window.top}
519			}
520			var count, written dword
521			count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
522			procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
523			procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
524		case 'K':
525			n, err := strconv.Atoi(buf.String())
526			if err != nil {
527				continue
528			}
529			var cursor coord
530			switch n {
531			case 0:
532				cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
533			case 1:
534				cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
535			case 2:
536				cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
537			}
538			var count, written dword
539			count = dword(csbi.size.x - csbi.cursorPosition.x)
540			procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
541			procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
542		case 'm':
543			attr := csbi.attributes
544			cs := buf.String()
545			if cs == "" {
546				procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
547				continue
548			}
549			token := strings.Split(cs, ";")
550			for i := 0; i < len(token); i += 1 {
551				ns := token[i]
552				if n, err = strconv.Atoi(ns); err == nil {
553					switch {
554					case n == 0 || n == 100:
555						attr = w.oldattr
556					case 1 <= n && n <= 5:
557						attr |= foregroundIntensity
558					case n == 7:
559						attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
560					case 22 == n || n == 25 || n == 25:
561						attr |= foregroundIntensity
562					case n == 27:
563						attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
564					case 30 <= n && n <= 37:
565						attr = (attr & backgroundMask)
566						if (n-30)&1 != 0 {
567							attr |= foregroundRed
568						}
569						if (n-30)&2 != 0 {
570							attr |= foregroundGreen
571						}
572						if (n-30)&4 != 0 {
573							attr |= foregroundBlue
574						}
575					case n == 38: // set foreground color.
576						if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") {
577							if n256, err := strconv.Atoi(token[i+2]); err == nil {
578								if n256foreAttr == nil {
579									n256setup()
580								}
581								attr &= backgroundMask
582								attr |= n256foreAttr[n256]
583								i += 2
584							}
585						} else {
586							attr = attr & (w.oldattr & backgroundMask)
587						}
588					case n == 39: // reset foreground color.
589						attr &= backgroundMask
590						attr |= w.oldattr & foregroundMask
591					case 40 <= n && n <= 47:
592						attr = (attr & foregroundMask)
593						if (n-40)&1 != 0 {
594							attr |= backgroundRed
595						}
596						if (n-40)&2 != 0 {
597							attr |= backgroundGreen
598						}
599						if (n-40)&4 != 0 {
600							attr |= backgroundBlue
601						}
602					case n == 48: // set background color.
603						if i < len(token)-2 && token[i+1] == "5" {
604							if n256, err := strconv.Atoi(token[i+2]); err == nil {
605								if n256backAttr == nil {
606									n256setup()
607								}
608								attr &= foregroundMask
609								attr |= n256backAttr[n256]
610								i += 2
611							}
612						} else {
613							attr = attr & (w.oldattr & foregroundMask)
614						}
615					case n == 49: // reset foreground color.
616						attr &= foregroundMask
617						attr |= w.oldattr & backgroundMask
618					case 90 <= n && n <= 97:
619						attr = (attr & backgroundMask)
620						attr |= foregroundIntensity
621						if (n-90)&1 != 0 {
622							attr |= foregroundRed
623						}
624						if (n-90)&2 != 0 {
625							attr |= foregroundGreen
626						}
627						if (n-90)&4 != 0 {
628							attr |= foregroundBlue
629						}
630					case 100 <= n && n <= 107:
631						attr = (attr & foregroundMask)
632						attr |= backgroundIntensity
633						if (n-100)&1 != 0 {
634							attr |= backgroundRed
635						}
636						if (n-100)&2 != 0 {
637							attr |= backgroundGreen
638						}
639						if (n-100)&4 != 0 {
640							attr |= backgroundBlue
641						}
642					}
643					procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
644				}
645			}
646		}
647	}
648	return len(data) - w.lastbuf.Len(), nil
649}
650
651type consoleColor struct {
652	rgb       int
653	red       bool
654	green     bool
655	blue      bool
656	intensity bool
657}
658
659func (c consoleColor) foregroundAttr() (attr word) {
660	if c.red {
661		attr |= foregroundRed
662	}
663	if c.green {
664		attr |= foregroundGreen
665	}
666	if c.blue {
667		attr |= foregroundBlue
668	}
669	if c.intensity {
670		attr |= foregroundIntensity
671	}
672	return
673}
674
675func (c consoleColor) backgroundAttr() (attr word) {
676	if c.red {
677		attr |= backgroundRed
678	}
679	if c.green {
680		attr |= backgroundGreen
681	}
682	if c.blue {
683		attr |= backgroundBlue
684	}
685	if c.intensity {
686		attr |= backgroundIntensity
687	}
688	return
689}
690
691var color16 = []consoleColor{
692	consoleColor{0x000000, false, false, false, false},
693	consoleColor{0x000080, false, false, true, false},
694	consoleColor{0x008000, false, true, false, false},
695	consoleColor{0x008080, false, true, true, false},
696	consoleColor{0x800000, true, false, false, false},
697	consoleColor{0x800080, true, false, true, false},
698	consoleColor{0x808000, true, true, false, false},
699	consoleColor{0xc0c0c0, true, true, true, false},
700	consoleColor{0x808080, false, false, false, true},
701	consoleColor{0x0000ff, false, false, true, true},
702	consoleColor{0x00ff00, false, true, false, true},
703	consoleColor{0x00ffff, false, true, true, true},
704	consoleColor{0xff0000, true, false, false, true},
705	consoleColor{0xff00ff, true, false, true, true},
706	consoleColor{0xffff00, true, true, false, true},
707	consoleColor{0xffffff, true, true, true, true},
708}
709
710type hsv struct {
711	h, s, v float32
712}
713
714func (a hsv) dist(b hsv) float32 {
715	dh := a.h - b.h
716	switch {
717	case dh > 0.5:
718		dh = 1 - dh
719	case dh < -0.5:
720		dh = -1 - dh
721	}
722	ds := a.s - b.s
723	dv := a.v - b.v
724	return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))
725}
726
727func toHSV(rgb int) hsv {
728	r, g, b := float32((rgb&0xFF0000)>>16)/256.0,
729		float32((rgb&0x00FF00)>>8)/256.0,
730		float32(rgb&0x0000FF)/256.0
731	min, max := minmax3f(r, g, b)
732	h := max - min
733	if h > 0 {
734		if max == r {
735			h = (g - b) / h
736			if h < 0 {
737				h += 6
738			}
739		} else if max == g {
740			h = 2 + (b-r)/h
741		} else {
742			h = 4 + (r-g)/h
743		}
744	}
745	h /= 6.0
746	s := max - min
747	if max != 0 {
748		s /= max
749	}
750	v := max
751	return hsv{h: h, s: s, v: v}
752}
753
754type hsvTable []hsv
755
756func toHSVTable(rgbTable []consoleColor) hsvTable {
757	t := make(hsvTable, len(rgbTable))
758	for i, c := range rgbTable {
759		t[i] = toHSV(c.rgb)
760	}
761	return t
762}
763
764func (t hsvTable) find(rgb int) consoleColor {
765	hsv := toHSV(rgb)
766	n := 7
767	l := float32(5.0)
768	for i, p := range t {
769		d := hsv.dist(p)
770		if d < l {
771			l, n = d, i
772		}
773	}
774	return color16[n]
775}
776
777func minmax3f(a, b, c float32) (min, max float32) {
778	if a < b {
779		if b < c {
780			return a, c
781		} else if a < c {
782			return a, b
783		} else {
784			return c, b
785		}
786	} else {
787		if a < c {
788			return b, c
789		} else if b < c {
790			return b, a
791		} else {
792			return c, a
793		}
794	}
795}
796
797var n256foreAttr []word
798var n256backAttr []word
799
800func n256setup() {
801	n256foreAttr = make([]word, 256)
802	n256backAttr = make([]word, 256)
803	t := toHSVTable(color16)
804	for i, rgb := range color256 {
805		c := t.find(rgb)
806		n256foreAttr[i] = c.foregroundAttr()
807		n256backAttr[i] = c.backgroundAttr()
808	}
809}
810
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger toHSV code on LambdaTest Cloud Grid

Execute automation tests with toHSV on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)