aboutsummaryrefslogtreecommitdiff
path: root/color
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-15 23:44:32 -0400
committerhistoria <[not public]>2026-07-15 23:44:32 -0400
commitecf4c872bb33381abc065f1816e204befcde610c (patch)
tree65e08a55bd577fcba6d714a13124b4912443be08 /color
parent1068432d94252b9b4dec447e424f85f712fa16c2 (diff)
downloadxterm256-color-palette-ecf4c872bb33381abc065f1816e204befcde610c.tar.gz
initial commit
Diffstat (limited to 'color')
-rw-r--r--color/color.go103
1 files changed, 101 insertions, 2 deletions
diff --git a/color/color.go b/color/color.go
index a3cbd16..243869b 100644
--- a/color/color.go
+++ b/color/color.go
@@ -99,9 +99,52 @@ func (xyz XYZColor) String() string {
return fmt.Sprintf("XYZ:{%4.7f %4.7f %4.7f}", xyz.X, xyz.Y, xyz.Z)
}
+// линейные RGB-компоненты (без гамма-коррекции и ограничения диапазона)
+func (xyz XYZColor) rgbLinear() (float64, float64, float64) {
+ //
+ // [R] [ 3.2406 -1.5372 -0.4986] [X]
+ // [G] = [-0.9689 1.8758 0.0415] x [Y]
+ // [B] [ 0.0557 -0.2040 1.0570] [Z]
+ //
+ // Observer. = 2°, Illuminant = D65
+ r := xyz.X*3.2406 + xyz.Y*-1.5372 + xyz.Z*-0.4986
+ g := xyz.X*-0.9689 + xyz.Y*1.8758 + xyz.Z*0.0415
+ b := xyz.X*0.0557 + xyz.Y*-0.2040 + xyz.Z*1.0570
+ return r, g, b
+}
+
func (xyz XYZColor) RGB() RGBColor {
- // TODO!!!
- return RGBColor{0, 0, 0}
+
+ f := func(n float64) int {
+ if n > 0.0031308 {
+ n = 1.055*math.Pow(n, 1.0/2.4) - 0.055
+ } else {
+ n = n * 12.92
+ }
+ v := int(math.Round(n * 255.0))
+ if v < 0 {
+ v = 0
+ }
+ if v > 255 {
+ v = 255
+ }
+ return v
+ }
+
+ r, g, b := xyz.rgbLinear()
+ return RGBColor{f(r), f(g), f(b)}
+}
+
+// InGamut сообщает, представим ли цвет в sRGB
+func InGamut(c Colorer) bool {
+ const tolerance = 1e-4
+ r, g, b := c.XYZ().rgbLinear()
+ for _, n := range [3]float64{r, g, b} {
+ if n < -tolerance || n > 1.0+tolerance {
+ return false
+ }
+ }
+ return true
}
func (xyz XYZColor) XYZ() XYZColor {
@@ -367,6 +410,35 @@ func Approximate(color Colorer, comparer Comparer) (float64, int) {
return bestdist, best + 17
}
+// ApproximateAll ищет ближайший цвет среди всех 256 цветов xterm,
+// включая 16 системных (их реальный вид зависит от темы терминала)
+func ApproximateAll(color Colorer, comparer Comparer) (float64, int) {
+ bestdist, best := Approximate(color, comparer)
+ for i, applicant := range SystemLabPalette {
+ if dist := comparer.Compare(color, applicant); dist < bestdist {
+ best, bestdist = i+1, dist
+ }
+ }
+ return bestdist, best
+}
+
+// TermRGB возвращает RGB-значение по termbox-атрибуту (1..256).
+// Для системных цветов используются стандартные значения xterm.
+func TermRGB(c int) RGBColor {
+ if c-1 < 16 {
+ return SystemRGBPalette[c-1]
+ }
+ return XtermRGBPalette[c-17]
+}
+
+// TermLab возвращает Lab-значение по termbox-атрибуту (1..256)
+func TermLab(c int) LabColor {
+ if c-1 < 16 {
+ return SystemLabPalette[c-1]
+ }
+ return XtermLabPalette[c-17]
+}
+
//color = round(36 * (r * 5) + 6 * (g * 5) + (b * 5) + 16)
func HackApproximate(color Colorer) int {
c := color.RGB()
@@ -623,6 +695,28 @@ var (
*/
XtermRGBPalette [240]RGBColor
XtermLabPalette [240]LabColor
+
+ // standard xterm defaults for the 16 system colors (0-15);
+ // actual appearance depends on the terminal theme
+ SystemRGBPalette = [16]RGBColor{
+ {0x00, 0x00, 0x00}, // 0 black
+ {0xCD, 0x00, 0x00}, // 1 red
+ {0x00, 0xCD, 0x00}, // 2 green
+ {0xCD, 0xCD, 0x00}, // 3 yellow
+ {0x00, 0x00, 0xEE}, // 4 blue
+ {0xCD, 0x00, 0xCD}, // 5 magenta
+ {0x00, 0xCD, 0xCD}, // 6 cyan
+ {0xE5, 0xE5, 0xE5}, // 7 white
+ {0x7F, 0x7F, 0x7F}, // 8 bright black
+ {0xFF, 0x00, 0x00}, // 9 bright red
+ {0x00, 0xFF, 0x00}, // 10 bright green
+ {0xFF, 0xFF, 0x00}, // 11 bright yellow
+ {0x5C, 0x5C, 0xFF}, // 12 bright blue
+ {0xFF, 0x00, 0xFF}, // 13 bright magenta
+ {0x00, 0xFF, 0xFF}, // 14 bright cyan
+ {0xFF, 0xFF, 0xFF}, // 15 bright white
+ }
+ SystemLabPalette [16]LabColor
)
func init() {
@@ -646,4 +740,9 @@ func init() {
for i, color := range XtermRGBPalette {
XtermLabPalette[i] = color.Lab()
}
+
+ // calculate Lab palette for the 16 system colors
+ for i, color := range SystemRGBPalette {
+ SystemLabPalette[i] = color.Lab()
+ }
}