diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 32466c2d42..8b955cd422 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -97,6 +97,7 @@ export class DomRenderer extends Disposable implements IRenderer { this._widthCache = new WidthCache(document); this._widthCache.setFont(this._optionsService.rawOptions.fontFamily, this._optionsService.rawOptions.fontSize); + this._setDefaultSpacing(); } private _updateDimensions(): void { @@ -231,9 +232,25 @@ export class DomRenderer extends Disposable implements IRenderer { this._themeStyle.setCss(styles); } + /** + * default letter spacing + * Due to rounding issues in dimensions dpr calc glyph might render + * slightly too wide or too narrow. The method corrects the stacking offsets + * by applying a default letter-spacing for all chars. + * The value gets passed to the row factory to avoid setting this value again + * (render speedup is roughly 10%). + */ + private _setDefaultSpacing(): void { + // measure same char as in CharSizeService to get the base deviation + const spacing = this.dimensions.css.cell.width - this._widthCache.get('W', false, false); + this._rowContainer.style.letterSpacing = `${spacing}px`; + this._rowFactory.defaultSpacing = spacing; + } + public handleDevicePixelRatioChange(): void { this._updateDimensions(); this._widthCache.clear(); + this._setDefaultSpacing(); } private _refreshRowElements(cols: number, rows: number): void { @@ -257,6 +274,7 @@ export class DomRenderer extends Disposable implements IRenderer { public handleCharSizeChanged(): void { this._updateDimensions(); this._widthCache.clear(); + this._setDefaultSpacing(); } public handleBlur(): void { @@ -341,6 +359,7 @@ export class DomRenderer extends Disposable implements IRenderer { this._injectCss(this._themeService.colors); // update spacing cache this._widthCache.setFont(this._optionsService.rawOptions.fontFamily, this._optionsService.rawOptions.fontSize); + this._setDefaultSpacing(); } public clear(): void { diff --git a/src/browser/renderer/dom/DomRendererRowFactory.ts b/src/browser/renderer/dom/DomRendererRowFactory.ts index fc04fd91a9..3f9765f0f0 100644 --- a/src/browser/renderer/dom/DomRendererRowFactory.ts +++ b/src/browser/renderer/dom/DomRendererRowFactory.ts @@ -38,6 +38,8 @@ export class DomRendererRowFactory { private _selectionEnd: [number, number] | undefined; private _columnSelectMode: boolean = false; + public defaultSpacing = 0; + constructor( private readonly _document: Document, @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService, @@ -390,12 +392,7 @@ export class DomRendererRowFactory { charElement.textContent = text; } // apply letter-spacing rule - if (spacing) { - /** - * TODO: - * - check if we can ignore tiny spacings here (saves ~400ms) - * - check if we can apply a global spacing to rows element - */ + if (spacing !== this.defaultSpacing) { charElement.style.letterSpacing = `${spacing}px`; }