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