Logic move to CellColorResolver

This commit is contained in:
tisilent
2023-08-24 10:57:05 +08:00
parent 25afc19895
commit 2b0106f7e2
14 changed files with 106 additions and 106 deletions
@@ -13,7 +13,7 @@ import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { ReadonlyColorSet } from 'browser/Types';
import { CellData } from 'common/buffer/CellData';
import { ExtFlags, WHITESPACE_CELL_CODE } from 'common/buffer/Constants';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
import { IBufferService, IDecorationService, IOptionsService, IUnicodeService } from 'common/services/Services';
import { ICellData, IDisposable } from 'common/Types';
import { Terminal } from 'xterm';
import { IRenderLayer } from './Types';
@@ -55,10 +55,11 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
protected readonly _bufferService: IBufferService,
protected readonly _optionsService: IOptionsService,
protected readonly _decorationService: IDecorationService,
protected readonly _coreBrowserService: ICoreBrowserService
protected readonly _coreBrowserService: ICoreBrowserService,
private readonly _unicodeService: IUnicodeService
) {
super();
this._cellColorResolver = new CellColorResolver(this._terminal, this._selectionModel, this._decorationService, this._coreBrowserService, this._themeService);
this._cellColorResolver = new CellColorResolver(this._terminal, this._selectionModel, this._decorationService, this._coreBrowserService, this._themeService, _unicodeService);
this._canvas = document.createElement('canvas');
this._canvas.classList.add(`xterm-${id}-layer`);
this._canvas.style.zIndex = zIndex.toString();
@@ -365,12 +366,9 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
* Draws one or more characters at a cell. If possible this will draw using
* the character atlas to reduce draw time.
*/
protected _drawChars(cell: ICellData, x: number, y: number, variantOffset: number = 0): void {
protected _drawChars(cell: ICellData, x: number, y: number): void {
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;
this._cellColorResolver.resolve(cell, x, this._bufferService.buffer.ydisp + y, this._deviceCellWidth);
if (!this._charAtlas) {
return;
+1 -1
View File
@@ -54,7 +54,7 @@ export class CanvasAddon extends Disposable implements ITerminalAddon {
setTraceLogger(logService);
this._renderer = new CanvasRenderer(terminal, screenElement, linkifier, bufferService, charSizeService, optionsService, characterJoinerService, coreService, coreBrowserService, decorationService, themeService, unicodeService);
this.register(forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas));
this.register(forwardEvent(this._renderer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas));
renderService.setRenderer(this._renderer);
@@ -50,9 +50,9 @@ export class CanvasRenderer extends Disposable implements IRenderer {
const allowTransparency = this._optionsService.rawOptions.allowTransparency;
this._renderLayers = [
new TextRenderLayer(this._terminal, this._screenElement, 0, allowTransparency, this._bufferService, this._optionsService, characterJoinerService, decorationService, this._coreBrowserService, _themeService, _unicodeService),
new SelectionRenderLayer(this._terminal, this._screenElement, 1, this._bufferService, this._coreBrowserService, decorationService, this._optionsService, _themeService),
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)
new SelectionRenderLayer(this._terminal, this._screenElement, 1, this._bufferService, this._coreBrowserService, decorationService, this._optionsService, _themeService, _unicodeService),
new LinkRenderLayer(this._terminal, this._screenElement, 2, linkifier2, this._bufferService, this._optionsService, decorationService, this._coreBrowserService, _themeService, _unicodeService),
new CursorRenderLayer(this._terminal, this._screenElement, 3, this._onRequestRedraw, this._bufferService, this._optionsService, coreService, this._coreBrowserService, decorationService, _themeService, _unicodeService)
];
for (const layer of this._renderLayers) {
forwardEvent(layer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas);
@@ -8,7 +8,7 @@ import { BaseRenderLayer } from './BaseRenderLayer';
import { ICellData } from 'common/Types';
import { CellData } from 'common/buffer/CellData';
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
import { IBufferService, IOptionsService, ICoreService, IDecorationService } from 'common/services/Services';
import { IBufferService, IOptionsService, ICoreService, IDecorationService, IUnicodeService } from 'common/services/Services';
import { IEventEmitter } from 'common/EventEmitter';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { Terminal } from 'xterm';
@@ -45,9 +45,10 @@ export class CursorRenderLayer extends BaseRenderLayer {
private readonly _coreService: ICoreService,
coreBrowserService: ICoreBrowserService,
decorationService: IDecorationService,
themeService: IThemeService
themeService: IThemeService,
unicodeService: IUnicodeService
) {
super(terminal, container, 'cursor', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService);
super(terminal, container, 'cursor', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService, unicodeService);
this._state = {
x: 0,
y: 0,
@@ -8,7 +8,7 @@ import { BaseRenderLayer } from './BaseRenderLayer';
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { IColorSet, ILinkifierEvent, ILinkifier2, ReadonlyColorSet } from 'browser/Types';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
import { IBufferService, IDecorationService, IOptionsService, IUnicodeService } from 'common/services/Services';
import { is256Color } from 'browser/renderer/shared/CharAtlasUtils';
import { Terminal } from 'xterm';
@@ -24,9 +24,10 @@ export class LinkRenderLayer extends BaseRenderLayer {
optionsService: IOptionsService,
decorationService: IDecorationService,
coreBrowserService: ICoreBrowserService,
themeService: IThemeService
themeService: IThemeService,
unicodeService: IUnicodeService
) {
super(terminal, container, 'link', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService);
super(terminal, container, 'link', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService, unicodeService);
this.register(linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e)));
this.register(linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e)));
@@ -5,7 +5,7 @@
import { IRenderDimensions } from 'browser/renderer/shared/Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
import { IBufferService, IDecorationService, IOptionsService, IUnicodeService } from 'common/services/Services';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { Terminal } from 'xterm';
@@ -27,9 +27,10 @@ export class SelectionRenderLayer extends BaseRenderLayer {
coreBrowserService: ICoreBrowserService,
decorationService: IDecorationService,
optionsService: IOptionsService,
themeService: IThemeService
themeService: IThemeService,
unicodeService: IUnicodeService
) {
super(terminal, container, 'selection', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService);
super(terminal, container, 'selection', zIndex, true, themeService, bufferService, optionsService, decorationService, coreBrowserService, unicodeService);
this._clearState();
}
@@ -16,6 +16,7 @@ import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'bro
import { JoinedCellData } from 'browser/services/CharacterJoinerService';
import { color, css } from 'common/Color';
import { Terminal } from 'xterm';
import { computeVarinatOffset } from 'browser/renderer/shared/RendererUtils';
/**
* This CharData looks like a null character, which will forc a clear and render
@@ -42,9 +43,9 @@ export class TextRenderLayer extends BaseRenderLayer {
decorationService: IDecorationService,
coreBrowserService: ICoreBrowserService,
themeService: IThemeService,
private readonly _unicodeService: IUnicodeService
unicodeService: IUnicodeService
) {
super(terminal, container, 'text', zIndex, alpha, themeService, bufferService, optionsService, decorationService, coreBrowserService);
super(terminal, container, 'text', zIndex, alpha, themeService, bufferService, optionsService, decorationService, coreBrowserService, unicodeService);
this._state = new GridCache<CharData>();
this.register(optionsService.onSpecificOptionChange('allowTransparency', value => this._setTransparency(value)));
}
@@ -75,20 +76,13 @@ export class TextRenderLayer extends BaseRenderLayer {
callback: (
cell: ICellData,
x: number,
y: number,
variantOffset: number
y: number
) => void
): void {
const fontSize = this._optionsService.rawOptions.fontSize;
const drp = this._coreBrowserService.dpr;
const lineWidth = Math.max(1, Math.floor(fontSize * drp / 15));
const deviceCellWidth = this._charAtlas?.getDeviceCellWidth();
let variantOffset: number = -1;
for (let y = firstRow; y <= lastRow; y++) {
const row = y + this._bufferService.buffer.ydisp;
const line = this._bufferService.buffer.lines.get(row);
const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
variantOffset = 0;
for (let x = 0; x < this._bufferService.cols; x++) {
line!.loadCell(x, this._workCell);
let cell = this._workCell;
@@ -100,20 +94,9 @@ export class TextRenderLayer extends BaseRenderLayer {
// The character to the left is a wide character, drawing is owned by
// the char at x-1
if (cell.getWidth() === 0) {
if (cell.extended.underlineStyle !== UnderlineStyle.DOTTED) {
variantOffset = 0;
}
continue;
}
const code = cell.getCode();
let chWidth: number;
if (typeof code === 'number') {
chWidth = this._unicodeService.wcwidth(code);
} else {
chWidth = this._unicodeService.getStringCellWidth(code);
}
// exit early for NULL and SP
// NOTE: commented out due to #4120 (needs a more clever patch to keep things performant)
// const code = cell.getCode();
@@ -167,18 +150,9 @@ export class TextRenderLayer extends BaseRenderLayer {
callback(
cell,
x,
y,
variantOffset
y
);
if (cell.extended.underlineStyle === UnderlineStyle.DOTTED) {
if (code !== NULL_CELL_CODE) {
variantOffset = ((deviceCellWidth! * chWidth) - ((lineWidth * 2) - variantOffset)) % (lineWidth * 2);
}
} else {
variantOffset = 0;
}
x = lastCharX;
}
}
@@ -263,7 +237,7 @@ export class TextRenderLayer extends BaseRenderLayer {
}
private _drawForeground(firstRow: number, lastRow: number): void {
this._forEachCell(firstRow, lastRow, (cell, x, y, variantOffset) => this._drawChars(cell, x, y, variantOffset ?? 0));
this._forEachCell(firstRow, lastRow, (cell, x, y) => this._drawChars(cell, x, y));
}
public handleGridChanged(firstRow: number, lastRow: number): void {
+5 -1
View File
@@ -54,7 +54,11 @@ class ExtendedAttrsImage implements IExtendedAttrsImage {
}
public get underlineVarinatOffset(): number {
return (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;
const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;
if (val < 0) {
return val ^ 4294967288;
}
return val;
}
public set underlineVarinatOffset(value: number) {
this._ext &= ~ExtFlags.VARIANT_OFFSET;
+3 -39
View File
@@ -14,7 +14,7 @@ import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IThemeS
import { ITerminal } from 'browser/Types';
import { AttributeData } from 'common/buffer/AttributeData';
import { CellData } from 'common/buffer/CellData';
import { Attributes, Content, ExtFlags, NULL_CELL_CHAR, NULL_CELL_CODE, UnderlineStyle } from 'common/buffer/Constants';
import { Attributes, Content, NULL_CELL_CHAR, NULL_CELL_CODE, UnderlineStyle } from 'common/buffer/Constants';
import { EventEmitter, forwardEvent } from 'common/EventEmitter';
import { Disposable, MutableDisposable, getDisposeArrayDisposable, toDisposable } from 'common/Lifecycle';
import { ICoreService, IDecorationService, ILogService, IOptionsService, IUnicodeService } from 'common/services/Services';
@@ -78,7 +78,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
this.register(this._themeService.onChangeColors(() => this._handleColorChange()));
this._cellColorResolver = new CellColorResolver(this._terminal, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService);
this._cellColorResolver = new CellColorResolver(this._terminal, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService, this._unicodeService);
this._core = (this._terminal as any)._core;
@@ -396,7 +396,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
let i: number;
let x: number;
let j: number;
let variantOffset: number = -1;
start = clamp(start, terminal.rows - 1, 0);
end = clamp(end, terminal.rows - 1, 0);
@@ -411,18 +410,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._model.cursor = undefined;
let modelUpdated = false;
const fontSize = this._optionsService.rawOptions.fontSize;
const drp = this._coreBrowserService.dpr;
const lineWidth = Math.max(1, Math.floor(fontSize * drp / 15));
const deviceCellWidth = this._charAtlas?.getDeviceCellWidth();
for (y = start; y <= end; y++) {
row = y + terminal.buffer.ydisp;
line = terminal.buffer.lines.get(row)!;
this._model.lineLengths[y] = 0;
joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
// row start variant init
variantOffset = 0;
for (x = 0; x < terminal.cols; x++) {
lastBg = this._cellColorResolver.result.bg;
line.loadCell(x, cell);
@@ -457,17 +449,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
chars = cell.getChars();
code = cell.getCode();
let chWidth: number;
if (typeof code === 'number') {
chWidth = this._unicodeService.wcwidth(code);
} else {
chWidth = this._unicodeService.getStringCellWidth(code);
}
i = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL;
// Load colors/resolve overrides into work colors
this._cellColorResolver.resolve(cell, x, row);
this._cellColorResolver.resolve(cell, x, row, this.dimensions.device.cell.width);
// Override colors for cursor cell
if (isCursorVisible && row === cursorY) {
@@ -497,27 +482,13 @@ export class WebglRenderer extends Disposable implements IRenderer {
if (code !== NULL_CELL_CODE) {
this._model.lineLengths[y] = x + 1;
} else {
if (cell.extended.underlineStyle !== UnderlineStyle.DOTTED) {
variantOffset = 0;
}
}
this._cellColorResolver.result.ext &= ~ExtFlags.VARIANT_OFFSET;
this._cellColorResolver.result.ext |= (variantOffset << 29) & ExtFlags.VARIANT_OFFSET;
// Nothing has changed, no updates needed
if (this._model.cells[i] === code &&
this._model.cells[i + RENDER_MODEL_BG_OFFSET] === this._cellColorResolver.result.bg &&
this._model.cells[i + RENDER_MODEL_FG_OFFSET] === this._cellColorResolver.result.fg &&
this._model.cells[i + RENDER_MODEL_EXT_OFFSET] === this._cellColorResolver.result.ext) {
if (cell.extended.underlineStyle === UnderlineStyle.DOTTED) {
if (code !== NULL_CELL_CODE) {
variantOffset = ((deviceCellWidth! * chWidth) - ((lineWidth * 2) - variantOffset)) % (lineWidth * 2);
}
} else {
variantOffset = 0;
}
continue;
}
@@ -535,13 +506,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._model.cells[i + RENDER_MODEL_EXT_OFFSET] = this._cellColorResolver.result.ext;
this._glyphRenderer!.updateCell(x, y, code, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext, chars, lastBg);
if (cell.extended.underlineStyle === UnderlineStyle.DOTTED) {
if (code !== NULL_CELL_CODE) {
variantOffset = ((deviceCellWidth! * chWidth) - ((lineWidth * 2) - variantOffset)) % (lineWidth * 2);
}
} else {
variantOffset = 0;
}
if (isJoined) {
// Restore work cell
@@ -1,8 +1,9 @@
import { computeVarinatOffset } from 'browser/renderer/shared/RendererUtils';
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
import { Attributes, BgFlags, FgFlags } from 'common/buffer/Constants';
import { IDecorationService } from 'common/services/Services';
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from 'common/buffer/Constants';
import { IDecorationService, IUnicodeService } from 'common/services/Services';
import { ICellData } from 'common/Types';
import { Terminal } from 'xterm';
@@ -13,6 +14,9 @@ let $hasFg = false;
let $hasBg = false;
let $isSelected = false;
let $colors: ReadonlyColorSet | undefined;
let $x = -1;
let $y = -1;
let $variantOffset = 0;
export class CellColorResolver {
/**
@@ -30,7 +34,8 @@ export class CellColorResolver {
private readonly _selectionRenderModel: ISelectionRenderModel,
private readonly _decorationService: IDecorationService,
private readonly _coreBrowserService: ICoreBrowserService,
private readonly _themeService: IThemeService
private readonly _themeService: IThemeService,
private readonly _unicodeService: IUnicodeService
) {
}
@@ -38,7 +43,7 @@ export class CellColorResolver {
* Resolves colors for the cell, putting the result into the shared {@link result}. This resolves
* overrides, inverse and selection for the cell which can then be used to feed into the renderer.
*/
public resolve(cell: ICellData, x: number, y: number): void {
public resolve(cell: ICellData, x: number, y: number,deviceCellWidth: number): void {
this.result.bg = cell.bg;
this.result.fg = cell.fg;
this.result.ext = cell.bg & BgFlags.HAS_EXTENDED ? cell.extended.ext : 0;
@@ -53,6 +58,26 @@ export class CellColorResolver {
$isSelected = false;
$colors = this._themeService.colors;
if ($y !== y) {
$variantOffset = 0;
}
$x = x;
$y = y;
const code = cell.getCode();
if (code === NULL_CELL_CODE && cell.extended.underlineStyle !== UnderlineStyle.DOTTED) {
$variantOffset = 0;
}
const fontSize = this._terminal.options.fontSize;
const drp = this._coreBrowserService.dpr;
const lineWidth = Math.max(1, Math.floor(fontSize! * drp / 15));
let chWidth: number;
if (typeof code === 'number') {
chWidth = this._unicodeService.wcwidth(code);
} else {
chWidth = this._unicodeService.getStringCellWidth(code);
}
// Apply decorations on the bottom layer
this._decorationService.forEachDecorationAtCell(x, y, 'bottom', d => {
if (d.backgroundColorRGB) {
@@ -133,5 +158,17 @@ export class CellColorResolver {
// Use the override if it exists
this.result.bg = $hasBg ? $bg : this.result.bg;
this.result.fg = $hasFg ? $fg : this.result.fg;
this.result.ext &= ~ExtFlags.VARIANT_OFFSET;
this.result.ext |= ($variantOffset << 29) & ExtFlags.VARIANT_OFFSET;
// compute next varinatOffset
if (cell.extended.underlineStyle === UnderlineStyle.DOTTED) {
if (code !== NULL_CELL_CODE) {
$variantOffset = computeVarinatOffset(deviceCellWidth * chWidth, lineWidth, $variantOffset);
}
} else {
$variantOffset = 0;
}
}
}
@@ -56,3 +56,7 @@ function createDimension(): IDimensions {
height: 0
};
}
export function computeVarinatOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number {
return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2);
}
+7 -5
View File
@@ -9,7 +9,7 @@ import { IColor } from 'common/Types';
import { AttributeData } from 'common/buffer/AttributeData';
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 { computeVarinatOffset, excludeFromContrastRatioDemands, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
import { IUnicodeService } from 'common/services/Services';
import { FourKeyMap } from 'common/MultiKeyMap';
import { IdleTaskQueue } from 'common/TaskQueue';
@@ -597,14 +597,16 @@ export class TextureAtlas implements ITextureAtlas {
);
break;
case UnderlineStyle.DOTTED:
const offsetWidth = nextOffset >= lineWidth ? lineWidth * 2 - nextOffset : lineWidth - nextOffset;
const offsetWidth = nextOffset === 0 ? 0 :
(nextOffset >= lineWidth ? lineWidth * 2 - nextOffset : lineWidth - nextOffset);
if (offsetWidth === 0) {
this._tmpCtx.setLineDash([Math.round(lineWidth), Math.round(lineWidth)]);
this._tmpCtx.moveTo(xChLeft, yTop);
this._tmpCtx.lineTo(xChRight, yTop);
} else {
const isFull = nextOffset >= lineWidth ? false : true;
if (isFull === false) {
// a line and a gap.
const isLineStart = nextOffset >= lineWidth ? false : true;
if (isLineStart === false) {
this._tmpCtx.setLineDash([Math.round(lineWidth), Math.round(lineWidth)]);
this._tmpCtx.moveTo(xChLeft + offsetWidth, yTop);
this._tmpCtx.lineTo(xChRight, yTop);
@@ -616,7 +618,7 @@ export class TextureAtlas implements ITextureAtlas {
this._tmpCtx.lineTo(xChRight, yTop);
}
}
nextOffset = (xChRight - xChLeft - ((lineWidth * 2) - nextOffset)) % (Math.round(lineWidth) * 2);
nextOffset = computeVarinatOffset(xChRight - xChLeft, lineWidth, nextOffset);
break;
case UnderlineStyle.DASHED:
this._tmpCtx.setLineDash([this._config.devicePixelRatio * 4, this._config.devicePixelRatio * 3]);
+6 -4
View File
@@ -127,9 +127,7 @@ export class AttributeData implements IAttributeData {
: UnderlineStyle.NONE;
}
public getUnderlineVarinatOffset(): number {
return this.fg & FgFlags.UNDERLINE
? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineVarinatOffset : 0)
: 0;
return this.extended.underlineVarinatOffset;
}
}
@@ -180,7 +178,11 @@ export class ExtendedAttrs implements IExtendedAttrs {
}
public get underlineVarinatOffset(): number {
return (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;
const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;
if (val < 0) {
return val ^ 4294967288;
}
return val;
}
public set underlineVarinatOffset(value: number) {
this._ext &= ~ExtFlags.VARIANT_OFFSET;
+12
View File
@@ -119,6 +119,18 @@ describe('AttributeData', () => {
attrs.fg &= ~FgFlags.UNDERLINE;
assert.equal(attrs.getUnderlineStyle(), UnderlineStyle.NONE);
});
it('getUnderlineVarinatOffset', () => {
const attrs = new AttributeData();
// defaults to no offset
assert.equal(attrs.getUnderlineVarinatOffset(), 0);
// should return 0 - 7
for (let i = 0; i < 8; ++i) {
attrs.extended.underlineVarinatOffset = i;
assert.equal(attrs.getUnderlineVarinatOffset(), i);
}
});
});
});