From 4fd9b3f249ae7788ff0664f76f875b3202fdced4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 30 Apr 2019 00:58:18 +0200 Subject: [PATCH 1/2] jix joined cell representation as overloaded CellData type --- src/renderer/BaseRenderLayer.ts | 5 +-- src/renderer/CharacterJoinerRegistry.ts | 47 +++++++++++++++++++++++-- src/renderer/TextRenderLayer.ts | 14 ++++---- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index d851b2f26b..00b38dcd3b 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -10,6 +10,7 @@ import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { CellData, AttributeData } from '../BufferLine'; import { WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer'; +import { JoinedCellData } from './CharacterJoinerRegistry'; export abstract class BaseRenderLayer implements IRenderLayer { private _canvas: HTMLCanvasElement; @@ -260,8 +261,8 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { - // skip cache right away if we draw in RGB - if (cell.isFgRGB() || cell.isBgRGB()) { + // skip cache right away if we draw in RGB or have joined cells + if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof JoinedCellData) { this._drawUncachedChars(terminal, cell, x, y); return; } diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 8c521dd9d6..6a47ee2226 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -1,8 +1,51 @@ -import { ITerminal, IBufferLine } from '../Types'; +import { ITerminal, IBufferLine, ICellData, CharData } from '../Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData } from '../BufferLine'; +import { CellData, Content } from '../BufferLine'; import { WHITESPACE_CELL_CHAR } from '../Buffer'; +export class JoinedCellData extends CellData implements ICellData { + private _width: number = 0; + private _code: number = 0x1FFFFF; // highest allowed codepoint, meant as -1 + + public content: number = 0; + public fg: number = 0; + public bg: number = 0; + public combinedData: string = ''; + + constructor(firstCell: ICellData, chars: string, width: number) { + super(); + this.fg = firstCell.fg; + this.bg = firstCell.bg; + this.combinedData = chars; + this._width = width; + } + + public isCombined(): number { + // always mark joined cell data as combined + return Content.IS_COMBINED_MASK; + } + + public getWidth(): number { + return this._width; + } + + public getChars(): string { + return this.combinedData; + } + + public getCode(): number { + return this._code; + } + + public setFromCharData(value: CharData): void { + throw new Error('not implemented'); + } + + public getAsCharData(): CharData { + return [this.fg, this.getChars(), this.getWidth(), this.getCode()]; + } +} + export class CharacterJoinerRegistry implements ICharacterJoinerRegistry { private _characterJoiners: ICharacterJoiner[] = []; diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index c4bdf19fd9..d54008b8ab 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -9,6 +9,7 @@ import { CharData, ITerminal, ICellData } from '../Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; import { CellData, AttributeData, Content } from '../BufferLine'; +import { JoinedCellData } from './CharacterJoinerRegistry'; /** * This CharData looks like a null character, which will forc a clear and render @@ -89,15 +90,12 @@ export class TextRenderLayer extends BaseRenderLayer { // We already know the exact start and end column of the joined range, // so we get the string and width representing it directly - cell = CellData.fromCharData([ - 0, + + cell = new JoinedCellData( + this._workCell, line.translateToString(true, range[0], range[1]), - range[1] - range[0], - 0xFFFFFF - ]); - // hacky: patch attrs - cell.fg = this._workCell.fg; - cell.bg = this._workCell.bg; + range[1] - range[0] + ); // Skip over the cells occupied by this range in the loop lastCharX = range[1] - 1; From ffcdba8d5b86231e5847fa913a0722da0b8f303b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 5 May 2019 21:48:35 +0200 Subject: [PATCH 2/2] simplify JoinedCellData --- src/renderer/BaseRenderLayer.ts | 5 ++++- src/renderer/CharacterJoinerRegistry.ts | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 00b38dcd3b..ace1f6781a 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -261,7 +261,10 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { - // skip cache right away if we draw in RGB or have joined cells + // skip cache right away if we draw in RGB + // Note: to avoid bad runtime JoinedCellData will be skipped + // in the cache handler (atlasDidDraw == false) itself and + // fall through to uncached later down below if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof JoinedCellData) { this._drawUncachedChars(terminal, cell, x, y); return; diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 6a47ee2226..7a3bb8e05b 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -1,15 +1,15 @@ import { ITerminal, IBufferLine, ICellData, CharData } from '../Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData, Content } from '../BufferLine'; +import { CellData, Content, AttributeData } from '../BufferLine'; import { WHITESPACE_CELL_CHAR } from '../Buffer'; -export class JoinedCellData extends CellData implements ICellData { - private _width: number = 0; - private _code: number = 0x1FFFFF; // highest allowed codepoint, meant as -1 - +export class JoinedCellData extends AttributeData implements ICellData { + private _width: number; + // .content carries no meaning for joined CellData, simply nullify it + // thus we have to overload all other .content accessors public content: number = 0; - public fg: number = 0; - public bg: number = 0; + public fg: number; + public bg: number; public combinedData: string = ''; constructor(firstCell: ICellData, chars: string, width: number) { @@ -34,7 +34,9 @@ export class JoinedCellData extends CellData implements ICellData { } public getCode(): number { - return this._code; + // code always gets the highest possible fake codepoint (read as -1) + // this is needed as code is used by caches as identifier + return 0x1FFFFF; } public setFromCharData(value: CharData): void {