-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathprofile.go
More file actions
108 lines (95 loc) · 1.98 KB
/
profile.go
File metadata and controls
108 lines (95 loc) · 1.98 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
package colorprofile
import (
"image/color"
"sync"
"github.com/charmbracelet/x/ansi"
)
// Profile is a color profile: NoTTY, Ascii, ANSI, ANSI256, or TrueColor.
type Profile byte
const (
// Unknown is a profile that represents the absence of a profile.
Unknown Profile = iota
// NoTTY is a profile with no terminal support.
NoTTY
// ASCII is a profile with no color support.
ASCII
// ANSI is a profile with 16 colors (4-bit).
ANSI
// ANSI256 is a profile with 256 colors (8-bit).
ANSI256
// TrueColor is a profile with 16 million colors (24-bit).
TrueColor
)
// Ascii is an alias for the [ASCII] profile for backwards compatibility.
const Ascii = ASCII //nolint:revive
// String returns the string representation of a Profile.
func (p Profile) String() string {
switch p {
case TrueColor:
return "TrueColor"
case ANSI256:
return "ANSI256"
case ANSI:
return "ANSI"
case ASCII:
return "Ascii"
case NoTTY:
return "NoTTY"
default:
return "Unknown"
}
}
var (
cache = map[Profile]map[color.Color]color.Color{
ANSI256: {},
ANSI: {},
}
mu sync.RWMutex
)
// Convert transforms a given Color to a Color supported within the Profile.
func (p Profile) Convert(c color.Color) (cc color.Color) {
if p <= ASCII {
return nil
}
if p == TrueColor {
// TrueColor is a passthrough.
return c
}
// Do we have a cached color for this profile and color?
mu.RLock()
if c != nil && cache[p] != nil {
if cc, ok := cache[p][c]; ok {
mu.RUnlock()
return cc
}
}
mu.RUnlock()
// If we don't have a cached color, we need to convert it and cache it.
defer func() {
mu.Lock()
if cc != nil && cache[p] != nil {
if _, ok := cache[p][c]; !ok {
cache[p][c] = cc
}
}
mu.Unlock()
}()
switch c.(type) {
case ansi.BasicColor:
return c
case ansi.IndexedColor:
if p == ANSI {
return ansi.Convert16(c)
}
return c
default:
switch p {
case ANSI256:
return ansi.Convert256(c)
case ANSI:
return ansi.Convert16(c)
default:
return c
}
}
}