using relative values instead of absolute values for the font size and the line height (#286006)

* using relative values instead of absolute values for the font size and the line height

* renaming to multiplier

* setting back to font size and line height

* Revert "renaming to multiplier"

This reverts commit 5588855659.

* doing some polishing work

* changing the api

* updating to higher version of vscode-textmate

* also changing the vscode textmate package version for the remote extension

* increasing the vscode textmate version in remote/web

* updating package lock json

* using css variables instead of fetching font size from config service

* removing the second multiplier event

* adding ? after dom element style

* Ensure dots from floating fontSize are stripped from class names

---------

Co-authored-by: Alexandru Dima <alexdima@microsoft.com>
This commit is contained in:
Aiday Marlen Kyzy
2026-01-14 10:02:47 +01:00
committed by GitHub
parent 49cb3560c1
commit 27782b41f2
18 changed files with 67 additions and 49 deletions

View File

@@ -899,6 +899,7 @@
"--vscode-window-inactiveBorder"
],
"others": [
"--editor-font-size",
"--background-dark",
"--background-light",
"--chat-editing-last-edit-shift",

8
package-lock.json generated
View File

@@ -53,7 +53,7 @@
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "^9.3.0",
"vscode-textmate": "^9.3.1",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
@@ -17696,9 +17696,9 @@
}
},
"node_modules/vscode-textmate": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.0.tgz",
"integrity": "sha512-zHiZZOdb9xqj5/X1C4a29sbgT2HngdWxPLSl3PyHRQF+5visI4uNM020OHiLJjsMxUssyk/pGVAg/9LCIobrVg==",
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.1.tgz",
"integrity": "sha512-U19nFkCraZF9/bkQKQYsb9mRqM9NwpToQQFl40nGiioZTH9gRtdtCHwp48cubayVfreX3ivnoxgxQgNwrTVmQg==",
"license": "MIT"
},
"node_modules/vscode-uri": {

View File

@@ -116,7 +116,7 @@
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "^9.3.0",
"vscode-textmate": "^9.3.1",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},

View File

@@ -42,7 +42,7 @@
"tas-client": "0.3.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "^9.3.0",
"vscode-textmate": "^9.3.1",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
}
@@ -1400,9 +1400,9 @@
}
},
"node_modules/vscode-textmate": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.0.tgz",
"integrity": "sha512-zHiZZOdb9xqj5/X1C4a29sbgT2HngdWxPLSl3PyHRQF+5visI4uNM020OHiLJjsMxUssyk/pGVAg/9LCIobrVg==",
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.1.tgz",
"integrity": "sha512-U19nFkCraZF9/bkQKQYsb9mRqM9NwpToQQFl40nGiioZTH9gRtdtCHwp48cubayVfreX3ivnoxgxQgNwrTVmQg==",
"license": "MIT"
},
"node_modules/wrappy": {

View File

@@ -37,7 +37,7 @@
"tas-client": "0.3.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "^9.3.0",
"vscode-textmate": "^9.3.1",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},

View File

@@ -26,7 +26,7 @@
"katex": "^0.16.22",
"tas-client": "0.3.1",
"vscode-oniguruma": "1.7.0",
"vscode-textmate": "^9.3.0"
"vscode-textmate": "^9.3.1"
}
},
"node_modules/@microsoft/1ds-core-js": {
@@ -266,9 +266,9 @@
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
},
"node_modules/vscode-textmate": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.0.tgz",
"integrity": "sha512-zHiZZOdb9xqj5/X1C4a29sbgT2HngdWxPLSl3PyHRQF+5visI4uNM020OHiLJjsMxUssyk/pGVAg/9LCIobrVg==",
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.3.1.tgz",
"integrity": "sha512-U19nFkCraZF9/bkQKQYsb9mRqM9NwpToQQFl40nGiioZTH9gRtdtCHwp48cubayVfreX3ivnoxgxQgNwrTVmQg==",
"license": "MIT"
},
"node_modules/yallist": {

View File

@@ -21,6 +21,6 @@
"katex": "^0.16.22",
"tas-client": "0.3.1",
"vscode-oniguruma": "1.7.0",
"vscode-textmate": "^9.3.0"
"vscode-textmate": "^9.3.1"
}
}

View File

@@ -286,6 +286,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
this._configuration = this._register(this._createConfiguration(codeEditorWidgetOptions.isSimpleWidget || false,
codeEditorWidgetOptions.contextMenuId ?? (codeEditorWidgetOptions.isSimpleWidget ? MenuId.SimpleEditorContext : MenuId.EditorContext),
options, accessibilityService));
this._domElement.style?.setProperty('--editor-font-size', this._configuration.options.get(EditorOption.fontSize) + 'px');
this._register(this._configuration.onDidChange((e) => {
this._onDidChangeConfiguration.fire(e);
@@ -294,6 +295,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
const layoutInfo = options.get(EditorOption.layoutInfo);
this._onDidLayoutChange.fire(layoutInfo);
}
if (e.hasChanged(EditorOption.fontSize)) {
this._domElement.style.setProperty('--editor-font-size', options.get(EditorOption.fontSize) + 'px');
}
}));
this._contextKeyService = this._register(contextKeyService.createScoped(this._domElement));

View File

@@ -72,8 +72,8 @@ export interface IFontToken {
readonly startIndex: number;
readonly endIndex: number;
readonly fontFamily: string | null;
readonly fontSize: string | null;
readonly lineHeight: number | null;
readonly fontSizeMultiplier: number | null;
readonly lineHeightMultiplier: number | null;
}
/**

View File

@@ -429,10 +429,10 @@ export function generateTokensCSSForFontMap(fontMap: readonly IFontTokenOptions[
const fonts = new Set<string>();
for (let i = 1, len = fontMap.length; i < len; i++) {
const font = fontMap[i];
if (!font.fontFamily && !font.fontSize) {
if (!font.fontFamily && !font.fontSizeMultiplier) {
continue;
}
const className = classNameForFontTokenDecorations(font.fontFamily ?? '', font.fontSize ?? '');
const className = classNameForFontTokenDecorations(font.fontFamily ?? '', font.fontSizeMultiplier ?? 0);
if (fonts.has(className)) {
continue;
}
@@ -441,8 +441,8 @@ export function generateTokensCSSForFontMap(fontMap: readonly IFontTokenOptions[
if (font.fontFamily) {
rule += `font-family: ${font.fontFamily};`;
}
if (font.fontSize) {
rule += `font-size: ${font.fontSize};`;
if (font.fontSizeMultiplier) {
rule += `font-size: calc(var(--editor-font-size)*${font.fontSizeMultiplier});`;
}
rule += `}`;
rules.push(rule);
@@ -450,6 +450,19 @@ export function generateTokensCSSForFontMap(fontMap: readonly IFontTokenOptions[
return rules.join('\n');
}
export function classNameForFontTokenDecorations(fontFamily: string, fontSize: string): string {
return `font-decoration-${fontFamily.toLowerCase()}-${fontSize.toLowerCase()}`;
export function classNameForFontTokenDecorations(fontFamily: string, fontSize: number): string {
const safeFontFamily = sanitizeFontFamilyForClassName(fontFamily);
return cleanClassName(`font-decoration-${safeFontFamily}-${fontSize}`);
}
function sanitizeFontFamilyForClassName(fontFamily: string): string {
const normalized = fontFamily.toLowerCase().trim();
if (!normalized) {
return 'default';
}
return cleanClassName(normalized);
}
function cleanClassName(className: string): string {
return className.replace(/[^a-z0-9_-]/gi, '-');
}

View File

@@ -75,8 +75,8 @@ export class TokenizationFontDecorationProvider extends Disposable implements De
};
TokenizationFontDecorationProvider.DECORATION_COUNT++;
if (annotation.annotation.lineHeight) {
affectedLineHeights.add(new LineHeightChangingDecoration(0, decorationId, lineNumber, annotation.annotation.lineHeight));
if (annotation.annotation.lineHeightMultiplier) {
affectedLineHeights.add(new LineHeightChangingDecoration(0, decorationId, lineNumber, annotation.annotation.lineHeightMultiplier));
}
affectedLineFonts.add(new LineFontChangingDecoration(0, decorationId, lineNumber));
@@ -135,8 +135,8 @@ export class TokenizationFontDecorationProvider extends Disposable implements De
const annotationEndPosition = this.textModel.getPositionAt(annotation.range.endExclusive);
const range = Range.fromPositions(annotationStartPosition, annotationEndPosition);
const anno = annotation.annotation;
const className = classNameForFontTokenDecorations(anno.fontToken.fontFamily ?? '', anno.fontToken.fontSize ?? '');
const affectsFont = !!(anno.fontToken.fontFamily || anno.fontToken.fontSize);
const className = classNameForFontTokenDecorations(anno.fontToken.fontFamily ?? '', anno.fontToken.fontSizeMultiplier ?? 0);
const affectsFont = !!(anno.fontToken.fontFamily || anno.fontToken.fontSizeMultiplier);
const id = anno.decorationId;
decorations.push({
id: id,

View File

@@ -162,11 +162,11 @@ export interface IFontTokenOption {
/**
* Font size of the token.
*/
readonly fontSize?: string;
readonly fontSizeMultiplier?: number;
/**
* Line height of the token.
*/
readonly lineHeight?: number;
readonly lineHeightMultiplier?: number;
}
/**
@@ -189,8 +189,8 @@ export function serializeFontTokenOptions(): (options: IFontTokenOption) => IFon
return (annotation: IFontTokenOption) => {
return {
fontFamily: annotation.fontFamily ?? '',
fontSize: annotation.fontSize ?? '',
lineHeight: annotation.lineHeight ?? 0
fontSizeMultiplier: annotation.fontSizeMultiplier ?? 0,
lineHeightMultiplier: annotation.lineHeightMultiplier ?? 0
};
};
}
@@ -202,8 +202,8 @@ export function deserializeFontTokenOptions(): (options: IFontTokenOption) => IF
return (annotation: IFontTokenOption) => {
return {
fontFamily: annotation.fontFamily ? String(annotation.fontFamily) : undefined,
fontSize: annotation.fontSize ? String(annotation.fontSize) : undefined,
lineHeight: annotation.lineHeight ? Number(annotation.lineHeight) : undefined
fontSizeMultiplier: annotation.fontSizeMultiplier ? Number(annotation.fontSizeMultiplier) : undefined,
lineHeightMultiplier: annotation.lineHeightMultiplier ? Number(annotation.lineHeightMultiplier) : undefined
};
};
}
@@ -348,13 +348,13 @@ export class ModelLineHeightChanged {
/**
* The line height on the line.
*/
public readonly lineHeight: number | null;
public readonly lineHeightMultiplier: number | null;
constructor(ownerId: number, decorationId: string, lineNumber: number, lineHeight: number | null) {
constructor(ownerId: number, decorationId: string, lineNumber: number, lineHeightMultiplier: number | null) {
this.ownerId = ownerId;
this.decorationId = decorationId;
this.lineNumber = lineNumber;
this.lineHeight = lineHeight;
this.lineHeightMultiplier = lineHeightMultiplier;
}
}

View File

@@ -451,10 +451,10 @@ export class ViewModel extends Disposable implements IViewModel {
this.viewLayout.changeSpecialLineHeights((accessor: ILineHeightChangeAccessor) => {
for (const change of filteredChanges) {
const { decorationId, lineNumber, lineHeight } = change;
const { decorationId, lineNumber, lineHeightMultiplier } = change;
const viewRange = this.coordinatesConverter.convertModelRangeToViewRange(new Range(lineNumber, 1, lineNumber, this.model.getLineMaxColumn(lineNumber)));
if (lineHeight !== null) {
accessor.insertOrChangeCustomLineHeight(decorationId, viewRange.startLineNumber, viewRange.endLineNumber, lineHeight);
if (lineHeightMultiplier !== null) {
accessor.insertOrChangeCustomLineHeight(decorationId, viewRange.startLineNumber, viewRange.endLineNumber, lineHeightMultiplier * this._configuration.options.get(EditorOption.lineHeight));
} else {
accessor.removeCustomLineHeight(decorationId);
}

View File

@@ -83,8 +83,8 @@ export interface IColorTheme {
export class IFontTokenOptions {
fontFamily?: string;
fontSize?: string;
lineHeight?: number;
fontSizeMultiplier?: number;
lineHeightMultiplier?: number;
}
export interface IFileIconTheme {

View File

@@ -198,8 +198,8 @@ export class TextMateWorkerTokenizer extends MirrorTextModel {
range: new OffsetRange(offsetAtLineStart + fontInfo.startIndex, offsetAtLineStart + fontInfo.endIndex),
annotation: {
fontFamily: fontInfo.fontFamily ?? undefined,
fontSize: fontInfo.fontSize ?? undefined,
lineHeight: fontInfo.lineHeight ?? undefined
fontSizeMultiplier: fontInfo.fontSizeMultiplier ?? undefined,
lineHeightMultiplier: fontInfo.lineHeightMultiplier ?? undefined
}
});
}

View File

@@ -1014,8 +1014,8 @@ class TokenFontIndex {
this._font2id = new Map();
}
public add(fontFamily: string | undefined, fontSize: string | undefined, lineHeight: number | undefined): number {
const font: IFontTokenOptions = { fontFamily, fontSize, lineHeight };
public add(fontFamily: string | undefined, fontSizeMultiplier: number | undefined, lineHeightMultiplier: number | undefined): number {
const font: IFontTokenOptions = { fontFamily, fontSizeMultiplier, lineHeightMultiplier };
let value = this._font2id.get(font);
if (value) {
return value;

View File

@@ -175,12 +175,12 @@ const textmateColorSchema: IJSONSchema = {
description: nls.localize('schema.token.fontFamily', 'Font family for the token (e.g., "Fira Code", "JetBrains Mono").')
},
fontSize: {
type: 'string',
description: nls.localize('schema.token.fontSize', 'Font size string for the token (e.g., "14px", "1.2em").')
type: 'number',
description: nls.localize('schema.token.fontSize', 'Font size multiplier for the token (e.g., 1.2 will use 1.2 times the default font size).')
},
lineHeight: {
type: 'number',
description: nls.localize('schema.token.lineHeight', 'Line height number for the token (e.g., "20").')
description: nls.localize('schema.token.lineHeight', 'Line height multiplier for the token (e.g., 1.2 will use 1.2 times the default height).')
}
},
additionalProperties: false,

View File

@@ -478,7 +478,7 @@ export interface ITokenColorizationSetting {
background?: string;
fontStyle?: string; /* [italic|bold|underline|strikethrough] */
fontFamily?: string;
fontSize?: string;
fontSize?: number;
lineHeight?: number;
}