Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/config/fontInfo.ts
5272 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as platform from '../../../base/common/platform.js';
7
import { EditorOption, FindComputedEditorOptionValueById } from './editorOptions.js';
8
import { EditorZoom } from './editorZoom.js';
9
10
/**
11
* Determined from empirical observations.
12
* @internal
13
*/
14
export const GOLDEN_LINE_HEIGHT_RATIO = platform.isMacintosh ? 1.5 : 1.35;
15
16
/**
17
* @internal
18
*/
19
export const MINIMUM_LINE_HEIGHT = 8;
20
21
/**
22
* @internal
23
*/
24
export interface IValidatedEditorOptions {
25
get<T extends EditorOption>(id: T): FindComputedEditorOptionValueById<T>;
26
}
27
28
export class BareFontInfo {
29
readonly _bareFontInfoBrand: void = undefined;
30
31
/**
32
* @internal
33
*/
34
public static _create(fontFamily: string, fontWeight: string, fontSize: number, fontFeatureSettings: string, fontVariationSettings: string, lineHeight: number, letterSpacing: number, pixelRatio: number, ignoreEditorZoom: boolean): BareFontInfo {
35
if (lineHeight === 0) {
36
lineHeight = GOLDEN_LINE_HEIGHT_RATIO * fontSize;
37
} else if (lineHeight < MINIMUM_LINE_HEIGHT) {
38
// Values too small to be line heights in pixels are in ems.
39
lineHeight = lineHeight * fontSize;
40
}
41
42
// Enforce integer, minimum constraints
43
lineHeight = Math.round(lineHeight);
44
if (lineHeight < MINIMUM_LINE_HEIGHT) {
45
lineHeight = MINIMUM_LINE_HEIGHT;
46
}
47
48
const editorZoomLevelMultiplier = 1 + (ignoreEditorZoom ? 0 : EditorZoom.getZoomLevel() * 0.1);
49
fontSize *= editorZoomLevelMultiplier;
50
lineHeight *= editorZoomLevelMultiplier;
51
52
if (fontVariationSettings === FONT_VARIATION_TRANSLATE) {
53
if (fontWeight === 'normal' || fontWeight === 'bold') {
54
fontVariationSettings = FONT_VARIATION_OFF;
55
} else {
56
const fontWeightAsNumber = parseInt(fontWeight, 10);
57
fontVariationSettings = `'wght' ${fontWeightAsNumber}`;
58
fontWeight = 'normal';
59
}
60
}
61
62
return new BareFontInfo({
63
pixelRatio: pixelRatio,
64
fontFamily: fontFamily,
65
fontWeight: fontWeight,
66
fontSize: fontSize,
67
fontFeatureSettings: fontFeatureSettings,
68
fontVariationSettings,
69
lineHeight: lineHeight,
70
letterSpacing: letterSpacing
71
});
72
}
73
74
readonly pixelRatio: number;
75
readonly fontFamily: string;
76
readonly fontWeight: string;
77
readonly fontSize: number;
78
readonly fontFeatureSettings: string;
79
readonly fontVariationSettings: string;
80
readonly lineHeight: number;
81
readonly letterSpacing: number;
82
83
/**
84
* @internal
85
*/
86
protected constructor(opts: {
87
pixelRatio: number;
88
fontFamily: string;
89
fontWeight: string;
90
fontSize: number;
91
fontFeatureSettings: string;
92
fontVariationSettings: string;
93
lineHeight: number;
94
letterSpacing: number;
95
}) {
96
this.pixelRatio = opts.pixelRatio;
97
this.fontFamily = String(opts.fontFamily);
98
this.fontWeight = String(opts.fontWeight);
99
this.fontSize = opts.fontSize;
100
this.fontFeatureSettings = opts.fontFeatureSettings;
101
this.fontVariationSettings = opts.fontVariationSettings;
102
this.lineHeight = opts.lineHeight | 0;
103
this.letterSpacing = opts.letterSpacing;
104
}
105
106
/**
107
* @internal
108
*/
109
public getId(): string {
110
return `${this.pixelRatio}-${this.fontFamily}-${this.fontWeight}-${this.fontSize}-${this.fontFeatureSettings}-${this.fontVariationSettings}-${this.lineHeight}-${this.letterSpacing}`;
111
}
112
113
/**
114
* @internal
115
*/
116
public getMassagedFontFamily(): string {
117
const fallbackFontFamily = EDITOR_FONT_DEFAULTS.fontFamily;
118
const fontFamily = BareFontInfo._wrapInQuotes(this.fontFamily);
119
if (fallbackFontFamily && this.fontFamily !== fallbackFontFamily) {
120
return `${fontFamily}, ${fallbackFontFamily}`;
121
}
122
return fontFamily;
123
}
124
125
private static _wrapInQuotes(fontFamily: string): string {
126
if (/[,"']/.test(fontFamily)) {
127
// Looks like the font family might be already escaped
128
return fontFamily;
129
}
130
if (/[+ ]/.test(fontFamily)) {
131
// Wrap a font family using + or <space> with quotes
132
return `"${fontFamily}"`;
133
}
134
return fontFamily;
135
}
136
}
137
138
// change this whenever `FontInfo` members are changed
139
export const SERIALIZED_FONT_INFO_VERSION = 2;
140
141
export class FontInfo extends BareFontInfo {
142
readonly _editorStylingBrand: void = undefined;
143
144
readonly version: number = SERIALIZED_FONT_INFO_VERSION;
145
readonly isTrusted: boolean;
146
readonly isMonospace: boolean;
147
readonly typicalHalfwidthCharacterWidth: number;
148
readonly typicalFullwidthCharacterWidth: number;
149
readonly canUseHalfwidthRightwardsArrow: boolean;
150
readonly spaceWidth: number;
151
readonly middotWidth: number;
152
readonly wsmiddotWidth: number;
153
readonly maxDigitWidth: number;
154
155
/**
156
* @internal
157
*/
158
constructor(opts: {
159
pixelRatio: number;
160
fontFamily: string;
161
fontWeight: string;
162
fontSize: number;
163
fontFeatureSettings: string;
164
fontVariationSettings: string;
165
lineHeight: number;
166
letterSpacing: number;
167
isMonospace: boolean;
168
typicalHalfwidthCharacterWidth: number;
169
typicalFullwidthCharacterWidth: number;
170
canUseHalfwidthRightwardsArrow: boolean;
171
spaceWidth: number;
172
middotWidth: number;
173
wsmiddotWidth: number;
174
maxDigitWidth: number;
175
}, isTrusted: boolean) {
176
super(opts);
177
this.isTrusted = isTrusted;
178
this.isMonospace = opts.isMonospace;
179
this.typicalHalfwidthCharacterWidth = opts.typicalHalfwidthCharacterWidth;
180
this.typicalFullwidthCharacterWidth = opts.typicalFullwidthCharacterWidth;
181
this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow;
182
this.spaceWidth = opts.spaceWidth;
183
this.middotWidth = opts.middotWidth;
184
this.wsmiddotWidth = opts.wsmiddotWidth;
185
this.maxDigitWidth = opts.maxDigitWidth;
186
}
187
188
/**
189
* @internal
190
*/
191
public equals(other: FontInfo): boolean {
192
return (
193
this.fontFamily === other.fontFamily
194
&& this.fontWeight === other.fontWeight
195
&& this.fontSize === other.fontSize
196
&& this.fontFeatureSettings === other.fontFeatureSettings
197
&& this.fontVariationSettings === other.fontVariationSettings
198
&& this.lineHeight === other.lineHeight
199
&& this.letterSpacing === other.letterSpacing
200
&& this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth
201
&& this.typicalFullwidthCharacterWidth === other.typicalFullwidthCharacterWidth
202
&& this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
203
&& this.spaceWidth === other.spaceWidth
204
&& this.middotWidth === other.middotWidth
205
&& this.wsmiddotWidth === other.wsmiddotWidth
206
&& this.maxDigitWidth === other.maxDigitWidth
207
);
208
}
209
}
210
/**
211
* @internal
212
*/
213
export const FONT_VARIATION_OFF = 'normal';
214
/**
215
* @internal
216
*/
217
export const FONT_VARIATION_TRANSLATE = 'translate';
218
219
/**
220
* @internal
221
*/
222
export const DEFAULT_WINDOWS_FONT_FAMILY = 'Consolas, \'Courier New\', monospace';
223
/**
224
* @internal
225
*/
226
export const DEFAULT_MAC_FONT_FAMILY = 'Menlo, Monaco, \'Courier New\', monospace';
227
/**
228
* @internal
229
*/
230
export const DEFAULT_LINUX_FONT_FAMILY = '\'Droid Sans Mono\', monospace';
231
/**
232
* @internal
233
*/
234
export const EDITOR_FONT_DEFAULTS = {
235
fontFamily: (
236
platform.isMacintosh ? DEFAULT_MAC_FONT_FAMILY : (platform.isWindows ? DEFAULT_WINDOWS_FONT_FAMILY : DEFAULT_LINUX_FONT_FAMILY)
237
),
238
fontWeight: 'normal',
239
fontSize: (
240
platform.isMacintosh ? 12 : 14
241
),
242
lineHeight: 0,
243
letterSpacing: 0,
244
};
245
246