From 095ceda639f15c348c62a015ef4e95ff826c0832 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 30 Oct 2022 14:53:01 -0700 Subject: [PATCH] Show canvas atlas pages in demo --- .../xterm-addon-canvas/src/BaseRenderLayer.ts | 21 +++++++++++++------ addons/xterm-addon-canvas/src/CanvasAddon.ts | 3 +++ .../xterm-addon-canvas/src/CanvasRenderer.ts | 7 ++++++- addons/xterm-addon-canvas/src/Types.d.ts | 1 + .../typings/xterm-addon-canvas.d.ts | 3 +++ demo/client.ts | 2 ++ 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts index b9b74db2..ac82739c 100644 --- a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts @@ -21,6 +21,7 @@ import { IRenderLayer } from './Types'; import { CellColorResolver } from 'browser/renderer/shared/CellColorResolver'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { isSafari } from 'common/Platform'; +import { EventEmitter, forwardEvent } from 'common/EventEmitter'; export abstract class BaseRenderLayer extends Disposable implements IRenderLayer { private _canvas: HTMLCanvasElement; @@ -34,7 +35,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer protected _selectionModel: ISelectionRenderModel = createSelectionRenderModel(); private _cellColorResolver: CellColorResolver; - private _bitmapGenerator?: BitmapGenerator; + private _bitmapGenerator: (BitmapGenerator | undefined)[] = []; protected _charAtlas!: ITextureAtlas; @@ -42,6 +43,9 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer // TODO: Support multiple pages public get cacheCanvas(): HTMLCanvasElement { return this._charAtlas?.pages[0].canvas!; } + private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter()); + public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event; + constructor( private readonly _terminal: Terminal, private _container: HTMLElement, @@ -118,8 +122,12 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer return; } this._charAtlas = acquireTextureAtlas(this._terminal, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr); + // TODO: Dispose this when there's a new atlas + forwardEvent(this._charAtlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas); this._charAtlas.warmUp(); - this._bitmapGenerator = new BitmapGenerator(this._charAtlas.pages[0].canvas); + for (let i = 0; i < this._charAtlas.pages.length; i++) { + this._bitmapGenerator[i] = new BitmapGenerator(this._charAtlas.pages[i].canvas); + } } public resize(dim: IRenderDimensions): void { @@ -368,12 +376,13 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer this._ctx.save(); this._clipRow(y); // Draw the image, use the bitmap if it's available - if (this._charAtlas.pages[0].hasCanvasChanged) { - this._bitmapGenerator?.refresh(); - this._charAtlas.pages[0].hasCanvasChanged = false; + if (this._charAtlas.pages[glyph.texturePage].hasCanvasChanged) { + this._bitmapGenerator[glyph.texturePage]?.refresh(); + this._charAtlas.pages[glyph.texturePage].hasCanvasChanged = false; } + // TODO: Create generator if there's a new page this._ctx.drawImage( - this._bitmapGenerator?.bitmap || this._charAtlas!.pages[0].canvas, + this._bitmapGenerator[glyph.texturePage]?.bitmap || this._charAtlas!.pages[glyph.texturePage].canvas, glyph.texturePosition.x, glyph.texturePosition.y, glyph.size.x, diff --git a/addons/xterm-addon-canvas/src/CanvasAddon.ts b/addons/xterm-addon-canvas/src/CanvasAddon.ts index e39b56f1..2a13c95e 100644 --- a/addons/xterm-addon-canvas/src/CanvasAddon.ts +++ b/addons/xterm-addon-canvas/src/CanvasAddon.ts @@ -17,6 +17,8 @@ export class CanvasAddon extends Disposable implements ITerminalAddon { private readonly _onChangeTextureAtlas = this.register(new EventEmitter()); public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event; + private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter()); + public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event; public get textureAtlas(): HTMLCanvasElement | undefined { return this._renderer?.textureAtlas; @@ -46,6 +48,7 @@ export class CanvasAddon extends Disposable implements ITerminalAddon { this._renderer = new CanvasRenderer(terminal, screenElement, linkifier, bufferService, charSizeService, optionsService, characterJoinerService, coreService, coreBrowserService, decorationService, themeService); this.register(forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas)); + this.register(forwardEvent(this._renderer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas)); renderService.setRenderer(this._renderer); renderService.handleResize(bufferService.cols, bufferService.rows); diff --git a/addons/xterm-addon-canvas/src/CanvasRenderer.ts b/addons/xterm-addon-canvas/src/CanvasRenderer.ts index d4563c5c..090d0e09 100644 --- a/addons/xterm-addon-canvas/src/CanvasRenderer.ts +++ b/addons/xterm-addon-canvas/src/CanvasRenderer.ts @@ -9,7 +9,7 @@ import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils'; import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types'; import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { ILinkifier2 } from 'browser/Types'; -import { EventEmitter } from 'common/EventEmitter'; +import { EventEmitter, forwardEvent } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; import { Terminal } from 'xterm'; @@ -29,6 +29,8 @@ export class CanvasRenderer extends Disposable implements IRenderer { public readonly onRequestRedraw = this._onRequestRedraw.event; private readonly _onChangeTextureAtlas = this.register(new EventEmitter()); public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event; + private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter()); + public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event; constructor( private readonly _terminal: Terminal, @@ -51,6 +53,9 @@ export class CanvasRenderer extends Disposable implements IRenderer { new LinkRenderLayer(this._terminal, this._screenElement, 2, linkifier2, this._bufferService, this._optionsService, decorationService, this._coreBrowserService, _themeService), new CursorRenderLayer(this._terminal, this._screenElement, 3, this._onRequestRedraw, this._bufferService, this._optionsService, coreService, this._coreBrowserService, decorationService, _themeService) ]; + for (const layer of this._renderLayers) { + forwardEvent(layer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas); + } this.dimensions = createRenderDimensions(); this._devicePixelRatio = this._coreBrowserService.dpr; this._updateDimensions(); diff --git a/addons/xterm-addon-canvas/src/Types.d.ts b/addons/xterm-addon-canvas/src/Types.d.ts index 7e582535..73e6c836 100644 --- a/addons/xterm-addon-canvas/src/Types.d.ts +++ b/addons/xterm-addon-canvas/src/Types.d.ts @@ -42,6 +42,7 @@ export interface IRenderLayer extends IDisposable { readonly canvas: HTMLCanvasElement; readonly cacheCanvas: HTMLCanvasElement; + readonly onAddTextureAtlasCanvas: IEvent; /** * Called when the terminal loses focus. */ diff --git a/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts b/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts index 6a2b98d4..73eff529 100644 --- a/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts +++ b/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts @@ -17,6 +17,9 @@ declare module 'xterm-addon-canvas' { */ public readonly onChangeTextureAtlas: IEvent; + // TODO: Doc + public readonly onAddTextureAtlasCanvas: IEvent; + constructor(); /** diff --git a/demo/client.ts b/demo/client.ts index 8e97deae..033ea41b 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -556,11 +556,13 @@ function initAddons(term: TerminalType): void { setTimeout(() => { setTextureAtlas(addons.webgl.instance.textureAtlas); addons.webgl.instance.onChangeTextureAtlas(e => setTextureAtlas(e)); + addons.webgl.instance.onAddTextureAtlasCanvas(e => appendTextureAtlas(e)); }, 0); } else if (name === 'canvas') { setTimeout(() => { setTextureAtlas(addons.canvas.instance.textureAtlas); addons.canvas.instance.onChangeTextureAtlas(e => setTextureAtlas(e)); + addons.canvas.instance.onAddTextureAtlasCanvas(e => appendTextureAtlas(e)); }, 0); } else if (name === 'unicode11') { term.unicode.activeVersion = '11';