Support selection color

This commit is contained in:
Daniel
2019-11-10 01:19:27 -08:00
parent 811307562b
commit 01628362f5
3 changed files with 9 additions and 42 deletions
@@ -1,14 +0,0 @@
/**
* @license MIT
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
*/
import { IColor } from 'browser/Types';
export function getLuminance(color: IColor): number {
// Coefficients taken from: https://www.w3.org/TR/AERT/#color-contrast
const r = color.rgba >> 24 & 0xff;
const g = color.rgba >> 16 & 0xff;
const b = color.rgba >> 8 & 0xff;
return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
}
+9 -14
View File
@@ -6,11 +6,10 @@
import { createProgram, PROJECTION_MATRIX, throwIfFalsy } from './WebglUtils'; import { createProgram, PROJECTION_MATRIX, throwIfFalsy } from './WebglUtils';
import { WebglCharAtlas } from './atlas/WebglCharAtlas'; import { WebglCharAtlas } from './atlas/WebglCharAtlas';
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types'; import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types';
import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_INDICIES_PER_CELL } from './RenderModel'; import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_INDICIES_PER_CELL, RENDER_MODEL_FG_OFFSET } from './RenderModel';
import { fill } from 'common/TypedArrayUtils'; import { fill } from 'common/TypedArrayUtils';
import { slice } from './TypedArray'; import { slice } from './TypedArray';
import { NULL_CELL_CODE, WHITESPACE_CELL_CODE, Attributes } from 'common/buffer/Constants'; import { NULL_CELL_CODE, WHITESPACE_CELL_CODE, Attributes } from 'common/buffer/Constants';
import { getLuminance } from './ColorUtils';
import { Terminal, IBufferLine } from 'xterm'; import { Terminal, IBufferLine } from 'xterm';
import { IColorSet } from 'browser/Types'; import { IColorSet } from 'browser/Types';
import { IRenderDimensions } from 'browser/renderer/Types'; import { IRenderDimensions } from 'browser/renderer/Types';
@@ -219,41 +218,37 @@ export class GlyphRenderer {
this._vertices.selectionAttributes = slice(this._vertices.attributes, 0); this._vertices.selectionAttributes = slice(this._vertices.attributes, 0);
// TODO: Make fg and bg configurable, currently since the buffer doesn't const bg = (this._colors.selection.rgba >>> 8) | Attributes.CM_RGB;
// support truecolor the char atlas cannot store it.
const lumi = getLuminance(this._colors.background);
const fg = (lumi > 0.5 ? 7 : 0) | Attributes.CM_P16;
const bg = (lumi > 0.5 ? 0 : 7) | Attributes.CM_P16;
if (columnSelectMode) { if (columnSelectMode) {
const startCol = model.selection.startCol; const startCol = model.selection.startCol;
const width = model.selection.endCol - startCol; const width = model.selection.endCol - startCol;
const height = model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow + 1; const height = model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow + 1;
for (let y = model.selection.viewportCappedStartRow; y < model.selection.viewportCappedStartRow + height; y++) { for (let y = model.selection.viewportCappedStartRow; y < model.selection.viewportCappedStartRow + height; y++) {
this._updateSelectionRange(startCol, startCol + width, y, model, bg, fg); this._updateSelectionRange(startCol, startCol + width, y, model, bg);
} }
} else { } else {
// Draw first row // Draw first row
const startCol = model.selection.viewportStartRow === model.selection.viewportCappedStartRow ? model.selection.startCol : 0; const startCol = model.selection.viewportStartRow === model.selection.viewportCappedStartRow ? model.selection.startCol : 0;
const startRowEndCol = model.selection.viewportCappedStartRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols; const startRowEndCol = model.selection.viewportCappedStartRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols;
this._updateSelectionRange(startCol, startRowEndCol, model.selection.viewportCappedStartRow, model, bg, fg); this._updateSelectionRange(startCol, startRowEndCol, model.selection.viewportCappedStartRow, model, bg);
// Draw middle rows // Draw middle rows
const middleRowsCount = Math.max(model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow - 1, 0); const middleRowsCount = Math.max(model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow - 1, 0);
for (let y = model.selection.viewportCappedStartRow + 1; y <= model.selection.viewportCappedStartRow + middleRowsCount; y++) { for (let y = model.selection.viewportCappedStartRow + 1; y <= model.selection.viewportCappedStartRow + middleRowsCount; y++) {
this._updateSelectionRange(0, startRowEndCol, y, model, bg, fg); this._updateSelectionRange(0, startRowEndCol, y, model, bg);
} }
// Draw final row // Draw final row
if (model.selection.viewportCappedStartRow !== model.selection.viewportCappedEndRow) { if (model.selection.viewportCappedStartRow !== model.selection.viewportCappedEndRow) {
// Only draw viewportEndRow if it's not the same as viewportStartRow // Only draw viewportEndRow if it's not the same as viewportStartRow
const endCol = model.selection.viewportEndRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols; const endCol = model.selection.viewportEndRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols;
this._updateSelectionRange(0, endCol, model.selection.viewportCappedEndRow, model, bg, fg); this._updateSelectionRange(0, endCol, model.selection.viewportCappedEndRow, model, bg);
} }
} }
} }
private _updateSelectionRange(startCol: number, endCol: number, y: number, model: IRenderModel, bg: number, fg: number): void { private _updateSelectionRange(startCol: number, endCol: number, y: number, model: IRenderModel, bg: number): void {
const terminal = this._terminal; const terminal = this._terminal;
const row = y + terminal.buffer.viewportY; const row = y + terminal.buffer.viewportY;
let line: IBufferLine | undefined; let line: IBufferLine | undefined;
@@ -265,9 +260,9 @@ export class GlyphRenderer {
line = terminal.buffer.getLine(row); line = terminal.buffer.getLine(row);
} }
const chars = line!.getCell(x)!.char; const chars = line!.getCell(x)!.char;
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg, chars); this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, model.cells[offset + RENDER_MODEL_FG_OFFSET], chars);
} else { } else {
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg); this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, model.cells[offset + RENDER_MODEL_FG_OFFSET]);
} }
} }
} }
@@ -16,7 +16,6 @@ import { RenderModel, COMBINED_CHAR_BIT_MASK, RENDER_MODEL_BG_OFFSET, RENDER_MOD
import { Disposable } from 'common/Lifecycle'; import { Disposable } from 'common/Lifecycle';
import { DEFAULT_COLOR, NULL_CELL_CODE, FgFlags } from 'common/buffer/Constants'; import { DEFAULT_COLOR, NULL_CELL_CODE, FgFlags } from 'common/buffer/Constants';
import { Terminal, IEvent } from 'xterm'; import { Terminal, IEvent } from 'xterm';
import { getLuminance } from './ColorUtils';
import { IRenderLayer } from './renderLayer/Types'; import { IRenderLayer } from './renderLayer/Types';
import { IRenderDimensions, IRenderer, IRequestRefreshRowsEvent } from 'browser/renderer/Types'; import { IRenderDimensions, IRenderer, IRequestRefreshRowsEvent } from 'browser/renderer/Types';
import { IColorSet } from 'browser/Types'; import { IColorSet } from 'browser/Types';
@@ -52,8 +51,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._core = (<any>this._terminal)._core; this._core = (<any>this._terminal)._core;
this._applyBgLuminanceBasedSelection();
this._renderLayers = [ this._renderLayers = [
new LinkRenderLayer(this._core.screenElement, 2, this._colors, this._core), new LinkRenderLayer(this._core.screenElement, 2, this._colors, this._core),
new CursorRenderLayer(this._core.screenElement, 3, this._colors, this._onRequestRefreshRows) new CursorRenderLayer(this._core.screenElement, 3, this._colors, this._onRequestRefreshRows)
@@ -101,20 +98,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
super.dispose(); super.dispose();
} }
private _applyBgLuminanceBasedSelection(): void {
// HACK: This is needed until webgl renderer adds support for selection colors
if (getLuminance(this._colors.background) > 0.5) {
this._colors.selection = { css: '#000', rgba: 255 };
} else {
this._colors.selection = { css: '#fff', rgba: 4294967295 };
}
}
public setColors(colors: IColorSet): void { public setColors(colors: IColorSet): void {
this._colors = colors; this._colors = colors;
this._applyBgLuminanceBasedSelection();
// Clear layers and force a full render // Clear layers and force a full render
this._renderLayers.forEach(l => { this._renderLayers.forEach(l => {
l.setColors(this._terminal, this._colors); l.setColors(this._terminal, this._colors);