Skip to content

Commit

Permalink
Truecolor proof of concept
Browse files Browse the repository at this point in the history
Part of xtermjs#484
  • Loading branch information
Tyriar committed Jul 2, 2017
1 parent 31aab8e commit 00e7a21
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 26 deletions.
25 changes: 21 additions & 4 deletions src/InputHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,21 @@ export class InputHandler implements IInputHandler {
if (removed[2] === 0
&& this._terminal.lines.get(row)[this._terminal.cols - 2]
&& this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) {
this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1, this._terminal.curTrueColor];
}

// insert empty cell at cursor
this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1, this._terminal.curTrueColor]);
}
}

this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];
this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width, this._terminal.curTrueColor];
this._terminal.x++;
this._terminal.updateRange(this._terminal.y);

// fullwidth char - set next cell width to zero and advance cursor
if (ch_width === 2) {
this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];
this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0, this._terminal.curTrueColor];
this._terminal.x++;
}
}
Expand Down Expand Up @@ -1222,6 +1222,7 @@ export class InputHandler implements IInputHandler {
, fg = (this._terminal.curAttr >> 9) & 0x1ff
, bg = this._terminal.curAttr & 0x1ff
, p;
let trueColor: number;

for (; i < l; i++) {
p = params[i];
Expand Down Expand Up @@ -1288,6 +1289,10 @@ export class InputHandler implements IInputHandler {
// fg color 256
if (params[i + 1] === 2) {
i += 2;
trueColor = this._getTrueColorCode(
params[i] & 0xff,
params[i + 1] & 0xff,
params[i + 2] & 0xff, true);
fg = this._terminal.matchColor(
params[i] & 0xff,
params[i + 1] & 0xff,
Expand All @@ -1303,6 +1308,11 @@ export class InputHandler implements IInputHandler {
// bg color 256
if (params[i + 1] === 2) {
i += 2;
trueColor = this._getTrueColorCode(
params[i] & 0xff,
params[i + 1] & 0xff,
params[i + 2] & 0xff, false);
console.log('getTrueColorCode: ', trueColor.toString(16));
bg = this._terminal.matchColor(
params[i] & 0xff,
params[i + 1] & 0xff,
Expand All @@ -1324,6 +1334,13 @@ export class InputHandler implements IInputHandler {
}

this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;
this._terminal.curTrueColor = trueColor;
console.log('this._terminal.curTrueColor', this._terminal.curTrueColor);
}

private _getTrueColorCode(r: number, g: number, b: number, fg: boolean): number {
// In format: 0x1RRGGBB for foreground, 0x0RRGGBB for background
return (fg ? 1 << 24 : 0) + (r << 16) + (g << 8) + b;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface ITerminal {
textarea: HTMLTextAreaElement;
ybase: number;
ydisp: number;
lines: ICircularList<string>;
lines: ICircularList<any>;
rows: number;
cols: number;
browser: IBrowser;
Expand Down
59 changes: 38 additions & 21 deletions src/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export class Renderer {
}

let attr = this._terminal.defAttr;
let lastTrueColor = undefined;

const documentFragment = document.createDocumentFragment();
let innerHTML = '';
Expand All @@ -170,6 +171,7 @@ export class Renderer {
let data: any = line[i][0];
const ch = line[i][1];
const ch_width: any = line[i][2];
const trueColor: number = line[i][3];
if (!ch_width) {
continue;
}
Expand All @@ -178,16 +180,16 @@ export class Renderer {
data = -1;
}

if (data !== attr) {
if (attr !== this._terminal.defAttr) {
if (data !== attr || (i > 1 && lastTrueColor !== trueColor)) {
if (attr !== this._terminal.defAttr || lastTrueColor !== undefined || (i > 1 && lastTrueColor !== trueColor)) {
if (innerHTML) {
currentElement.innerHTML = innerHTML;
innerHTML = '';
}
documentFragment.appendChild(currentElement);
currentElement = null;
}
if (data !== this._terminal.defAttr) {
if (data !== this._terminal.defAttr || lastTrueColor !== trueColor) {
if (innerHTML && !currentElement) {
currentElement = this._spanElementObjectPool.acquire();
}
Expand Down Expand Up @@ -239,28 +241,42 @@ export class Renderer {
currentElement.classList.add('xterm-hidden');
}

/**
* Weird situation: Invert flag used black foreground and white background results
* in invalid background color, positioned at the 256 index of the 256 terminal
* color map. Pin the colors manually in such a case.
*
* Source: https://github.com/sourcelair/xterm.js/issues/57
*/
if (flags & FLAGS.INVERSE) {
if (bg === 257) {
bg = 15;
if (trueColor) {
const fg = trueColor & 0x1000000;
let rgb = (trueColor & 0x0FFFFFF).toString(16);
while (rgb.length < 6) {
rgb = '0' + rgb;
}
if (fg === 256) {
fg = 0;

if (fg) {
currentElement.style.color = `#${rgb}`;
} else {
currentElement.style.backgroundColor = `#${rgb}`;
}
} else {
/**
* Weird situation: Invert flag used black foreground and white background results
* in invalid background color, positioned at the 256 index of the 256 terminal
* color map. Pin the colors manually in such a case.
*
* Source: https://github.com/sourcelair/xterm.js/issues/57
*/
if (flags & FLAGS.INVERSE) {
if (bg === 257) {
bg = 15;
}
if (fg === 256) {
fg = 0;
}
}
}

if (bg < 256) {
currentElement.classList.add(`xterm-bg-color-${bg}`);
}
if (bg < 256) {
currentElement.classList.add(`xterm-bg-color-${bg}`);
}

if (fg < 256) {
currentElement.classList.add(`xterm-color-${fg}`);
if (fg < 256) {
currentElement.classList.add(`xterm-color-${fg}`);
}
}
}
}
Expand Down Expand Up @@ -295,6 +311,7 @@ export class Renderer {
}

attr = data;
lastTrueColor = trueColor;
}

if (innerHTML && !currentElement) {
Expand Down
1 change: 1 addition & 0 deletions src/xterm.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ function Terminal(options) {

this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
this.curAttr = this.defAttr;
this.curTrueColor = null;

this.params = [];
this.currentParam = 0;
Expand Down

0 comments on commit 00e7a21

Please sign in to comment.