diff --git a/addons/xterm-addon-webgl/src/GlyphRenderer.ts b/addons/xterm-addon-webgl/src/GlyphRenderer.ts index ba6333aa2e..9e60a7fca1 100644 --- a/addons/xterm-addon-webgl/src/GlyphRenderer.ts +++ b/addons/xterm-addon-webgl/src/GlyphRenderer.ts @@ -169,11 +169,11 @@ export class GlyphRenderer extends Disposable { return this._atlas ? this._atlas.beginFrame() : true; } - public updateCell(x: number, y: number, code: number, bg: number, fg: number, chars: string): void { - this._updateCell(this._vertices.attributes, x, y, code, bg, fg, chars); + public updateCell(x: number, y: number, code: number, bg: number, fg: number, chars: string, lastBg: number): void { + this._updateCell(this._vertices.attributes, x, y, code, bg, fg, chars, lastBg); } - private _updateCell(array: Float32Array, x: number, y: number, code: number | undefined, bg: number, fg: number, chars?: string): void { + private _updateCell(array: Float32Array, x: number, y: number, code: number | undefined, bg: number, fg: number, chars: string, lastBg: number): void { const terminal = this._terminal; const i = (y * terminal.cols + x) * INDICES_PER_CELL; @@ -203,18 +203,34 @@ export class GlyphRenderer extends Disposable { return; } - // a_origin - array[i ] = -rasterizedGlyph.offset.x + this._dimensions.scaledCharLeft; - array[i + 1] = -rasterizedGlyph.offset.y + this._dimensions.scaledCharTop; - // a_size - array[i + 2] = rasterizedGlyph.size.x / this._dimensions.scaledCanvasWidth; - array[i + 3] = rasterizedGlyph.size.y / this._dimensions.scaledCanvasHeight; - // a_texcoord - array[i + 4] = rasterizedGlyph.texturePositionClipSpace.x; - array[i + 5] = rasterizedGlyph.texturePositionClipSpace.y; - // a_texsize - array[i + 6] = rasterizedGlyph.sizeClipSpace.x; - array[i + 7] = rasterizedGlyph.sizeClipSpace.y; + if (bg !== lastBg && rasterizedGlyph.offset.x > 0) { + const clippedPixels = rasterizedGlyph.offset.x; + // a_origin + array[i ] = this._dimensions.scaledCharLeft; + array[i + 1] = -rasterizedGlyph.offset.y + this._dimensions.scaledCharTop; + // a_size + array[i + 2] = (rasterizedGlyph.size.x - clippedPixels) / this._dimensions.scaledCanvasWidth; + array[i + 3] = rasterizedGlyph.size.y / this._dimensions.scaledCanvasHeight; + // a_texcoord + array[i + 4] = rasterizedGlyph.texturePositionClipSpace.x + clippedPixels / this._atlas.cacheCanvas.width; + array[i + 5] = rasterizedGlyph.texturePositionClipSpace.y; + // a_texsize + array[i + 6] = rasterizedGlyph.sizeClipSpace.x - clippedPixels / this._atlas.cacheCanvas.width; + array[i + 7] = rasterizedGlyph.sizeClipSpace.y; + } else { + // a_origin + array[i ] = -rasterizedGlyph.offset.x + this._dimensions.scaledCharLeft; + array[i + 1] = -rasterizedGlyph.offset.y + this._dimensions.scaledCharTop; + // a_size + array[i + 2] = rasterizedGlyph.size.x / this._dimensions.scaledCanvasWidth; + array[i + 3] = rasterizedGlyph.size.y / this._dimensions.scaledCanvasHeight; + // a_texcoord + array[i + 4] = rasterizedGlyph.texturePositionClipSpace.x; + array[i + 5] = rasterizedGlyph.texturePositionClipSpace.y; + // a_texsize + array[i + 6] = rasterizedGlyph.sizeClipSpace.x; + array[i + 7] = rasterizedGlyph.sizeClipSpace.y; + } // a_cellpos only changes on resize } diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index b971f609af..1e385b3399 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -291,6 +291,7 @@ export class WebglRenderer extends Disposable implements IRenderer { private _updateModel(start: number, end: number): void { const terminal = this._core; let cell: ICellData = this._workCell; + let lastBg: number = 0; for (let y = start; y <= end; y++) { const row = y + terminal.buffer.ydisp; @@ -298,8 +299,13 @@ export class WebglRenderer extends Disposable implements IRenderer { this._model.lineLengths[y] = 0; const joinedRanges = this._characterJoinerService.getJoinedCharacters(row); for (let x = 0; x < terminal.cols; x++) { + lastBg = this._workColors.bg; line.loadCell(x, cell); + if (x === 0) { + lastBg = this._workColors.bg; + } + // If true, indicates that the current character(s) to draw were joined. let isJoined = false; let lastCharX = x; @@ -351,7 +357,7 @@ export class WebglRenderer extends Disposable implements IRenderer { this._model.cells[i + RENDER_MODEL_BG_OFFSET] = this._workColors.bg; this._model.cells[i + RENDER_MODEL_FG_OFFSET] = this._workColors.fg; - this._glyphRenderer.updateCell(x, y, code, this._workColors.bg, this._workColors.fg, chars); + this._glyphRenderer.updateCell(x, y, code, this._workColors.bg, this._workColors.fg, chars, lastBg); if (isJoined) { // Restore work cell @@ -360,7 +366,7 @@ export class WebglRenderer extends Disposable implements IRenderer { // Null out non-first cells for (x++; x < lastCharX; x++) { const j = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL; - this._glyphRenderer.updateCell(x, y, NULL_CELL_CODE, 0, 0, NULL_CELL_CHAR); + this._glyphRenderer.updateCell(x, y, NULL_CELL_CODE, 0, 0, NULL_CELL_CHAR, 0); this._model.cells[j] = NULL_CELL_CODE; this._model.cells[j + RENDER_MODEL_BG_OFFSET] = this._workColors.bg; this._model.cells[j + RENDER_MODEL_FG_OFFSET] = this._workColors.fg;