Fix feedback

This commit is contained in:
Daniel Imms
2019-04-01 00:01:41 -07:00
parent 69f8700557
commit 5c8c680dac
11 changed files with 98 additions and 94 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ export const NULL_CELL_WIDTH = 1;
export const NULL_CELL_CODE = 0;
/**
* Whilespace cell.
* Whitespace cell.
* This is meant as a replacement for empty cells when needed
* during rendering lines to preserve correct aligment.
*/
+5 -5
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import * as chai from 'chai';
import { BufferLine, CellData, Content } from './BufferLine';
import { BufferLine, CellData, ContentMasks } from './BufferLine';
import { CharData, IBufferLine } from './Types';
import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './Buffer';
@@ -32,7 +32,7 @@ describe('CellData', () => {
// combining
cell.setFromCharData([123, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
chai.assert.deepEqual(cell.getAsCharData(), [123, 'e\u0301', 1, '\u0301'.charCodeAt(0)]);
chai.assert.equal(cell.isCombined(), Content.IS_COMBINED);
chai.assert.equal(cell.isCombined(), ContentMasks.IS_COMBINED);
// surrogate
cell.setFromCharData([123, '𝄞', 1, 0x1D11E]);
chai.assert.deepEqual(cell.getAsCharData(), [123, '𝄞', 1, 0x1D11E]);
@@ -40,7 +40,7 @@ describe('CellData', () => {
// surrogate + combining
cell.setFromCharData([123, '𓂀\u0301', 1, '𓂀\u0301'.charCodeAt(2)]);
chai.assert.deepEqual(cell.getAsCharData(), [123, '𓂀\u0301', 1, '𓂀\u0301'.charCodeAt(2)]);
chai.assert.equal(cell.isCombined(), Content.IS_COMBINED);
chai.assert.equal(cell.isCombined(), ContentMasks.IS_COMBINED);
// wide char
cell.setFromCharData([123, '', 2, ''.charCodeAt(0)]);
chai.assert.deepEqual(cell.getAsCharData(), [123, '', 2, ''.charCodeAt(0)]);
@@ -350,7 +350,7 @@ describe('BufferLine', function(): void {
// width is set to 1
chai.assert.deepEqual(cell.getAsCharData(), [123, 'e\u0301\u0301', 1, 0x0301]);
// do not account a single combining char as combined
chai.assert.equal(cell.isCombined(), Content.IS_COMBINED);
chai.assert.equal(cell.isCombined(), ContentMasks.IS_COMBINED);
});
it('should create combining string on taken cell', () => {
const line = new TestBufferLine(3, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false);
@@ -363,7 +363,7 @@ describe('BufferLine', function(): void {
// width is set to 1
chai.assert.deepEqual(cell.getAsCharData(), [123, 'e\u0301', 1, 0x0301]);
// do not account a single combining char as combined
chai.assert.equal(cell.isCombined(), Content.IS_COMBINED);
chai.assert.equal(cell.isCombined(), ContentMasks.IS_COMBINED);
});
});
});
+52 -49
View File
@@ -34,9 +34,9 @@ const enum Cell {
}
/**
* Bitmasks and helper for accessing data in `content`.
* Bitmasks for accessing data in `content`.
*/
export const enum Content {
export const enum ContentMasks {
/**
* bit 1..21 codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)
* read: `codepoint = content & Content.codepointMask;`
@@ -44,7 +44,7 @@ export const enum Content {
* shortcut if precondition `codepoint <= 0x10FFFF` is met:
* `content |= codepoint;`
*/
CODEPOINT_MASK = 0x1FFFFF,
CODEPOINT = 0x1FFFFF,
/**
* bit 22 flag indication whether a cell contains combined content
@@ -72,10 +72,11 @@ export const enum Content {
* shortcut if precondition `0 <= width <= 3` is met:
* `content |= width << Content.widthShift;`
*/
WIDTH_MASK = 0xC00000, // 3 << 22
WIDTH_SHIFT = 22
WIDTH = 0xC00000 // 3 << 22
}
const WIDTH_MASK_SHIFT = 22;
/**
* CellData - represents a single Cell in the terminal buffer.
*/
@@ -96,21 +97,21 @@ export class CellData implements ICellData {
/** Whether cell contains a combined string. */
public isCombined(): number {
return this.content & Content.IS_COMBINED;
return this.content & ContentMasks.IS_COMBINED;
}
/** Width of the cell. */
public getWidth(): number {
return this.content >> Content.WIDTH_SHIFT;
return this.content >> WIDTH_MASK_SHIFT;
}
/** JS string of the content. */
public getChars(): string {
if (this.content & Content.IS_COMBINED) {
if (this.content & ContentMasks.IS_COMBINED) {
return this.combinedData;
}
if (this.content & Content.CODEPOINT_MASK) {
return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);
if (this.content & ContentMasks.CODEPOINT) {
return stringFromCodePoint(this.content & ContentMasks.CODEPOINT);
}
return '';
}
@@ -124,7 +125,7 @@ export class CellData implements ICellData {
public getCode(): number {
return (this.isCombined())
? this.combinedData.charCodeAt(this.combinedData.length - 1)
: this.content & Content.CODEPOINT_MASK;
: this.content & ContentMasks.CODEPOINT;
}
/** Set data from CharData */
@@ -143,7 +144,7 @@ export class CellData implements ICellData {
if (0xD800 <= code && code <= 0xDBFF) {
const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);
if (0xDC00 <= second && second <= 0xDFFF) {
this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << WIDTH_MASK_SHIFT);
} else {
combined = true;
}
@@ -151,11 +152,11 @@ export class CellData implements ICellData {
combined = true;
}
} else {
this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << WIDTH_MASK_SHIFT);
}
if (combined) {
this.combinedData = value[CHAR_DATA_CHAR_INDEX];
this.content = Content.IS_COMBINED | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
this.content = ContentMasks.IS_COMBINED | (value[CHAR_DATA_WIDTH_INDEX] << WIDTH_MASK_SHIFT);
}
}
@@ -203,14 +204,14 @@ export class BufferLine implements IBufferLine {
*/
public get(index: number): CharData {
const content = this._data[index * CELL_SIZE + Cell.CONTENT];
const cp = content & Content.CODEPOINT_MASK;
const cp = content & ContentMasks.CODEPOINT;
return [
this._data[index * CELL_SIZE + Cell.FG],
(content & Content.IS_COMBINED)
(content & ContentMasks.IS_COMBINED)
? this._combined[index]
: (cp) ? stringFromCodePoint(cp) : '',
content >> Content.WIDTH_SHIFT,
(content & Content.IS_COMBINED)
content >> WIDTH_MASK_SHIFT,
(content & ContentMasks.IS_COMBINED)
? this._combined[index].charCodeAt(this._combined[index].length - 1)
: cp
];
@@ -224,9 +225,9 @@ export class BufferLine implements IBufferLine {
this._data[index * CELL_SIZE + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];
if (value[CHAR_DATA_CHAR_INDEX].length > 1) {
this._combined[index] = value[1];
this._data[index * CELL_SIZE + Cell.CONTENT] = index | Content.IS_COMBINED | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
this._data[index * CELL_SIZE + Cell.CONTENT] = index | ContentMasks.IS_COMBINED | (value[CHAR_DATA_WIDTH_INDEX] << WIDTH_MASK_SHIFT);
} else {
this._data[index * CELL_SIZE + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
this._data[index * CELL_SIZE + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << WIDTH_MASK_SHIFT);
}
}
@@ -235,21 +236,21 @@ export class BufferLine implements IBufferLine {
* use these when only one value is needed, otherwise use `loadCell`
*/
public getWidth(index: number): number {
return this._data[index * CELL_SIZE + Cell.CONTENT] >> Content.WIDTH_SHIFT;
return this._data[index * CELL_SIZE + Cell.CONTENT] >> WIDTH_MASK_SHIFT;
}
/** Test whether content has width. */
public hasWidth(index: number): number {
return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.WIDTH_MASK;
return this._data[index * CELL_SIZE + Cell.CONTENT] & ContentMasks.WIDTH;
}
/** Get FG cell component. */
public getFG(index: number): number {
public getFg(index: number): number {
return this._data[index * CELL_SIZE + Cell.FG];
}
/** Get BG cell component. */
public getBG(index: number): number {
public getBg(index: number): number {
return this._data[index * CELL_SIZE + Cell.BG];
}
@@ -259,7 +260,7 @@ export class BufferLine implements IBufferLine {
* from real empty cells.
* */
public hasContent(index: number): number {
return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT;
return this._data[index * CELL_SIZE + Cell.CONTENT] & ContentMasks.HAS_CONTENT;
}
/**
@@ -269,38 +270,40 @@ export class BufferLine implements IBufferLine {
*/
public getCodePoint(index: number): number {
const content = this._data[index * CELL_SIZE + Cell.CONTENT];
if (content & Content.IS_COMBINED) {
if (content & ContentMasks.IS_COMBINED) {
return this._combined[index].charCodeAt(this._combined[index].length - 1);
}
return content & Content.CODEPOINT_MASK;
return content & ContentMasks.CODEPOINT;
}
/** Test whether the cell contains a combined string. */
public isCombined(index: number): number {
return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.IS_COMBINED;
return this._data[index * CELL_SIZE + Cell.CONTENT] & ContentMasks.IS_COMBINED;
}
/** Returns the string content of the cell. */
public getString(index: number): string {
const content = this._data[index * CELL_SIZE + Cell.CONTENT];
if (content & Content.IS_COMBINED) {
if (content & ContentMasks.IS_COMBINED) {
return this._combined[index];
}
if (content & Content.CODEPOINT_MASK) {
return stringFromCodePoint(content & Content.CODEPOINT_MASK);
if (content & ContentMasks.CODEPOINT) {
return stringFromCodePoint(content & ContentMasks.CODEPOINT);
}
// return empty string for empty cells
return '';
}
/**
* Load data at `index` into `cell`.
* Load data at `index` into `cell`. This is used to access cells in a way that's more friendly
* to GC as it significantly reduced the amount of new objects/references needed.
*/
public loadCell(index: number, cell: ICellData): ICellData {
cell.content = this._data[index * CELL_SIZE + Cell.CONTENT];
cell.fg = this._data[index * CELL_SIZE + Cell.FG];
cell.bg = this._data[index * CELL_SIZE + Cell.BG];
if (cell.content & Content.IS_COMBINED) {
const startIndex = index * CELL_SIZE;
cell.content = this._data[startIndex + Cell.CONTENT];
cell.fg = this._data[startIndex + Cell.FG];
cell.bg = this._data[startIndex + Cell.BG];
if (cell.content & ContentMasks.IS_COMBINED) {
cell.combinedData = this._combined[index];
}
return cell;
@@ -310,7 +313,7 @@ export class BufferLine implements IBufferLine {
* Set data at `index` to `cell`.
*/
public setCell(index: number, cell: ICellData): void {
if (cell.content & Content.IS_COMBINED) {
if (cell.content & ContentMasks.IS_COMBINED) {
this._combined[index] = cell.combinedData;
}
this._data[index * CELL_SIZE + Cell.CONTENT] = cell.content;
@@ -324,7 +327,7 @@ export class BufferLine implements IBufferLine {
* it gets an optimized access method.
*/
public setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void {
this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);
this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << WIDTH_MASK_SHIFT);
this._data[index * CELL_SIZE + Cell.FG] = fg;
this._data[index * CELL_SIZE + Cell.BG] = bg;
}
@@ -337,21 +340,21 @@ export class BufferLine implements IBufferLine {
*/
public addCodepointToCell(index: number, codePoint: number): void {
let content = this._data[index * CELL_SIZE + Cell.CONTENT];
if (content & Content.IS_COMBINED) {
if (content & ContentMasks.IS_COMBINED) {
// we already have a combined string, simply add
this._combined[index] += stringFromCodePoint(codePoint);
} else {
if (content & Content.CODEPOINT_MASK) {
if (content & ContentMasks.CODEPOINT) {
// normal case for combining chars:
// - move current leading char + new one into combined string
// - set combined flag
this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint);
content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0
content |= Content.IS_COMBINED;
this._combined[index] = stringFromCodePoint(content & ContentMasks.CODEPOINT) + stringFromCodePoint(codePoint);
content &= ~ContentMasks.CODEPOINT; // set codepoint in buffer to 0
content |= ContentMasks.IS_COMBINED;
} else {
// should not happen - we actually have no data in the cell yet
// simply set the data in the cell buffer with a width of 1
content = codePoint | (1 << Content.WIDTH_SHIFT);
content = codePoint | (1 << WIDTH_MASK_SHIFT);
}
this._data[index * CELL_SIZE + Cell.CONTENT] = content;
}
@@ -473,8 +476,8 @@ export class BufferLine implements IBufferLine {
public getTrimmedLength(): number {
for (let i = this.length - 1; i >= 0; --i) {
if ((this._data[i * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT)) {
return i + (this._data[i * CELL_SIZE + Cell.CONTENT] >> Content.WIDTH_SHIFT);
if ((this._data[i * CELL_SIZE + Cell.CONTENT] & ContentMasks.HAS_CONTENT)) {
return i + (this._data[i * CELL_SIZE + Cell.CONTENT] >> WIDTH_MASK_SHIFT);
}
}
return 0;
@@ -513,9 +516,9 @@ export class BufferLine implements IBufferLine {
let result = '';
while (startCol < endCol) {
const content = this._data[startCol * CELL_SIZE + Cell.CONTENT];
const cp = content & Content.CODEPOINT_MASK;
result += (content & Content.IS_COMBINED) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;
startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by 1
const cp = content & ContentMasks.CODEPOINT;
result += (content & ContentMasks.IS_COMBINED) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR;
startCol += (content >> WIDTH_MASK_SHIFT) || 1; // always advance by 1
}
return result;
}
+5 -5
View File
@@ -106,7 +106,7 @@ class DECRQSS implements IDcsHandler {
export class InputHandler extends Disposable implements IInputHandler {
private _parseBuffer: Uint32Array = new Uint32Array(4096);
private _stringDecoder: StringToUtf32 = new StringToUtf32();
private _cell: CellData = new CellData();
private _workCell: CellData = new CellData();
constructor(
protected _terminal: IInputHandlingTerminal,
@@ -351,7 +351,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// since they always follow a cell consuming char
// therefore we can test for buffer.x to avoid overflow left
if (!chWidth && buffer.x) {
if (!bufferRow.loadCell(buffer.x - 1, this._cell).getWidth()) {
if (!bufferRow.getWidth(buffer.x - 1)) {
// found empty cell after fullwidth, need to go 2 cells back
// it is save to step 2 cells back here
// since an empty cell is only set by fullwidth chars
@@ -400,7 +400,7 @@ export class InputHandler extends Disposable implements IInputHandler {
// test last cell - since the last cell has only room for
// a halfwidth char any fullwidth shifted there is lost
// and will be set to empty cell
if (bufferRow.loadCell(cols - 1, this._cell).getWidth() === 2) {
if (bufferRow.getWidth(cols - 1) === 2) {
bufferRow.setCellFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr, 0);
}
}
@@ -970,10 +970,10 @@ export class InputHandler extends Disposable implements IInputHandler {
// make buffer local for faster access
const buffer = this._terminal.buffer;
const line = buffer.lines.get(buffer.ybase + buffer.y);
line.loadCell(buffer.x - 1, this._cell);
line.loadCell(buffer.x - 1, this._workCell);
line.replaceCells(buffer.x,
buffer.x + (params[0] || 1),
(this._cell.content !== undefined) ? this._cell : buffer.getNullCell(DEFAULT_ATTR)
(this._workCell.content !== undefined) ? this._workCell : buffer.getNullCell(DEFAULT_ATTR)
);
// FIXME: no updateRange here?
}
+1 -1
View File
@@ -231,7 +231,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
}
const line = this._terminal.buffer.lines.get(bufferIndex[0]);
const attr = line.getFG(bufferIndex[1]);
const attr = line.getFg(bufferIndex[1]);
let fg: number | undefined;
if (attr) {
fg = (attr >> 9) & 0x1ff;
+11 -11
View File
@@ -103,7 +103,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
private _mouseMoveListener: EventListener;
private _mouseUpListener: EventListener;
private _trimListener: XtermListener;
private _cell: CellData = new CellData();
private _workCell: CellData = new CellData();
private _mouseDownTimeStamp: number;
@@ -669,8 +669,8 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
private _convertViewportColToCharacterIndex(bufferLine: IBufferLine, coords: [number, number]): number {
let charIndex = coords[0];
for (let i = 0; coords[0] >= i; i++) {
const length = bufferLine.loadCell(i, this._cell).getChars().length;
if (this._cell.getWidth() === 0) {
const length = bufferLine.loadCell(i, this._workCell).getChars().length;
if (this._workCell.getWidth() === 0) {
// Wide characters aren't included in the line string so decrement the
// index so the index is back on the wide character.
charIndex--;
@@ -755,10 +755,10 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
}
// Expand the string in both directions until a space is hit
while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._cell))) {
bufferLine.loadCell(startCol - 1, this._cell);
const length = this._cell.getChars().length;
if (this._cell.getWidth() === 0) {
while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._workCell))) {
bufferLine.loadCell(startCol - 1, this._workCell);
const length = this._workCell.getChars().length;
if (this._workCell.getWidth() === 0) {
// If the next character is a wide char, record it and skip the column
leftWideCharCount++;
startCol--;
@@ -771,10 +771,10 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
startIndex--;
startCol--;
}
while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._cell))) {
bufferLine.loadCell(endCol + 1, this._cell);
const length = this._cell.getChars().length;
if (this._cell.getWidth() === 2) {
while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.loadCell(endCol + 1, this._workCell))) {
bufferLine.loadCell(endCol + 1, this._workCell);
const length = this._workCell.getChars().length;
if (this._workCell.getWidth() === 2) {
// If the next character is a wide char, record it and skip the column
rightWideCharCount++;
endCol++;
+1 -1
View File
@@ -1181,7 +1181,7 @@ 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()) {
if (!newLine || newLine.length !== this.cols || newLine.getFg(0) !== this.eraseAttr()) {
newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
this._blankLine = newLine;
}
+2 -2
View File
@@ -560,8 +560,8 @@ export interface IBufferLine {
/* direct access to cell attrs */
getWidth(index: number): number;
hasWidth(index: number): number;
getFG(index: number): number;
getBG(index: number): number;
getFg(index: number): number;
getBg(index: number): number;
hasContent(index: number): number;
getCodePoint(index: number): number;
isCombined(index: number): number;
+6 -6
View File
@@ -6,7 +6,7 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
private _characterJoiners: ICharacterJoiner[] = [];
private _nextCharacterJoinerId: number = 0;
private _cell: CellData = new CellData();
private _workCell: CellData = new CellData();
constructor(private _terminal: ITerminal) {
}
@@ -52,13 +52,13 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
let rangeStartColumn = 0;
let currentStringIndex = 0;
let rangeStartStringIndex = 0;
let rangeAttr = line.getFG(0) >> 9;
let rangeAttr = line.getFg(0) >> 9;
for (let x = 0; x < this._terminal.cols; x++) {
line.loadCell(x, this._cell);
const chars = this._cell.getChars();
const width = this._cell.getWidth();
const attr = this._cell.fg >> 9;
line.loadCell(x, this._workCell);
const chars = this._workCell.getChars();
const width = this._workCell.getWidth();
const attr = this._workCell.fg >> 9;
if (width === 0) {
// If this character is of width 0, skip it.
+7 -7
View File
@@ -25,7 +25,7 @@ export class TextRenderLayer extends BaseRenderLayer {
private _characterFont: string;
private _characterOverlapCache: { [key: string]: boolean } = {};
private _characterJoinerRegistry: ICharacterJoinerRegistry;
private _cell = new CellData();
private _workCell = new CellData();
constructor(container: HTMLElement, zIndex: number, colors: IColorSet, characterJoinerRegistry: ICharacterJoinerRegistry, alpha: boolean) {
super(container, 'text', zIndex, alpha, colors);
@@ -74,14 +74,14 @@ export class TextRenderLayer extends BaseRenderLayer {
const line = terminal.buffer.lines.get(row);
const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];
for (let x = 0; x < terminal.cols; x++) {
(line as any).loadCell(x, this._cell);
let code: number = this._cell.getCode() || WHITESPACE_CELL_CODE;
line.loadCell(x, this._workCell);
let code: number = this._workCell.getCode() || WHITESPACE_CELL_CODE;
// Can either represent character(s) for a single cell or multiple cells
// if indicated by a character joiner.
let chars = this._cell.getChars() || WHITESPACE_CELL_CHAR;
const attr = this._cell.fg;
let width = this._cell.getWidth();
let chars = this._workCell.getChars() || WHITESPACE_CELL_CHAR;
const attr = this._workCell.fg;
let width = this._workCell.getWidth();
// If true, indicates that the current character(s) to draw were joined.
let isJoined = false;
@@ -127,7 +127,7 @@ export class TextRenderLayer extends BaseRenderLayer {
// get removed, and `a` would not re-render because it thinks it's
// already in the correct state.
// this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA;
if (lastCharX < line.length - 1 && line.loadCell(lastCharX + 1, this._cell).getCode() === NULL_CELL_CODE) {
if (lastCharX < line.length - 1 && line.loadCell(lastCharX + 1, this._workCell).getCode() === NULL_CELL_CODE) {
width = 2;
// this._clearChar(x + 1, y);
// The overlapping char's char data will force a clear and render when the
+7 -6
View File
@@ -18,7 +18,8 @@ export const CURSOR_STYLE_BAR_CLASS = 'xterm-cursor-bar';
export const CURSOR_STYLE_UNDERLINE_CLASS = 'xterm-cursor-underline';
export class DomRendererRowFactory {
private _cell: CellData = new CellData();
private _workCell: CellData = new CellData();
constructor(
private _terminalOptions: ITerminalOptions,
private _document: Document
@@ -35,16 +36,16 @@ export class DomRendererRowFactory {
// the viewport).
let lineLength = 0;
for (let x = Math.min(lineData.length, cols) - 1; x >= 0; x--) {
if (lineData.loadCell(x, this._cell).getCode() !== NULL_CELL_CODE || (isCursorRow && x === cursorX)) {
if (lineData.loadCell(x, this._workCell).getCode() !== NULL_CELL_CODE || (isCursorRow && x === cursorX)) {
lineLength = x + 1;
break;
}
}
for (let x = 0; x < lineLength; x++) {
lineData.loadCell(x, this._cell);
const attr = this._cell.fg;
const width = this._cell.getWidth();
lineData.loadCell(x, this._workCell);
const attr = this._workCell.fg;
const width = this._workCell.getWidth();
// The character to the left is a wide character, drawing is owned by the char at x-1
if (width === 0) {
@@ -106,7 +107,7 @@ export class DomRendererRowFactory {
charElement.classList.add(ITALIC_CLASS);
}
charElement.textContent = this._cell.getChars() || WHITESPACE_CELL_CHAR;
charElement.textContent = this._workCell.getChars() || WHITESPACE_CELL_CHAR;
if (fg !== DEFAULT_COLOR) {
charElement.classList.add(`xterm-fg-${fg}`);
}