xterm-addon-webgl
Advanced tools
Comparing version 0.12.0-beta.30 to 0.12.0-beta.31
{ | ||
"name": "xterm-addon-webgl", | ||
"version": "0.12.0-beta.30", | ||
"version": "0.12.0-beta.31", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "The xterm.js authors", |
@@ -9,11 +9,7 @@ /** | ||
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types'; | ||
import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_INDICIES_PER_CELL, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_BG_OFFSET } from './RenderModel'; | ||
import { fill } from 'common/TypedArrayUtils'; | ||
import { slice } from './TypedArray'; | ||
import { NULL_CELL_CODE, Attributes, FgFlags } from 'common/buffer/Constants'; | ||
import { NULL_CELL_CODE } from 'common/buffer/Constants'; | ||
import { Terminal, IBufferLine } from 'xterm'; | ||
import { IColor } from 'common/Types'; | ||
import { IColorSet } from 'browser/Types'; | ||
import { IRenderDimensions } from 'browser/renderer/Types'; | ||
import { AttributeData } from 'common/buffer/AttributeData'; | ||
@@ -29,3 +25,2 @@ interface IVertices { | ||
attributesBuffers: Float32Array[]; | ||
selectionAttributes: Float32Array; | ||
count: number; | ||
@@ -97,4 +92,3 @@ } | ||
new Float32Array(0) | ||
], | ||
selectionAttributes: new Float32Array(0) | ||
] | ||
}; | ||
@@ -223,87 +217,2 @@ | ||
public updateSelection(model: IRenderModel): void { | ||
const terminal = this._terminal; | ||
this._vertices.selectionAttributes = slice(this._vertices.attributes, 0); | ||
const bg = (this._colors.selectionOpaque.rgba >>> 8) | Attributes.CM_RGB; | ||
if (model.selection.columnSelectMode) { | ||
const startCol = model.selection.startCol; | ||
const width = model.selection.endCol - startCol; | ||
const height = model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow + 1; | ||
for (let y = model.selection.viewportCappedStartRow; y < model.selection.viewportCappedStartRow + height; y++) { | ||
this._updateSelectionRange(startCol, startCol + width, y, model, bg); | ||
} | ||
} else { | ||
// Draw first row | ||
const startCol = model.selection.viewportStartRow === model.selection.viewportCappedStartRow ? model.selection.startCol : 0; | ||
const startRowEndCol = model.selection.viewportCappedStartRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols; | ||
this._updateSelectionRange(startCol, startRowEndCol, model.selection.viewportCappedStartRow, model, bg); | ||
// Draw middle rows | ||
const middleRowsCount = Math.max(model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow - 1, 0); | ||
for (let y = model.selection.viewportCappedStartRow + 1; y <= model.selection.viewportCappedStartRow + middleRowsCount; y++) { | ||
this._updateSelectionRange(0, startRowEndCol, y, model, bg); | ||
} | ||
// Draw final row | ||
if (model.selection.viewportCappedStartRow !== model.selection.viewportCappedEndRow) { | ||
// Only draw viewportEndRow if it's not the same as viewportStartRow | ||
const endCol = model.selection.viewportEndRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols; | ||
this._updateSelectionRange(0, endCol, model.selection.viewportCappedEndRow, model, bg); | ||
} | ||
} | ||
} | ||
private _updateSelectionRange(startCol: number, endCol: number, y: number, model: IRenderModel, bg: number): void { | ||
const terminal = this._terminal; | ||
const row = y + terminal.buffer.active.viewportY; | ||
let line: IBufferLine | undefined; | ||
for (let x = startCol; x < endCol; x++) { | ||
const offset = (y * this._terminal.cols + x) * RENDER_MODEL_INDICIES_PER_CELL; | ||
const code = model.cells[offset]; | ||
let fg = model.cells[offset + RENDER_MODEL_FG_OFFSET]; | ||
if (fg & FgFlags.INVERSE) { | ||
const workCell = new AttributeData(); | ||
workCell.fg = fg; | ||
workCell.bg = model.cells[offset + RENDER_MODEL_BG_OFFSET]; | ||
// Get attributes from fg (excluding inverse) and resolve inverse by pullibng rgb colors | ||
// from bg. This is needed since the inverse fg color should be based on the original bg | ||
// color, not on the selection color | ||
fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK | FgFlags.INVERSE); | ||
switch (workCell.getBgColorMode()) { | ||
case Attributes.CM_P16: | ||
case Attributes.CM_P256: | ||
const c = this._getColorFromAnsiIndex(workCell.getBgColor()).rgba; | ||
fg |= (c >> 8) & Attributes.RED_MASK | (c >> 8) & Attributes.GREEN_MASK | (c >> 8) & Attributes.BLUE_MASK; | ||
case Attributes.CM_RGB: | ||
const arr = AttributeData.toColorRGB(workCell.getBgColor()); | ||
fg |= arr[0] << Attributes.RED_SHIFT | arr[1] << Attributes.GREEN_SHIFT | arr[2] << Attributes.BLUE_SHIFT; | ||
case Attributes.CM_DEFAULT: | ||
default: | ||
const c2 = this._colors.background.rgba; | ||
fg |= (c2 >> 8) & Attributes.RED_MASK | (c2 >> 8) & Attributes.GREEN_MASK | (c2 >> 8) & Attributes.BLUE_MASK; | ||
} | ||
fg |= Attributes.CM_RGB; | ||
} | ||
if (code & COMBINED_CHAR_BIT_MASK) { | ||
if (!line) { | ||
line = terminal.buffer.active.getLine(row); | ||
} | ||
const chars = line!.getCell(x)!.getChars(); | ||
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg, chars); | ||
} else { | ||
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg); | ||
} | ||
} | ||
} | ||
private _getColorFromAnsiIndex(idx: number): IColor { | ||
if (idx >= this._colors.ansi.length) { | ||
throw new Error('No color found for idx ' + idx); | ||
} | ||
return this._colors.ansi[idx]; | ||
} | ||
public clear(force?: boolean): void { | ||
@@ -343,3 +252,3 @@ const terminal = this._terminal; | ||
public render(renderModel: IRenderModel, isSelectionVisible: boolean): void { | ||
public render(renderModel: IRenderModel): void { | ||
if (!this._atlas) { | ||
@@ -368,3 +277,3 @@ return; | ||
const si = y * this._terminal.cols * INDICES_PER_CELL; | ||
const sub = (isSelectionVisible ? this._vertices.selectionAttributes : this._vertices.attributes).subarray(si, si + renderModel.lineLengths[y] * INDICES_PER_CELL); | ||
const sub = this._vertices.attributes.subarray(si, si + renderModel.lineLengths[y] * INDICES_PER_CELL); | ||
activeBuffer.set(sub, bufferLength); | ||
@@ -371,0 +280,0 @@ bufferLength += sub.length; |
@@ -7,4 +7,3 @@ /** | ||
import { createProgram, expandFloat32Array, PROJECTION_MATRIX, throwIfFalsy } from './WebglUtils'; | ||
import { IRenderModel, IWebGLVertexArrayObject, IWebGL2RenderingContext, ISelectionRenderModel } from './Types'; | ||
import { fill } from 'common/TypedArrayUtils'; | ||
import { IRenderModel, IWebGLVertexArrayObject, IWebGL2RenderingContext } from './Types'; | ||
import { Attributes, FgFlags } from 'common/buffer/Constants'; | ||
@@ -54,3 +53,2 @@ import { Terminal } from 'xterm'; | ||
attributes: Float32Array; | ||
selection: Float32Array; | ||
count: number; | ||
@@ -72,8 +70,6 @@ } | ||
private _bgFloat!: Float32Array; | ||
private _selectionFloat!: Float32Array; | ||
private _vertices: IVertices = { | ||
count: 0, | ||
attributes: new Float32Array(INITIAL_BUFFER_RECTANGLE_CAPACITY), | ||
selection: new Float32Array(3 * INDICES_PER_RECTANGLE) | ||
attributes: new Float32Array(INITIAL_BUFFER_RECTANGLE_CAPACITY) | ||
}; | ||
@@ -144,7 +140,2 @@ | ||
gl.drawElementsInstanced(this._gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, this._vertices.count); | ||
// Bind selection buffer and draw | ||
gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer); | ||
gl.bufferData(gl.ARRAY_BUFFER, this._vertices.selection, gl.DYNAMIC_DRAW); | ||
gl.drawElementsInstanced(this._gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 3); | ||
} | ||
@@ -163,3 +154,2 @@ | ||
this._bgFloat = this._colorToFloat32Array(this._colors.background); | ||
this._selectionFloat = this._colorToFloat32Array(this._colors.selectionOpaque); | ||
} | ||
@@ -180,69 +170,2 @@ | ||
public updateSelection(model: ISelectionRenderModel): void { | ||
const terminal = this._terminal; | ||
if (!model.hasSelection) { | ||
fill(this._vertices.selection, 0, 0); | ||
return; | ||
} | ||
if (model.columnSelectMode) { | ||
const startCol = model.startCol; | ||
const width = model.endCol - startCol; | ||
const height = model.viewportCappedEndRow - model.viewportCappedStartRow + 1; | ||
this._addRectangleFloat( | ||
this._vertices.selection, | ||
0, | ||
startCol * this._dimensions.scaledCellWidth, | ||
model.viewportCappedStartRow * this._dimensions.scaledCellHeight, | ||
width * this._dimensions.scaledCellWidth, | ||
height * this._dimensions.scaledCellHeight, | ||
this._selectionFloat | ||
); | ||
fill(this._vertices.selection, 0, INDICES_PER_RECTANGLE); | ||
} else { | ||
// Draw first row | ||
const startCol = model.viewportStartRow === model.viewportCappedStartRow ? model.startCol : 0; | ||
const startRowEndCol = model.viewportCappedStartRow === model.viewportEndRow ? model.endCol : terminal.cols; | ||
this._addRectangleFloat( | ||
this._vertices.selection, | ||
0, | ||
startCol * this._dimensions.scaledCellWidth, | ||
model.viewportCappedStartRow * this._dimensions.scaledCellHeight, | ||
(startRowEndCol - startCol) * this._dimensions.scaledCellWidth, | ||
this._dimensions.scaledCellHeight, | ||
this._selectionFloat | ||
); | ||
// Draw middle rows | ||
const middleRowsCount = Math.max(model.viewportCappedEndRow - model.viewportCappedStartRow - 1, 0); | ||
this._addRectangleFloat( | ||
this._vertices.selection, | ||
INDICES_PER_RECTANGLE, | ||
0, | ||
(model.viewportCappedStartRow + 1) * this._dimensions.scaledCellHeight, | ||
terminal.cols * this._dimensions.scaledCellWidth, | ||
middleRowsCount * this._dimensions.scaledCellHeight, | ||
this._selectionFloat | ||
); | ||
// Draw final row | ||
if (model.viewportCappedStartRow !== model.viewportCappedEndRow) { | ||
// Only draw viewportEndRow if it's not the same as viewportStartRow | ||
const endCol = model.viewportEndRow === model.viewportCappedEndRow ? model.endCol : terminal.cols; | ||
this._addRectangleFloat( | ||
this._vertices.selection, | ||
INDICES_PER_RECTANGLE * 2, | ||
0, | ||
model.viewportCappedEndRow * this._dimensions.scaledCellHeight, | ||
endCol * this._dimensions.scaledCellWidth, | ||
this._dimensions.scaledCellHeight, | ||
this._selectionFloat | ||
); | ||
} else { | ||
fill(this._vertices.selection, 0, INDICES_PER_RECTANGLE * 2); | ||
} | ||
} | ||
} | ||
public updateBackgrounds(model: IRenderModel): void { | ||
@@ -249,0 +172,0 @@ const terminal = this._terminal; |
@@ -170,6 +170,2 @@ /** | ||
this._rectangleRenderer.onResize(); | ||
if (this._model.selection.hasSelection) { | ||
// Update selection as dimensions have changed | ||
this._rectangleRenderer.updateSelection(this._model.selection); | ||
} | ||
@@ -205,6 +201,4 @@ this._glyphRenderer.setDimensions(this.dimensions); | ||
} | ||
this._updateSelectionModel(start, end, columnSelectMode); | ||
this._onRequestRedraw.fire({ start: 0, end: this._terminal.rows - 1 }); | ||
this._requestRedrawViewport(); | ||
} | ||
@@ -251,3 +245,3 @@ | ||
this._updateModel(0, this._terminal.rows - 1); | ||
this._onRequestRedraw.fire({ start: 0, end: this._terminal.rows - 1 }); | ||
this._requestRedrawViewport(); | ||
} | ||
@@ -298,3 +292,3 @@ | ||
this._rectangleRenderer.render(); | ||
this._glyphRenderer.render(this._model, this._model.selection.hasSelection); | ||
this._glyphRenderer.render(this._model); | ||
} | ||
@@ -383,6 +377,2 @@ | ||
this._rectangleRenderer.updateBackgrounds(this._model); | ||
if (this._model.selection.hasSelection) { | ||
// Model could be updated but the selection is unchanged | ||
this._glyphRenderer.updateSelection(this._model); | ||
} | ||
} | ||
@@ -398,12 +388,18 @@ | ||
let bgOverride: number | undefined; | ||
let fgOverride: number | undefined; | ||
// Apply the selection color if needed | ||
if (this._isCellSelected(x, y)) { | ||
bgOverride = this._colors.selectionOpaque.rgba >> 8 & 0xFFFFFF; | ||
} | ||
// Get any decoration foreground/background overrides, this happens on the model to avoid | ||
// spreading decoration override logic throughout the different sub-renderers | ||
let bgOverride: number | undefined; | ||
let fgOverride: number | undefined; | ||
for (const d of this._decorationService.getDecorationsAtCell(x, y)) { | ||
if (d.backgroundColorRGB) { | ||
bgOverride = (d.backgroundColorRGB.rgba >> 8) >>> 0 & 0xFFFFFF; | ||
bgOverride = d.backgroundColorRGB.rgba >> 8 & 0xFFFFFF; | ||
} | ||
if (d.foregroundColorRGB) { | ||
fgOverride = (d.foregroundColorRGB.rgba >> 8) >>> 0 & 0xFFFFFF; | ||
fgOverride = d.foregroundColorRGB.rgba >> 8 & 0xFFFFFF; | ||
} | ||
@@ -449,2 +445,17 @@ } | ||
private _isCellSelected(x: number, y: number): boolean { | ||
if (!this._model.selection.hasSelection) { | ||
return false; | ||
} | ||
y -= this._terminal.buffer.active.viewportY; | ||
if (this._model.selection.columnSelectMode) { | ||
return x >= this._model.selection.startCol && y >= this._model.selection.viewportCappedStartRow && | ||
x < this._model.selection.endCol && y < this._model.selection.viewportCappedEndRow; | ||
} | ||
return (y > this._model.selection.viewportStartRow && y < this._model.selection.viewportEndRow) || | ||
(this._model.selection.viewportStartRow === this._model.selection.viewportEndRow && y === this._model.selection.viewportStartRow && x >= this._model.selection.startCol && x < this._model.selection.endCol) || | ||
(this._model.selection.viewportStartRow < this._model.selection.viewportEndRow && y === this._model.selection.viewportEndRow && x < this._model.selection.endCol) || | ||
(this._model.selection.viewportStartRow < this._model.selection.viewportEndRow && y === this._model.selection.viewportStartRow && x >= this._model.selection.startCol); | ||
} | ||
private _updateSelectionModel(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { | ||
@@ -456,3 +467,2 @@ const terminal = this._terminal; | ||
this._model.clearSelection(); | ||
this._rectangleRenderer.updateSelection(this._model.selection); | ||
return; | ||
@@ -470,3 +480,2 @@ } | ||
this._model.clearSelection(); | ||
this._rectangleRenderer.updateSelection(this._model.selection); | ||
return; | ||
@@ -483,4 +492,2 @@ } | ||
this._model.selection.endCol = end[0]; | ||
this._rectangleRenderer.updateSelection(this._model.selection); | ||
} | ||
@@ -559,2 +566,6 @@ | ||
} | ||
private _requestRedrawViewport(): void { | ||
this._onRequestRedraw.fire({ start: 0, end: this._terminal.rows - 1 }); | ||
} | ||
} | ||
@@ -561,0 +572,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
471253
3020