From c81dfee43c718f86155fd44444eca6b86c40be1b Mon Sep 17 00:00:00 2001 From: tisilent Date: Mon, 21 Aug 2023 20:54:16 +0800 Subject: [PATCH] Using ext to store variants. --- .../xterm-addon-canvas/src/BaseRenderLayer.ts | 9 +++-- addons/xterm-addon-image/src/ImageStorage.ts | 8 +++++ addons/xterm-addon-webgl/src/GlyphRenderer.ts | 4 +-- src/browser/renderer/shared/TextureAtlas.ts | 33 +++++++++---------- src/browser/renderer/shared/Types.d.ts | 4 +-- src/common/Types.d.ts | 2 ++ src/common/buffer/AttributeData.ts | 13 ++++++++ 7 files changed, 49 insertions(+), 24 deletions(-) diff --git a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts index 4622ab42..91d55353 100644 --- a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts @@ -12,7 +12,7 @@ import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRen import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { ReadonlyColorSet } from 'browser/Types'; import { CellData } from 'common/buffer/CellData'; -import { WHITESPACE_CELL_CODE } from 'common/buffer/Constants'; +import { ExtFlags, WHITESPACE_CELL_CODE } from 'common/buffer/Constants'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; import { ICellData, IDisposable } from 'common/Types'; import { Terminal } from 'xterm'; @@ -369,15 +369,18 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer const chars = cell.getChars(); this._cellColorResolver.resolve(cell, x, this._bufferService.buffer.ydisp + y); + this._cellColorResolver.result.ext &= ~ExtFlags.VARIANT_OFFSET; + this._cellColorResolver.result.ext |= (variantOffset << 29) & ExtFlags.VARIANT_OFFSET; + if (!this._charAtlas) { return; } let glyph: IRasterizedGlyph; if (chars && chars.length > 1) { - glyph = this._charAtlas.getRasterizedGlyphCombinedChar(chars, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, variantOffset, true); + glyph = this._charAtlas.getRasterizedGlyphCombinedChar(chars, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, true); } else { - glyph = this._charAtlas.getRasterizedGlyph(cell.getCode() || WHITESPACE_CELL_CODE, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, variantOffset, true); + glyph = this._charAtlas.getRasterizedGlyph(cell.getCode() || WHITESPACE_CELL_CODE, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, true); } if (!glyph.size.x || !glyph.size.y) { return; diff --git a/addons/xterm-addon-image/src/ImageStorage.ts b/addons/xterm-addon-image/src/ImageStorage.ts index 97eef852..ef13ca11 100644 --- a/addons/xterm-addon-image/src/ImageStorage.ts +++ b/addons/xterm-addon-image/src/ImageStorage.ts @@ -53,6 +53,14 @@ class ExtendedAttrsImage implements IExtendedAttrsImage { this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK); } + public get underlineVarinatOffset(): number { + return (this._ext & ExtFlags.VARIANT_OFFSET) >> 29; + } + public set underlineVarinatOffset(value: number) { + this._ext &= ~ExtFlags.VARIANT_OFFSET; + this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET; + } + private _urlId: number = 0; public get urlId(): number { return this._urlId; diff --git a/addons/xterm-addon-webgl/src/GlyphRenderer.ts b/addons/xterm-addon-webgl/src/GlyphRenderer.ts index 09523a9e..cd204a1f 100644 --- a/addons/xterm-addon-webgl/src/GlyphRenderer.ts +++ b/addons/xterm-addon-webgl/src/GlyphRenderer.ts @@ -239,9 +239,9 @@ export class GlyphRenderer extends Disposable { // Get the glyph if (chars && chars.length > 1) { - $glyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext, variantOffset, false); + $glyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext, false); } else { - $glyph = this._atlas.getRasterizedGlyph(code, bg, fg, ext, variantOffset, false); + $glyph = this._atlas.getRasterizedGlyph(code, bg, fg, ext, false); } $leftCellPadding = Math.floor((this._dimensions.device.cell.width - this._dimensions.device.char.width) / 2); diff --git a/src/browser/renderer/shared/TextureAtlas.ts b/src/browser/renderer/shared/TextureAtlas.ts index bc8fd2dc..b063c14b 100644 --- a/src/browser/renderer/shared/TextureAtlas.ts +++ b/src/browser/renderer/shared/TextureAtlas.ts @@ -11,7 +11,7 @@ import { color, NULL_COLOR, rgba } from 'common/Color'; import { tryDrawCustomChar } from 'browser/renderer/shared/CustomGlyphs'; import { excludeFromContrastRatioDemands, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; import { IUnicodeService } from 'common/services/Services'; -import { FiveKeyMap } from 'common/MultiKeyMap'; +import { FourKeyMap } from 'common/MultiKeyMap'; import { IdleTaskQueue } from 'common/TaskQueue'; import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, IRequestRedrawEvent, ITextureAtlas } from 'browser/renderer/shared/Types'; import { EventEmitter } from 'common/EventEmitter'; @@ -58,8 +58,8 @@ let $glyph = undefined; export class TextureAtlas implements ITextureAtlas { private _didWarmUp: boolean = false; - private _cacheMap: FiveKeyMap = new FiveKeyMap(); - private _cacheMapCombined: FiveKeyMap = new FiveKeyMap(); + private _cacheMap: FourKeyMap = new FourKeyMap(); + private _cacheMapCombined: FourKeyMap = new FourKeyMap(); // The texture that the atlas is drawn to private _pages: AtlasPage[] = []; @@ -121,9 +121,9 @@ export class TextureAtlas implements ITextureAtlas { const queue = new IdleTaskQueue(); for (let i = 33; i < 126; i++) { queue.enqueue(() => { - if (!this._cacheMap.get(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, 1)) { - const rasterizedGlyph = this._drawToCache(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, 0); - this._cacheMap.set(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, 1, rasterizedGlyph); + if (!this._cacheMap.get(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT)) { + const rasterizedGlyph = this._drawToCache(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT); + this._cacheMap.set(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, rasterizedGlyph); } }); } @@ -244,30 +244,29 @@ export class TextureAtlas implements ITextureAtlas { } } - public getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, variantOffset: number, restrictToCellHeight: boolean): IRasterizedGlyph { - return this._getFromCacheMap(this._cacheMapCombined, chars, bg, fg, ext, variantOffset, restrictToCellHeight); + public getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph { + return this._getFromCacheMap(this._cacheMapCombined, chars, bg, fg, ext, restrictToCellHeight); } - public getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, variantOffset: number, restrictToCellHeight: boolean): IRasterizedGlyph { - return this._getFromCacheMap(this._cacheMap, code, bg, fg, ext, variantOffset, restrictToCellHeight); + public getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph { + return this._getFromCacheMap(this._cacheMap, code, bg, fg, ext, restrictToCellHeight); } /** * Gets the glyphs texture coords, drawing the texture if it's not already */ private _getFromCacheMap( - cacheMap: FiveKeyMap, + cacheMap: FourKeyMap, key: string | number, bg: number, fg: number, ext: number, - variantOffset: number, restrictToCellHeight: boolean = false ): IRasterizedGlyph { - $glyph = cacheMap.get(key, bg, fg, ext, variantOffset); + $glyph = cacheMap.get(key, bg, fg, ext); if (!$glyph) { - $glyph = this._drawToCache(key, bg, fg, ext, variantOffset, restrictToCellHeight); - cacheMap.set(key, bg, fg, ext, variantOffset, $glyph); + $glyph = this._drawToCache(key, bg, fg, ext, restrictToCellHeight); + cacheMap.set(key, bg, fg, ext, $glyph); } return $glyph; } @@ -428,7 +427,7 @@ export class TextureAtlas implements ITextureAtlas { } @traceCall - private _drawToCache(codeOrChars: number | string, bg: number, fg: number, ext: number,variantOffset: number = 0, restrictToCellHeight: boolean = false): IRasterizedGlyph { + private _drawToCache(codeOrChars: number | string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean = false): IRasterizedGlyph { const chars = typeof codeOrChars === 'number' ? String.fromCharCode(codeOrChars) : codeOrChars; // Uncomment for debugging @@ -548,7 +547,7 @@ export class TextureAtlas implements ITextureAtlas { const yTop = Math.ceil(padding + this._config.deviceCharHeight) - yOffset - (restrictToCellHeight ? lineWidth * 2 : 0); const yMid = yTop + lineWidth; const yBot = yTop + lineWidth * 2; - let nextOffset = variantOffset; + let nextOffset = this._workAttributeData.getUnderlineVarinatOffset(); for (let i = 0; i < chWidth; i++) { this._tmpCtx.save(); diff --git a/src/browser/renderer/shared/Types.d.ts b/src/browser/renderer/shared/Types.d.ts index be910e37..66affd94 100644 --- a/src/browser/renderer/shared/Types.d.ts +++ b/src/browser/renderer/shared/Types.d.ts @@ -109,8 +109,8 @@ export interface ITextureAtlas extends IDisposable { * Clear all glyphs from the texture atlas. */ clearTexture(): void; - getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, variantOffset: number, restrictToCellHeight: boolean): IRasterizedGlyph; - getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, variantOffset: number, restrictToCellHeight: boolean): IRasterizedGlyph; + getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph; + getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph; } /** diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index ca9e25ff..fcd28d19 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -119,6 +119,7 @@ export interface IExtendedAttrs { ext: number; underlineStyle: UnderlineStyle; underlineColor: number; + underlineVarinatOffset: number; urlId: number; clone(): IExtendedAttrs; isEmpty(): boolean; @@ -209,6 +210,7 @@ export interface IAttributeData { isUnderlineColorPalette(): boolean; isUnderlineColorDefault(): boolean; getUnderlineStyle(): number; + getUnderlineVarinatOffset(): number; } /** Cell data */ diff --git a/src/common/buffer/AttributeData.ts b/src/common/buffer/AttributeData.ts index f4d12c2b..5333e108 100644 --- a/src/common/buffer/AttributeData.ts +++ b/src/common/buffer/AttributeData.ts @@ -126,6 +126,11 @@ export class AttributeData implements IAttributeData { ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE) : UnderlineStyle.NONE; } + public getUnderlineVarinatOffset(): number { + return this.fg & FgFlags.UNDERLINE + ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineVarinatOffset : 0) + : 0; + } } @@ -174,6 +179,14 @@ export class ExtendedAttrs implements IExtendedAttrs { this._urlId = value; } + public get underlineVarinatOffset(): number { + return (this._ext & ExtFlags.VARIANT_OFFSET) >> 29; + } + public set underlineVarinatOffset(value: number) { + this._ext &= ~ExtFlags.VARIANT_OFFSET; + this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET; + } + constructor( ext: number = 0, urlId: number = 0