diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 66b07fac..92e95cd2 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -44,6 +44,40 @@ export abstract class BaseRenderLayer implements IRenderLayer { } } } + + protected drawChar(char: string, code: number, fg: number, x: number, y: number, scaledCharWidth: number, scaledCharHeight: number): void { + let colorIndex = 0; + if (fg < 256) { + colorIndex = fg + 1; + } + if (code < 256 && (colorIndex > 0 || fg > 255)) { + // ImageBitmap's draw about twice as fast as from a canvas + this._ctx.drawImage(BaseRenderLayer._charAtlas, + code * scaledCharWidth, colorIndex * scaledCharHeight, scaledCharWidth, scaledCharHeight, + x * scaledCharWidth, y * scaledCharHeight, scaledCharWidth, scaledCharHeight); + } else { + this._drawUncachedChar(char, fg, x, y, scaledCharWidth, scaledCharHeight); + } + // This draws the atlas (for debugging purposes) + // this._ctx.drawImage(BaseRenderLayer._charAtlas, 0, 0); + } + + private _drawUncachedChar(char: string, fg: number, x: number, y: number, scaledCharWidth: number, scaledCharHeight: number): void { + this._ctx.save(); + this._ctx.font = `${16 * window.devicePixelRatio}px courier`; + this._ctx.textBaseline = 'top'; + + // 256 color support + if (fg < 256) { + this._ctx.fillStyle = COLORS[fg]; + } else { + this._ctx.fillStyle = '#ffffff'; + } + + // TODO: Do we care about width for rendering wide chars? + this._ctx.fillText(char, x * scaledCharWidth, y * scaledCharHeight); + this._ctx.restore(); + } } class CharAtlasGenerator { diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 11496610..da32aaa8 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -1,6 +1,6 @@ import { IDataRenderLayer } from './Interfaces'; import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces'; -import { CHAR_DATA_ATTR_INDEX } from '../Buffer'; +import { CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; import { COLORS } from './Color'; import { GridCache } from './GridCache'; import { FLAGS } from './Types'; @@ -43,14 +43,14 @@ export class CursorRenderLayer extends BaseRenderLayer implements IDataRenderLay this._clearCursor(scaledCharWidth, scaledCharHeight); } - // TODO: Draw text in COLORS[0], using the char atlas if possible - // const charData = terminal.buffer.lines.get(viewportRelativeCursorY)[terminal.buffer.x]; - this._ctx.save(); this._ctx.fillStyle = COLORS[7]; this._ctx.fillRect(terminal.buffer.x * scaledCharWidth, viewportRelativeCursorY * scaledCharHeight, scaledCharWidth, scaledCharHeight); this._ctx.restore(); + const charData = terminal.buffer.lines.get(viewportRelativeCursorY)[terminal.buffer.x]; + this.drawChar(charData[CHAR_DATA_CHAR_INDEX], charData[CHAR_DATA_CODE_INDEX], 0, terminal.buffer.x, viewportRelativeCursorY, scaledCharWidth, scaledCharHeight); + this._state = [terminal.buffer.x, viewportRelativeCursorY]; } diff --git a/src/renderer/ForegroundRenderLayer.ts b/src/renderer/ForegroundRenderLayer.ts index 38700712..c3cb833f 100644 --- a/src/renderer/ForegroundRenderLayer.ts +++ b/src/renderer/ForegroundRenderLayer.ts @@ -26,6 +26,7 @@ export class ForegroundRenderLayer extends BaseRenderLayer implements IDataRende // TODO: Ensure that the render is eventually performed // Don't bother render until the atlas bitmap is ready + // TODO: Move this to BaseRenderLayer? if (!BaseRenderLayer._charAtlas) { return; } @@ -81,40 +82,8 @@ export class ForegroundRenderLayer extends BaseRenderLayer implements IDataRende } } - let colorIndex = 0; - if (fg < 16) { - colorIndex = fg + 1; - } - - if (code < 256 && (colorIndex > 0 || fg > 255)) { - // ImageBitmap's draw about twice as fast as from a canvas - this._ctx.drawImage(BaseRenderLayer._charAtlas, code * scaledCharWidth, colorIndex * scaledCharHeight, scaledCharWidth, scaledCharHeight, x * scaledCharWidth, y * scaledCharHeight, scaledCharWidth, scaledCharHeight); - } else { - // TODO: Evaluate how long it takes to convert from a number - const width: number = charData[CHAR_DATA_WIDTH_INDEX]; - this._drawUncachedChar(char, width, fg, x, y, scaledCharWidth, scaledCharHeight); - } + this.drawChar(char, code, fg, x, y, scaledCharWidth, scaledCharHeight); } } - - // This draws the atlas (for debugging purposes) - // this._ctx.drawImage(this._charAtlas, 0, 0); - } - - private _drawUncachedChar(char: string, width: number, fg: number, x: number, y: number, scaledCharWidth: number, scaledCharHeight: number): void { - this._ctx.save(); - this._ctx.font = `${16 * window.devicePixelRatio}px courier`; - this._ctx.textBaseline = 'top'; - - // 256 color support - if (fg < 256) { - this._ctx.fillStyle = COLORS[fg]; - } else { - this._ctx.fillStyle = '#ffffff'; - } - - // TODO: Do we care about width for rendering wide chars? - this._ctx.fillText(char, x * scaledCharWidth, y * scaledCharHeight); - this._ctx.restore(); } }