Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/BaseRenderLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/T
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;
Expand Down Expand Up @@ -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 < 256) {
} else if (is256Color(fg)) {
// 256 color support
this._ctx.fillStyle = this._colors.ansi[fg].css;
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/LinkRenderLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ILinkHoverEvent, ITerminal, ILinkifierAccessor, LinkHoverEventTypes } f
import { IColorSet, IRenderDimensions } from './Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { INVERTED_DEFAULT_COLOR } from './atlas/Types';
import { is256Color } from './atlas/CharAtlasUtils';

export class LinkRenderLayer extends BaseRenderLayer {
private _state: ILinkHoverEvent = null;
Expand Down Expand Up @@ -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 < 256) {
} else if (is256Color(e.fg)) {
// 256 color support
this._ctx.fillStyle = this._colors.ansi[e.fg].css;
} else {
Expand Down
11 changes: 6 additions & 5 deletions src/renderer/TextRenderLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
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';
import { is256Color } from './atlas/CharAtlasUtils';

/**
* This CharData looks like a null character, which will forc a clear and render
Expand Down Expand Up @@ -143,10 +144,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;
}
}
Expand Down Expand Up @@ -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 < 256) {
} else if (is256Color(bg)) {
nextFillStyle = this._colors.ansi[bg].css;
}

Expand Down Expand Up @@ -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 < 256) {
} else if (is256Color(fg)) {
// 256 color support
this._ctx.fillStyle = this._colors.ansi[fg].css;
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/renderer/atlas/CharAtlasUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion src/renderer/atlas/DynamicCharAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 6 additions & 5 deletions src/renderer/atlas/StaticCharAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* @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';
import { is256Color } from './CharAtlasUtils';

export default class StaticCharAtlas extends BaseCharAtlas {
private _texture: HTMLCanvasElement | ImageBitmap;
Expand Down Expand Up @@ -41,8 +42,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;
}

Expand All @@ -58,9 +59,9 @@ export default class StaticCharAtlas extends BaseCharAtlas {
}

let colorIndex = 0;
if (glyph.fg < 256) {
if (is256Color(glyph.fg)) {
colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0);
} else {
} else if (glyph.fg === DEFAULT_COLOR) {
// If default color and bold
if (glyph.bold) {
colorIndex = 1;
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/atlas/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* @license MIT
*/

export const INVERTED_DEFAULT_COLOR = -1;
export const DEFAULT_COLOR = 256;
export const INVERTED_DEFAULT_COLOR = 257;
export const DIM_OPACITY = 0.5;

export interface IGlyphIdentifier {
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/dom/DomRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -199,6 +200,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;
Expand Down
15 changes: 8 additions & 7 deletions src/renderer/dom/DomRendererRowFactory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -76,7 +77,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);
Expand All @@ -87,7 +88,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);
Expand All @@ -106,24 +107,24 @@ 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),
'<span class="xterm-fg-1 xterm-bg-15">a</span>'
'<span class="xterm-fg-1 xterm-bg-257">a</span>'
);
});

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),
'<span class="xterm-fg-0 xterm-bg-1">a</span>'
'<span class="xterm-fg-257 xterm-bg-1">a</span>'
);
});

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),
`<span class="xterm-bold xterm-fg-${i + 8}">a</span>`
Expand Down
16 changes: 9 additions & 7 deletions src/renderer/dom/DomRendererRowFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_ATTR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, NULL_CELL_CODE } from '../../Buffer';
import { FLAGS } from '../Types';
import { IBufferLine } from '../../Types';
import { DEFAULT_COLOR, INVERTED_DEFAULT_COLOR } from '../atlas/Types';

export const BOLD_CLASS = 'xterm-bold';
export const ITALIC_CLASS = 'xterm-italic';
Expand Down Expand Up @@ -79,16 +80,17 @@ export class DomRendererRowFactory {
const temp = bg;
bg = fg;
fg = temp;
if (fg === 256) {
fg = 0;
if (fg === DEFAULT_COLOR) {
fg = INVERTED_DEFAULT_COLOR;
}
if (bg === 257) {
bg = 15;
if (bg === DEFAULT_COLOR) {
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;
}
Expand All @@ -100,10 +102,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);
Expand Down