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
|
// 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
}
|