cleanup. improve BCE. remove old code.
This commit is contained in:
parent
00e680d413
commit
346e39b723
|
@ -62,6 +62,86 @@ exports.matchColor = function(hex) {
|
|||
return exports._cache[hex] = li;
|
||||
};
|
||||
|
||||
exports.matchColor_ = function(r1, g1, b1) {
|
||||
if (typeof r1 === 'string' && g1 == null) {
|
||||
var hex = r1;
|
||||
if (hex[0] !== '#') {
|
||||
return hex;
|
||||
}
|
||||
if (hex.length === 4) {
|
||||
hex = hex[0]
|
||||
+ hex[1] + hex[1]
|
||||
+ hex[2] + hex[2]
|
||||
+ hex[3] + hex[3];
|
||||
}
|
||||
hex = exports.HexToRGB(hex);
|
||||
r1 = hex[0], g1 = hex[1], b1 = hex[2];
|
||||
}
|
||||
|
||||
var hash = r1 + '.' + g1 + '.' + 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];
|
||||
|
||||
if (r1 === r2 && g1 === g2 && b1 === b2) {
|
||||
diff = 0;
|
||||
} else {
|
||||
// diff = colorDistance3d(r1, g1, b1, r2, g2, b2);
|
||||
diff = colorDistance3dWeight(r1, g1, b1, r2, g2, b2);
|
||||
// diff = colorDistance3dWeightSqrt(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) {
|
||||
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. Maybe someone better at math can
|
||||
|
|
|
@ -1155,7 +1155,7 @@ Program.prototype._parseChar = function(text, attr) {
|
|||
this.x = 0;
|
||||
} else {
|
||||
this.x++;
|
||||
if (this.x >= this.width) {
|
||||
if (this.x >= this.cols) {
|
||||
this._wrapCursor();
|
||||
}
|
||||
}
|
||||
|
@ -1318,7 +1318,7 @@ Program.prototype.return = function() {
|
|||
Program.prototype.nel =
|
||||
Program.prototype.newline =
|
||||
Program.prototype.feed = function() {
|
||||
if (this.tput && this.tput.bools.eat_newline_glitch && this.x >= this.width) {
|
||||
if (this.tput && this.tput.bools.eat_newline_glitch && this.x >= this.cols) {
|
||||
return;
|
||||
}
|
||||
this.x = 0;
|
||||
|
@ -1383,7 +1383,8 @@ Program.prototype.tabSet = function() {
|
|||
|
||||
// ESC 7 Save Cursor (DECSC).
|
||||
Program.prototype.sc =
|
||||
Program.prototype.saveCursor = function() {
|
||||
Program.prototype.saveCursor = function(key) {
|
||||
if (key) return this.lsaveCursor(key);
|
||||
this.savedX = this.x || 0;
|
||||
this.savedY = this.y || 0;
|
||||
if (this.tput) return this.put.sc();
|
||||
|
@ -1392,13 +1393,40 @@ Program.prototype.saveCursor = function() {
|
|||
|
||||
// ESC 8 Restore Cursor (DECRC).
|
||||
Program.prototype.rc =
|
||||
Program.prototype.restoreCursor = function() {
|
||||
Program.prototype.restoreCursor = function(key, hide) {
|
||||
if (key) return this.lrestoreCursor(key, hide);
|
||||
this.x = this.savedX || 0;
|
||||
this.y = this.savedY || 0;
|
||||
if (this.tput) return this.put.rc();
|
||||
return this.esc('8');
|
||||
};
|
||||
|
||||
// Save Cursor Locally
|
||||
Program.prototype.lsaveCursor = function(key) {
|
||||
var key = key || 'local';
|
||||
this._saved = this._saved || {};
|
||||
this._saved[key] = this._saved[key] || {};
|
||||
this._saved[key].x = this.x;
|
||||
this._saved[key].y = this.y;
|
||||
this._saved[key].hidden = this.cursorHidden;
|
||||
};
|
||||
|
||||
// Restore Cursor Locally
|
||||
Program.prototype.lrestoreCursor = function(key, hide) {
|
||||
var key = key || 'local', pos;
|
||||
if (!this._saved || !this._saved[key]) return;
|
||||
pos = this._saved[key];
|
||||
delete this._saved[key];
|
||||
this.cup(pos.y, pos.x);
|
||||
if (hide && pos.hidden !== this.cursorHidden) {
|
||||
if (pos.hidden) {
|
||||
this.hideCursor();
|
||||
} else {
|
||||
this.showCursor();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ESC # 3 DEC line height/width
|
||||
Program.prototype.lineHeight = function() {
|
||||
return this.esc('#');
|
||||
|
|
192
lib/widget.js
192
lib/widget.js
|
@ -826,17 +826,17 @@ Screen.prototype.draw = function(start, end) {
|
|||
, attr
|
||||
, fg
|
||||
, bg
|
||||
, flags
|
||||
, acs
|
||||
, bc;
|
||||
, flags;
|
||||
|
||||
var clr
|
||||
, neq
|
||||
, xx;
|
||||
|
||||
var lx = -1
|
||||
, ly = -1
|
||||
, o;
|
||||
|
||||
var bcx = -1
|
||||
, bcy = -1
|
||||
, bca = -1;
|
||||
var acs;
|
||||
|
||||
// var cx = this.program.x
|
||||
// , cy = this.program.y
|
||||
|
@ -844,7 +844,8 @@ Screen.prototype.draw = function(start, end) {
|
|||
//
|
||||
// if (!ch) this.program.hideCursor();
|
||||
|
||||
this.program.saveCursor();
|
||||
// this.program.sc('draw');
|
||||
this.program.sc();
|
||||
|
||||
for (y = start; y <= end; y++) {
|
||||
line = this.lines[y];
|
||||
|
@ -861,63 +862,75 @@ Screen.prototype.draw = function(start, end) {
|
|||
data = line[x][0];
|
||||
ch = line[x][1];
|
||||
|
||||
// Take advantage of xterm's back_color_erase
|
||||
// feature by using a lookahead.
|
||||
if (this.tput.bools.back_color_erase && ch === ' ' && line[x + 1]) {
|
||||
var ne = false
|
||||
, cl = true;
|
||||
// Take advantage of xterm's back_color_erase feature by using a
|
||||
// lookahead. Stop spitting out so many damn spaces. NOTE: Is checking
|
||||
// the bg for non BCE terminals worth the overhead?
|
||||
if (ch === ' '
|
||||
&& ((this.tput && this.tput.bools.back_color_erase)
|
||||
|| (data & 0x1ff) === (this.dattr & 0x1ff))
|
||||
&& ((data >> 18) & 8) === ((this.dattr >> 18) & 8)) {
|
||||
clr = true;
|
||||
neq = false;
|
||||
|
||||
for (var xi = x; xi < this.cols; xi++) {
|
||||
if (line[xi][0] !== data || line[xi][1] !== ' ') {
|
||||
cl = false;
|
||||
for (xx = x; xx < this.cols; xx++) {
|
||||
if (line[xx][0] !== data || line[xx][1] !== ' ') {
|
||||
clr = false;
|
||||
break;
|
||||
}
|
||||
if (line[xi][0] !== o[xi][0] || line[xi][1] !== o[xi][1]) {
|
||||
ne = true;
|
||||
if (line[xx][0] !== o[xx][0] || line[xx][1] !== o[xx][1]) {
|
||||
neq = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cl && ne) {
|
||||
if (clr && neq) {
|
||||
if (data !== attr) {
|
||||
out += this.codeAttr(data);
|
||||
attr = data;
|
||||
}
|
||||
out += this.tput.el(0);
|
||||
for (var xi = x; xi < this.cols; xi++) {
|
||||
o[xi][0] = data;
|
||||
o[xi][1] = ' ';
|
||||
for (xx = x; xx < this.cols; xx++) {
|
||||
o[xx][0] = data;
|
||||
o[xx][1] = ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// comment the break in the first xi loop above for this to work.
|
||||
// if (!ne) {
|
||||
// If there's more than 10 spaces, use EL regardless
|
||||
// and start over drawing the rest of line. Might
|
||||
// not be worth it.
|
||||
// if (!clr && neq && (xx - x) > 10) {
|
||||
// if (data !== attr) {
|
||||
// out += this.codeAttr(data);
|
||||
// attr = data;
|
||||
// }
|
||||
// out += this.tput.el(0) + this.tput.cuf(xx - x);
|
||||
// clr = xx; // tmp
|
||||
// for (xx = x; xx < this.cols; xx++) {
|
||||
// o[xx][0] = data;
|
||||
// o[xx][1] = ' ';
|
||||
// }
|
||||
// x = clr - 1;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Skip to the next line if the
|
||||
// rest of the line is already drawn.
|
||||
// Comment the break in the first
|
||||
// xx loop above for this to work.
|
||||
// Which carries less overhead?
|
||||
// OR use another for loop:
|
||||
// for (xx = x; xx < this.cols; xx++) {
|
||||
// if (line[xx][0] !== o[xx][0] || line[xx][1] !== o[xx][1]) {
|
||||
// neq = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!neq) {
|
||||
// attr = data;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
// Take advantage of xterm's back_color_erase feature.
|
||||
// Stop spitting out so many damn spaces.
|
||||
if (0) if (this.tput.bools.back_color_erase) {
|
||||
if (ch === ' ' && (bca === -1 || bca === data)) {
|
||||
if (bcy === -1) {
|
||||
bcx = x;
|
||||
bcy = y;
|
||||
bca = data;
|
||||
}
|
||||
//ch = '';
|
||||
} else if (bcy !== -1) {
|
||||
// If it's more than ten spaces, just EL and jump forward.
|
||||
// Might break things since it could alter the output buffer.
|
||||
// out += x - bcx > 10
|
||||
// ? this.tput.el(0) + this.tput.cuf(x - bcx)
|
||||
// : Array((x - bcx) + 1).join(' ');
|
||||
out += Array((x - bcx) + 1).join(' ');
|
||||
bcx = -1, bcy = -1, bca = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize by comparing the real output
|
||||
// buffer to the pending output buffer.
|
||||
if (data === o[x][0] && ch === o[x][1]) {
|
||||
|
@ -1013,7 +1026,6 @@ Screen.prototype.draw = function(start, end) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Attempt to use ACS for supported characters.
|
||||
// This is not ideal, but it's how ncurses works.
|
||||
// There are a lot of terminals that support ACS
|
||||
|
@ -1028,33 +1040,6 @@ Screen.prototype.draw = function(start, end) {
|
|||
// Maybe remove !this.tput.unicode check, however,
|
||||
// this seems to be the way ncurses does it.
|
||||
if (this.tput) {
|
||||
if (this.tput.strings.enter_alt_charset_mode
|
||||
&& this.tput.acscr[ch]
|
||||
&& (!this.tput.brokenACS || !this.tput.unicode)) {
|
||||
ch = this.tput.smacs()
|
||||
+ this.tput.acscr[ch]
|
||||
+ this.tput.rmacs();
|
||||
} else if (!this.tput.strings.enter_alt_charset_mode) {
|
||||
// U8 is not consistently correct. Some terminfo's
|
||||
// terminals that do not declare it may actually
|
||||
// support utf8 (e.g. urxvt), but if the terminal
|
||||
// does not declare support for ACS (and U8), chances
|
||||
// are it does not support UTF8. This is probably
|
||||
// the "safest" way to do this. Should fix things
|
||||
// like sun-color.
|
||||
if (this.tput.numbers.U8 !== 1 && this.utoa[ch]) {
|
||||
ch = this.tput.utoa[ch] || '?';
|
||||
}
|
||||
}
|
||||
// } else if (this.program.term('sun') && ch > '~') {
|
||||
// } else if (this.tput.numbers.U8 !== 1 && ch > '~') {
|
||||
// // If this terminal doesn't explicitly support UTF8,
|
||||
// // replace unicode characters with ugly shitty ones.
|
||||
// ch = this.tput.utoa[ch] || '?';
|
||||
// }
|
||||
}
|
||||
*/
|
||||
|
||||
if (this.tput.strings.enter_alt_charset_mode) {
|
||||
if (!this.tput.brokenACS || !this.tput.unicode) {
|
||||
if (this.tput.acscr[ch]) {
|
||||
|
@ -1071,32 +1056,29 @@ Screen.prototype.draw = function(start, end) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// U8 is not consistently correct. Some terminfo's
|
||||
// terminals that do not declare it may actually
|
||||
// support utf8 (e.g. urxvt), but if the terminal
|
||||
// does not declare support for ACS (and U8), chances
|
||||
// are it does not support UTF8. This is probably
|
||||
// the "safest" way to do this. Should fix things
|
||||
// like sun-color.
|
||||
// if (this.program.term('sun') && ch > '~') {
|
||||
// if (this.tput.numbers.U8 !== 1 && ch > '~') {
|
||||
if (this.tput.numbers.U8 !== 1 && this.utoa[ch]) {
|
||||
ch = this.tput.utoa[ch] || '?';
|
||||
}
|
||||
}
|
||||
|
||||
if (0) if (bcy !== -1) ch = '';
|
||||
}
|
||||
|
||||
out += ch;
|
||||
attr = data;
|
||||
}
|
||||
|
||||
if (0) if (bcy !== -1) {
|
||||
out += this.tput.el(0);
|
||||
bcx = -1, bcy = -1, bca = -1;
|
||||
}
|
||||
|
||||
if (attr !== this.dattr) {
|
||||
out += '\x1b[m';
|
||||
}
|
||||
|
||||
//if (this.tput.bools.back_color_erase && out && lx === -1) {
|
||||
// out = this._replaceSpaces(out);
|
||||
//}
|
||||
|
||||
if (this.tput) {
|
||||
if (out) this.program.write(this.tput.cup(y, 0) + out);
|
||||
} else {
|
||||
|
@ -1107,28 +1089,8 @@ Screen.prototype.draw = function(start, end) {
|
|||
// this.program.cup(cy, cx);
|
||||
// if (ch) this.program.hideCursor();
|
||||
|
||||
this.program.restoreCursor();
|
||||
};
|
||||
|
||||
Screen.prototype._replaceSpaces = function(out) {
|
||||
if (!this._sr) this._sr = this._spaceReplacer.bind(this);
|
||||
return out.replace(/ {5,}/g, this._sr);
|
||||
};
|
||||
|
||||
Screen.prototype._spaceReplacer = function(ch) {
|
||||
return this.tput.el(0) + this.tput.cuf(ch.length);
|
||||
};
|
||||
|
||||
Screen.prototype._replaceSpaces = function(out) {
|
||||
if (!this._sr) this._sr = this._spaceReplacer.bind(this);
|
||||
// / +(?=(?:\x1b\[m)?(?:\x1b\[[\d;]*H|$))/g,
|
||||
return out.replace(
|
||||
/ {5,}(?=(?:\x1b\[[\d;]*m)*(?:\x1b\[[\d;]*H|$))/g,
|
||||
this._sr);
|
||||
};
|
||||
|
||||
Screen.prototype._spaceReplacer = function(ch) {
|
||||
return this.tput.el(0);
|
||||
// this.program.rc('draw', true);
|
||||
this.program.rc();
|
||||
};
|
||||
|
||||
Screen.prototype._reduceColor = function(col) {
|
||||
|
@ -1196,15 +1158,31 @@ Screen.prototype.attrCode = function(code, cur) {
|
|||
case 28:
|
||||
flags &= ~16;
|
||||
break;
|
||||
case 100: // default fg/bg
|
||||
bg = 0x1ff;
|
||||
fg = 0x1ff;
|
||||
break;
|
||||
default: // color
|
||||
if (c === 48 && code[i+1] === '5') {
|
||||
if (c === 48 && +code[i+1] === 5) {
|
||||
i += 2;
|
||||
bg = +code[i];
|
||||
break;
|
||||
} else if (c === 38 && code[i+1] === '5') {
|
||||
} else if (c === 48 && +code[i+1] === 2) {
|
||||
i += 2;
|
||||
bg = colors.matchColor(
|
||||
colors.RGBToHex(+code[i], +code[i+1], +code[i+2]));
|
||||
i += 2;
|
||||
break;
|
||||
} else if (c === 38 && +code[i+1] === 5) {
|
||||
i += 2;
|
||||
fg = +code[i];
|
||||
break;
|
||||
} else if (c === 38 && +code[i+1] === 2) {
|
||||
i += 2;
|
||||
fg = colors.matchColor(
|
||||
colors.RGBToHex(+code[i], +code[i+1], +code[i+2]));
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
if (c >= 40 && c <= 47) {
|
||||
bg = c - 40;
|
||||
|
|
Loading…
Reference in New Issue