@xterm/addon-webgl 0.20.0-beta.2 → 0.20.0-beta.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/addon-webgl.js +1 -1
- package/lib/addon-webgl.js.map +1 -1
- package/lib/addon-webgl.mjs +5 -31
- package/lib/addon-webgl.mjs.map +4 -4
- package/package.json +4 -4
- package/src/CellColorResolver.ts +5 -2
- package/src/CharAtlasCache.ts +6 -3
- package/src/CharAtlasUtils.ts +2 -2
- package/src/CursorBlinkStateManager.ts +67 -8
- package/src/DevicePixelObserver.ts +1 -1
- package/src/GlyphRenderer.ts +3 -3
- package/src/RectangleRenderer.ts +1 -1
- package/src/TextureAtlas.ts +77 -56
- package/src/Types.ts +3 -3
- package/src/WebglAddon.ts +16 -18
- package/src/WebglRenderer.ts +65 -11
- package/src/customGlyphs/CustomGlyphDefinitions.ts +1019 -0
- package/src/customGlyphs/CustomGlyphRasterizer.ts +740 -0
- package/src/customGlyphs/Types.ts +85 -0
- package/src/renderLayer/BaseRenderLayer.ts +1 -1
- package/typings/addon-webgl.d.ts +31 -1
- package/src/CustomGlyphs.ts +0 -839
package/src/WebglRenderer.ts
CHANGED
|
@@ -13,7 +13,8 @@ import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeS
|
|
|
13
13
|
import { CharData, IBufferLine, ICellData } from 'common/Types';
|
|
14
14
|
import { AttributeData } from 'common/buffer/AttributeData';
|
|
15
15
|
import { CellData } from 'common/buffer/CellData';
|
|
16
|
-
import { Attributes, Content, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
|
|
16
|
+
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
|
|
17
|
+
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
|
|
17
18
|
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
|
18
19
|
import { Terminal } from '@xterm/xterm';
|
|
19
20
|
import { GlyphRenderer } from './GlyphRenderer';
|
|
@@ -22,14 +23,15 @@ import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_BG_OFFSET, RENDER_MODEL_EXT_OFFSET
|
|
|
22
23
|
import { IWebGL2RenderingContext, type ITextureAtlas } from './Types';
|
|
23
24
|
import { LinkRenderLayer } from './renderLayer/LinkRenderLayer';
|
|
24
25
|
import { IRenderLayer } from './renderLayer/Types';
|
|
25
|
-
import { Emitter,
|
|
26
|
-
import { addDisposableListener } from '
|
|
27
|
-
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from '
|
|
26
|
+
import { Emitter, EventUtils } from 'common/Event';
|
|
27
|
+
import { addDisposableListener } from 'browser/Dom';
|
|
28
|
+
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
28
29
|
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
|
|
29
30
|
|
|
30
31
|
export class WebglRenderer extends Disposable implements IRenderer {
|
|
31
32
|
private _renderLayers: IRenderLayer[];
|
|
32
|
-
private _cursorBlinkStateManager: MutableDisposable<CursorBlinkStateManager> = new MutableDisposable();
|
|
33
|
+
private _cursorBlinkStateManager: MutableDisposable<CursorBlinkStateManager> = this._register(new MutableDisposable());
|
|
34
|
+
private _textBlinkStateManager: TextBlinkStateManager;
|
|
33
35
|
private _charAtlasDisposable = this._register(new MutableDisposable());
|
|
34
36
|
private _charAtlas: ITextureAtlas | undefined;
|
|
35
37
|
private _devicePixelRatio: number;
|
|
@@ -37,8 +39,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
37
39
|
private _observerDisposable = this._register(new MutableDisposable());
|
|
38
40
|
|
|
39
41
|
private _model: RenderModel = new RenderModel();
|
|
42
|
+
private _rowHasBlinkingCells: boolean[] = [];
|
|
43
|
+
private _rowHasBlinkingCellsCount: number = 0;
|
|
40
44
|
private _workCell: ICellData = new CellData();
|
|
41
|
-
private _workCell2: ICellData = new CellData();
|
|
42
45
|
private _cellColorResolver: CellColorResolver;
|
|
43
46
|
|
|
44
47
|
private _canvas: HTMLCanvasElement;
|
|
@@ -72,6 +75,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
72
75
|
private readonly _decorationService: IDecorationService,
|
|
73
76
|
private readonly _optionsService: IOptionsService,
|
|
74
77
|
private readonly _themeService: IThemeService,
|
|
78
|
+
private readonly _customGlyphs: boolean = true,
|
|
75
79
|
preserveDrawingBuffer?: boolean
|
|
76
80
|
) {
|
|
77
81
|
super();
|
|
@@ -104,6 +108,12 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
104
108
|
this._updateDimensions();
|
|
105
109
|
this._updateCursorBlink();
|
|
106
110
|
this._register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
|
|
111
|
+
this._textBlinkStateManager = this._register(new TextBlinkStateManager(
|
|
112
|
+
() => this._requestRedrawViewport(),
|
|
113
|
+
this._coreBrowserService,
|
|
114
|
+
this._optionsService
|
|
115
|
+
));
|
|
116
|
+
this._resetBlinkingRowState();
|
|
107
117
|
|
|
108
118
|
this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
|
|
109
119
|
|
|
@@ -135,6 +145,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
135
145
|
this._observerDisposable.value = observeDevicePixelDimensions(this._canvas, w, (w, h) => this._setCanvasDevicePixelDimensions(w, h));
|
|
136
146
|
}));
|
|
137
147
|
|
|
148
|
+
this._register(addDisposableListener(this._coreBrowserService.mainDocument, 'mousedown', () => this._cursorBlinkStateManager.value?.restartBlinkAnimation()));
|
|
149
|
+
|
|
138
150
|
this._core.screenElement!.appendChild(this._canvas);
|
|
139
151
|
|
|
140
152
|
[this._rectangleRenderer.value, this._glyphRenderer.value] = this._initializeWebGLState();
|
|
@@ -175,6 +187,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
175
187
|
this._updateDimensions();
|
|
176
188
|
|
|
177
189
|
this._model.resize(this._terminal.cols, this._terminal.rows);
|
|
190
|
+
this._resetBlinkingRowState();
|
|
178
191
|
|
|
179
192
|
// Resize all render layers
|
|
180
193
|
for (const l of this._renderLayers) {
|
|
@@ -201,6 +214,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
201
214
|
// Force a full refresh. Resizing `_glyphRenderer` should clear it already,
|
|
202
215
|
// so there is no need to clear it again here.
|
|
203
216
|
this._clearModel(false);
|
|
217
|
+
|
|
218
|
+
// Render synchronously to avoid flicker when the canvas is cleared
|
|
219
|
+
this._onRequestRedraw.fire({ start: 0, end: this._terminal.rows - 1, sync: true });
|
|
204
220
|
}
|
|
205
221
|
|
|
206
222
|
public handleCharSizeChanged(): void {
|
|
@@ -225,6 +241,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
225
241
|
this._requestRedrawViewport();
|
|
226
242
|
}
|
|
227
243
|
|
|
244
|
+
public handleViewportVisibilityChange(isVisible: boolean): void {
|
|
245
|
+
this._textBlinkStateManager.setViewportVisible(isVisible);
|
|
246
|
+
}
|
|
247
|
+
|
|
228
248
|
public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
|
229
249
|
for (const l of this._renderLayers) {
|
|
230
250
|
l.handleSelectionChanged(this._terminal, start, end, columnSelectMode);
|
|
@@ -278,13 +298,14 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
278
298
|
this.dimensions.device.char.width,
|
|
279
299
|
this.dimensions.device.char.height,
|
|
280
300
|
this._coreBrowserService.dpr,
|
|
281
|
-
this._deviceMaxTextureSize
|
|
301
|
+
this._deviceMaxTextureSize,
|
|
302
|
+
this._customGlyphs
|
|
282
303
|
);
|
|
283
304
|
if (this._charAtlas !== atlas) {
|
|
284
305
|
this._onChangeTextureAtlas.fire(atlas.pages[0].canvas);
|
|
285
306
|
this._charAtlasDisposable.value = combinedDisposable(
|
|
286
|
-
|
|
287
|
-
|
|
307
|
+
EventUtils.forward(atlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas),
|
|
308
|
+
EventUtils.forward(atlas.onRemoveTextureAtlasCanvas, this._onRemoveTextureAtlasCanvas)
|
|
288
309
|
);
|
|
289
310
|
}
|
|
290
311
|
this._charAtlas = atlas;
|
|
@@ -316,6 +337,9 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
316
337
|
l.reset(this._terminal);
|
|
317
338
|
}
|
|
318
339
|
|
|
340
|
+
this._resetBlinkingRowState();
|
|
341
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(false);
|
|
342
|
+
|
|
319
343
|
this._cursorBlinkStateManager.value?.restartBlinkAnimation();
|
|
320
344
|
this._updateCursorBlink();
|
|
321
345
|
}
|
|
@@ -413,6 +437,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
413
437
|
for (y = start; y <= end; y++) {
|
|
414
438
|
row = y + terminal.buffer.ydisp;
|
|
415
439
|
line = terminal.buffer.lines.get(row)!;
|
|
440
|
+
let rowHasBlinkingCells = false;
|
|
416
441
|
this._model.lineLengths[y] = 0;
|
|
417
442
|
isCursorRow = cursorY === row;
|
|
418
443
|
skipJoinedCheckUntilX = 0;
|
|
@@ -470,8 +495,12 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
470
495
|
code = cell.getCode();
|
|
471
496
|
i = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL;
|
|
472
497
|
|
|
498
|
+
if (!rowHasBlinkingCells && cell.isBlink()) {
|
|
499
|
+
rowHasBlinkingCells = true;
|
|
500
|
+
}
|
|
501
|
+
|
|
473
502
|
// Load colors/resolve overrides into work colors
|
|
474
|
-
this._cellColorResolver.resolve(cell, x, row, this.dimensions.device.cell.width);
|
|
503
|
+
this._cellColorResolver.resolve(cell, x, row, this.dimensions.device.cell.width, this.dimensions.device.cell.height);
|
|
475
504
|
|
|
476
505
|
// Override colors for cursor cell
|
|
477
506
|
if (isCursorVisible && row === cursorY) {
|
|
@@ -499,6 +528,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
499
528
|
}
|
|
500
529
|
}
|
|
501
530
|
|
|
531
|
+
if (this._textBlinkStateManager.isEnabled && !this._textBlinkStateManager.isBlinkOn && cell.isBlink()) {
|
|
532
|
+
this._cellColorResolver.result.fg |= FgFlags.INVISIBLE;
|
|
533
|
+
}
|
|
534
|
+
|
|
502
535
|
if (code !== NULL_CELL_CODE) {
|
|
503
536
|
this._model.lineLengths[y] = x + 1;
|
|
504
537
|
}
|
|
@@ -545,11 +578,31 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
545
578
|
x--; // Go back to the previous update cell for next iteration
|
|
546
579
|
}
|
|
547
580
|
}
|
|
581
|
+
this._setRowBlinkState(y, rowHasBlinkingCells);
|
|
548
582
|
}
|
|
549
583
|
if (modelUpdated) {
|
|
550
584
|
this._rectangleRenderer.value!.updateBackgrounds(this._model);
|
|
551
585
|
}
|
|
552
586
|
this._rectangleRenderer.value!.updateCursor(this._model);
|
|
587
|
+
this._updateTextBlinkState();
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
private _resetBlinkingRowState(): void {
|
|
591
|
+
this._rowHasBlinkingCells = new Array(this._terminal.rows).fill(false);
|
|
592
|
+
this._rowHasBlinkingCellsCount = 0;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {
|
|
596
|
+
const previous = this._rowHasBlinkingCells[row];
|
|
597
|
+
if (previous === hasBlinkingCells) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
this._rowHasBlinkingCells[row] = hasBlinkingCells;
|
|
601
|
+
this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
private _updateTextBlinkState(): void {
|
|
605
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);
|
|
553
606
|
}
|
|
554
607
|
|
|
555
608
|
/**
|
|
@@ -615,7 +668,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
|
|
615
668
|
// the change as it's an exact multiple of the cell sizes.
|
|
616
669
|
this._canvas.width = width;
|
|
617
670
|
this._canvas.height = height;
|
|
618
|
-
|
|
671
|
+
// Render synchronously to avoid flicker when the canvas is cleared
|
|
672
|
+
this._onRequestRedraw.fire({ start: 0, end: this._terminal.rows - 1, sync: true });
|
|
619
673
|
}
|
|
620
674
|
|
|
621
675
|
private _requestRedrawViewport(): void {
|