Logic move to CellColorResolver
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user