Imported Upstream version 0.0~git20150719.0.3b18c85
Tim Potter
8 years ago
0 | Copyright (c) 2015, David Deng | |
1 | All rights reserved. | |
2 | ||
3 | Redistribution and use in source and binary forms, with or without | |
4 | modification, are permitted provided that the following conditions are met: | |
5 | ||
6 | * Redistributions of source code must retain the above copyright notice, this | |
7 | list of conditions and the following disclaimer. | |
8 | ||
9 | * Redistributions in binary form must reproduce the above copyright notice, | |
10 | this list of conditions and the following disclaimer in the documentation | |
11 | and/or other materials provided with the distribution. | |
12 | ||
13 | * Neither the name of go-colortext nor the names of its | |
14 | contributors may be used to endorse or promote products derived from | |
15 | this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
0 | go-colortext package [![GoSearch](http://go-search.org/badge?id=github.com%2Fdaviddengcn%2Fgo-colortext)](http://go-search.org/view?id=github.com%2Fdaviddengcn%2Fgo-colortext) | |
1 | ==================== | |
2 | ||
3 | This is a package to change the color of the text and background in the console, working both under Windows and other systems. | |
4 | ||
5 | Under Windows, the console APIs are used. Otherwise, ANSI texts are output. | |
6 | ||
7 | Docs: http://godoc.org/github.com/daviddengcn/go-colortext ([packages that import ct](http://go-search.org/view?id=github.com%2fdaviddengcn%2fgo-colortext)) | |
8 | ||
9 | Usage: | |
10 | ```go | |
11 | Foreground(Green, false) | |
12 | fmt.Println("Green text starts here...") | |
13 | ChangeColor(Red, true, White, false) | |
14 | fmt.Println(...) | |
15 | ResetColor() | |
16 | ``` | |
17 | ||
18 | LICENSE | |
19 | ======= | |
20 | BSD license |
0 | /* | |
1 | ct package provides functions to change the color of console text. | |
2 | ||
3 | Under windows platform, the Console api is used. Under other systems, ANSI text mode is used. | |
4 | */ | |
5 | package ct | |
6 | ||
7 | // Color is the type of color to be set. | |
8 | type Color int | |
9 | ||
10 | const ( | |
11 | // No change of color | |
12 | None = Color(iota) | |
13 | Black | |
14 | Red | |
15 | Green | |
16 | Yellow | |
17 | Blue | |
18 | Magenta | |
19 | Cyan | |
20 | White | |
21 | ) | |
22 | ||
23 | /* | |
24 | ResetColor resets the foreground and background to original colors | |
25 | */ | |
26 | func ResetColor() { | |
27 | resetColor() | |
28 | } | |
29 | ||
30 | // ChangeColor sets the foreground and background colors. If the value of the color is None, | |
31 | // the corresponding color keeps unchanged. | |
32 | // If fgBright or bgBright is set true, corresponding color use bright color. bgBright may be | |
33 | // ignored in some OS environment. | |
34 | func ChangeColor(fg Color, fgBright bool, bg Color, bgBright bool) { | |
35 | changeColor(fg, fgBright, bg, bgBright) | |
36 | } | |
37 | ||
38 | // Foreground changes the foreground color. | |
39 | func Foreground(cl Color, bright bool) { | |
40 | ChangeColor(cl, bright, None, false) | |
41 | } | |
42 | ||
43 | // Background changes the background color. | |
44 | func Background(cl Color, bright bool) { | |
45 | ChangeColor(None, false, cl, bright) | |
46 | } |
0 | // +build !windows | |
1 | ||
2 | package ct | |
3 | ||
4 | import ( | |
5 | "fmt" | |
6 | ) | |
7 | ||
8 | func resetColor() { | |
9 | fmt.Print("\x1b[0m") | |
10 | } | |
11 | ||
12 | func changeColor(fg Color, fgBright bool, bg Color, bgBright bool) { | |
13 | if fg == None && bg == None { | |
14 | return | |
15 | } // if | |
16 | ||
17 | s := "" | |
18 | if fg != None { | |
19 | s = fmt.Sprintf("%s%d", s, 30+(int)(fg-Black)) | |
20 | if fgBright { | |
21 | s += ";1" | |
22 | } // if | |
23 | } // if | |
24 | ||
25 | if bg != None { | |
26 | if s != "" { | |
27 | s += ";" | |
28 | } // if | |
29 | s = fmt.Sprintf("%s%d", s, 40+(int)(bg-Black)) | |
30 | } // if | |
31 | ||
32 | s = "\x1b[0;" + s + "m" | |
33 | fmt.Print(s) | |
34 | } |
0 | package ct | |
1 | ||
2 | import ( | |
3 | "fmt" | |
4 | "testing" | |
5 | ) | |
6 | ||
7 | func TestChangeColor(t *testing.T) { | |
8 | defer ResetColor() | |
9 | fmt.Println("Normal text...") | |
10 | text := "This is an demo of using ChangeColor to output colorful texts" | |
11 | i := 1 | |
12 | for _, c := range text { | |
13 | ChangeColor(Color(i/2%8)+Black, i%2 == 1, Color((i+2)/2%8)+Black, false) | |
14 | fmt.Print(string(c)) | |
15 | i++ | |
16 | } | |
17 | fmt.Println() | |
18 | ChangeColor(Red, true, White, false) | |
19 | fmt.Println("Before reset.") | |
20 | ChangeColor(Red, false, White, true) | |
21 | fmt.Println("Before reset.") | |
22 | ResetColor() | |
23 | fmt.Println("After reset.") | |
24 | fmt.Println("After reset.") | |
25 | } | |
26 | ||
27 | func TestForeground(t *testing.T) { | |
28 | ResetColor() | |
29 | defer ResetColor() | |
30 | ||
31 | fmt.Println("Please check the words under the following text shows with the corresponding front color:") | |
32 | ||
33 | colorToText := [...]string{ | |
34 | Black: "black", | |
35 | Red: "red", | |
36 | Green: "green", | |
37 | Yellow: "yellow", | |
38 | Blue: "blue", | |
39 | Magenta: "magenta", | |
40 | Cyan: "cyan", | |
41 | White: "white", | |
42 | } | |
43 | ||
44 | for i := range colorToText { | |
45 | cl := Color(i) | |
46 | if cl != None { | |
47 | Foreground(cl, false) | |
48 | fmt.Print(colorToText[i], ",") | |
49 | Foreground(cl, true) | |
50 | fmt.Print(colorToText[i], ",") | |
51 | } | |
52 | } | |
53 | fmt.Println() | |
54 | } | |
55 | ||
56 | func TestBackground(t *testing.T) { | |
57 | ResetColor() | |
58 | defer ResetColor() | |
59 | ||
60 | fmt.Println("Please check the words under the following text shows with the corresponding background color:") | |
61 | ||
62 | colorToText := [...]string{ | |
63 | Black: "black", | |
64 | Red: "red", | |
65 | Green: "green", | |
66 | Yellow: "yellow", | |
67 | Blue: "blue", | |
68 | Magenta: "magenta", | |
69 | Cyan: "cyan", | |
70 | White: "white", | |
71 | } | |
72 | ||
73 | for i := range colorToText { | |
74 | cl := Color(i) | |
75 | if cl != None { | |
76 | Background(cl, false) | |
77 | fmt.Print(colorToText[i], ",") | |
78 | Background(cl, true) | |
79 | fmt.Print(colorToText[i], ",") | |
80 | } | |
81 | } | |
82 | fmt.Println() | |
83 | } |
0 | // +build windows | |
1 | ||
2 | package ct | |
3 | ||
4 | import ( | |
5 | "syscall" | |
6 | "unsafe" | |
7 | ) | |
8 | ||
9 | var fg_colors = []uint16{ | |
10 | 0, | |
11 | 0, | |
12 | foreground_red, | |
13 | foreground_green, | |
14 | foreground_red | foreground_green, | |
15 | foreground_blue, | |
16 | foreground_red | foreground_blue, | |
17 | foreground_green | foreground_blue, | |
18 | foreground_red | foreground_green | foreground_blue} | |
19 | ||
20 | var bg_colors = []uint16{ | |
21 | 0, | |
22 | 0, | |
23 | background_red, | |
24 | background_green, | |
25 | background_red | background_green, | |
26 | background_blue, | |
27 | background_red | background_blue, | |
28 | background_green | background_blue, | |
29 | background_red | background_green | background_blue} | |
30 | ||
31 | const ( | |
32 | foreground_blue = uint16(0x0001) | |
33 | foreground_green = uint16(0x0002) | |
34 | foreground_red = uint16(0x0004) | |
35 | foreground_intensity = uint16(0x0008) | |
36 | background_blue = uint16(0x0010) | |
37 | background_green = uint16(0x0020) | |
38 | background_red = uint16(0x0040) | |
39 | background_intensity = uint16(0x0080) | |
40 | ||
41 | foreground_mask = foreground_blue | foreground_green | foreground_red | foreground_intensity | |
42 | background_mask = background_blue | background_green | background_red | background_intensity | |
43 | ) | |
44 | ||
45 | var ( | |
46 | kernel32 = syscall.NewLazyDLL("kernel32.dll") | |
47 | ||
48 | procGetStdHandle = kernel32.NewProc("GetStdHandle") | |
49 | procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") | |
50 | procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") | |
51 | ||
52 | hStdout uintptr | |
53 | initScreenInfo *console_screen_buffer_info | |
54 | ) | |
55 | ||
56 | func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool { | |
57 | ret, _, _ := procSetConsoleTextAttribute.Call( | |
58 | hConsoleOutput, | |
59 | uintptr(wAttributes)) | |
60 | return ret != 0 | |
61 | } | |
62 | ||
63 | type coord struct { | |
64 | X, Y int16 | |
65 | } | |
66 | ||
67 | type small_rect struct { | |
68 | Left, Top, Right, Bottom int16 | |
69 | } | |
70 | ||
71 | type console_screen_buffer_info struct { | |
72 | DwSize coord | |
73 | DwCursorPosition coord | |
74 | WAttributes uint16 | |
75 | SrWindow small_rect | |
76 | DwMaximumWindowSize coord | |
77 | } | |
78 | ||
79 | func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *console_screen_buffer_info { | |
80 | var csbi console_screen_buffer_info | |
81 | ret, _, _ := procGetConsoleScreenBufferInfo.Call( | |
82 | hConsoleOutput, | |
83 | uintptr(unsafe.Pointer(&csbi))) | |
84 | if ret == 0 { | |
85 | return nil | |
86 | } | |
87 | return &csbi | |
88 | } | |
89 | ||
90 | const ( | |
91 | std_output_handle = uint32(-11 & 0xFFFFFFFF) | |
92 | ) | |
93 | ||
94 | func init() { | |
95 | kernel32 := syscall.NewLazyDLL("kernel32.dll") | |
96 | ||
97 | procGetStdHandle = kernel32.NewProc("GetStdHandle") | |
98 | ||
99 | hStdout, _, _ = procGetStdHandle.Call(uintptr(std_output_handle)) | |
100 | ||
101 | initScreenInfo = getConsoleScreenBufferInfo(hStdout) | |
102 | ||
103 | syscall.LoadDLL("") | |
104 | } | |
105 | ||
106 | func resetColor() { | |
107 | if initScreenInfo == nil { // No console info - Ex: stdout redirection | |
108 | return | |
109 | } | |
110 | setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes) | |
111 | } | |
112 | ||
113 | func changeColor(fg Color, fgBright bool, bg Color, bgBright bool) { | |
114 | attr := uint16(0) | |
115 | if fg == None || bg == None { | |
116 | cbufinfo := getConsoleScreenBufferInfo(hStdout) | |
117 | if cbufinfo == nil { // No console info - Ex: stdout redirection | |
118 | return | |
119 | } | |
120 | attr = getConsoleScreenBufferInfo(hStdout).WAttributes | |
121 | } // if | |
122 | ||
123 | if fg != None { | |
124 | attr = attr & ^foreground_mask | fg_colors[fg] | |
125 | if fgBright { | |
126 | attr |= foreground_intensity | |
127 | } // if | |
128 | } // if | |
129 | ||
130 | if bg != None { | |
131 | attr = attr & ^background_mask | bg_colors[bg] | |
132 | if bgBright { | |
133 | attr |= background_intensity | |
134 | } // if | |
135 | } // if | |
136 | ||
137 | setConsoleTextAttribute(hStdout, attr) | |
138 | } |