From 791c020a563b2acbd99e0c6f03f12273179f73c1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 9 Oct 2018 11:03:31 -0700 Subject: [PATCH 1/6] Allow inverse colors to be stored in glyph keys Fixes #1737 --- src/renderer/atlas/StaticCharAtlas.ts | 4 ++-- src/renderer/atlas/Types.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/atlas/StaticCharAtlas.ts b/src/renderer/atlas/StaticCharAtlas.ts index c0d8a814..5c56f019 100644 --- a/src/renderer/atlas/StaticCharAtlas.ts +++ b/src/renderer/atlas/StaticCharAtlas.ts @@ -41,7 +41,7 @@ export default class StaticCharAtlas extends BaseCharAtlas { const isAscii = glyph.code < 256; // A color is basic if it is one of the 4 bit ANSI colors. const isBasicColor = glyph.fg < 16; - const isDefaultColor = glyph.fg >= 256; + const isDefaultColor = glyph.fg === 256; const isDefaultBackground = glyph.bg >= 256; return isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !glyph.italic; } @@ -60,7 +60,7 @@ export default class StaticCharAtlas extends BaseCharAtlas { let colorIndex = 0; if (glyph.fg < 256) { colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0); - } else { + } else if (glyph.fg === 256) { // If default color and bold if (glyph.bold) { colorIndex = 1; diff --git a/src/renderer/atlas/Types.ts b/src/renderer/atlas/Types.ts index 6fb3c5d1..614a6e92 100644 --- a/src/renderer/atlas/Types.ts +++ b/src/renderer/atlas/Types.ts @@ -3,7 +3,7 @@ * @license MIT */ -export const INVERTED_DEFAULT_COLOR = -1; +export const INVERTED_DEFAULT_COLOR = 258; export const DIM_OPACITY = 0.5; export interface IGlyphIdentifier { From 1e9564788ef286ee50fc59261d80b72474d80b7a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 9 Oct 2018 11:12:35 -0700 Subject: [PATCH 2/6] Use constants for default colors --- src/Buffer.ts | 3 ++- src/renderer/BaseRenderLayer.ts | 4 ++-- src/renderer/LinkRenderLayer.ts | 4 ++-- src/renderer/TextRenderLayer.ts | 10 +++++----- src/renderer/atlas/DynamicCharAtlas.ts | 2 +- src/renderer/atlas/StaticCharAtlas.ts | 10 +++++----- src/renderer/atlas/Types.ts | 3 ++- src/renderer/dom/DomRendererRowFactory.test.ts | 11 ++++++----- src/renderer/dom/DomRendererRowFactory.ts | 9 +++++---- 9 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index e54f752b..7b5ee99a 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -8,8 +8,9 @@ import { CharData, ITerminal, IBuffer, IBufferLine, BufferIndex, IBufferStringIt import { EventEmitter } from './common/EventEmitter'; import { IMarker } from 'xterm'; import { BufferLine, BufferLineTypedArray } from './BufferLine'; +import { DEFAULT_COLOR } from './renderer/atlas/Types'; -export const DEFAULT_ATTR = (0 << 18) | (257 << 9) | (256 << 0); +export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); export const CHAR_DATA_ATTR_INDEX = 0; export const CHAR_DATA_CHAR_INDEX = 1; export const CHAR_DATA_WIDTH_INDEX = 2; diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 84e290e7..827356af 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -5,7 +5,7 @@ import { IRenderLayer, IColorSet, IRenderDimensions } from './Types'; import { CharData, ITerminal } from '../Types'; -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/Types'; +import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier, DEFAULT_COLOR } from './atlas/Types'; import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { CHAR_DATA_CHAR_INDEX } from '../Buffer'; @@ -298,7 +298,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { if (fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (fg < 256) { + } else if (fg < DEFAULT_COLOR) { // 256 color support this._ctx.fillStyle = this._colors.ansi[fg].css; } else { diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index 8679939a..c0d190ac 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -6,7 +6,7 @@ import { ILinkHoverEvent, ITerminal, ILinkifierAccessor, LinkHoverEventTypes } from '../Types'; import { IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { INVERTED_DEFAULT_COLOR } from './atlas/Types'; +import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkHoverEvent = null; @@ -42,7 +42,7 @@ export class LinkRenderLayer extends BaseRenderLayer { private _onLinkHover(e: ILinkHoverEvent): void { if (e.fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (e.fg < 256) { + } else if (e.fg < DEFAULT_COLOR) { // 256 color support this._ctx.fillStyle = this._colors.ansi[e.fg].css; } else { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 7f10e7c9..984272f6 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -6,7 +6,7 @@ import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, NULL_CELL_CODE } from '../Buffer'; import { FLAGS, IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types'; import { CharData, ITerminal } from '../Types'; -import { INVERTED_DEFAULT_COLOR } from './atlas/Types'; +import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; @@ -143,10 +143,10 @@ export class TextRenderLayer extends BaseRenderLayer { const temp = bg; bg = fg; fg = temp; - if (fg === 256) { + if (fg === DEFAULT_COLOR) { fg = INVERTED_DEFAULT_COLOR; } - if (bg === 257) { + if (bg === DEFAULT_COLOR) { bg = INVERTED_DEFAULT_COLOR; } } @@ -186,7 +186,7 @@ export class TextRenderLayer extends BaseRenderLayer { let nextFillStyle = null; // null represents default background color if (bg === INVERTED_DEFAULT_COLOR) { nextFillStyle = this._colors.foreground.css; - } else if (bg < 256) { + } else if (bg < DEFAULT_COLOR) { nextFillStyle = this._colors.ansi[bg].css; } @@ -230,7 +230,7 @@ export class TextRenderLayer extends BaseRenderLayer { this._ctx.save(); if (fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (fg < 256) { + } else if (fg < DEFAULT_COLOR) { // 256 color support this._ctx.fillStyle = this._colors.ansi[fg].css; } else { diff --git a/src/renderer/atlas/DynamicCharAtlas.ts b/src/renderer/atlas/DynamicCharAtlas.ts index e67fe4f0..950fdd1d 100644 --- a/src/renderer/atlas/DynamicCharAtlas.ts +++ b/src/renderer/atlas/DynamicCharAtlas.ts @@ -42,7 +42,7 @@ interface IGlyphCacheValue { inBitmap: boolean; } -function getGlyphCacheKey(glyph: IGlyphIdentifier): number { +export function getGlyphCacheKey(glyph: IGlyphIdentifier): number { // Note that this only returns a valid key when code < 256 // Layout: // 0b00000000000000000000000000000001: italic (1) diff --git a/src/renderer/atlas/StaticCharAtlas.ts b/src/renderer/atlas/StaticCharAtlas.ts index 5c56f019..673a1509 100644 --- a/src/renderer/atlas/StaticCharAtlas.ts +++ b/src/renderer/atlas/StaticCharAtlas.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { DIM_OPACITY, IGlyphIdentifier } from './Types'; +import { DIM_OPACITY, IGlyphIdentifier, DEFAULT_COLOR } from './Types'; import { CHAR_ATLAS_CELL_SPACING, ICharAtlasConfig } from '../../shared/atlas/Types'; import { generateStaticCharAtlasTexture } from '../../shared/atlas/CharAtlasGenerator'; import BaseCharAtlas from './BaseCharAtlas'; @@ -41,8 +41,8 @@ export default class StaticCharAtlas extends BaseCharAtlas { const isAscii = glyph.code < 256; // A color is basic if it is one of the 4 bit ANSI colors. const isBasicColor = glyph.fg < 16; - const isDefaultColor = glyph.fg === 256; - const isDefaultBackground = glyph.bg >= 256; + const isDefaultColor = glyph.fg === DEFAULT_COLOR; + const isDefaultBackground = glyph.bg === DEFAULT_COLOR; return isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !glyph.italic; } @@ -58,9 +58,9 @@ export default class StaticCharAtlas extends BaseCharAtlas { } let colorIndex = 0; - if (glyph.fg < 256) { + if (glyph.fg < DEFAULT_COLOR) { colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0); - } else if (glyph.fg === 256) { + } else if (glyph.fg === DEFAULT_COLOR) { // If default color and bold if (glyph.bold) { colorIndex = 1; diff --git a/src/renderer/atlas/Types.ts b/src/renderer/atlas/Types.ts index 614a6e92..76cfd07d 100644 --- a/src/renderer/atlas/Types.ts +++ b/src/renderer/atlas/Types.ts @@ -3,7 +3,8 @@ * @license MIT */ -export const INVERTED_DEFAULT_COLOR = 258; +export const DEFAULT_COLOR = 256; +export const INVERTED_DEFAULT_COLOR = 257; export const DIM_OPACITY = 0.5; export interface IGlyphIdentifier { diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index 2c46d8cc..a19865cd 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -10,6 +10,7 @@ import { DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '. import { FLAGS } from '../Types'; import { BufferLine } from '../../BufferLine'; import { IBufferLine } from '../../Types'; +import { DEFAULT_COLOR } from '../atlas/Types'; describe('DomRendererRowFactory', () => { let dom: jsdom.JSDOM; @@ -80,7 +81,7 @@ describe('DomRendererRowFactory', () => { }); it('should add classes for 256 foreground colors', () => { - const defaultAttrNoFgColor = (0 << 9) | (256 << 0); + const defaultAttrNoFgColor = (0 << 9) | (DEFAULT_COLOR << 0); for (let i = 0; i < 256; i++) { lineData.set(0, [defaultAttrNoFgColor | (i << 9), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); @@ -92,7 +93,7 @@ describe('DomRendererRowFactory', () => { }); it('should add classes for 256 background colors', () => { - const defaultAttrNoBgColor = (257 << 9) | (0 << 0); + const defaultAttrNoBgColor = (DEFAULT_ATTR << 9) | (0 << 0); for (let i = 0; i < 256; i++) { lineData.set(0, [defaultAttrNoBgColor | (i << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); @@ -113,7 +114,7 @@ describe('DomRendererRowFactory', () => { }); it('should correctly invert default fg color', () => { - lineData.set(0, [(FLAGS.INVERSE << 18) | (257 << 9) | (1 << 0), 'a', 1, 'a'.charCodeAt(0)]); + lineData.set(0, [(FLAGS.INVERSE << 18) | (DEFAULT_ATTR << 9) | (1 << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); assert.equal(getFragmentHtml(fragment), 'a' + @@ -122,7 +123,7 @@ describe('DomRendererRowFactory', () => { }); it('should correctly invert default bg color', () => { - lineData.set(0, [(FLAGS.INVERSE << 18) | (1 << 9) | (256 << 0), 'a', 1, 'a'.charCodeAt(0)]); + lineData.set(0, [(FLAGS.INVERSE << 18) | (1 << 9) | (DEFAULT_COLOR << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); assert.equal(getFragmentHtml(fragment), 'a' + @@ -132,7 +133,7 @@ describe('DomRendererRowFactory', () => { it('should turn bold fg text bright', () => { for (let i = 0; i < 8; i++) { - lineData.set(0, [(FLAGS.BOLD << 18) | (i << 9) | (256 << 0), 'a', 1, 'a'.charCodeAt(0)]); + lineData.set(0, [(FLAGS.BOLD << 18) | (i << 9) | (DEFAULT_COLOR << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); assert.equal(getFragmentHtml(fragment), `a` + diff --git a/src/renderer/dom/DomRendererRowFactory.ts b/src/renderer/dom/DomRendererRowFactory.ts index 4bb59902..877f3fdd 100644 --- a/src/renderer/dom/DomRendererRowFactory.ts +++ b/src/renderer/dom/DomRendererRowFactory.ts @@ -6,6 +6,7 @@ import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../../Buffer'; import { FLAGS } from '../Types'; import { IBufferLine } from '../../Types'; +import { DEFAULT_COLOR } from '../atlas/Types'; export const BOLD_CLASS = 'xterm-bold'; export const ITALIC_CLASS = 'xterm-italic'; @@ -70,10 +71,10 @@ export class DomRendererRowFactory { const temp = bg; bg = fg; fg = temp; - if (fg === 256) { + if (fg === DEFAULT_COLOR) { fg = 0; } - if (bg === 257) { + if (bg === DEFAULT_COLOR) { bg = 15; } } @@ -91,10 +92,10 @@ export class DomRendererRowFactory { } charElement.textContent = char; - if (fg !== 257) { + if (fg < DEFAULT_COLOR) { charElement.classList.add(`xterm-fg-${fg}`); } - if (bg !== 256) { + if (bg < DEFAULT_COLOR) { charElement.classList.add(`xterm-bg-${bg}`); } fragment.appendChild(charElement); From bc16a8b7e747107807d189327f87efd4eaebbee9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 9 Oct 2018 11:35:48 -0700 Subject: [PATCH 3/6] Handle inverted default colors properly in DOM renderer This uses the actual fg for bg and bg to fg, rather than the black/white theme colors Fixes #1738 --- src/renderer/dom/DomRenderer.ts | 4 ++++ src/renderer/dom/DomRendererRowFactory.ts | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/renderer/dom/DomRenderer.ts b/src/renderer/dom/DomRenderer.ts index 8f51c4ef..069e9a13 100644 --- a/src/renderer/dom/DomRenderer.ts +++ b/src/renderer/dom/DomRenderer.ts @@ -10,6 +10,7 @@ import { EventEmitter } from '../../common/EventEmitter'; import { ColorManager } from '../ColorManager'; import { RenderDebouncer } from '../../ui/RenderDebouncer'; import { BOLD_CLASS, ITALIC_CLASS, CURSOR_CLASS, CURSOR_STYLE_BLOCK_CLASS, CURSOR_STYLE_BAR_CLASS, CURSOR_STYLE_UNDERLINE_CLASS, DomRendererRowFactory } from './DomRendererRowFactory'; +import { INVERTED_DEFAULT_COLOR } from '../atlas/Types'; const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-'; const ROW_CONTAINER_CLASS = 'xterm-rows'; @@ -196,6 +197,9 @@ export class DomRenderer extends EventEmitter implements IRenderer { `${this._terminalSelector} .${FG_CLASS_PREFIX}${i} { color: ${c.css}; }` + `${this._terminalSelector} .${BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`; }); + styles += + `${this._terminalSelector} .${FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${this.colorManager.colors.background.css}; }` + + `${this._terminalSelector} .${BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${this.colorManager.colors.foreground.css}; }`; this._themeStyleElement.innerHTML = styles; return this.colorManager.colors; diff --git a/src/renderer/dom/DomRendererRowFactory.ts b/src/renderer/dom/DomRendererRowFactory.ts index 877f3fdd..9f8ac357 100644 --- a/src/renderer/dom/DomRendererRowFactory.ts +++ b/src/renderer/dom/DomRendererRowFactory.ts @@ -6,7 +6,7 @@ import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../../Buffer'; import { FLAGS } from '../Types'; import { IBufferLine } from '../../Types'; -import { DEFAULT_COLOR } from '../atlas/Types'; +import { DEFAULT_COLOR, INVERTED_DEFAULT_COLOR } from '../atlas/Types'; export const BOLD_CLASS = 'xterm-bold'; export const ITALIC_CLASS = 'xterm-italic'; @@ -72,15 +72,16 @@ export class DomRendererRowFactory { bg = fg; fg = temp; if (fg === DEFAULT_COLOR) { - fg = 0; + fg = INVERTED_DEFAULT_COLOR; } if (bg === DEFAULT_COLOR) { - bg = 15; + bg = INVERTED_DEFAULT_COLOR; } } if (flags & FLAGS.BOLD) { - // Convert the FG color to the bold variant + // Convert the FG color to the bold variant. This should not happen when + // the fg is the inverse default color as there is no bold variant. if (fg < 8) { fg += 8; } @@ -92,10 +93,10 @@ export class DomRendererRowFactory { } charElement.textContent = char; - if (fg < DEFAULT_COLOR) { + if (fg !== DEFAULT_COLOR) { charElement.classList.add(`xterm-fg-${fg}`); } - if (bg < DEFAULT_COLOR) { + if (bg !== DEFAULT_COLOR) { charElement.classList.add(`xterm-bg-${bg}`); } fragment.appendChild(charElement); From 18035e239eb93a92b73911514a429cc1122ff47f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 9 Oct 2018 11:56:00 -0700 Subject: [PATCH 4/6] Fix tests --- src/renderer/dom/DomRendererRowFactory.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index a19865cd..5bc849ed 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -117,7 +117,7 @@ describe('DomRendererRowFactory', () => { lineData.set(0, [(FLAGS.INVERSE << 18) | (DEFAULT_ATTR << 9) | (1 << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); assert.equal(getFragmentHtml(fragment), - 'a' + + 'a' + ' ' ); }); @@ -126,7 +126,7 @@ describe('DomRendererRowFactory', () => { lineData.set(0, [(FLAGS.INVERSE << 18) | (1 << 9) | (DEFAULT_COLOR << 0), 'a', 1, 'a'.charCodeAt(0)]); const fragment = rowFactory.createRow(lineData, false, undefined, 0, 5, 20); assert.equal(getFragmentHtml(fragment), - 'a' + + 'a' + ' ' ); }); From c7eb727220edc4a48423c49811296c953ca44f08 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Fri, 26 Oct 2018 00:07:13 -0500 Subject: [PATCH 5/6] Only show cross-hairs when terminal has focus Fixes #1767 --- src/Terminal.ts | 4 ++-- src/xterm.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index e8871462..4674f776 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1154,9 +1154,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II */ public updateCursorStyle(ev: KeyboardEvent): void { if (this.selectionManager && this.selectionManager.shouldColumnSelect(ev)) { - this.element.classList.add('xterm-cursor-crosshair'); + this.element.classList.add('column-select'); } else { - this.element.classList.remove('xterm-cursor-crosshair'); + this.element.classList.remove('column-select'); } } diff --git a/src/xterm.css b/src/xterm.css index 8e129f50..24cd475f 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -139,7 +139,7 @@ cursor: pointer; } -.xterm.xterm-cursor-crosshair { +.xterm.column-select.focus { /* Column selection mode */ cursor: crosshair; } From c6f1de797086949619981fa642de1ec677ff59e5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 24 Nov 2018 05:24:15 -0800 Subject: [PATCH 6/6] Introduce is256Color helper --- src/renderer/BaseRenderLayer.ts | 5 +++-- src/renderer/LinkRenderLayer.ts | 5 +++-- src/renderer/TextRenderLayer.ts | 5 +++-- src/renderer/atlas/CharAtlasUtils.ts | 5 +++++ src/renderer/atlas/StaticCharAtlas.ts | 3 ++- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 827356af..2afdebb5 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -5,10 +5,11 @@ import { IRenderLayer, IColorSet, IRenderDimensions } from './Types'; import { CharData, ITerminal } from '../Types'; -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier, DEFAULT_COLOR } from './atlas/Types'; +import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/Types'; import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { CHAR_DATA_CHAR_INDEX } from '../Buffer'; +import { is256Color } from './atlas/CharAtlasUtils'; export abstract class BaseRenderLayer implements IRenderLayer { private _canvas: HTMLCanvasElement; @@ -298,7 +299,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { if (fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (fg < DEFAULT_COLOR) { + } else if (is256Color(fg)) { // 256 color support this._ctx.fillStyle = this._colors.ansi[fg].css; } else { diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index c0d190ac..855830e4 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -6,7 +6,8 @@ import { ILinkHoverEvent, ITerminal, ILinkifierAccessor, LinkHoverEventTypes } from '../Types'; import { IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types'; +import { INVERTED_DEFAULT_COLOR } from './atlas/Types'; +import { is256Color } from './atlas/CharAtlasUtils'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkHoverEvent = null; @@ -42,7 +43,7 @@ export class LinkRenderLayer extends BaseRenderLayer { private _onLinkHover(e: ILinkHoverEvent): void { if (e.fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (e.fg < DEFAULT_COLOR) { + } else if (is256Color(e.fg)) { // 256 color support this._ctx.fillStyle = this._colors.ansi[e.fg].css; } else { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 984272f6..7b3feed7 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -9,6 +9,7 @@ import { CharData, ITerminal } from '../Types'; import { INVERTED_DEFAULT_COLOR, DEFAULT_COLOR } from './atlas/Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; +import { is256Color } from './atlas/CharAtlasUtils'; /** * This CharData looks like a null character, which will forc a clear and render @@ -186,7 +187,7 @@ export class TextRenderLayer extends BaseRenderLayer { let nextFillStyle = null; // null represents default background color if (bg === INVERTED_DEFAULT_COLOR) { nextFillStyle = this._colors.foreground.css; - } else if (bg < DEFAULT_COLOR) { + } else if (is256Color(bg)) { nextFillStyle = this._colors.ansi[bg].css; } @@ -230,7 +231,7 @@ export class TextRenderLayer extends BaseRenderLayer { this._ctx.save(); if (fg === INVERTED_DEFAULT_COLOR) { this._ctx.fillStyle = this._colors.background.css; - } else if (fg < DEFAULT_COLOR) { + } else if (is256Color(fg)) { // 256 color support this._ctx.fillStyle = this._colors.ansi[fg].css; } else { diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/renderer/atlas/CharAtlasUtils.ts index 59ac07df..c504f77e 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/renderer/atlas/CharAtlasUtils.ts @@ -6,6 +6,7 @@ import { ITerminal } from '../../Types'; import { IColorSet } from '../Types'; import { ICharAtlasConfig } from '../../shared/atlas/Types'; +import { DEFAULT_COLOR } from './Types'; export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig { // null out some fields that don't matter @@ -51,3 +52,7 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean a.colors.foreground === b.colors.foreground && a.colors.background === b.colors.background; } + +export function is256Color(colorCode: number): boolean { + return colorCode < DEFAULT_COLOR; +} diff --git a/src/renderer/atlas/StaticCharAtlas.ts b/src/renderer/atlas/StaticCharAtlas.ts index 673a1509..8dc8be74 100644 --- a/src/renderer/atlas/StaticCharAtlas.ts +++ b/src/renderer/atlas/StaticCharAtlas.ts @@ -7,6 +7,7 @@ import { DIM_OPACITY, IGlyphIdentifier, DEFAULT_COLOR } from './Types'; import { CHAR_ATLAS_CELL_SPACING, ICharAtlasConfig } from '../../shared/atlas/Types'; import { generateStaticCharAtlasTexture } from '../../shared/atlas/CharAtlasGenerator'; import BaseCharAtlas from './BaseCharAtlas'; +import { is256Color } from './CharAtlasUtils'; export default class StaticCharAtlas extends BaseCharAtlas { private _texture: HTMLCanvasElement | ImageBitmap; @@ -58,7 +59,7 @@ export default class StaticCharAtlas extends BaseCharAtlas { } let colorIndex = 0; - if (glyph.fg < DEFAULT_COLOR) { + if (is256Color(glyph.fg)) { colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0); } else if (glyph.fg === DEFAULT_COLOR) { // If default color and bold