From 3773b22439b6630aac5c838a225e93cae91b7694 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 9 Nov 2019 23:41:00 -0800 Subject: [PATCH] Support true color... mostly --- .../src/RectangleRenderer.ts | 22 +++++++++------ .../src/atlas/WebglCharAtlas.ts | 27 ++++++++++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/addons/xterm-addon-webgl/src/RectangleRenderer.ts b/addons/xterm-addon-webgl/src/RectangleRenderer.ts index 0a0880343..4e7118462 100644 --- a/addons/xterm-addon-webgl/src/RectangleRenderer.ts +++ b/addons/xterm-addon-webgl/src/RectangleRenderer.ts @@ -11,6 +11,7 @@ import { Terminal } from 'xterm'; import { IColorSet, IColor } from 'browser/Types'; import { IRenderDimensions } from 'browser/renderer/Types'; import { RENDER_MODEL_BG_OFFSET, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_INDICIES_PER_CELL } from './RenderModel'; +import { AttributeData } from 'common/buffer/AttributeData'; const enum VertexAttribLocations { POSITION = 0, @@ -274,26 +275,31 @@ export class RectangleRenderer { } private _updateRectangle(vertices: IVertices, offset: number, fg: number, bg: number, startX: number, endX: number, y: number): void { - let color: IColor | null = null; + let rgba: number | undefined; + const colorMode = bg & Attributes.CM_MASK; if (fg & FgFlags.INVERSE) { // Inverted color - color = this._colors.foreground; + rgba = this._colors.foreground.rgba; } 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]; + rgba = this._colors.ansi[bg & Attributes.PCOLOR_MASK].rgba; + } else if (colorMode === Attributes.CM_RGB) { + // True color + // TODO: Use a switch instead? + rgba = (bg & Attributes.RGB_MASK) << 8; } else { - // TODO: Support true color // Default color - color = this._colors.background; + rgba = this._colors.background.rgba; } if (vertices.attributes.length < offset + 4) { vertices.attributes = expandFloat32Array(vertices.attributes, this._terminal.rows * this._terminal.cols * INDICES_PER_RECTANGLE); } const x1 = startX * this._dimensions.scaledCellWidth; const y1 = y * this._dimensions.scaledCellHeight; - const r = ((color.rgba >> 24) & 0xFF) / 255; - const g = ((color.rgba >> 16) & 0xFF) / 255; - const b = ((color.rgba >> 8 ) & 0xFF) / 255; + const r = ((rgba >> 24) & 0xFF) / 255; + const g = ((rgba >> 16) & 0xFF) / 255; + const b = ((rgba >> 8 ) & 0xFF) / 255; + console.log(r, g, b); this._addRectangle(vertices.attributes, offset, x1, y1, (endX - startX) * this._dimensions.scaledCellWidth, this._dimensions.scaledCellHeight, r, g, b, 1); } diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index b9c4a827d..00b249885 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -11,6 +11,7 @@ import { is256Color } from './CharAtlasUtils'; import { throwIfFalsy } from '../WebglUtils'; import { IColor } from 'browser/Types'; import { IDisposable } from 'xterm'; +import { AttributeData } from 'common/buffer/AttributeData'; // In practice we're probably never going to exhaust a texture this large. For debugging purposes, // however, it can be useful to set this to a really tiny value, to verify that LRU eviction works. @@ -186,18 +187,33 @@ export class WebglCharAtlas implements IDisposable { return this._config.colors.foreground; } else if (is256Color(bg)) { return this._getColorFromAnsiIndex(bg & Attributes.PCOLOR_MASK); + } else if ((bg & Attributes.CM_MASK) === Attributes.CM_RGB) { + // TODO: Use a switch for the color mode? + // True color + const rgb = bg & Attributes.RGB_MASK; + const arr = AttributeData.toColorRGB(rgb); + // TODO: This object creation is slow + return { + rgba: rgb << 255, + css: `#${toPaddedHex(arr[0])}${toPaddedHex(arr[1])}${toPaddedHex(arr[2])}` + }; } - // TODO: Support true color return this._config.colors.background; } - private _getForegroundColor(fg: number): IColor { + private _getForegroundColor(fg: number): { css: string } { + // TODO: Just return the string value if (fg & FgFlags.INVERSE) { return this._config.colors.background; } else if (is256Color(fg)) { return this._getColorFromAnsiIndex(fg & Attributes.PCOLOR_MASK); + } else if ((fg & Attributes.CM_MASK) === Attributes.CM_RGB) { + // TODO: Use a switch for the color mode? + // TODO: True color + const rgb = fg & Attributes.RGB_MASK; + const arr = AttributeData.toColorRGB(rgb); + return { css: `#${toPaddedHex(arr[0])}${toPaddedHex(arr[1])}${toPaddedHex(arr[2])}` }; } - // TODO: Support true color return this._config.colors.foreground; } @@ -411,3 +427,8 @@ function clearColor(imageData: ImageData, color: IColor): boolean { } return isEmpty; } + +function toPaddedHex(c: number): string { + const s = c.toString(16); + return s.length < 2 ? '0' + s : s; +}