forked from jesseduffield/gocui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
attribute.go
165 lines (143 loc) · 5.18 KB
/
attribute.go
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
// Copyright 2020 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gocui
import "github.com/gdamore/tcell/v2"
// Attribute affects the presentation of characters, such as color, boldness, etc.
type Attribute uint64
const (
// ColorDefault is used to leave the Color unchanged from whatever system or teminal default may exist.
ColorDefault = Attribute(tcell.ColorDefault)
// AttrIsValidColor is used to indicate the color value is actually
// valid (initialized). This is useful to permit the zero value
// to be treated as the default.
AttrIsValidColor = Attribute(tcell.ColorValid)
// AttrIsRGBColor is used to indicate that the Attribute value is RGB value of color.
// The lower order 3 bytes are RGB.
// (It's not a color in basic ANSI range 256).
AttrIsRGBColor = Attribute(tcell.ColorIsRGB)
// AttrColorBits is a mask where color is located in Attribute
AttrColorBits = 0xffffffffff // roughly 5 bytes, tcell uses 4 bytes and half-byte as a special flags for color (rest is reserved for future)
// AttrStyleBits is a mask where character attributes (e.g.: bold, italic, underline) are located in Attribute
AttrStyleBits = 0xffffff0000000000 // remaining 3 bytes in the 8 bytes Attribute (tcell is not using it, so we should be fine)
)
// Color attributes. These colors are compatible with tcell.Color type and can be expanded like:
// g.FgColor := gocui.Attribute(tcell.ColorLime)
const (
ColorBlack Attribute = AttrIsValidColor + iota
ColorRed
ColorGreen
ColorYellow
ColorBlue
ColorMagenta
ColorCyan
ColorWhite
)
// grayscale indexes (for backward compatibility with termbox-go original grayscale)
var grayscale = []tcell.Color{
16, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 231,
}
// Attributes are not colors, but effects (e.g.: bold, dim) which affect the display of text.
// They can be combined.
const (
AttrBold Attribute = 1 << (40 + iota)
AttrBlink
AttrReverse
AttrUnderline
AttrDim
AttrItalic
AttrStrikeThrough
AttrNone Attribute = 0 // Just normal text.
)
// AttrAll represents all the text effect attributes turned on
const AttrAll = AttrBold | AttrBlink | AttrReverse | AttrUnderline | AttrDim | AttrItalic
// IsValidColor indicates if the Attribute is a valid color value (has been set).
func (a Attribute) IsValidColor() bool {
return a&AttrIsValidColor != 0
}
// Hex returns the color's hexadecimal RGB 24-bit value with each component
// consisting of a single byte, ala R << 16 | G << 8 | B. If the color
// is unknown or unset, -1 is returned.
//
// This function produce the same output as `tcell.Hex()` with additional
// support for `termbox-go` colors (to 256).
func (a Attribute) Hex() int32 {
if !a.IsValidColor() {
return -1
}
tc := getTcellColor(a, OutputTrue)
return tc.Hex()
}
// RGB returns the red, green, and blue components of the color, with
// each component represented as a value 0-255. If the color
// is unknown or unset, -1 is returned for each component.
//
// This function produce the same output as `tcell.RGB()` with additional
// support for `termbox-go` colors (to 256).
func (a Attribute) RGB() (int32, int32, int32) {
v := a.Hex()
if v < 0 {
return -1, -1, -1
}
return (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff
}
// GetColor creates a Color from a color name (W3C name). A hex value may
// be supplied as a string in the format "#ffffff".
func GetColor(color string) Attribute {
return Attribute(tcell.GetColor(color))
}
// Get256Color creates Attribute which stores ANSI color (0-255)
func Get256Color(color int32) Attribute {
return Attribute(color) | AttrIsValidColor
}
// GetRGBColor creates Attribute which stores RGB color.
// Color is passed as 24bit RGB value, where R << 16 | G << 8 | B
func GetRGBColor(color int32) Attribute {
return Attribute(color) | AttrIsValidColor | AttrIsRGBColor
}
// NewRGBColor creates Attribute which stores RGB color.
func NewRGBColor(r, g, b int32) Attribute {
return Attribute(tcell.NewRGBColor(r, g, b))
}
// getTcellColor transform Attribute into tcell.Color
func getTcellColor(c Attribute, omode OutputMode) tcell.Color {
c = c & AttrColorBits
// Default color is 0 in tcell/v2 and was 0 in termbox-go, so we are good here
if c == ColorDefault {
return tcell.ColorDefault
}
tc := tcell.ColorDefault
// Check if we have valid color
if c.IsValidColor() {
tc = tcell.Color(c)
} else if c > 0 && c <= 256 {
// It's not valid color, but it has value in range 1-256
// This is old Attribute style of color from termbox-go (black=1, etc.)
// convert to tcell color (black=0|ColorValid)
tc = tcell.Color(c-1) | tcell.ColorValid
}
switch omode {
case OutputTrue:
return tc
case OutputNormal:
tc &= tcell.Color(0xf) | tcell.ColorValid
case Output256:
tc &= tcell.Color(0xff) | tcell.ColorValid
case Output216:
tc &= tcell.Color(0xff)
if tc > 215 {
return tcell.ColorDefault
}
tc += tcell.Color(16) | tcell.ColorValid
case OutputGrayscale:
tc &= tcell.Color(0x1f)
if tc > 26 {
return tcell.ColorDefault
}
tc = grayscale[tc] | tcell.ColorValid
default:
return tcell.ColorDefault
}
return tc
}