apply weight settings in width cache

This commit is contained in:
Jörg Breitbart
2023-07-31 16:49:58 +02:00
parent e75ec5b51f
commit c796514de8
2 changed files with 45 additions and 14 deletions
+12 -2
View File
@@ -98,7 +98,12 @@ export class DomRenderer extends Disposable implements IRenderer {
}));
this._widthCache = new WidthCache(document);
this._widthCache.setFont(this._optionsService.rawOptions.fontFamily, this._optionsService.rawOptions.fontSize);
this._widthCache.setFont(
this._optionsService.rawOptions.fontFamily,
this._optionsService.rawOptions.fontSize,
this._optionsService.rawOptions.fontWeight,
this._optionsService.rawOptions.fontWeightBold
);
this._setDefaultSpacing();
}
@@ -373,7 +378,12 @@ export class DomRenderer extends Disposable implements IRenderer {
// Refresh CSS
this._injectCss(this._themeService.colors);
// update spacing cache
this._widthCache.setFont(this._optionsService.rawOptions.fontFamily, this._optionsService.rawOptions.fontSize);
this._widthCache.setFont(
this._optionsService.rawOptions.fontFamily,
this._optionsService.rawOptions.fontSize,
this._optionsService.rawOptions.fontWeight,
this._optionsService.rawOptions.fontWeightBold
);
this._setDefaultSpacing();
}
+33 -12
View File
@@ -4,6 +4,7 @@
*/
import { IDisposable } from 'common/Types';
import { FontWeight } from 'common/services/Services';
const enum CacheSettings {
@@ -14,13 +15,18 @@ const enum CacheSettings {
export class WidthCache implements IDisposable {
// flat cache for regular
// flat cache for regular variant up to CacheSettings.FLAT_SIZE
// NOTE: ~4x faster access than holey (serving >>80% of terminal content)
private _flat = new Float32Array(CacheSettings.FLAT_SIZE);
// holey cache for bold, italic and bold&italic for any string
// FIXME: can grow really big over time, so a shared API across terminals is needed
private _holey = new Map<string, number>();
private _font = '';
private _fontSize = 0;
private _weight: FontWeight = 'normal';
private _weightBold: FontWeight = 'bold';
private _container: HTMLDivElement;
private _measureElements: HTMLSpanElement[] = [];
@@ -31,6 +37,7 @@ export class WidthCache implements IDisposable {
this._container.style.position = 'absolute';
this._container.style.top = '-50000px';
this._container.style.width = '50000px';
// SP should stack in spans
this._container.style.whiteSpace = 'pre';
// avoid undercuts in non-monospace fonts from kerning
this._container.style.fontKerning = 'none';
@@ -62,11 +69,11 @@ export class WidthCache implements IDisposable {
public dispose(): void {
this._container.remove();
this._measureElements.length = 0;
this._holey.clear();
this._holey.clear(); // also free memory
}
/**
* Clear the spacing cache.
* Clear the width cache.
*/
public clear(): void {
this._flat.fill(CacheSettings.FLAT_UNSET);
@@ -75,18 +82,32 @@ export class WidthCache implements IDisposable {
/**
* Set the font for measuring.
* Must be called for any fontFamily or fontSize changes.
* Must be called for any changes on font settings.
* Also clears the cache.
*/
public setFont(font: string, fontSize: number): void {
if (font !== this._font || fontSize !== this._fontSize) {
this._font = font;
this._fontSize = fontSize;
this.clear();
this._container.style.fontFamily = this._font;
this._container.style.fontSize = `${this._fontSize}px`;
public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {
// skip if nothing changed
if (font === this._font
&& fontSize === this._fontSize
&& weight === this._weight
&& weightBold === this._weightBold
) {
return;
}
this._font = font;
this._fontSize = fontSize;
this._weight = weight;
this._weightBold = weightBold;
this._container.style.fontFamily = this._font;
this._container.style.fontSize = `${this._fontSize}px`;
this._measureElements[0].style.fontWeight = `${weight}`; // regular
this._measureElements[1].style.fontWeight = `${weightBold}`; // bold
this._measureElements[2].style.fontWeight = `${weight}`; // italic
this._measureElements[3].style.fontWeight = `${weightBold}`; // boldItalic
this.clear();
}
/**