remove get CharData calls from codebase (beside tests)

This commit is contained in:
Jörg Breitbart
2019-01-05 01:01:10 +01:00
parent b93b774971
commit 62dfa84d5d
8 changed files with 75 additions and 74 deletions
+1 -1
View File
@@ -227,7 +227,7 @@ export class Buffer implements IBuffer {
return [-1, -1];
}
for (let i = 0; i < line.length; ++i) {
stringIndex -= line.get(i)[CHAR_DATA_CHAR_INDEX].length;
stringIndex -= line.getString(i).length;
if (stringIndex < 0) {
return [lineIndex, i];
}
+3 -5
View File
@@ -8,7 +8,6 @@ import { ILinkHoverEvent, ILinkMatcher, LinkMatcherHandler, LinkHoverEventTypes,
import { MouseZone } from './ui/MouseZoneManager';
import { EventEmitter } from './common/EventEmitter';
import { getStringCellWidth } from './CharWidth';
import { CellData } from './BufferLine';
/**
* The Linkifier applies links to rows shortly after they have been refreshed.
@@ -34,7 +33,6 @@ export class Linkifier extends EventEmitter implements ILinkifier {
private _rowsTimeoutId: number;
private _nextLinkMatcherId = 0;
private _rowsToLinkify: { start: number, end: number };
private _cell: CellData = new CellData();
constructor(
protected _terminal: ITerminal
@@ -233,10 +231,10 @@ export class Linkifier extends EventEmitter implements ILinkifier {
}
const line = this._terminal.buffer.lines.get(bufferIndex[0]);
line.loadCell(bufferIndex[1], this._cell);
const attr = line.getFG(bufferIndex[1]);
let fg: number | undefined;
if (this._cell.fg) {
fg = (this._cell.fg >> 9) & 0x1ff;
if (attr) {
fg = (attr >> 9) & 0x1ff;
}
if (matcher.validationCallback) {
+36 -34
View File
@@ -3,15 +3,15 @@
* @license MIT
*/
import { ITerminal, ISelectionManager, IBuffer, CharData, IBufferLine } from './Types';
import { ITerminal, ISelectionManager, IBuffer, IBufferLine } from './Types';
import { XtermListener } from './common/Types';
import { MouseHelper } from './ui/MouseHelper';
import * as Browser from './core/Platform';
import { CharMeasure } from './ui/CharMeasure';
import { EventEmitter } from './common/EventEmitter';
import { SelectionModel } from './SelectionModel';
import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_CODE_INDEX } from './Buffer';
import { AltClickHandler } from './handlers/AltClickHandler';
import { CellData } from './BufferLine';
/**
* The number of pixels the mouse needs to be above or below the viewport in
@@ -103,6 +103,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
private _mouseMoveListener: EventListener;
private _mouseUpListener: EventListener;
private _trimListener: XtermListener;
private _cell: CellData = new CellData();
private _mouseDownTimeStamp: number;
@@ -506,8 +507,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
// If the mouse is over the second half of a wide character, adjust the
// selection to cover the whole character
const char = line.get(this._model.selectionStart[0]);
if (char[CHAR_DATA_WIDTH_INDEX] === 0) {
if (line.hasWidth(this._model.selectionStart[0]) === 0) {
this._model.selectionStart[0]++;
}
}
@@ -596,8 +596,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
// selection. Note that selections at the very end of the line will never
// have a character.
if (this._model.selectionEnd[1] < this._buffer.lines.length) {
const char = this._buffer.lines.get(this._model.selectionEnd[1]).get(this._model.selectionEnd[0]);
if (char && char[CHAR_DATA_WIDTH_INDEX] === 0) {
if (this._buffer.lines.get(this._model.selectionEnd[1]).hasWidth(this._model.selectionEnd[0]) === 0) {
this._model.selectionEnd[0]++;
}
}
@@ -670,16 +669,16 @@ 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 char = bufferLine.get(i);
if (char[CHAR_DATA_WIDTH_INDEX] === 0) {
const length = bufferLine.loadCell(i, this._cell).chars.length;
if (this._cell.width === 0) {
// Wide characters aren't included in the line string so decrement the
// index so the index is back on the wide character.
charIndex--;
} else if (char[CHAR_DATA_CHAR_INDEX].length > 1 && coords[0] !== i) {
} else if (length > 1 && coords[0] !== i) {
// Emojis take up multiple characters, so adjust accordingly. For these
// we don't want ot include the character at the column as we're
// returning the start index in the string, not the end index.
charIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;
charIndex += length - 1;
}
}
return charIndex;
@@ -739,48 +738,51 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
// Consider the initial position, skip it and increment the wide char
// variable
if (bufferLine.get(startCol)[CHAR_DATA_WIDTH_INDEX] === 0) {
if (bufferLine.getWidth(startCol) === 0) {
leftWideCharCount++;
startCol--;
}
if (bufferLine.get(endCol)[CHAR_DATA_WIDTH_INDEX] === 2) {
if (bufferLine.getWidth(endCol) === 2) {
rightWideCharCount++;
endCol++;
}
// Adjust the end index for characters whose length are > 1 (emojis)
if (bufferLine.get(endCol)[CHAR_DATA_CHAR_INDEX].length > 1) {
rightLongCharOffset += bufferLine.get(endCol)[CHAR_DATA_CHAR_INDEX].length - 1;
endIndex += bufferLine.get(endCol)[CHAR_DATA_CHAR_INDEX].length - 1;
const length = bufferLine.getString(endCol).length;
if (length > 1) {
rightLongCharOffset += length - 1;
endIndex += length - 1;
}
// Expand the string in both directions until a space is hit
while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.get(startCol - 1))) {
const char = bufferLine.get(startCol - 1);
if (char[CHAR_DATA_WIDTH_INDEX] === 0) {
while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine.loadCell(startCol - 1, this._cell))) {
bufferLine.loadCell(startCol - 1, this._cell);
const length = this._cell.chars.length;
if (this._cell.width === 0) {
// If the next character is a wide char, record it and skip the column
leftWideCharCount++;
startCol--;
} else if (char[CHAR_DATA_CHAR_INDEX].length > 1) {
} else if (length > 1) {
// If the next character's string is longer than 1 char (eg. emoji),
// adjust the index
leftLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1;
startIndex -= char[CHAR_DATA_CHAR_INDEX].length - 1;
leftLongCharOffset += length - 1;
startIndex -= length - 1;
}
startIndex--;
startCol--;
}
while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine.get(endCol + 1))) {
const char = bufferLine.get(endCol + 1);
if (char[CHAR_DATA_WIDTH_INDEX] === 2) {
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.chars.length;
if (this._cell.width === 2) {
// If the next character is a wide char, record it and skip the column
rightWideCharCount++;
endCol++;
} else if (char[CHAR_DATA_CHAR_INDEX].length > 1) {
} else if (length > 1) {
// If the next character's string is longer than 1 char (eg. emoji),
// adjust the index
rightLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1;
endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;
rightLongCharOffset += length - 1;
endIndex += length - 1;
}
endIndex++;
endCol++;
@@ -814,9 +816,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
// Recurse upwards if the line is wrapped and the word wraps to the above line
if (followWrappedLinesAbove) {
if (start === 0 && bufferLine.get(0)[CHAR_DATA_CODE_INDEX] !== 32 /*' '*/) {
if (start === 0 && bufferLine.getCodePoint(0) !== 32 /*' '*/) {
const previousBufferLine = this._buffer.lines.get(coords[1] - 1);
if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.get(this._terminal.cols - 1)[CHAR_DATA_CODE_INDEX] !== 32 /*' '*/) {
if (previousBufferLine && bufferLine.isWrapped && previousBufferLine.getCodePoint(this._terminal.cols - 1) !== 32 /*' '*/) {
const previousLineWordPosition = this._getWordAt([this._terminal.cols - 1, coords[1] - 1], false, true, false);
if (previousLineWordPosition) {
const offset = this._terminal.cols - previousLineWordPosition.start;
@@ -829,9 +831,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
// Recurse downwards if the line is wrapped and the word wraps to the next line
if (followWrappedLinesBelow) {
if (start + length === this._terminal.cols && bufferLine.get(this._terminal.cols - 1)[CHAR_DATA_CODE_INDEX] !== 32 /*' '*/) {
if (start + length === this._terminal.cols && bufferLine.getCodePoint(this._terminal.cols - 1) !== 32 /*' '*/) {
const nextBufferLine = this._buffer.lines.get(coords[1] + 1);
if (nextBufferLine && nextBufferLine.isWrapped && nextBufferLine.get(0)[CHAR_DATA_CODE_INDEX] !== 32 /*' '*/) {
if (nextBufferLine && nextBufferLine.isWrapped && nextBufferLine.getCodePoint(0) !== 32 /*' '*/) {
const nextLineWordPosition = this._getWordAt([0, coords[1] + 1], false, false, true);
if (nextLineWordPosition) {
length += nextLineWordPosition.length;
@@ -894,13 +896,13 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
* word logic.
* @param char The character to check.
*/
private _isCharWordSeparator(charData: CharData): boolean {
private _isCharWordSeparator(cell: CellData): boolean {
// Zero width characters are never separators as they are always to the
// right of wide characters
if (charData[CHAR_DATA_WIDTH_INDEX] === 0) {
if (cell.width === 0) {
return false;
}
return WORD_SEPARATORS.indexOf(charData[CHAR_DATA_CHAR_INDEX]) >= 0;
return WORD_SEPARATORS.indexOf(cell.chars) >= 0;
}
/**
+2 -2
View File
@@ -25,7 +25,7 @@ import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions
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, CHAR_DATA_ATTR_INDEX } from './Buffer';
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer';
import { CompositionHelper } from './CompositionHelper';
import { EventEmitter } from './common/EventEmitter';
import { Viewport } from './Viewport';
@@ -1175,7 +1175,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.get(0)[CHAR_DATA_ATTR_INDEX] !== this.eraseAttr()) {
if (!newLine || newLine.length !== this.cols || newLine.getFG(0) !== this.eraseAttr()) {
newLine = this.buffer.getBlankLine(this.eraseAttr(), isWrapped);
this._blankLine = newLine;
}
+5 -5
View File
@@ -4,12 +4,12 @@
*/
import { IRenderLayer, IColorSet, IRenderDimensions } from './Types';
import { CharData, ITerminal } from '../Types';
import { ITerminal } from '../Types';
import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/Types';
import BaseCharAtlas from './atlas/BaseCharAtlas';
import { acquireCharAtlas } from './atlas/CharAtlasCache';
import { CHAR_DATA_CHAR_INDEX } from '../Buffer';
import { is256Color } from './atlas/CharAtlasUtils';
import { CellData } from '../BufferLine';
export abstract class BaseRenderLayer implements IRenderLayer {
private _canvas: HTMLCanvasElement;
@@ -229,17 +229,17 @@ export abstract class BaseRenderLayer implements IRenderLayer {
* ensure that it fits with the cell, including the cell to the right if it's
* a wide character. This uses the existing fillStyle on the context.
* @param terminal The terminal.
* @param charData The char data for the character to draw.
* @param cell The cell data for the character to draw.
* @param x The column to draw at.
* @param y The row to draw at.
* @param color The color of the character.
*/
protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void {
protected fillCharTrueColor(terminal: ITerminal, cell: CellData, x: number, y: number): void {
this._ctx.font = this._getFont(terminal, false, false);
this._ctx.textBaseline = 'middle';
this._clipRow(terminal, y);
this._ctx.fillText(
charData[CHAR_DATA_CHAR_INDEX],
cell.chars,
x * this._scaledCellWidth + this._scaledCharLeft,
(y + 0.5) * this._scaledCellHeight + this._scaledCharTop);
}
+9 -9
View File
@@ -1,11 +1,12 @@
import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';
import { ITerminal, IBufferLine } from '../Types';
import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types';
import { CellData } from '../BufferLine';
export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
private _characterJoiners: ICharacterJoiner[] = [];
private _nextCharacterJoinerId: number = 0;
private _cell: CellData = new CellData();
constructor(private _terminal: ITerminal) {
}
@@ -51,13 +52,13 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
let rangeStartColumn = 0;
let currentStringIndex = 0;
let rangeStartStringIndex = 0;
let rangeAttr = line.get(0)[CHAR_DATA_ATTR_INDEX] >> 9;
let rangeAttr = line.getFG(0) >> 9;
for (let x = 0; x < this._terminal.cols; x++) {
const charData = line.get(x);
const chars = charData[CHAR_DATA_CHAR_INDEX];
const width = charData[CHAR_DATA_WIDTH_INDEX];
const attr = charData[CHAR_DATA_ATTR_INDEX] >> 9;
line.loadCell(x, this._cell);
const chars = this._cell.chars;
const width = this._cell.width;
const attr = this._cell.fg >> 9;
if (width === 0) {
// If this character is of width 0, skip it.
@@ -152,9 +153,8 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
}
for (let x = startCol; x < this._terminal.cols; x++) {
const charData = line.get(x);
const width = charData[CHAR_DATA_WIDTH_INDEX];
const length = charData[CHAR_DATA_CHAR_INDEX].length;
const width = line.getWidth(x);
const length = line.getString(x).length;
// We skip zero-width characters when creating the string to join the text
// so we do the same here
+18 -17
View File
@@ -3,10 +3,10 @@
* @license MIT
*/
import { CHAR_DATA_WIDTH_INDEX } from '../Buffer';
import { IColorSet, IRenderDimensions } from './Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { CharData, ITerminal } from '../Types';
import { ITerminal, ICellData } from '../Types';
import { CellData } from '../BufferLine';
interface ICursorState {
x: number;
@@ -23,8 +23,9 @@ const BLINK_INTERVAL = 600;
export class CursorRenderLayer extends BaseRenderLayer {
private _state: ICursorState;
private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, charData: CharData) => void};
private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, cell: ICellData) => void};
private _cursorBlinkStateManager: CursorBlinkStateManager;
private _cell: ICellData = new CellData();
constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {
super(container, 'cursor', zIndex, true, colors);
@@ -127,8 +128,8 @@ export class CursorRenderLayer extends BaseRenderLayer {
return;
}
const charData = terminal.buffer.lines.get(cursorY).get(terminal.buffer.x);
if (!charData) {
terminal.buffer.lines.get(cursorY).loadCell(terminal.buffer.x, this._cell);
if (this._cell.content === undefined) {
return;
}
@@ -136,13 +137,13 @@ export class CursorRenderLayer extends BaseRenderLayer {
this._clearCursor();
this._ctx.save();
this._ctx.fillStyle = this._colors.cursor.css;
this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, charData);
this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);
this._ctx.restore();
this._state.x = terminal.buffer.x;
this._state.y = viewportRelativeCursorY;
this._state.isFocused = false;
this._state.style = terminal.options.cursorStyle;
this._state.width = charData[CHAR_DATA_WIDTH_INDEX];
this._state.width = this._cell.width;
return;
}
@@ -158,21 +159,21 @@ export class CursorRenderLayer extends BaseRenderLayer {
this._state.y === viewportRelativeCursorY &&
this._state.isFocused === terminal.isFocused &&
this._state.style === terminal.options.cursorStyle &&
this._state.width === charData[CHAR_DATA_WIDTH_INDEX]) {
this._state.width === this._cell.width) {
return;
}
this._clearCursor();
}
this._ctx.save();
this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, charData);
this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell);
this._ctx.restore();
this._state.x = terminal.buffer.x;
this._state.y = viewportRelativeCursorY;
this._state.isFocused = false;
this._state.style = terminal.options.cursorStyle;
this._state.width = charData[CHAR_DATA_WIDTH_INDEX];
this._state.width = this._cell.width;
}
private _clearCursor(): void {
@@ -188,33 +189,33 @@ export class CursorRenderLayer extends BaseRenderLayer {
}
}
private _renderBarCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {
private _renderBarCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {
this._ctx.save();
this._ctx.fillStyle = this._colors.cursor.css;
this.fillLeftLineAtCell(x, y);
this._ctx.restore();
}
private _renderBlockCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {
private _renderBlockCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {
this._ctx.save();
this._ctx.fillStyle = this._colors.cursor.css;
this.fillCells(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1);
this.fillCells(x, y, cell.width, 1);
this._ctx.fillStyle = this._colors.cursorAccent.css;
this.fillCharTrueColor(terminal, charData, x, y);
this.fillCharTrueColor(terminal, cell, x, y);
this._ctx.restore();
}
private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {
private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {
this._ctx.save();
this._ctx.fillStyle = this._colors.cursor.css;
this.fillBottomLineAtCells(x, y);
this._ctx.restore();
}
private _renderBlurCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {
private _renderBlurCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void {
this._ctx.save();
this._ctx.strokeStyle = this._colors.cursor.css;
this.strokeRectAtCell(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1);
this.strokeRectAtCell(x, y, cell.width, 1);
this._ctx.restore();
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer';
import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer';
import { FLAGS, IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types';
import { CharData, ITerminal } from '../Types';
import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types';