Support selection color
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user