Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
1b7366e4e6
commit
6793ed701b
530
js/term/colors.js
Normal file
530
js/term/colors.js
Normal file
|
@ -0,0 +1,530 @@
|
|||
/**
|
||||
* colors.js - color-related functions for blessed.
|
||||
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
|
||||
* https://github.com/chjj/blessed
|
||||
*/
|
||||
|
||||
exports.match = function(r1, g1, b1) {
|
||||
if (typeof r1 === 'string') {
|
||||
var hex = r1;
|
||||
if (hex[0] !== '#') {
|
||||
return -1;
|
||||
}
|
||||
hex = exports.hexToRGB(hex);
|
||||
r1 = hex[0], g1 = hex[1], b1 = hex[2];
|
||||
} else if (Array.isArray(r1)) {
|
||||
b1 = r1[2], g1 = r1[1], r1 = r1[0];
|
||||
}
|
||||
|
||||
var hash = (r1 << 16) | (g1 << 8) | b1;
|
||||
|
||||
if (exports._cache[hash] != null) {
|
||||
return exports._cache[hash];
|
||||
}
|
||||
|
||||
var ldiff = Infinity
|
||||
, li = -1
|
||||
, i = 0
|
||||
, c
|
||||
, r2
|
||||
, g2
|
||||
, b2
|
||||
, diff;
|
||||
|
||||
for (; i < exports.vcolors.length; i++) {
|
||||
c = exports.vcolors[i];
|
||||
r2 = c[0];
|
||||
g2 = c[1];
|
||||
b2 = c[2];
|
||||
|
||||
diff = colorDistance(r1, g1, b1, r2, g2, b2);
|
||||
|
||||
if (diff === 0) {
|
||||
li = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (diff < ldiff) {
|
||||
ldiff = diff;
|
||||
li = i;
|
||||
}
|
||||
}
|
||||
|
||||
return exports._cache[hash] = li;
|
||||
};
|
||||
|
||||
exports.RGBToHex = function(r, g, b) {
|
||||
if (Array.isArray(r)) {
|
||||
b = r[2], g = r[1], r = r[0];
|
||||
}
|
||||
|
||||
function hex(n) {
|
||||
n = n.toString(16);
|
||||
if (n.length < 2) n = '0' + n;
|
||||
return n;
|
||||
}
|
||||
|
||||
return '#' + hex(r) + hex(g) + hex(b);
|
||||
};
|
||||
|
||||
exports.hexToRGB = function(hex) {
|
||||
if (hex.length === 4) {
|
||||
hex = hex[0]
|
||||
+ hex[1] + hex[1]
|
||||
+ hex[2] + hex[2]
|
||||
+ hex[3] + hex[3];
|
||||
}
|
||||
|
||||
var col = parseInt(hex.substring(1), 16)
|
||||
, r = (col >> 16) & 0xff
|
||||
, g = (col >> 8) & 0xff
|
||||
, b = col & 0xff;
|
||||
|
||||
return [r, g, b];
|
||||
};
|
||||
|
||||
// As it happens, comparing how similar two colors are is really hard. Here is
|
||||
// one of the simplest solutions, which doesn't require conversion to another
|
||||
// color space, posted on stackoverflow[1]. Maybe someone better at math can
|
||||
// propose a superior solution.
|
||||
// [1] http://stackoverflow.com/questions/1633828
|
||||
|
||||
function colorDistance(r1, g1, b1, r2, g2, b2) {
|
||||
return Math.pow(30 * (r1 - r2), 2)
|
||||
+ Math.pow(59 * (g1 - g2), 2)
|
||||
+ Math.pow(11 * (b1 - b2), 2);
|
||||
}
|
||||
|
||||
// This might work well enough for a terminal's colors: treat RGB as XYZ in a
|
||||
// 3-dimensional space and go midway between the two points.
|
||||
exports.mixColors = function(c1, c2, alpha) {
|
||||
// if (c1 === 0x1ff) return c1;
|
||||
// if (c2 === 0x1ff) return c1;
|
||||
if (c1 === 0x1ff) c1 = 0;
|
||||
if (c2 === 0x1ff) c2 = 0;
|
||||
if (alpha == null) alpha = 0.5;
|
||||
|
||||
c1 = exports.vcolors[c1];
|
||||
var r1 = c1[0];
|
||||
var g1 = c1[1];
|
||||
var b1 = c1[2];
|
||||
|
||||
c2 = exports.vcolors[c2];
|
||||
var r2 = c2[0];
|
||||
var g2 = c2[1];
|
||||
var b2 = c2[2];
|
||||
|
||||
r1 += (r2 - r1) * alpha | 0;
|
||||
g1 += (g2 - g1) * alpha | 0;
|
||||
b1 += (b2 - b1) * alpha | 0;
|
||||
|
||||
return exports.match([r1, g1, b1]);
|
||||
};
|
||||
|
||||
exports.blend = function blend(attr, attr2, alpha) {
|
||||
var name, i, c, nc;
|
||||
|
||||
var bg = attr & 0x1ff;
|
||||
if (attr2 != null) {
|
||||
var bg2 = attr2 & 0x1ff;
|
||||
if (bg === 0x1ff) bg = 0;
|
||||
if (bg2 === 0x1ff) bg2 = 0;
|
||||
bg = exports.mixColors(bg, bg2, alpha);
|
||||
} else {
|
||||
if (blend._cache[bg] != null) {
|
||||
bg = blend._cache[bg];
|
||||
// } else if (bg < 8) {
|
||||
// bg += 8;
|
||||
} else if (bg >= 8 && bg <= 15) {
|
||||
bg -= 8;
|
||||
} else {
|
||||
name = exports.ncolors[bg];
|
||||
if (name) {
|
||||
for (i = 0; i < exports.ncolors.length; i++) {
|
||||
if (name === exports.ncolors[i] && i !== bg) {
|
||||
c = exports.vcolors[bg];
|
||||
nc = exports.vcolors[i];
|
||||
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
|
||||
blend._cache[bg] = i;
|
||||
bg = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attr &= ~0x1ff;
|
||||
attr |= bg;
|
||||
|
||||
var fg = (attr >> 9) & 0x1ff;
|
||||
if (attr2 != null) {
|
||||
var fg2 = (attr2 >> 9) & 0x1ff;
|
||||
// 0, 7, 188, 231, 251
|
||||
if (fg === 0x1ff) {
|
||||
// XXX workaround
|
||||
fg = 248;
|
||||
} else {
|
||||
if (fg === 0x1ff) fg = 7;
|
||||
if (fg2 === 0x1ff) fg2 = 7;
|
||||
fg = exports.mixColors(fg, fg2, alpha);
|
||||
}
|
||||
} else {
|
||||
if (blend._cache[fg] != null) {
|
||||
fg = blend._cache[fg];
|
||||
// } else if (fg < 8) {
|
||||
// fg += 8;
|
||||
} else if (fg >= 8 && fg <= 15) {
|
||||
fg -= 8;
|
||||
} else {
|
||||
name = exports.ncolors[fg];
|
||||
if (name) {
|
||||
for (i = 0; i < exports.ncolors.length; i++) {
|
||||
if (name === exports.ncolors[i] && i !== fg) {
|
||||
c = exports.vcolors[fg];
|
||||
nc = exports.vcolors[i];
|
||||
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
|
||||
blend._cache[fg] = i;
|
||||
fg = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attr &= ~(0x1ff << 9);
|
||||
attr |= fg << 9;
|
||||
|
||||
return attr;
|
||||
};
|
||||
|
||||
exports.blend._cache = {};
|
||||
|
||||
exports._cache = {};
|
||||
|
||||
exports.reduce = function(color, total) {
|
||||
if (color >= 16 && total <= 16) {
|
||||
color = exports.ccolors[color];
|
||||
} else if (color >= 8 && total <= 8) {
|
||||
color -= 8;
|
||||
} else if (color >= 2 && total <= 2) {
|
||||
color %= 2;
|
||||
}
|
||||
return color;
|
||||
};
|
||||
|
||||
// XTerm Colors
|
||||
// These were actually tough to track down. The xterm source only uses color
|
||||
// keywords. The X11 source needed to be examined to find the actual values.
|
||||
// They then had to be mapped to rgb values and then converted to hex values.
|
||||
exports.xterm = [
|
||||
'#000000', // black
|
||||
'#cd0000', // red3
|
||||
'#00cd00', // green3
|
||||
'#cdcd00', // yellow3
|
||||
'#0000ee', // blue2
|
||||
'#cd00cd', // magenta3
|
||||
'#00cdcd', // cyan3
|
||||
'#e5e5e5', // gray90
|
||||
'#7f7f7f', // gray50
|
||||
'#ff0000', // red
|
||||
'#00ff00', // green
|
||||
'#ffff00', // yellow
|
||||
'#5c5cff', // rgb:5c/5c/ff
|
||||
'#ff00ff', // magenta
|
||||
'#00ffff', // cyan
|
||||
'#ffffff' // white
|
||||
];
|
||||
|
||||
// Seed all 256 colors. Assume xterm defaults.
|
||||
// Ported from the xterm color generation script.
|
||||
exports.colors = (function() {
|
||||
var cols = exports.colors = []
|
||||
, _cols = exports.vcolors = []
|
||||
, r
|
||||
, g
|
||||
, b
|
||||
, i
|
||||
, l;
|
||||
|
||||
function hex(n) {
|
||||
n = n.toString(16);
|
||||
if (n.length < 2) n = '0' + n;
|
||||
return n;
|
||||
}
|
||||
|
||||
function push(i, r, g, b) {
|
||||
cols[i] = '#' + hex(r) + hex(g) + hex(b);
|
||||
_cols[i] = [r, g, b];
|
||||
}
|
||||
|
||||
// 0 - 15
|
||||
exports.xterm.forEach(function(c, i) {
|
||||
c = parseInt(c.substring(1), 16);
|
||||
push(i, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
|
||||
});
|
||||
|
||||
// 16 - 231
|
||||
for (r = 0; r < 6; r++) {
|
||||
for (g = 0; g < 6; g++) {
|
||||
for (b = 0; b < 6; b++) {
|
||||
i = 16 + (r * 36) + (g * 6) + b;
|
||||
push(i,
|
||||
r ? (r * 40 + 55) : 0,
|
||||
g ? (g * 40 + 55) : 0,
|
||||
b ? (b * 40 + 55) : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 232 - 255 are grey.
|
||||
for (g = 0; g < 24; g++) {
|
||||
l = (g * 10) + 8;
|
||||
i = 232 + g;
|
||||
push(i, l, l, l);
|
||||
}
|
||||
|
||||
return cols;
|
||||
})();
|
||||
|
||||
// Map higher colors to the first 8 colors.
|
||||
// This allows translation of high colors to low colors on 8-color terminals.
|
||||
exports.ccolors = (function() {
|
||||
var _cols = exports.vcolors.slice()
|
||||
, cols = exports.colors.slice()
|
||||
, out;
|
||||
|
||||
exports.vcolors = exports.vcolors.slice(0, 8);
|
||||
exports.colors = exports.colors.slice(0, 8);
|
||||
|
||||
out = cols.map(exports.match);
|
||||
|
||||
exports.colors = cols;
|
||||
exports.vcolors = _cols;
|
||||
exports.ccolors = out;
|
||||
|
||||
return out;
|
||||
})();
|
||||
|
||||
var colorNames = exports.colorNames = {
|
||||
// special
|
||||
default: -1,
|
||||
normal: -1,
|
||||
bg: -1,
|
||||
fg: -1,
|
||||
// normal
|
||||
black: 0,
|
||||
red: 1,
|
||||
green: 2,
|
||||
yellow: 3,
|
||||
blue: 4,
|
||||
magenta: 5,
|
||||
cyan: 6,
|
||||
white: 7,
|
||||
// light
|
||||
lightblack: 8,
|
||||
lightred: 9,
|
||||
lightgreen: 10,
|
||||
lightyellow: 11,
|
||||
lightblue: 12,
|
||||
lightmagenta: 13,
|
||||
lightcyan: 14,
|
||||
lightwhite: 15,
|
||||
// bright
|
||||
brightblack: 8,
|
||||
brightred: 9,
|
||||
brightgreen: 10,
|
||||
brightyellow: 11,
|
||||
brightblue: 12,
|
||||
brightmagenta: 13,
|
||||
brightcyan: 14,
|
||||
brightwhite: 15,
|
||||
// alternate spellings
|
||||
grey: 8,
|
||||
gray: 8,
|
||||
lightgrey: 7,
|
||||
lightgray: 7,
|
||||
brightgrey: 7,
|
||||
brightgray: 7
|
||||
};
|
||||
|
||||
exports.convert = function(color) {
|
||||
if (typeof color === 'number') {
|
||||
;
|
||||
} else if (typeof color === 'string') {
|
||||
color = color.replace(/[\- ]/g, '');
|
||||
if (colorNames[color] != null) {
|
||||
color = colorNames[color];
|
||||
} else {
|
||||
color = exports.match(color);
|
||||
}
|
||||
} else if (Array.isArray(color)) {
|
||||
color = exports.match(color);
|
||||
} else {
|
||||
color = -1;
|
||||
}
|
||||
return color !== -1 ? color : 0x1ff;
|
||||
};
|
||||
|
||||
// Map higher colors to the first 8 colors.
|
||||
// This allows translation of high colors to low colors on 8-color terminals.
|
||||
// Why the hell did I do this by hand?
|
||||
exports.ccolors = {
|
||||
blue: [
|
||||
4,
|
||||
12,
|
||||
[17, 21],
|
||||
[24, 27],
|
||||
[31, 33],
|
||||
[38, 39],
|
||||
45,
|
||||
[54, 57],
|
||||
[60, 63],
|
||||
[67, 69],
|
||||
[74, 75],
|
||||
81,
|
||||
[91, 93],
|
||||
[97, 99],
|
||||
[103, 105],
|
||||
[110, 111],
|
||||
117,
|
||||
[128, 129],
|
||||
[134, 135],
|
||||
[140, 141],
|
||||
[146, 147],
|
||||
153,
|
||||
165,
|
||||
171,
|
||||
177,
|
||||
183,
|
||||
189
|
||||
],
|
||||
|
||||
green: [
|
||||
2,
|
||||
10,
|
||||
22,
|
||||
[28, 29],
|
||||
[34, 36],
|
||||
[40, 43],
|
||||
[46, 50],
|
||||
[64, 65],
|
||||
[70, 72],
|
||||
[76, 79],
|
||||
[82, 86],
|
||||
[106, 108],
|
||||
[112, 115],
|
||||
[118, 122],
|
||||
[148, 151],
|
||||
[154, 158],
|
||||
[190, 194]
|
||||
],
|
||||
|
||||
cyan: [
|
||||
6,
|
||||
14,
|
||||
23,
|
||||
30,
|
||||
37,
|
||||
44,
|
||||
51,
|
||||
66,
|
||||
73,
|
||||
80,
|
||||
87,
|
||||
109,
|
||||
116,
|
||||
123,
|
||||
152,
|
||||
159,
|
||||
195
|
||||
],
|
||||
|
||||
red: [
|
||||
1,
|
||||
9,
|
||||
52,
|
||||
[88, 89],
|
||||
[94, 95],
|
||||
[124, 126],
|
||||
[130, 132],
|
||||
[136, 138],
|
||||
[160, 163],
|
||||
[166, 169],
|
||||
[172, 175],
|
||||
[178, 181],
|
||||
[196, 200],
|
||||
[202, 206],
|
||||
[208, 212],
|
||||
[214, 218],
|
||||
[220, 224]
|
||||
],
|
||||
|
||||
magenta: [
|
||||
5,
|
||||
13,
|
||||
53,
|
||||
90,
|
||||
96,
|
||||
127,
|
||||
133,
|
||||
139,
|
||||
164,
|
||||
170,
|
||||
176,
|
||||
182,
|
||||
201,
|
||||
207,
|
||||
213,
|
||||
219,
|
||||
225
|
||||
],
|
||||
|
||||
yellow: [
|
||||
3,
|
||||
11,
|
||||
58,
|
||||
[100, 101],
|
||||
[142, 144],
|
||||
[184, 187],
|
||||
[226, 230]
|
||||
],
|
||||
|
||||
black: [
|
||||
0,
|
||||
8,
|
||||
16,
|
||||
59,
|
||||
102,
|
||||
[232, 243]
|
||||
],
|
||||
|
||||
white: [
|
||||
7,
|
||||
15,
|
||||
145,
|
||||
188,
|
||||
231,
|
||||
[244, 255]
|
||||
]
|
||||
};
|
||||
|
||||
exports.ncolors = [];
|
||||
|
||||
Object.keys(exports.ccolors).forEach(function(name) {
|
||||
exports.ccolors[name].forEach(function(offset) {
|
||||
if (typeof offset === 'number') {
|
||||
exports.ncolors[offset] = name;
|
||||
exports.ccolors[offset] = exports.colorNames[name];
|
||||
return;
|
||||
}
|
||||
for (var i = offset[0], l = offset[1]; i <= l; i++) {
|
||||
exports.ncolors[i] = name;
|
||||
exports.ccolors[i] = exports.colorNames[name];
|
||||
}
|
||||
});
|
||||
delete exports.ccolors[name];
|
||||
});
|
Loading…
Reference in New Issue
Block a user