From 5c2d5dcd274335f1e7067f45b4a74960f9d9aa4f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Sep 2017 19:34:57 -0700 Subject: [PATCH] Document methods of BaseRenderLayer --- src/renderer/BaseRenderLayer.ts | 94 +++++++++++++++++++++++---- src/renderer/CursorRenderLayer.ts | 10 +-- src/renderer/ForegroundRenderLayer.ts | 2 +- 3 files changed, 88 insertions(+), 18 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 08a229ed..7bb7e9c5 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -41,6 +41,11 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._refreshCharAtlas(terminal, colorSet); } + /** + * Refreshes the char atlas, aquiring a new one if necessary. + * @param terminal The terminal. + * @param colorSet The color set to use for the char atlas. + */ private _refreshCharAtlas(terminal: ITerminal, colorSet: IColorSet): void { this._charAtlas = null; const result = acquireCharAtlas(terminal, this.colors); @@ -68,11 +73,24 @@ export abstract class BaseRenderLayer implements IRenderLayer { public abstract reset(terminal: ITerminal): void; - protected fillCells(startCol: number, startRow: number, colWidth: number, colHeight: number): void { - this._ctx.fillRect(startCol * this.scaledCharWidth, startRow * this.scaledLineHeight, colWidth * this.scaledCharWidth, colHeight * this.scaledLineHeight); + /** + * Fills 1+ cells completely. This uses the existing fillStyle on the context. + * @param x The column to start at. + * @param y The row to start at + * @param width The number of columns to fill. + * @param height The number of rows to fill. + */ + protected fillCells(x: number, y: number, width: number, height: number): void { + this._ctx.fillRect(x * this.scaledCharWidth, y * this.scaledLineHeight, width * this.scaledCharWidth, height * this.scaledLineHeight); } - protected drawBottomLineAtCell(x: number, y: number): void { + /** + * Fills a 1px line (2px on HDPI) at the bottom of the cell. This uses the + * existing fillStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected fillBottomLineAtCell(x: number, y: number): void { this._ctx.fillRect( x * this.scaledCharWidth, (y + 1) * this.scaledLineHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */, @@ -80,7 +98,13 @@ export abstract class BaseRenderLayer implements IRenderLayer { window.devicePixelRatio); } - protected drawLeftLineAtCell(x: number, y: number): void { + /** + * Fills a 1px line (2px on HDPI) at the left of the cell. This uses the + * existing fillStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected fillLeftLineAtCell(x: number, y: number): void { this._ctx.fillRect( x * this.scaledCharWidth, y * this.scaledLineHeight, @@ -88,8 +112,13 @@ export abstract class BaseRenderLayer implements IRenderLayer { this.scaledLineHeight); } - protected drawRectAtCell(x: number, y: number, width: number, height: number, color: string): void { - this._ctx.strokeStyle = color; + /** + * Strokes a 1px rectangle (2px on HDPI) around a cell. This uses the existing + * strokeStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected strokeRectAtCell(x: number, y: number, width: number, height: number): void { this._ctx.lineWidth = window.devicePixelRatio; this._ctx.strokeRect( x * this.scaledCharWidth + window.devicePixelRatio / 2, @@ -98,19 +127,37 @@ export abstract class BaseRenderLayer implements IRenderLayer { (height * this.scaledLineHeight) - window.devicePixelRatio); } + /** + * Clears the entire canvas. + */ protected clearAll(): void { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); } - protected clearCells(startCol: number, startRow: number, colWidth: number, colHeight: number): void { - this._ctx.clearRect(startCol * this.scaledCharWidth, startRow * this.scaledLineHeight, colWidth * this.scaledCharWidth, colHeight * this.scaledLineHeight); + /** + * Clears 1+ cells completely. + * @param x The column to start at. + * @param y The row to start at. + * @param width The number of columns to clear. + * @param height The number of rows to clear. + */ + protected clearCells(x: number, y: number, width: number, height: number): void { + this._ctx.clearRect(x * this.scaledCharWidth, y * this.scaledLineHeight, width * this.scaledCharWidth, height * this.scaledLineHeight); } - protected drawCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number, color: string): void { - this._ctx.save(); + /** + * Draws a truecolor character at the cell. The character will be clipped to + * ensure that it fits with the cell, including the cell to the right if it's + * a wide character. This uses the existing fillStyle on the context. + * @param terminal The terminal. + * @param charData The char data for the character to draw. + * @param x The column to draw at. + * @param y The row to draw at. + * @param color The color of the character. + */ + protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void { this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; this._ctx.textBaseline = 'top'; - this._ctx.fillStyle = color; // Since uncached characters are not coming off the char atlas with source // coordinates, it means that text drawn to the canvas (particularly '_') @@ -119,11 +166,21 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._ctx.beginPath(); this._ctx.rect(x * this.scaledCharWidth, y * this.scaledLineHeight + this.scaledLineDrawY, charData[CHAR_DATA_WIDTH_INDEX] * this.scaledCharWidth, this.scaledCharHeight); this._ctx.clip(); - this._ctx.fillText(charData[CHAR_DATA_CHAR_INDEX], x * this.scaledCharWidth, y * this.scaledCharHeight); - this._ctx.restore(); } + /** + * Draws a character at a cell. If possible this will draw using the character + * atlas to reduce draw time. + * @param terminal The terminal. + * @param char The character. + * @param code The character code. + * @param width The width of the character. + * @param x The column to draw at. + * @param y The row to draw at. + * @param fg The foreground color, in the format stored within the attributes. + * @param bold Whether the text is bold. + */ protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bold: boolean): void { // Clear the cell next to this character if it's wide if (width === 2) { @@ -157,6 +214,17 @@ export abstract class BaseRenderLayer implements IRenderLayer { // this._ctx.drawImage(this._charAtlas, 0, 0); } + /** + * Draws a character at a cell. The character will be clipped to + * ensure that it fits with the cell, including the cell to the right if it's + * a wide character. + * @param terminal The terminal. + * @param char The character. + * @param width The width of the character. + * @param fg The foreground color, in the format stored within the attributes. + * @param x The column to draw at. + * @param y The row to draw at. + */ private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number): void { this._ctx.save(); this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 00abfb93..9f5136ff 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -186,7 +186,7 @@ export class CursorRenderLayer extends BaseRenderLayer { private _renderBarCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { this._ctx.save(); this._ctx.fillStyle = this.colors.cursor; - this.drawLeftLineAtCell(x, y); + this.fillLeftLineAtCell(x, y); this._ctx.restore(); } @@ -194,20 +194,22 @@ export class CursorRenderLayer extends BaseRenderLayer { this._ctx.save(); this._ctx.fillStyle = this.colors.cursor; this.fillCells(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.fillStyle = this.colors.background; + this.fillCharTrueColor(terminal, charData, x, y); this._ctx.restore(); - this.drawCharTrueColor(terminal, charData, x, y, this.colors.background); } private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { this._ctx.save(); this._ctx.fillStyle = this.colors.cursor; - this.drawBottomLineAtCell(x, y); + this.fillBottomLineAtCell(x, y); this._ctx.restore(); } private _renderBlurCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { this._ctx.save(); - this.drawRectAtCell(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1, this.colors.cursor); + this._ctx.strokeStyle = this.colors.cursor; + this.strokeRectAtCell(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1); this._ctx.restore(); } } diff --git a/src/renderer/ForegroundRenderLayer.ts b/src/renderer/ForegroundRenderLayer.ts index ef9c3c60..05141aed 100644 --- a/src/renderer/ForegroundRenderLayer.ts +++ b/src/renderer/ForegroundRenderLayer.ts @@ -139,7 +139,7 @@ export class ForegroundRenderLayer extends BaseRenderLayer { } else { this._ctx.fillStyle = this.colors.foreground; } - this.drawBottomLineAtCell(x, y); + this.fillBottomLineAtCell(x, y); } this.drawChar(terminal, char, code, width, x, y, fg, !!(flags & FLAGS.BOLD));