Merge remote-tracking branch 'upstream/master' into pr/silamon/4004

This commit is contained in:
Daniel Imms
2022-09-02 13:05:52 -07:00
68 changed files with 1620 additions and 767 deletions
+72
View File
@@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '41 17 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+1 -1
View File
@@ -140,7 +140,7 @@ Xterm.js is used in several world-class applications to provide great terminal e
- [**Fluent Terminal**](https://github.com/felixse/FluentTerminal): A terminal emulator based on UWP and web technologies.
- [**Hyper**](https://hyper.is): A terminal built on web technologies.
- [**Diag**](https://diag.ai): A better way to troubleshoot problems faster. Capture, share and reapply troubleshooting knowledge so you can focus on solving problems that matter.
- [**GoTTY**](https://github.com/yudai/gotty): A simple command line tool that shares your terminal as a web application based on xterm.js.
- [**GoTTY**](https://github.com/sorenisanerd/gotty): A simple command line tool that shares your terminal as a web application based on xterm.js.
- [**genact**](https://github.com/svenstaro/genact): A nonsense activity generator.
- [**cPanel & WHM**](https://cpanel.com): The hosting platform of choice.
- [**Nutanix**](https://github.com/nutanix): Nutanix Enterprise Cloud uses xterm in the webssh functionality within Nutanix Calm, and is also looking to move our old noserial (termjs) functionality to xterm.js.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
@@ -344,7 +344,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
// Draw custom characters if applicable
let drawSuccess = false;
if (this._optionsService.rawOptions.customGlyphs !== false) {
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight, this._optionsService.rawOptions.fontSize);
}
// Draw the character
@@ -404,12 +404,11 @@ export abstract class BaseRenderLayer implements IRenderLayer {
// Don't try cache the glyph if it uses any decoration foreground/background override.
let hasOverrides = false;
for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
this._decorationService.forEachDecorationAtCell(x, y, undefined, d => {
if (d.backgroundColorRGB || d.foregroundColorRGB) {
hasOverrides = true;
break;
}
}
});
const atlasDidDraw = hasOverrides ? false : this._charAtlas?.draw(this._ctx, this._currentGlyphIdentifier, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop);
@@ -473,7 +472,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
// Draw custom characters if applicable
let drawSuccess = false;
if (this._optionsService.rawOptions.customGlyphs !== false) {
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight, this._optionsService.rawOptions.fontSize);
}
// Draw the character
@@ -519,9 +518,9 @@ export abstract class BaseRenderLayer implements IRenderLayer {
let bgOverride: number | undefined;
let fgOverride: number | undefined;
let isTop = false;
for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
this._decorationService.forEachDecorationAtCell(x, y, undefined, d => {
if (d.options.layer !== 'top' && isTop) {
continue;
return;
}
if (d.backgroundColorRGB) {
bgOverride = d.backgroundColorRGB.rgba;
@@ -530,7 +529,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
fgOverride = d.foregroundColorRGB.rgba;
}
isTop = d.options.layer === 'top';
}
});
// Apply selection foreground if applicable
if (!isTop) {
@@ -3,12 +3,11 @@
* @license MIT
*/
import { IRenderDimensions, IRequestRedrawEvent } from 'browser/renderer/Types';
import { IRenderDimensions } from 'browser/renderer/Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { IColorSet } from 'browser/Types';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
import { ICoreBrowserService } from 'browser/services/Services';
import { IEventEmitter } from 'common/EventEmitter';
interface ISelectionState {
start?: [number, number];
@@ -187,15 +187,15 @@ export class TextRenderLayer extends BaseRenderLayer {
// Get any decoration foreground/background overrides, this must be fetched before the early
// exist but applied after inverse
let isTop = false;
for (const d of this._decorationService.getDecorationsAtCell(x, this._bufferService.buffer.ydisp + y)) {
this._decorationService.forEachDecorationAtCell(x, this._bufferService.buffer.ydisp + y, undefined, d => {
if (d.options.layer !== 'top' && isTop) {
continue;
return;
}
if (d.backgroundColorRGB) {
nextFillStyle = d.backgroundColorRGB.css;
}
isTop = d.options.layer === 'top';
}
});
if (prevFillStyle === null) {
// This is either the first iteration, or the default background was set. Either way, we
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es6"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es6",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es6",
],
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2015",
"lib": [
"es2015"
],
-1
View File
@@ -2,7 +2,6 @@
An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables a WebGL2-based renderer. This addon requires xterm.js v4+.
### Install
```bash
+37 -34
View File
@@ -8,7 +8,7 @@ import { WebglCharAtlas } from './atlas/WebglCharAtlas';
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types';
import { fill } from 'common/TypedArrayUtils';
import { NULL_CELL_CODE } from 'common/buffer/Constants';
import { Terminal, IBufferLine } from 'xterm';
import { Terminal } from 'xterm';
import { IColorSet } from 'browser/Types';
import { IRenderDimensions } from 'browser/renderer/Types';
import { Disposable, toDisposable } from 'common/Lifecycle';
@@ -70,6 +70,14 @@ const INDICES_PER_CELL = 10;
const BYTES_PER_CELL = INDICES_PER_CELL * Float32Array.BYTES_PER_ELEMENT;
const CELL_POSITION_INDICES = 2;
/** Work variables to avoid garbage collection. */
const w: { i: number, glyph: IRasterizedGlyph | undefined, leftCellPadding: number, clippedPixels: number } = {
i: 0,
glyph: undefined,
leftCellPadding: 0,
clippedPixels: 0
};
export class GlyphRenderer extends Disposable {
private _atlas: WebglCharAtlas | undefined;
@@ -122,7 +130,7 @@ export class GlyphRenderer extends Disposable {
gl.vertexAttribPointer(VertexAttribLocations.UNIT_QUAD, 2, this._gl.FLOAT, false, 0, 0);
// Setup the unit quad element array buffer, this points to indices in
// unitQuadVertuces to allow is to draw 2 triangles from the vertices
// unitQuadVertices to allow is to draw 2 triangles from the vertices
const unitQuadElementIndices = new Uint8Array([0, 1, 3, 0, 2, 3]);
const elementIndicesBuffer = gl.createBuffer();
this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
@@ -170,18 +178,20 @@ export class GlyphRenderer extends Disposable {
}
public updateCell(x: number, y: number, code: number, bg: number, fg: number, ext: number, chars: string, lastBg: number): void {
// Since this function is called for every cell (`rows*cols`), it must be very optimized. It
// should not instantiate any variables unless a new glyph is drawn to the cache where the
// slight slowdown is acceptable for the developer ergonomics provided as it's a once of for
// each glyph.
this._updateCell(this._vertices.attributes, x, y, code, bg, fg, ext, chars, lastBg);
}
private _updateCell(array: Float32Array, x: number, y: number, code: number | undefined, bg: number, fg: number, ext: number, chars: string, lastBg: number): void {
const terminal = this._terminal;
const i = (y * terminal.cols + x) * INDICES_PER_CELL;
w.i = (y * this._terminal.cols + x) * INDICES_PER_CELL;
// Exit early if this is a null character, allow space character to continue as it may have
// underline/strikethrough styles
if (code === NULL_CELL_CODE || code === undefined/* This is used for the right side of wide chars */) {
fill(array, 0, i, i + INDICES_PER_CELL - 1 - CELL_POSITION_INDICES);
fill(array, 0, w.i, w.i + INDICES_PER_CELL - 1 - CELL_POSITION_INDICES);
return;
}
@@ -190,47 +200,40 @@ export class GlyphRenderer extends Disposable {
}
// Get the glyph
let rasterizedGlyph: IRasterizedGlyph;
if (chars && chars.length > 1) {
rasterizedGlyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext);
w.glyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext);
} else {
rasterizedGlyph = this._atlas.getRasterizedGlyph(code, bg, fg, ext);
w.glyph = this._atlas.getRasterizedGlyph(code, bg, fg, ext);
}
// Fill empty if no glyph was found
if (!rasterizedGlyph) {
fill(array, 0, i, i + INDICES_PER_CELL - 1 - CELL_POSITION_INDICES);
return;
}
const leftCellPadding = Math.floor((this._dimensions.scaledCellWidth - this._dimensions.scaledCharWidth) / 2);
if (bg !== lastBg && rasterizedGlyph.offset.x > leftCellPadding) {
const clippedPixels = rasterizedGlyph.offset.x - leftCellPadding;
w.leftCellPadding = Math.floor((this._dimensions.scaledCellWidth - this._dimensions.scaledCharWidth) / 2);
if (bg !== lastBg && w.glyph.offset.x > w.leftCellPadding) {
w.clippedPixels = w.glyph.offset.x - w.leftCellPadding;
// a_origin
array[i ] = -(rasterizedGlyph.offset.x - clippedPixels) + this._dimensions.scaledCharLeft;
array[i + 1] = -rasterizedGlyph.offset.y + this._dimensions.scaledCharTop;
array[w.i ] = -(w.glyph.offset.x - w.clippedPixels) + this._dimensions.scaledCharLeft;
array[w.i + 1] = -w.glyph.offset.y + this._dimensions.scaledCharTop;
// a_size
array[i + 2] = (rasterizedGlyph.size.x - clippedPixels) / this._dimensions.scaledCanvasWidth;
array[i + 3] = rasterizedGlyph.size.y / this._dimensions.scaledCanvasHeight;
array[w.i + 2] = (w.glyph.size.x - w.clippedPixels) / this._dimensions.scaledCanvasWidth;
array[w.i + 3] = w.glyph.size.y / this._dimensions.scaledCanvasHeight;
// a_texcoord
array[i + 4] = rasterizedGlyph.texturePositionClipSpace.x + clippedPixels / this._atlas.cacheCanvas.width;
array[i + 5] = rasterizedGlyph.texturePositionClipSpace.y;
array[w.i + 4] = w.glyph.texturePositionClipSpace.x + w.clippedPixels / this._atlas.cacheCanvas.width;
array[w.i + 5] = w.glyph.texturePositionClipSpace.y;
// a_texsize
array[i + 6] = rasterizedGlyph.sizeClipSpace.x - clippedPixels / this._atlas.cacheCanvas.width;
array[i + 7] = rasterizedGlyph.sizeClipSpace.y;
array[w.i + 6] = w.glyph.sizeClipSpace.x - w.clippedPixels / this._atlas.cacheCanvas.width;
array[w.i + 7] = w.glyph.sizeClipSpace.y;
} else {
// a_origin
array[i ] = -rasterizedGlyph.offset.x + this._dimensions.scaledCharLeft;
array[i + 1] = -rasterizedGlyph.offset.y + this._dimensions.scaledCharTop;
array[w.i ] = -w.glyph.offset.x + this._dimensions.scaledCharLeft;
array[w.i + 1] = -w.glyph.offset.y + this._dimensions.scaledCharTop;
// a_size
array[i + 2] = rasterizedGlyph.size.x / this._dimensions.scaledCanvasWidth;
array[i + 3] = rasterizedGlyph.size.y / this._dimensions.scaledCanvasHeight;
array[w.i + 2] = w.glyph.size.x / this._dimensions.scaledCanvasWidth;
array[w.i + 3] = w.glyph.size.y / this._dimensions.scaledCanvasHeight;
// a_texcoord
array[i + 4] = rasterizedGlyph.texturePositionClipSpace.x;
array[i + 5] = rasterizedGlyph.texturePositionClipSpace.y;
array[w.i + 4] = w.glyph.texturePositionClipSpace.x;
array[w.i + 5] = w.glyph.texturePositionClipSpace.y;
// a_texsize
array[i + 6] = rasterizedGlyph.sizeClipSpace.x;
array[i + 7] = rasterizedGlyph.sizeClipSpace.y;
array[w.i + 6] = w.glyph.sizeClipSpace.x;
array[w.i + 7] = w.glyph.sizeClipSpace.y;
}
// a_cellpos only changes on resize
}
@@ -28,12 +28,11 @@ layout (location = ${VertexAttribLocations.COLOR}) in vec4 a_color;
layout (location = ${VertexAttribLocations.UNIT_QUAD}) in vec2 a_unitquad;
uniform mat4 u_projection;
uniform vec2 u_resolution;
out vec4 v_color;
void main() {
vec2 zeroToOne = (a_position + (a_unitquad * a_size)) / u_resolution;
vec2 zeroToOne = a_position + (a_unitquad * a_size);
gl_Position = u_projection * vec4(zeroToOne, 0.0, 1.0);
v_color = a_color;
}`;
@@ -59,11 +58,22 @@ const BYTES_PER_RECTANGLE = INDICES_PER_RECTANGLE * Float32Array.BYTES_PER_ELEME
const INITIAL_BUFFER_RECTANGLE_CAPACITY = 20 * INDICES_PER_RECTANGLE;
/** Work variables to avoid garbage collection. */
const w: { rgba: number, isDefault: boolean, x1: number, y1: number, r: number, g: number, b: number, a: number } = {
rgba: 0,
isDefault: false,
x1: 0,
y1: 0,
r: 0,
g: 0,
b: 0,
a: 0
};
export class RectangleRenderer extends Disposable {
private _program: WebGLProgram;
private _vertexArrayObject: IWebGLVertexArrayObject;
private _resolutionLocation: WebGLUniformLocation;
private _attributesBuffer: WebGLBuffer;
private _projectionLocation: WebGLUniformLocation;
private _bgFloat!: Float32Array;
@@ -87,7 +97,6 @@ export class RectangleRenderer extends Disposable {
this.register(toDisposable(() => gl.deleteProgram(this._program)));
// Uniform locations
this._resolutionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_resolution'));
this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));
// Create and set the vertex array object
@@ -104,7 +113,7 @@ export class RectangleRenderer extends Disposable {
gl.vertexAttribPointer(VertexAttribLocations.UNIT_QUAD, 2, this._gl.FLOAT, false, 0, 0);
// Setup the unit quad element array buffer, this points to indices in
// unitQuadVertuces to allow is to draw 2 triangles from the vertices
// unitQuadVertices to allow is to draw 2 triangles from the vertices
const unitQuadElementIndices = new Uint8Array([0, 1, 3, 0, 2, 3]);
const elementIndicesBuffer = gl.createBuffer();
this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
@@ -136,7 +145,6 @@ export class RectangleRenderer extends Disposable {
gl.bindVertexArray(this._vertexArrayObject);
gl.uniformMatrix4fv(this._projectionLocation, false, PROJECTION_MATRIX);
gl.uniform2f(this._resolutionLocation, gl.canvas.width, gl.canvas.height);
// Bind attributes buffer and draw
gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
@@ -153,6 +161,10 @@ export class RectangleRenderer extends Disposable {
this._updateViewportRectangle();
}
public setDimensions(dimensions: IRenderDimensions): void {
this._dimensions = dimensions;
}
private _updateCachedColors(): void {
this._bgFloat = this._colorToFloat32Array(this._colors.background);
}
@@ -174,22 +186,34 @@ export class RectangleRenderer extends Disposable {
const terminal = this._terminal;
const vertices = this._vertices;
// Declare variable ahead of time to avoid garbage collection
let rectangleCount = 1;
let y: number;
let x: number;
let currentStartX: number;
let currentBg: number;
let currentFg: number;
let currentInverse: boolean;
let modelIndex: number;
let bg: number;
let fg: number;
let inverse: boolean;
let offset: number;
for (let y = 0; y < terminal.rows; y++) {
let currentStartX = -1;
let currentBg = 0;
let currentFg = 0;
let currentInverse = false;
for (let x = 0; x < terminal.cols; x++) {
const modelIndex = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL;
const bg = model.cells[modelIndex + RENDER_MODEL_BG_OFFSET];
const fg = model.cells[modelIndex + RENDER_MODEL_FG_OFFSET];
const inverse = !!(fg & FgFlags.INVERSE);
for (y = 0; y < terminal.rows; y++) {
currentStartX = -1;
currentBg = 0;
currentFg = 0;
currentInverse = false;
for (x = 0; x < terminal.cols; x++) {
modelIndex = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL;
bg = model.cells[modelIndex + RENDER_MODEL_BG_OFFSET];
fg = model.cells[modelIndex + RENDER_MODEL_FG_OFFSET];
inverse = !!(fg & FgFlags.INVERSE);
if (bg !== currentBg || (fg !== currentFg && (currentInverse || inverse))) {
// A rectangle needs to be drawn if going from non-default to another color
if (currentBg !== 0 || (currentInverse && currentFg !== 0)) {
const offset = rectangleCount++ * INDICES_PER_RECTANGLE;
offset = rectangleCount++ * INDICES_PER_RECTANGLE;
this._updateRectangle(vertices, offset, currentFg, currentBg, currentStartX, x, y);
}
currentStartX = x;
@@ -200,7 +224,7 @@ export class RectangleRenderer extends Disposable {
}
// Finish rectangle if it's still going
if (currentBg !== 0 || (currentInverse && currentFg !== 0)) {
const offset = rectangleCount++ * INDICES_PER_RECTANGLE;
offset = rectangleCount++ * INDICES_PER_RECTANGLE;
this._updateRectangle(vertices, offset, currentFg, currentBg, currentStartX, terminal.cols, y);
}
}
@@ -208,55 +232,54 @@ export class RectangleRenderer extends Disposable {
}
private _updateRectangle(vertices: IVertices, offset: number, fg: number, bg: number, startX: number, endX: number, y: number): void {
let rgba: number | undefined;
let isDefault = false;
w.isDefault = false;
if (fg & FgFlags.INVERSE) {
switch (fg & Attributes.CM_MASK) {
case Attributes.CM_P16:
case Attributes.CM_P256:
rgba = this._colors.ansi[fg & Attributes.PCOLOR_MASK].rgba;
w.rgba = this._colors.ansi[fg & Attributes.PCOLOR_MASK].rgba;
break;
case Attributes.CM_RGB:
rgba = (fg & Attributes.RGB_MASK) << 8;
w.rgba = (fg & Attributes.RGB_MASK) << 8;
break;
case Attributes.CM_DEFAULT:
default:
rgba = this._colors.foreground.rgba;
w.rgba = this._colors.foreground.rgba;
}
} else {
switch (bg & Attributes.CM_MASK) {
case Attributes.CM_P16:
case Attributes.CM_P256:
rgba = this._colors.ansi[bg & Attributes.PCOLOR_MASK].rgba;
w.rgba = this._colors.ansi[bg & Attributes.PCOLOR_MASK].rgba;
break;
case Attributes.CM_RGB:
rgba = (bg & Attributes.RGB_MASK) << 8;
w.rgba = (bg & Attributes.RGB_MASK) << 8;
break;
case Attributes.CM_DEFAULT:
default:
rgba = this._colors.background.rgba;
isDefault = true;
w.rgba = this._colors.background.rgba;
w.isDefault = true;
}
}
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 = ((rgba >> 24) & 0xFF) / 255;
const g = ((rgba >> 16) & 0xFF) / 255;
const b = ((rgba >> 8 ) & 0xFF) / 255;
const a = (!isDefault && bg & BgFlags.DIM) ? DIM_OPACITY : 1;
w.x1 = startX * this._dimensions.scaledCellWidth;
w.y1 = y * this._dimensions.scaledCellHeight;
w.r = ((w.rgba >> 24) & 0xFF) / 255;
w.g = ((w.rgba >> 16) & 0xFF) / 255;
w.b = ((w.rgba >> 8 ) & 0xFF) / 255;
w.a = (!w.isDefault && bg & BgFlags.DIM) ? DIM_OPACITY : 1;
this._addRectangle(vertices.attributes, offset, x1, y1, (endX - startX) * this._dimensions.scaledCellWidth, this._dimensions.scaledCellHeight, r, g, b, a);
this._addRectangle(vertices.attributes, offset, w.x1, w.y1, (endX - startX) * this._dimensions.scaledCellWidth, this._dimensions.scaledCellHeight, w.r, w.g, w.b, w.a);
}
private _addRectangle(array: Float32Array, offset: number, x1: number, y1: number, width: number, height: number, r: number, g: number, b: number, a: number): void {
array[offset ] = x1;
array[offset + 1] = y1;
array[offset + 2] = width;
array[offset + 3] = height;
array[offset ] = x1 / this._dimensions.scaledCanvasWidth;
array[offset + 1] = y1 / this._dimensions.scaledCanvasHeight;
array[offset + 2] = width / this._dimensions.scaledCanvasWidth;
array[offset + 3] = height / this._dimensions.scaledCanvasHeight;
array[offset + 4] = r;
array[offset + 5] = g;
array[offset + 6] = b;
@@ -264,10 +287,10 @@ export class RectangleRenderer extends Disposable {
}
private _addRectangleFloat(array: Float32Array, offset: number, x1: number, y1: number, width: number, height: number, color: Float32Array): void {
array[offset ] = x1;
array[offset + 1] = y1;
array[offset + 2] = width;
array[offset + 3] = height;
array[offset ] = x1 / this._dimensions.scaledCanvasWidth;
array[offset + 1] = y1 / this._dimensions.scaledCanvasHeight;
array[offset + 2] = width / this._dimensions.scaledCanvasWidth;
array[offset + 3] = height / this._dimensions.scaledCanvasHeight;
array[offset + 4] = color[0];
array[offset + 5] = color[1];
array[offset + 6] = color[2];
-4
View File
@@ -3,10 +3,6 @@
* @license MIT
*/
export interface IRasterizedGlyphSet {
[bg: number]: { [fg: number]: { [ext: number]: IRasterizedGlyph } } | undefined;
}
/**
* Represents a rasterized glyph within a texture atlas. Some numbers are
* tracked in CSS pixels as well in order to reduce calculations during the

Some files were not shown because too many files have changed in this diff Show More