RGB support in buffer and attributes
This commit is contained in:
+16
-79
@@ -21,11 +21,11 @@
|
||||
* http://linux.die.net/man/7/urxvt
|
||||
*/
|
||||
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharData, CharacterJoinerHandler, IBufferLine } from './Types';
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData } from './Types';
|
||||
import { IMouseZoneManager } from './ui/Types';
|
||||
import { IRenderer } from './renderer/Types';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
|
||||
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer';
|
||||
import { CompositionHelper } from './CompositionHelper';
|
||||
import { EventEmitter } from './common/EventEmitter';
|
||||
import { Viewport } from './Viewport';
|
||||
@@ -41,7 +41,6 @@ import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
import * as Strings from './Strings';
|
||||
import { MouseHelper } from './ui/MouseHelper';
|
||||
import { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager';
|
||||
import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
|
||||
import { MouseZoneManager } from './ui/MouseZoneManager';
|
||||
import { AccessibilityManager } from './AccessibilityManager';
|
||||
import { ScreenDprMonitor } from './ui/ScreenDprMonitor';
|
||||
@@ -52,6 +51,7 @@ import { IKeyboardEvent } from './common/Types';
|
||||
import { evaluateKeyboardEvent } from './core/input/Keyboard';
|
||||
import { KeyboardResultType, ICharset } from './core/Types';
|
||||
import { clone } from './common/Clone';
|
||||
import { Attributes } from './BufferLine';
|
||||
|
||||
// Let it work inside Node.js for automated testing purposes.
|
||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||
@@ -168,7 +168,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
private _refreshEnd: number;
|
||||
public savedCols: number;
|
||||
|
||||
public curAttr: number;
|
||||
public curAttrData: IAttributeData;
|
||||
private _eraseAttrData: IAttributeData;
|
||||
|
||||
public params: (string | number)[];
|
||||
public currentParam: string | number;
|
||||
@@ -288,7 +289,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
// TODO: Can this be just []?
|
||||
this.charsets = [null];
|
||||
|
||||
this.curAttr = DEFAULT_ATTR;
|
||||
this.curAttrData = DEFAULT_ATTR_DATA.clone();
|
||||
this._eraseAttrData = DEFAULT_ATTR_DATA.clone();
|
||||
|
||||
this.params = [];
|
||||
this.currentParam = 0;
|
||||
@@ -328,9 +330,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
/**
|
||||
* back_color_erase feature for xterm.
|
||||
*/
|
||||
public eraseAttr(): number {
|
||||
// if (this.is('screen')) return DEFAULT_ATTR;
|
||||
return (DEFAULT_ATTR & ~0x1ff) | (this.curAttr & 0x1ff);
|
||||
public eraseAttrData(): IAttributeData {
|
||||
this._eraseAttrData.bg &= ~(Attributes.CM_MASK | 0xFFFFFF);
|
||||
this._eraseAttrData.bg |= this.curAttrData.bg & ~0xFC000000;
|
||||
return this._eraseAttrData;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1175,8 +1178,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
public scroll(isWrapped: boolean = false): void {
|
||||
let newLine: IBufferLine;
|
||||
newLine = this._blankLine;
|
||||
if (!newLine || newLine.length !== this.cols || newLine.getFG(0) !== this.eraseAttr()) {
|
||||
newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
|
||||
const eraseAttr = this.eraseAttrData();
|
||||
if (!newLine || newLine.length !== this.cols || newLine.getFG(0) !== eraseAttr.fg || newLine.getBG(0) !== eraseAttr.bg) {
|
||||
newLine = this.buffer.getBlankLine(eraseAttr, isWrapped);
|
||||
this._blankLine = newLine;
|
||||
}
|
||||
newLine.isWrapped = isWrapped;
|
||||
@@ -1745,23 +1749,12 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
this.buffer.ybase = 0;
|
||||
this.buffer.y = 0;
|
||||
for (let i = 1; i < this.rows; i++) {
|
||||
this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR));
|
||||
this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
}
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.emit('scroll', this.buffer.ydisp);
|
||||
}
|
||||
|
||||
/**
|
||||
* If cur return the back color xterm feature attribute. Else return default attribute.
|
||||
* @param cur
|
||||
*/
|
||||
public ch(cur?: boolean): CharData {
|
||||
if (cur) {
|
||||
return [this.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
|
||||
}
|
||||
return [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate if the current terminal is the given argument.
|
||||
* @param term The terminal name to evaluate
|
||||
@@ -1837,7 +1830,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
// blankLine(true) is xterm/linux behavior
|
||||
const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop;
|
||||
this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1);
|
||||
this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.eraseAttr()));
|
||||
this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.buffer.getBlankLine(this.eraseAttrData()));
|
||||
this.updateRange(this.buffer.scrollTop);
|
||||
this.updateRange(this.buffer.scrollBottom);
|
||||
} else {
|
||||
@@ -1882,46 +1875,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Remove when true color is implemented
|
||||
public matchColor(r1: number, g1: number, b1: number): number {
|
||||
const hash = (r1 << 16) | (g1 << 8) | b1;
|
||||
|
||||
if (matchColorCache[hash] !== null && matchColorCache[hash] !== undefined) {
|
||||
return matchColorCache[hash];
|
||||
}
|
||||
|
||||
let ldiff = Infinity;
|
||||
let li = -1;
|
||||
let i = 0;
|
||||
let c: number;
|
||||
let r2: number;
|
||||
let g2: number;
|
||||
let b2: number;
|
||||
let diff: number;
|
||||
|
||||
for (; i < DEFAULT_ANSI_COLORS.length; i++) {
|
||||
c = DEFAULT_ANSI_COLORS[i].rgba;
|
||||
r2 = c >>> 24;
|
||||
g2 = c >>> 16 & 0xFF;
|
||||
b2 = c >>> 8 & 0xFF;
|
||||
// assume that alpha is 0xFF
|
||||
|
||||
diff = matchColorDistance(r1, g1, b1, r2, g2, b2);
|
||||
|
||||
if (diff === 0) {
|
||||
li = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (diff < ldiff) {
|
||||
ldiff = diff;
|
||||
li = i;
|
||||
}
|
||||
}
|
||||
|
||||
return matchColorCache[hash] = li;
|
||||
}
|
||||
|
||||
private _visualBell(): boolean {
|
||||
return false;
|
||||
// return this.options.bellStyle === 'visual' ||
|
||||
@@ -1944,19 +1897,3 @@ function wasModifierKeyOnlyEvent(ev: KeyboardEvent): boolean {
|
||||
ev.keyCode === 17 || // Ctrl
|
||||
ev.keyCode === 18; // Alt
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* The below color-related code can be removed when true color is implemented.
|
||||
* It's only purpose is to match true color requests with the closest matching
|
||||
* ANSI color code.
|
||||
*/
|
||||
|
||||
const matchColorCache: {[colorRGBHash: number]: number} = {};
|
||||
|
||||
// http://stackoverflow.com/questions/1633828
|
||||
function matchColorDistance(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number): number {
|
||||
return Math.pow(30 * (r1 - r2), 2)
|
||||
+ Math.pow(59 * (g1 - g2), 2)
|
||||
+ Math.pow(11 * (b1 - b2), 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user