From a68c83369254ecdf2c4187567dc32d5bce727e4b Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 10 Aug 2013 08:20:25 -0500 Subject: [PATCH] support CSI 38 2 R G B m. --- lib/term.js | 113 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 22 deletions(-) diff --git a/lib/term.js b/lib/term.js index 3a211942..001419a5 100644 --- a/lib/term.js +++ b/lib/term.js @@ -314,6 +314,24 @@ Terminal.colors = (function() { return colors; })(); +Terminal.vcolors = (function() { + var out = [] + , colors = Terminal.colors + , i = 0 + , color; + + for (; i < colors.length; i++) { + color = parseInt(colors[i].substring(1), 16); + out.push([ + (color >> 16) & 0xff, + (color >> 8) & 0xff, + color & 0xff + ]); + } + + return out; +})(); + // Default BG/FG Terminal.defaultColors = { bg: '#000000', @@ -2863,30 +2881,34 @@ Terminal.prototype.charAttributes = function(params) { bg = this.defAttr & 0x1ff; } else if (p === 38) { // fg color 256 - //if (params[i+1] === 2) { - // // match rgb - // i += 2; - // var r = params[i] & 0xff, g = params[i + 1] & 0xff, b = params[i + 2] & 0xff; - //} else - if (params[i+1] !== 5) continue; - i += 2; - p = params[i] & 0xff; - // convert 88 colors to 256 - // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0; - fg = p; + if (params[i + 1] === 2) { + i += 2; + fg = matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (fg === -1) fg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } } else if (p === 48) { // bg color 256 - //if (params[i+1] === 2) { - // // match rgb - // i += 2; - // var r = params[i] & 0xff, g = params[i + 1] & 0xff, b = params[i + 2] & 0xff; - //} else - if (params[i+1] !== 5) continue; - i += 2; - p = params[i] & 0xff; - // convert 88 colors to 256 - // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0; - bg = p; + if (params[i + 1] === 2) { + i += 2; + bg = matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (bg === -1) bg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } } } @@ -4357,6 +4379,53 @@ var dwidthChars = new RegExp('([' + '\\uffe8-\\uffee' + '])', 'g'); +function matchColor(r1, g1, b1) { + var hash = (r1 << 16) | (g1 << 8) | b1; + + if (matchColor._cache[hash] != null) { + return matchColor._cache[hash]; + } + + var ldiff = Infinity + , li = -1 + , i = 0 + , c + , r2 + , g2 + , b2 + , diff; + + for (; i < Terminal.vcolors.length; i++) { + c = Terminal.vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + + diff = matchColor.distance(r1, g1, b1, r2, g2, b2); + + if (diff === 0) { + li = i; + break; + } + + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + + return matchColor._cache[hash] = li; +} + +matchColor._cache = {}; + +// http://stackoverflow.com/questions/1633828 +matchColor.distance = function(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); +}; + /** * Expose */