Merge branch 'master' into fix_weblinks

This commit is contained in:
Jörg Breitbart
2022-12-19 14:19:43 +01:00
30 changed files with 414 additions and 255 deletions
@@ -122,7 +122,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
return;
}
this._charAtlasDisposable?.dispose();
this._charAtlas = acquireTextureAtlas(this._terminal, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
this._charAtlas = acquireTextureAtlas(this._terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
this._charAtlasDisposable = forwardEvent(this._charAtlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas);
this._charAtlas.warmUp();
for (let i = 0; i < this._charAtlas.pages.length; i++) {
@@ -373,6 +373,9 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
} else {
glyph = this._charAtlas.getRasterizedGlyph(cell.getCode() || WHITESPACE_CELL_CODE, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
}
if (!glyph.size.x || !glyph.size.y) {
return;
}
this._ctx.save();
this._clipRow(y);
// Draw the image, use the bitmap if it's available
@@ -389,8 +392,8 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
glyph.texturePosition.y,
glyph.size.x,
glyph.size.y,
x * this._deviceCellWidth - glyph.offset.x,
y * this._deviceCellHeight - glyph.offset.y,
x * this._deviceCellWidth + this._deviceCharLeft - glyph.offset.x,
y * this._deviceCellHeight + this._deviceCharTop - glyph.offset.y,
glyph.size.x,
glyph.size.y
);
@@ -95,6 +95,12 @@ export class TextRenderLayer extends BaseRenderLayer {
continue;
}
// exit early for NULL and SP
const code = cell.getCode();
if (code === 0 || code === 32) {
continue;
}
// Process any joined character ranges as needed. Because of how the
// ranges are produced, we know that they are valid for the characters
// and attributes of our input.
+3 -5
View File
@@ -9,7 +9,6 @@ import { EventEmitter, forwardEvent } from 'common/EventEmitter';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { getSafariVersion, isSafari } from 'common/Platform';
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
import { ICoreTerminal } from 'common/Types';
import { ITerminalAddon, Terminal } from 'xterm';
import { WebglRenderer } from './WebglRenderer';
@@ -29,14 +28,13 @@ export class WebglAddon extends Disposable implements ITerminalAddon {
constructor(
private _preserveDrawingBuffer?: boolean
) {
if (isSafari && getSafariVersion() < 16) {
throw new Error('Webgl2 is only supported on Safari 16 and above');
}
super();
}
public activate(terminal: Terminal): void {
if (isSafari && getSafariVersion() < 16) {
throw new Error('Webgl2 is only supported on Safari 16 and above');
}
const core = (terminal as any)._core as ITerminal;
if (!terminal.element) {
this.register(core.onWillOpen(() => this.activate(terminal)));
+20 -15
View File
@@ -40,8 +40,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
private _canvas: HTMLCanvasElement;
private _gl: IWebGL2RenderingContext;
private _rectangleRenderer!: RectangleRenderer;
private _glyphRenderer!: GlyphRenderer;
private _rectangleRenderer: RectangleRenderer;
private _glyphRenderer: GlyphRenderer;
public readonly dimensions: IRenderDimensions;
@@ -67,7 +67,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
private readonly _coreBrowserService: ICoreBrowserService,
coreService: ICoreService,
private readonly _decorationService: IDecorationService,
optionsService: IOptionsService,
private readonly _optionsService: IOptionsService,
private readonly _themeService: IThemeService,
preserveDrawingBuffer?: boolean
) {
@@ -80,13 +80,13 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._core = (this._terminal as any)._core;
this._renderLayers = [
new LinkRenderLayer(this._core.screenElement!, 2, this._terminal, this._core.linkifier2, this._coreBrowserService, this._themeService),
new CursorRenderLayer(_terminal, this._core.screenElement!, 3, this._onRequestRedraw, this._coreBrowserService, coreService, this._themeService, optionsService)
new LinkRenderLayer(this._core.screenElement!, 2, this._terminal, this._core.linkifier2, this._coreBrowserService, _optionsService, this._themeService),
new CursorRenderLayer(_terminal, this._core.screenElement!, 3, this._onRequestRedraw, this._coreBrowserService, coreService, _optionsService, this._themeService)
];
this.dimensions = createRenderDimensions();
this._devicePixelRatio = this._coreBrowserService.dpr;
this._updateDimensions();
this.register(optionsService.onOptionChange(() => this._handleOptionsChanged()));
this.register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
this._canvas = document.createElement('canvas');
@@ -127,7 +127,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._core.screenElement!.appendChild(this._canvas);
this._initializeWebGLState();
[this._rectangleRenderer, this._glyphRenderer] = this._initializeWebGLState();
this._isAttached = this._coreBrowserService.window.document.body.contains(this._core.screenElement!);
@@ -235,7 +235,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
/**
* Initializes members dependent on WebGL context state.
*/
private _initializeWebGLState(): void {
private _initializeWebGLState(): [RectangleRenderer, GlyphRenderer] {
// Dispose any previous rectangle and glyph renderers before creating new ones.
this._rectangleRenderer?.dispose();
this._glyphRenderer?.dispose();
@@ -245,6 +245,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
// Update dimensions and acquire char atlas
this.handleCharSizeChanged();
return [this._rectangleRenderer, this._glyphRenderer];
}
/**
@@ -259,6 +261,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
const atlas = acquireTextureAtlas(
this._terminal,
this._optionsService.rawOptions,
this._themeService.colors,
this.dimensions.device.cell.width,
this.dimensions.device.cell.height,
@@ -267,7 +270,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._coreBrowserService.dpr
);
if (this._charAtlas !== atlas) {
this._charAtlasDisposable?.dispose();
this._onChangeTextureAtlas.fire(atlas.pages[0].canvas);
this._charAtlasDisposable = getDisposeArrayDisposable([
@@ -350,7 +352,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
let lastBg: number;
let y: number;
let row: number;
let line: IBufferLine;
let line: IBufferLine | undefined;
let joinedRanges: [number, number][];
let isJoined: boolean;
let lastCharX: number;
@@ -363,7 +365,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
for (y = start; y <= end; y++) {
row = y + terminal.buffer.ydisp;
line = terminal.buffer.lines.get(row)!;
line = terminal.buffer.lines.get(row);
if (!line) {
break;
}
this._model.lineLengths[y] = 0;
joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
for (x = 0; x < terminal.cols; x++) {
@@ -469,18 +474,18 @@ export class WebglRenderer extends Disposable implements IRenderer {
// Calculate the device cell height, if lineHeight is _not_ 1, the resulting value will be
// floored since lineHeight can never be lower then 1, this guarentees the device cell height
// will always be larger than device char height.
this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._terminal.options.lineHeight);
this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);
// Calculate the y offset within a cell that glyph should draw at in order for it to be centered
// correctly within the cell.
this.dimensions.device.char.top = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.device.cell.height - this.dimensions.device.char.height) / 2);
this.dimensions.device.char.top = this._optionsService.rawOptions.lineHeight === 1 ? 0 : Math.round((this.dimensions.device.cell.height - this.dimensions.device.char.height) / 2);
// Calculate the device cell width, taking the letterSpacing into account.
this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._terminal.options.letterSpacing);
this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);
// Calculate the x offset with a cell that text should draw from in order for it to be centered
// correctly within the cell.
this.dimensions.device.char.left = Math.floor(this._terminal.options.letterSpacing / 2);
this.dimensions.device.char.left = Math.floor(this._optionsService.rawOptions.letterSpacing / 2);
// Recalculate the canvas dimensions, the device dimensions define the actual number of pixel in
// the canvas
@@ -13,6 +13,7 @@ import { IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types'
import { CellData } from 'common/buffer/CellData';
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IOptionsService } from 'common/services/Services';
export abstract class BaseRenderLayer extends Disposable implements IRenderLayer {
private _canvas: HTMLCanvasElement;
@@ -33,6 +34,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
zIndex: number,
private _alpha: boolean,
protected readonly _coreBrowserService: ICoreBrowserService,
protected readonly _optionsService: IOptionsService,
protected readonly _themeService: IThemeService
) {
super();
@@ -93,7 +95,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
if (this._deviceCharWidth <= 0 && this._deviceCharHeight <= 0) {
return;
}
this._charAtlas = acquireTextureAtlas(terminal, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
this._charAtlas = acquireTextureAtlas(terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
this._charAtlas.warmUp();
}
@@ -39,10 +39,10 @@ export class CursorRenderLayer extends BaseRenderLayer {
private _onRequestRefreshRowsEvent: IEventEmitter<IRequestRedrawEvent>,
coreBrowserService: ICoreBrowserService,
private readonly _coreService: ICoreService,
themeService: IThemeService,
optionsService: IOptionsService
optionsService: IOptionsService,
themeService: IThemeService
) {
super(terminal, container, 'cursor', zIndex, true, coreBrowserService, themeService);
super(terminal, container, 'cursor', zIndex, true, coreBrowserService, optionsService, themeService);
this._state = {
x: 0,
y: 0,
@@ -213,7 +213,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
private _renderBarCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void {
this._ctx.save();
this._ctx.fillStyle = this._themeService.colors.cursor.css;
this._fillLeftLineAtCell(x, y, terminal.options.cursorWidth);
this._fillLeftLineAtCell(x, y, this._optionsService.rawOptions.cursorWidth);
this._ctx.restore();
}
@@ -8,6 +8,7 @@ import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
import { IRenderDimensions } from 'browser/renderer/shared/Types';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { ILinkifier2, ILinkifierEvent } from 'browser/Types';
import { IOptionsService } from 'common/services/Services';
import { Terminal } from 'xterm';
import { BaseRenderLayer } from './BaseRenderLayer';
@@ -20,9 +21,10 @@ export class LinkRenderLayer extends BaseRenderLayer {
terminal: Terminal,
linkifier2: ILinkifier2,
coreBrowserService: ICoreBrowserService,
optionsService: IOptionsService,
themeService: IThemeService
) {
super(terminal, container, 'link', zIndex, true, coreBrowserService, themeService);
super(terminal, container, 'link', zIndex, true, coreBrowserService, optionsService, themeService);
this.register(linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e)));
this.register(linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e)));