diff --git a/lib/colors.js b/lib/colors.js index feb17d3..226bf55 100644 --- a/lib/colors.js +++ b/lib/colors.js @@ -97,11 +97,12 @@ function colorDistance(r1, g1, b1, r2, g2, b2) { // 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) { +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]; @@ -113,14 +114,93 @@ exports.mixColors = function(c1, c2) { var g2 = c2[1]; var b2 = c2[2]; - // XXX Maybe allow opacity instead of 0.5? - r1 += (r2 - r1) * 0.5 | 0; - g1 += (g2 - g1) * 0.5 | 0; - b1 += (b2 - b1) * 0.5 | 0; + 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 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 { + var name = exports.ncolors[bg]; + if (name) { + for (var i = 0; i < exports.ncolors.length; i++) { + if (name === exports.ncolors[i] && i !== bg) { + var c = exports.vcolors[bg]; + var 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 { + var name = exports.ncolors[fg]; + if (name) { + for (var i = 0; i < exports.ncolors.length; i++) { + if (name === exports.ncolors[i] && i !== fg) { + var c = exports.vcolors[fg]; + var 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 = {}; // XTerm Colors diff --git a/lib/widgets/element.js b/lib/widgets/element.js index 57c4ebb..d80acf0 100644 --- a/lib/widgets/element.js +++ b/lib/widgets/element.js @@ -1946,7 +1946,7 @@ Element.prototype.render = function() { if (!lines[y]) break; for (x = Math.max(xi, 0); x < xl; x++) { if (!lines[y][x]) break; - lines[y][x][0] = this._blend(attr, lines[y][x][0]); + lines[y][x][0] = colors.blend(attr, lines[y][x][0]); lines[y][x][1] = ch; lines[y].dirty = true; } @@ -2035,7 +2035,7 @@ Element.prototype.render = function() { cell = lines[y][x]; if (!cell) break; if (this.style.transparent) { - lines[y][x][0] = this._blend(attr, lines[y][x][0]); + lines[y][x][0] = colors.blend(attr, lines[y][x][0]); if (content[ci]) lines[y][x][1] = ch; lines[y].dirty = true; } else { @@ -2074,8 +2074,10 @@ Element.prototype.render = function() { } } + if (this._noFill) continue; + if (this.style.transparent) { - lines[y][x][0] = this._blend(attr, lines[y][x][0]); + lines[y][x][0] = colors.blend(attr, lines[y][x][0]); if (content[ci]) lines[y][x][1] = ch; lines[y].dirty = true; } else { @@ -2309,8 +2311,8 @@ Element.prototype.render = function() { x = xl; for (; x < xl + 2; x++) { if (!lines[y][x]) break; - // lines[y][x][0] = this._blend(this.dattr, lines[y][x][0]); - lines[y][x][0] = this._blend(lines[y][x][0]); + // lines[y][x][0] = colors.blend(this.dattr, lines[y][x][0]); + lines[y][x][0] = colors.blend(lines[y][x][0]); lines[y].dirty = true; } } @@ -2320,8 +2322,8 @@ Element.prototype.render = function() { if (!lines[y]) break; for (x = Math.max(xi + 1, 0); x < xl; x++) { if (!lines[y][x]) break; - // lines[y][x][0] = this._blend(this.dattr, lines[y][x][0]); - lines[y][x][0] = this._blend(lines[y][x][0]); + // lines[y][x][0] = colors.blend(this.dattr, lines[y][x][0]); + lines[y][x][0] = colors.blend(lines[y][x][0]); lines[y].dirty = true; } } @@ -2347,90 +2349,6 @@ Element.prototype.render = function() { Element.prototype._render = Element.prototype.render; -/** - * Blending and Shadows - */ - -Element.prototype._blend = function blend(attr, attr2) { - var bg = attr & 0x1ff; - if (attr2 != null) { - var bg2 = attr2 & 0x1ff; - if (bg === 0x1ff) bg = 0; - if (bg2 === 0x1ff) bg2 = 0; - bg = colors.mixColors(bg, bg2); - } 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 { - var name = colors.ncolors[bg]; - if (name) { - for (var i = 0; i < colors.ncolors.length; i++) { - if (name === colors.ncolors[i] && i !== bg) { - var c = colors.vcolors[bg]; - var nc = colors.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 = colors.mixColors(fg, fg2); - } - } 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 { - var name = colors.ncolors[fg]; - if (name) { - for (var i = 0; i < colors.ncolors.length; i++) { - if (name === colors.ncolors[i] && i !== fg) { - var c = colors.vcolors[fg]; - var nc = colors.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; -}; - -Element.prototype._blend._cache = {}; - /** * Content Methods */