From e72ee3c58dc87ccfaffd103eff24439e1554ce96 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 9 Nov 2019 22:28:59 -0800 Subject: [PATCH] Move webgl drawing over from compat Still need to tackle glyph key --- .../src/RectangleRenderer.ts | 25 ++++++++++++------- addons/xterm-addon-webgl/src/WebglRenderer.ts | 22 +++++++--------- .../src/atlas/CharAtlasUtils.ts | 4 +-- .../src/atlas/WebglCharAtlas.ts | 14 +++++------ 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/addons/xterm-addon-webgl/src/RectangleRenderer.ts b/addons/xterm-addon-webgl/src/RectangleRenderer.ts index 2c464d2ae..70b5ee3c1 100644 --- a/addons/xterm-addon-webgl/src/RectangleRenderer.ts +++ b/addons/xterm-addon-webgl/src/RectangleRenderer.ts @@ -8,7 +8,7 @@ import { IRenderModel, IWebGLVertexArrayObject, IWebGL2RenderingContext, ISelect import { fill } from 'common/TypedArrayUtils'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { is256Color } from './atlas/CharAtlasUtils'; -import { DEFAULT_COLOR } from 'common/buffer/Constants'; +import { DEFAULT_COLOR, Attributes, FgFlags } from 'common/buffer/Constants'; import { Terminal } from 'xterm'; import { IColorSet, IColor } from 'browser/Types'; import { IRenderDimensions } from 'browser/renderer/Types'; @@ -248,37 +248,44 @@ export class RectangleRenderer { for (let y = 0; y < terminal.rows; y++) { let currentStartX = -1; let currentBg = DEFAULT_COLOR; + let currentFg = DEFAULT_COLOR; for (let x = 0; x < terminal.cols; x++) { const modelIndex = ((y * terminal.cols) + x) * 4; const bg = model.cells[modelIndex + 2]; + const fg = model.cells[modelIndex + 1]; if (bg !== currentBg) { // A rectangle needs to be drawn if going from non-default to another color + // TODO: DEFAULT_COLOR probably isn't right anymore? if (currentBg !== DEFAULT_COLOR) { const offset = rectangleCount++ * INDICES_PER_RECTANGLE; - this._updateRectangle(vertices, offset, currentBg, currentStartX, x, y); + this._updateRectangle(vertices, offset, currentFg, currentBg, currentStartX, x, y); } currentStartX = x; currentBg = bg; + currentFg = fg; } } // Finish rectangle if it's still going if (currentBg !== DEFAULT_COLOR) { const offset = rectangleCount++ * INDICES_PER_RECTANGLE; - this._updateRectangle(vertices, offset, currentBg, currentStartX, terminal.cols, y); + this._updateRectangle(vertices, offset, currentFg, currentBg, currentStartX, terminal.cols, y); } } vertices.count = rectangleCount; } - private _updateRectangle(vertices: IVertices, offset: number, bg: number, startX: number, endX: number, y: number): void { + private _updateRectangle(vertices: IVertices, offset: number, fg: number, bg: number, startX: number, endX: number, y: number): void { let color: IColor | null = null; - if (bg === INVERTED_DEFAULT_COLOR) { + if (fg & FgFlags.INVERSE) { + // Inverted color color = this._colors.foreground; - } else if (is256Color(bg)) { - color = this._colors.ansi[bg]; + } else if ((bg & Attributes.CM_MASK) === Attributes.CM_P16 || (bg & Attributes.CM_MASK) === Attributes.CM_P256) { + // 256 palette + color = this._colors.ansi[bg & Attributes.PCOLOR_MASK]; } else { - // TODO: Add support for true color - color = this._colors.foreground; + // TODO: Support true color + // Default color + color = this._colors.background; } if (vertices.attributes.length < offset + 4) { vertices.attributes = expandFloat32Array(vertices.attributes, this._terminal.rows * this._terminal.cols * INDICES_PER_RECTANGLE); diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 785f6e69f..ef20f6143 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -14,7 +14,7 @@ import { IWebGL2RenderingContext } from './Types'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { RenderModel, COMBINED_CHAR_BIT_MASK } from './RenderModel'; import { Disposable } from 'common/Lifecycle'; -import { DEFAULT_COLOR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_CODE_INDEX, NULL_CELL_CODE } from 'common/buffer/Constants'; +import { DEFAULT_COLOR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, FgFlags } from 'common/buffer/Constants'; import { Terminal, IEvent } from 'xterm'; import { getLuminance } from './ColorUtils'; import { IRenderLayer } from './renderLayer/Types'; @@ -262,17 +262,11 @@ export class WebglRenderer extends Disposable implements IRenderer { for (let x = 0; x < terminal.cols; x++) { line.loadCell(x, this._workCell); - // const charData = line.get(x); - // const chars = charData[CHAR_DATA_CHAR_INDEX]; const chars = this._workCell.getChars(); - // let code = charData[CHAR_DATA_CODE_INDEX]; let code = this._workCell.getCode(); const attr = getCompatAttr(line, x); // charData[CHAR_DATA_ATTR_INDEX]; const i = ((y * terminal.cols) + x) * INDICIES_PER_CELL; - // console.log('workcell', this._workCell); - // console.log('attr: ' + attr); - if (code !== NULL_CELL_CODE) { this._model.lineLengths[y] = x + 1; } @@ -283,12 +277,11 @@ export class WebglRenderer extends Disposable implements IRenderer { } // Resolve bg and fg and cache in the model - const flags = attr >> 18; - let bg = attr & 0x1ff; - let fg = (attr >> 9) & 0x1ff; + let bg = this._workCell.bg; + let fg = this._workCell.fg; // If inverse flag is on, the foreground should become the background. - if (flags & FLAGS.INVERSE) { + if (this._workCell.isInverse()) { const temp = bg; bg = fg; fg = temp; @@ -299,8 +292,11 @@ export class WebglRenderer extends Disposable implements IRenderer { bg = INVERTED_DEFAULT_COLOR; } } - const drawInBrightColor = terminal.options.drawBoldTextInBrightColors && !!(flags & FLAGS.BOLD) && fg < 8 && fg !== INVERTED_DEFAULT_COLOR; - fg += drawInBrightColor ? 8 : 0; + + // Apply drawBoldTextInBrightColors + if (terminal.options.drawBoldTextInBrightColors && this._workCell.isBold() && fg & FgFlags.BOLD && this._workCell.getFgColor() < 8) { + fg += 8; + } // Flag combined chars with a bit mask so they're easily identifiable if (chars.length > 1) { diff --git a/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts b/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts index 857fa6287..821b53a48 100644 --- a/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts +++ b/addons/xterm-addon-webgl/src/atlas/CharAtlasUtils.ts @@ -4,7 +4,7 @@ */ import { ICharAtlasConfig } from './Types'; -import { DEFAULT_COLOR } from 'common/buffer/Constants'; +import { DEFAULT_COLOR, Attributes } from 'common/buffer/Constants'; import { Terminal, FontWeight } from 'xterm'; import { IColorSet, IColor } from 'browser/Types'; @@ -57,5 +57,5 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean } export function is256Color(colorCode: number): boolean { - return colorCode < DEFAULT_COLOR; + return (colorCode & Attributes.CM_MASK) === Attributes.CM_P16 || (colorCode & Attributes.CM_MASK) === Attributes.CM_P256; } diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 8d8e995bf..14cd017d6 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -6,7 +6,7 @@ import { ICharAtlasConfig } from './Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { IRasterizedGlyph, IBoundingBox, IRasterizedGlyphSet } from '../Types'; -import { DEFAULT_COLOR, DEFAULT_ATTR } from 'common/buffer/Constants'; +import { DEFAULT_COLOR, DEFAULT_ATTR, FgFlags, Attributes } from 'common/buffer/Constants'; import { is256Color } from './CharAtlasUtils'; import { throwIfFalsy } from '../WebglUtils'; import { IColor } from 'browser/Types'; @@ -161,26 +161,26 @@ export class WebglCharAtlas implements IDisposable { return this._config.colors.ansi[idx]; } - private _getBackgroundColor(bg: number): IColor { + private _getBackgroundColor(bg: number, fg: number): IColor { if (this._config.allowTransparency) { // The background color might have some transparency, so we need to render it as fully // transparent in the atlas. Otherwise we'd end up drawing the transparent background twice // around the anti-aliased edges of the glyph, and it would look too dark. return TRANSPARENT_COLOR; - } else if (bg === INVERTED_DEFAULT_COLOR) { + } else if (fg & FgFlags.INVERSE) { return this._config.colors.foreground; } else if (is256Color(bg)) { - return this._getColorFromAnsiIndex(bg); + return this._getColorFromAnsiIndex(bg & Attributes.PCOLOR_MASK); } // TODO: Support true color return this._config.colors.background; } private _getForegroundColor(fg: number): IColor { - if (fg === INVERTED_DEFAULT_COLOR) { + if (fg & FgFlags.INVERSE) { return this._config.colors.background; } else if (is256Color(fg)) { - return this._getColorFromAnsiIndex(fg); + return this._getColorFromAnsiIndex(fg & Attributes.PCOLOR_MASK); } // TODO: Support true color return this._config.colors.foreground; @@ -202,7 +202,7 @@ export class WebglCharAtlas implements IDisposable { this._tmpCtx.save(); // draw the background - const backgroundColor = this._getBackgroundColor(bg); + const backgroundColor = this._getBackgroundColor(bg, fg); // Use a 'copy' composite operation to clear any existing glyph out of _tmpCtxWithAlpha, regardless of // transparency in backgroundColor this._tmpCtx.globalCompositeOperation = 'copy';