Skip to content

Commit f13ea5e

Browse files
authored
Merge pull request microsoft#153968 from chengluyu/main
Support variable fonts (microsoft#153291)
2 parents 0646122 + c981ea2 commit f13ea5e

File tree

9 files changed

+294
-184
lines changed

9 files changed

+294
-184
lines changed

src/vs/base/browser/fastDomNode.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export class FastDomNode<T extends HTMLElement> {
2121
private _fontSize: string = '';
2222
private _fontStyle: string = '';
2323
private _fontFeatureSettings: string = '';
24+
private _fontVariationSettings: string = '';
2425
private _textDecoration: string = '';
2526
private _lineHeight: string = '';
2627
private _letterSpacing: string = '';
@@ -178,6 +179,14 @@ export class FastDomNode<T extends HTMLElement> {
178179
this.domNode.style.fontFeatureSettings = this._fontFeatureSettings;
179180
}
180181

182+
public setFontVariationSettings(fontVariationSettings: string): void {
183+
if (this._fontVariationSettings === fontVariationSettings) {
184+
return;
185+
}
186+
this._fontVariationSettings = fontVariationSettings;
187+
this.domNode.style.fontVariationSettings = this._fontVariationSettings;
188+
}
189+
181190
public setTextDecoration(textDecoration: string): void {
182191
if (this._textDecoration === textDecoration) {
183192
return;

src/vs/editor/browser/config/domFontInfo.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ export function applyFontInfo(domNode: FastDomNode<HTMLElement> | HTMLElement, f
1212
domNode.setFontWeight(fontInfo.fontWeight);
1313
domNode.setFontSize(fontInfo.fontSize);
1414
domNode.setFontFeatureSettings(fontInfo.fontFeatureSettings);
15+
domNode.setFontVariationSettings(fontInfo.fontVariationSettings);
1516
domNode.setLineHeight(fontInfo.lineHeight);
1617
domNode.setLetterSpacing(fontInfo.letterSpacing);
1718
} else {
1819
domNode.style.fontFamily = fontInfo.getMassagedFontFamily();
1920
domNode.style.fontWeight = fontInfo.fontWeight;
2021
domNode.style.fontSize = fontInfo.fontSize + 'px';
2122
domNode.style.fontFeatureSettings = fontInfo.fontFeatureSettings;
23+
domNode.style.fontVariationSettings = fontInfo.fontVariationSettings;
2224
domNode.style.lineHeight = fontInfo.lineHeight + 'px';
2325
domNode.style.letterSpacing = fontInfo.letterSpacing + 'px';
2426
}

src/vs/editor/browser/config/fontMeasurements.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface ISerializedFontInfo {
2020
readonly fontWeight: string;
2121
readonly fontSize: number;
2222
readonly fontFeatureSettings: string;
23+
readonly fontVariationSettings: string;
2324
readonly lineHeight: number;
2425
readonly letterSpacing: number;
2526
readonly isMonospace: boolean;
@@ -128,6 +129,7 @@ export class FontMeasurementsImpl extends Disposable {
128129
fontWeight: readConfig.fontWeight,
129130
fontSize: readConfig.fontSize,
130131
fontFeatureSettings: readConfig.fontFeatureSettings,
132+
fontVariationSettings: readConfig.fontVariationSettings,
131133
lineHeight: readConfig.lineHeight,
132134
letterSpacing: readConfig.letterSpacing,
133135
isMonospace: readConfig.isMonospace,
@@ -219,6 +221,7 @@ export class FontMeasurementsImpl extends Disposable {
219221
fontWeight: bareFontInfo.fontWeight,
220222
fontSize: bareFontInfo.fontSize,
221223
fontFeatureSettings: bareFontInfo.fontFeatureSettings,
224+
fontVariationSettings: bareFontInfo.fontVariationSettings,
222225
lineHeight: bareFontInfo.lineHeight,
223226
letterSpacing: bareFontInfo.letterSpacing,
224227
isMonospace: isMonospace,

src/vs/editor/common/config/editorOptions.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ export interface IEditorOptions {
231231
* Defaults to false.
232232
*/
233233
fontLigatures?: boolean | string;
234+
/**
235+
* Enable font variations.
236+
* Defaults to false.
237+
*/
238+
fontVariations?: boolean | string;
234239
/**
235240
* Disable the use of `transform: translate3d(0px, 0px, 0px)` for the editor margin and lines layers.
236241
* The usage of `transform: translate3d(0px, 0px, 0px)` acts as a hint for browsers to create an extra layer.
@@ -1649,6 +1654,66 @@ export class EditorFontFamily extends BaseEditorOption<EditorOption.fontFamily,
16491654

16501655
//#endregion
16511656

1657+
//#region fontVariations
1658+
1659+
/**
1660+
* @internal
1661+
*/
1662+
export class EditorFontVariations extends BaseEditorOption<EditorOption.fontVariations, boolean | string, string> {
1663+
// Text is laid out using default settings.
1664+
public static OFF = 'normal';
1665+
1666+
// Translate `fontWeight` config to the `font-variation-settings` CSS property.
1667+
public static TRANSLATE = 'translate';
1668+
1669+
constructor() {
1670+
super(
1671+
EditorOption.fontVariations, 'fontVariations', EditorFontVariations.OFF,
1672+
{
1673+
anyOf: [
1674+
{
1675+
type: 'boolean',
1676+
description: nls.localize('fontVariations', "Enables/Disables the translation from font-weight to font-variation-settings. Change this to a string for fine-grained control of the 'font-variation-settings' CSS property."),
1677+
},
1678+
{
1679+
type: 'string',
1680+
description: nls.localize('fontVariationSettings', "Explicit 'font-variation-settings' CSS property. A boolean can be passed instead if one only needs to translate font-weight to font-variation-settings.")
1681+
}
1682+
],
1683+
description: nls.localize('fontVariationsGeneral', "Configures font variations. Can be either a boolean to enable/disable the translation from font-weight to font-variation-settings or a string for the value of the CSS 'font-variation-settings' property."),
1684+
default: false
1685+
}
1686+
);
1687+
}
1688+
1689+
public validate(input: any): string {
1690+
if (typeof input === 'undefined') {
1691+
return this.defaultValue;
1692+
}
1693+
if (typeof input === 'string') {
1694+
if (input === 'false') {
1695+
return EditorFontVariations.OFF;
1696+
}
1697+
if (input === 'true') {
1698+
return EditorFontVariations.TRANSLATE;
1699+
}
1700+
return input;
1701+
}
1702+
if (Boolean(input)) {
1703+
return EditorFontVariations.TRANSLATE;
1704+
}
1705+
return EditorFontVariations.OFF;
1706+
}
1707+
1708+
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: string): string {
1709+
// The value is computed from the fontWeight if it is true.
1710+
// So take the result from env.fontInfo
1711+
return env.fontInfo.fontVariationSettings;
1712+
}
1713+
}
1714+
1715+
//#endregion
1716+
16521717
//#region fontInfo
16531718

16541719
class EditorFontInfo extends ComputedEditorOption<EditorOption.fontInfo, FontInfo> {
@@ -4709,6 +4774,7 @@ export const enum EditorOption {
47094774
fontLigatures,
47104775
fontSize,
47114776
fontWeight,
4777+
fontVariations,
47124778
formatOnPaste,
47134779
formatOnType,
47144780
glyphMargin,
@@ -5057,6 +5123,7 @@ export const EditorOptions = {
50575123
fontLigatures2: register(new EditorFontLigatures()),
50585124
fontSize: register(new EditorFontSize()),
50595125
fontWeight: register(new EditorFontWeight()),
5126+
fontVariations: register(new EditorFontVariations()),
50605127
formatOnPaste: register(new EditorBooleanOption(
50615128
EditorOption.formatOnPaste, 'formatOnPaste', false,
50625129
{ description: nls.localize('formatOnPaste', "Controls whether the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document.") }

src/vs/editor/common/config/fontInfo.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as platform from 'vs/base/common/platform';
7-
import { EditorOptions, EditorOption, FindComputedEditorOptionValueById, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
7+
import { EditorFontVariations, EditorOptions, EditorOption, FindComputedEditorOptionValueById, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
88
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
99

1010
/**
@@ -36,28 +36,30 @@ export class BareFontInfo {
3636
const fontWeight = options.get(EditorOption.fontWeight);
3737
const fontSize = options.get(EditorOption.fontSize);
3838
const fontFeatureSettings = options.get(EditorOption.fontLigatures);
39+
const fontVariationSettings = options.get(EditorOption.fontVariations);
3940
const lineHeight = options.get(EditorOption.lineHeight);
4041
const letterSpacing = options.get(EditorOption.letterSpacing);
41-
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom);
42+
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, fontVariationSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom);
4243
}
4344

4445
/**
4546
* @internal
4647
*/
47-
public static createFromRawSettings(opts: { fontFamily?: string | string[]; fontWeight?: string; fontSize?: number; fontLigatures?: boolean | string; lineHeight?: number; letterSpacing?: number }, pixelRatio: number, ignoreEditorZoom: boolean = false): BareFontInfo {
48+
public static createFromRawSettings(opts: { fontFamily?: string | string[]; fontWeight?: string; fontSize?: number; fontLigatures?: boolean | string; fontVariations?: boolean | string; lineHeight?: number; letterSpacing?: number }, pixelRatio: number, ignoreEditorZoom: boolean = false): BareFontInfo {
4849
const fontFamily = EditorOptions.fontFamily.validate(opts.fontFamily);
4950
const fontWeight = EditorOptions.fontWeight.validate(opts.fontWeight);
5051
const fontSize = EditorOptions.fontSize.validate(opts.fontSize);
5152
const fontFeatureSettings = EditorOptions.fontLigatures2.validate(opts.fontLigatures);
53+
const fontVariationSettings = EditorOptions.fontVariations.validate(opts.fontVariations);
5254
const lineHeight = EditorOptions.lineHeight.validate(opts.lineHeight);
5355
const letterSpacing = EditorOptions.letterSpacing.validate(opts.letterSpacing);
54-
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom);
56+
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, fontVariationSettings, lineHeight, letterSpacing, pixelRatio, ignoreEditorZoom);
5557
}
5658

5759
/**
5860
* @internal
5961
*/
60-
private static _create(fontFamily: string, fontWeight: string, fontSize: number, fontFeatureSettings: string, lineHeight: number, letterSpacing: number, pixelRatio: number, ignoreEditorZoom: boolean): BareFontInfo {
62+
private static _create(fontFamily: string, fontWeight: string, fontSize: number, fontFeatureSettings: string, fontVariationSettings: string, lineHeight: number, letterSpacing: number, pixelRatio: number, ignoreEditorZoom: boolean): BareFontInfo {
6163
if (lineHeight === 0) {
6264
lineHeight = GOLDEN_LINE_HEIGHT_RATIO * fontSize;
6365
} else if (lineHeight < MINIMUM_LINE_HEIGHT) {
@@ -75,12 +77,23 @@ export class BareFontInfo {
7577
fontSize *= editorZoomLevelMultiplier;
7678
lineHeight *= editorZoomLevelMultiplier;
7779

80+
if (fontVariationSettings === EditorFontVariations.TRANSLATE) {
81+
if (fontWeight === 'normal' || fontWeight === 'bold') {
82+
fontVariationSettings = EditorFontVariations.OFF;
83+
} else {
84+
const fontWeightAsNumber = parseInt(fontWeight, 10);
85+
fontVariationSettings = `'wght' ${fontWeightAsNumber}`;
86+
fontWeight = 'normal';
87+
}
88+
}
89+
7890
return new BareFontInfo({
7991
pixelRatio: pixelRatio,
8092
fontFamily: fontFamily,
8193
fontWeight: fontWeight,
8294
fontSize: fontSize,
8395
fontFeatureSettings: fontFeatureSettings,
96+
fontVariationSettings,
8497
lineHeight: lineHeight,
8598
letterSpacing: letterSpacing
8699
});
@@ -91,6 +104,7 @@ export class BareFontInfo {
91104
readonly fontWeight: string;
92105
readonly fontSize: number;
93106
readonly fontFeatureSettings: string;
107+
readonly fontVariationSettings: string;
94108
readonly lineHeight: number;
95109
readonly letterSpacing: number;
96110

@@ -103,6 +117,7 @@ export class BareFontInfo {
103117
fontWeight: string;
104118
fontSize: number;
105119
fontFeatureSettings: string;
120+
fontVariationSettings: string;
106121
lineHeight: number;
107122
letterSpacing: number;
108123
}) {
@@ -111,6 +126,7 @@ export class BareFontInfo {
111126
this.fontWeight = String(opts.fontWeight);
112127
this.fontSize = opts.fontSize;
113128
this.fontFeatureSettings = opts.fontFeatureSettings;
129+
this.fontVariationSettings = opts.fontVariationSettings;
114130
this.lineHeight = opts.lineHeight | 0;
115131
this.letterSpacing = opts.letterSpacing;
116132
}
@@ -119,7 +135,7 @@ export class BareFontInfo {
119135
* @internal
120136
*/
121137
public getId(): string {
122-
return `${this.pixelRatio}-${this.fontFamily}-${this.fontWeight}-${this.fontSize}-${this.fontFeatureSettings}-${this.lineHeight}-${this.letterSpacing}`;
138+
return `${this.pixelRatio}-${this.fontFamily}-${this.fontWeight}-${this.fontSize}-${this.fontFeatureSettings}-${this.fontVariationSettings}-${this.lineHeight}-${this.letterSpacing}`;
123139
}
124140

125141
/**
@@ -148,7 +164,7 @@ export class BareFontInfo {
148164
}
149165

150166
// change this whenever `FontInfo` members are changed
151-
export const SERIALIZED_FONT_INFO_VERSION = 1;
167+
export const SERIALIZED_FONT_INFO_VERSION = 2;
152168

153169
export class FontInfo extends BareFontInfo {
154170
readonly _editorStylingBrand: void = undefined;
@@ -173,6 +189,7 @@ export class FontInfo extends BareFontInfo {
173189
fontWeight: string;
174190
fontSize: number;
175191
fontFeatureSettings: string;
192+
fontVariationSettings: string;
176193
lineHeight: number;
177194
letterSpacing: number;
178195
isMonospace: boolean;
@@ -205,6 +222,7 @@ export class FontInfo extends BareFontInfo {
205222
&& this.fontWeight === other.fontWeight
206223
&& this.fontSize === other.fontSize
207224
&& this.fontFeatureSettings === other.fontFeatureSettings
225+
&& this.fontVariationSettings === other.fontVariationSettings
208226
&& this.lineHeight === other.lineHeight
209227
&& this.letterSpacing === other.letterSpacing
210228
&& this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth

0 commit comments

Comments
 (0)