From bde7bdc11d769d601ad98f1b5242842125c55a99 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Mon, 25 Sep 2023 18:21:02 -0700 Subject: [PATCH] Change setCellFromCodePoint API and rename to setCellFromCodepoint Replace fg, bg, and eAttrs parameters by single IAttributeData parameter. In addition to making for a simpler/cleaner API, it also increases flexibility for future CellData or BufferLine changes. (Rename function to reduce risk of using accidentally using old function.) Also removed redundant eraseAttr parameter in deleteCells, insertCells, and replaceCells. --- src/common/InputHandler.ts | 34 +++++++++++++++------------------ src/common/Types.d.ts | 8 ++++---- src/common/buffer/BufferLine.ts | 34 ++++++++++++++++----------------- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index b5c91bfb..faea43c7 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -519,7 +519,7 @@ export class InputHandler extends Disposable implements IInputHandler { // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x - 1, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr); } let precedingJoinState = this._parser.precedingJoinState; @@ -581,7 +581,7 @@ export class InputHandler extends Disposable implements IInputHandler { } // clear left over cells to the right while (oldCol < cols) { - oldRow.setCellFromCodePoint(oldCol++, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr); } } else { this._activeBuffer.x = cols - 1; @@ -605,7 +605,7 @@ export class InputHandler extends Disposable implements IInputHandler { bufferRow.addCodepointToCell(this._activeBuffer.x - offset, code, chWidth); for (let delta = chWidth - oldWidth; --delta >= 0; ) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, 0, 0, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr); } continue; } @@ -613,17 +613,17 @@ export class InputHandler extends Disposable implements IInputHandler { // insert mode: move characters to right if (insertMode) { // right shift cells according to the width - bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr), curAttr); + bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr)); // 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.getWidth(cols - 1) === 2) { - bufferRow.setCellFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr); } } // write current char to buffer and advance cursor - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, code, chWidth, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr); // fullwidth char - also set next cell to placeholder stub and advance cursor // for graphemes bigger than fullwidth we can simply loop to zero @@ -631,7 +631,7 @@ export class InputHandler extends Disposable implements IInputHandler { if (chWidth > 0) { while (--chWidth) { // other than a regular empty cell a cell following a wide char has no width - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, 0, 0, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr); } } } @@ -640,7 +640,7 @@ export class InputHandler extends Disposable implements IInputHandler { // handle wide chars: reset cell to the right if it is second cell of a wide char if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr); } this._dirtyRowTracker.markDirty(this._activeBuffer.y); @@ -1145,7 +1145,6 @@ export class InputHandler extends Disposable implements IInputHandler { start, end, this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData(), respectProtect ); if (clearWrap) { @@ -1366,8 +1365,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.insertCells( this._activeBuffer.x, params.params[0] || 1, - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } @@ -1393,8 +1391,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.deleteCells( this._activeBuffer.x, params.params[0] || 1, - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } @@ -1461,7 +1458,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1494,7 +1491,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1517,7 +1514,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1540,7 +1537,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1562,8 +1559,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.replaceCells( this._activeBuffer.x, this._activeBuffer.x + (params.params[0] || 1), - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index fc8fdf4e..eb316d8d 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -233,11 +233,11 @@ export interface IBufferLine { set(index: number, value: CharData): void; loadCell(index: number, cell: ICellData): ICellData; setCell(index: number, cell: ICellData): void; - setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number, eAttrs: IExtendedAttrs): void; + setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void; addCodepointToCell(index: number, codePoint: number, width: number): void; - insertCells(pos: number, n: number, ch: ICellData, eraseAttr?: IAttributeData): void; - deleteCells(pos: number, n: number, fill: ICellData, eraseAttr?: IAttributeData): void; - replaceCells(start: number, end: number, fill: ICellData, eraseAttr?: IAttributeData, respectProtect?: boolean): void; + insertCells(pos: number, n: number, ch: ICellData): void; + deleteCells(pos: number, n: number, fill: ICellData): void; + replaceCells(start: number, end: number, fill: ICellData, respectProtect?: boolean): void; resize(cols: number, fill: ICellData): boolean; cleanupMemory(): number; fill(fillCellData: ICellData, respectProtect?: boolean): void; diff --git a/src/common/buffer/BufferLine.ts b/src/common/buffer/BufferLine.ts index a268f2bc..2852c7f1 100644 --- a/src/common/buffer/BufferLine.ts +++ b/src/common/buffer/BufferLine.ts @@ -4,7 +4,7 @@ */ import { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from 'common/Types'; -import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData'; +import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; import { stringFromCodePoint } from 'common/input/TextDecoder'; @@ -212,13 +212,13 @@ export class BufferLine implements IBufferLine { * Since the input handler see the incoming chars as UTF32 codepoints, * it gets an optimized access method. */ - public setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number, eAttrs: IExtendedAttrs): void { - if (bg & BgFlags.HAS_EXTENDED) { - this._extendedAttrs[index] = eAttrs; + public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void { + if (attrs.bg & BgFlags.HAS_EXTENDED) { + this._extendedAttrs[index] = attrs.extended; } this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT); - this._data[index * CELL_SIZE + Cell.FG] = fg; - this._data[index * CELL_SIZE + Cell.BG] = bg; + this._data[index * CELL_SIZE + Cell.FG] = attrs.fg; + this._data[index * CELL_SIZE + Cell.BG] = attrs.bg; } /** @@ -253,12 +253,12 @@ export class BufferLine implements IBufferLine { this._data[index * CELL_SIZE + Cell.CONTENT] = content; } - public insertCells(pos: number, n: number, fillCellData: ICellData, eraseAttr?: IAttributeData): void { + public insertCells(pos: number, n: number, fillCellData: ICellData): void { pos %= this.length; // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char if (pos && this.getWidth(pos - 1) === 2) { - this.setCellFromCodePoint(pos - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData); } if (n < this.length - pos) { @@ -277,11 +277,11 @@ export class BufferLine implements IBufferLine { // handle fullwidth at line end: reset last cell if it is first cell of a wide char if (this.getWidth(this.length - 1) === 2) { - this.setCellFromCodePoint(this.length - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData); } } - public deleteCells(pos: number, n: number, fillCellData: ICellData, eraseAttr?: IAttributeData): void { + public deleteCells(pos: number, n: number, fillCellData: ICellData): void { pos %= this.length; if (n < this.length - pos) { const cell = new CellData(); @@ -301,21 +301,21 @@ export class BufferLine implements IBufferLine { // - reset pos-1 if wide char // - reset pos if width==0 (previous second cell of a wide char) if (pos && this.getWidth(pos - 1) === 2) { - this.setCellFromCodePoint(pos - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData); } if (this.getWidth(pos) === 0 && !this.hasContent(pos)) { - this.setCellFromCodePoint(pos, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos, 0, 1, fillCellData); } } - public replaceCells(start: number, end: number, fillCellData: ICellData, eraseAttr?: IAttributeData, respectProtect: boolean = false): void { + public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void { // full branching on respectProtect==true, hopefully getting fast JIT for standard case if (respectProtect) { if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) { - this.setCellFromCodePoint(start - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(start - 1, 0, 1, fillCellData); } if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) { - this.setCellFromCodePoint(end, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(end, 0, 1, fillCellData); } while (start < end && start < this.length) { if (!this.isProtected(start)) { @@ -328,11 +328,11 @@ export class BufferLine implements IBufferLine { // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char if (start && this.getWidth(start - 1) === 2) { - this.setCellFromCodePoint(start - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(start - 1, 0, 1, fillCellData); } // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char if (end < this.length && this.getWidth(end - 1) === 2) { - this.setCellFromCodePoint(end, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(end, 0, 1, fillCellData); } while (start < end && start < this.length) {