未验证 提交 ab0eb6de 编写于 作者: A Alex Dima

Fixes #82153: Allow `editor.fontLigatures` to contain font-feature-settings

上级 e1f09b52
......@@ -18,6 +18,7 @@ export class FastDomNode<T extends HTMLElement> {
private _fontFamily: string;
private _fontWeight: string;
private _fontSize: number;
private _fontFeatureSettings: string;
private _lineHeight: number;
private _letterSpacing: number;
private _className: string;
......@@ -38,6 +39,7 @@ export class FastDomNode<T extends HTMLElement> {
this._fontFamily = '';
this._fontWeight = '';
this._fontSize = -1;
this._fontFeatureSettings = '';
this._lineHeight = -1;
this._letterSpacing = -100;
this._className = '';
......@@ -135,6 +137,14 @@ export class FastDomNode<T extends HTMLElement> {
this.domNode.style.fontSize = this._fontSize + 'px';
}
public setFontFeatureSettings(fontFeatureSettings: string): void {
if (this._fontFeatureSettings === fontFeatureSettings) {
return;
}
this._fontFeatureSettings = fontFeatureSettings;
this.domNode.style.fontFeatureSettings = this._fontFeatureSettings;
}
public setLineHeight(lineHeight: number): void {
if (this._lineHeight === lineHeight) {
return;
......
......@@ -71,6 +71,7 @@ class DomCharWidthReader {
regularDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
regularDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
regularDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
regularDomNode.style.fontFeatureSettings = this._bareFontInfo.fontFeatureSettings;
regularDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
regularDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
container.appendChild(regularDomNode);
......@@ -79,6 +80,7 @@ class DomCharWidthReader {
boldDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
boldDomNode.style.fontWeight = 'bold';
boldDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
boldDomNode.style.fontFeatureSettings = this._bareFontInfo.fontFeatureSettings;
boldDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
boldDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
container.appendChild(boldDomNode);
......@@ -87,6 +89,7 @@ class DomCharWidthReader {
italicDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
italicDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
italicDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
italicDomNode.style.fontFeatureSettings = this._bareFontInfo.fontFeatureSettings;
italicDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
italicDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
italicDomNode.style.fontStyle = 'italic';
......
......@@ -11,7 +11,7 @@ import * as platform from 'vs/base/common/platform';
import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader';
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
import { EditorOption, IEditorConstructionOptions } from 'vs/editor/common/config/editorOptions';
import { EditorOption, IEditorConstructionOptions, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
import { IDimension } from 'vs/editor/common/editorCommon';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
......@@ -79,6 +79,7 @@ export interface ISerializedFontInfo {
readonly fontFamily: string;
readonly fontWeight: string;
readonly fontSize: number;
fontFeatureSettings: string;
readonly lineHeight: number;
readonly letterSpacing: number;
readonly isMonospace: boolean;
......@@ -151,11 +152,14 @@ class CSSBasedConfiguration extends Disposable {
return this._cache.getValues().filter(item => item.isTrusted);
}
public restoreFontInfo(savedFontInfo: ISerializedFontInfo[]): void {
public restoreFontInfo(savedFontInfos: ISerializedFontInfo[]): void {
// Take all the saved font info and insert them in the cache without the trusted flag.
// The reason for this is that a font might have been installed on the OS in the meantime.
for (let i = 0, len = savedFontInfo.length; i < len; i++) {
const fontInfo = new FontInfo(savedFontInfo[i], false);
for (let i = 0, len = savedFontInfos.length; i < len; i++) {
const savedFontInfo = savedFontInfos[i];
// compatibility with older versions of VS Code which did not store this...
savedFontInfo.fontFeatureSettings = savedFontInfo.fontFeatureSettings || EditorFontLigatures.OFF;
const fontInfo = new FontInfo(savedFontInfo, false);
this._writeToCache(fontInfo, fontInfo);
}
}
......@@ -171,6 +175,7 @@ class CSSBasedConfiguration extends Disposable {
fontFamily: readConfig.fontFamily,
fontWeight: readConfig.fontWeight,
fontSize: readConfig.fontSize,
fontFeatureSettings: readConfig.fontFeatureSettings,
lineHeight: readConfig.lineHeight,
letterSpacing: readConfig.letterSpacing,
isMonospace: readConfig.isMonospace,
......@@ -249,9 +254,9 @@ class CSSBasedConfiguration extends Disposable {
const maxDigitWidth = Math.max(digit0.width, digit1.width, digit2.width, digit3.width, digit4.width, digit5.width, digit6.width, digit7.width, digit8.width, digit9.width);
let isMonospace = true;
let isMonospace = (bareFontInfo.fontFeatureSettings === EditorFontLigatures.OFF);
const referenceWidth = monospace[0].width;
for (let i = 1, len = monospace.length; i < len; i++) {
for (let i = 1, len = monospace.length; isMonospace && i < len; i++) {
const diff = referenceWidth - monospace[i].width;
if (diff < -0.001 || diff > 0.001) {
isMonospace = false;
......@@ -276,6 +281,7 @@ class CSSBasedConfiguration extends Disposable {
fontFamily: bareFontInfo.fontFamily,
fontWeight: bareFontInfo.fontWeight,
fontSize: bareFontInfo.fontSize,
fontFeatureSettings: bareFontInfo.fontFeatureSettings,
lineHeight: bareFontInfo.lineHeight,
letterSpacing: bareFontInfo.letterSpacing,
isMonospace: isMonospace,
......@@ -294,6 +300,7 @@ export class Configuration extends CommonEditorConfiguration {
domNode.style.fontFamily = fontInfo.getMassagedFontFamily();
domNode.style.fontWeight = fontInfo.fontWeight;
domNode.style.fontSize = fontInfo.fontSize + 'px';
domNode.style.fontFeatureSettings = fontInfo.fontFeatureSettings;
domNode.style.lineHeight = fontInfo.lineHeight + 'px';
domNode.style.letterSpacing = fontInfo.letterSpacing + 'px';
}
......@@ -302,6 +309,7 @@ export class Configuration extends CommonEditorConfiguration {
domNode.setFontFamily(fontInfo.getMassagedFontFamily());
domNode.setFontWeight(fontInfo.fontWeight);
domNode.setFontSize(fontInfo.fontSize);
domNode.setFontFeatureSettings(fontInfo.fontFeatureSettings);
domNode.setLineHeight(fontInfo.lineHeight);
domNode.setLetterSpacing(fontInfo.letterSpacing);
}
......
......@@ -16,7 +16,7 @@ import { CharacterMapping, ForeignElementType, RenderLineInput, renderViewLine,
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
import { HIGH_CONTRAST, ThemeType } from 'vs/platform/theme/common/themeService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { EditorOption, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
const canUseFastRenderedViewLine = (function () {
if (platform.isNative) {
......@@ -77,7 +77,7 @@ export class ViewLineOptions {
public readonly canUseHalfwidthRightwardsArrow: boolean;
public readonly lineHeight: number;
public readonly stopRenderingLineAfter: number;
public readonly fontLigatures: boolean;
public readonly fontLigatures: string;
constructor(config: IConfiguration, themeType: ThemeType) {
this.themeType = themeType;
......@@ -89,7 +89,6 @@ export class ViewLineOptions {
this.useMonospaceOptimizations = (
fontInfo.isMonospace
&& !options.get(EditorOption.disableMonospaceOptimizations)
&& !options.get(EditorOption.fontLigatures)
);
this.canUseHalfwidthRightwardsArrow = fontInfo.canUseHalfwidthRightwardsArrow;
this.lineHeight = options.get(EditorOption.lineHeight);
......@@ -218,7 +217,7 @@ export class ViewLine implements IVisibleLine {
options.stopRenderingLineAfter,
options.renderWhitespace,
options.renderControlCharacters,
options.fontLigatures,
options.fontLigatures !== EditorFontLigatures.OFF,
selectionsOnLine
);
......
......@@ -20,7 +20,7 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { DiffReview } from 'vs/editor/browser/widget/diffReview';
import { IDiffEditorOptions, IEditorOptions, EditorLayoutInfo, IComputedEditorOptions, EditorOption, EditorOptions } from 'vs/editor/common/config/editorOptions';
import { IDiffEditorOptions, IEditorOptions, EditorLayoutInfo, IComputedEditorOptions, EditorOption, EditorOptions, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange, Range } from 'vs/editor/common/core/range';
import { ISelection, Selection } from 'vs/editor/common/core/selection';
......@@ -2060,7 +2060,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
const isBasicASCII = ViewLineRenderingData.isBasicASCII(lineContent, originalModel.mightContainNonBasicASCII());
const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, originalModel.mightContainRTL());
const output = renderViewLine(new RenderLineInput(
(fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations) && !options.get(EditorOption.fontLigatures)),
(fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations)),
fontInfo.canUseHalfwidthRightwardsArrow,
lineContent,
false,
......@@ -2074,7 +2074,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
options.get(EditorOption.stopRenderingLineAfter),
options.get(EditorOption.renderWhitespace),
options.get(EditorOption.renderControlCharacters),
options.get(EditorOption.fontLigatures),
options.get(EditorOption.fontLigatures) !== EditorFontLigatures.OFF,
null // Send no selections, original line cannot be selected
), sb);
......
......@@ -17,7 +17,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
import { IComputedEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { IComputedEditorOptions, EditorOption, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
import { LineTokens } from 'vs/editor/common/core/lineTokens';
import { Position } from 'vs/editor/common/core/position';
import { ILineChange, ScrollType } from 'vs/editor/common/editorCommon';
......@@ -770,7 +770,7 @@ export class DiffReview extends Disposable {
const isBasicASCII = ViewLineRenderingData.isBasicASCII(lineContent, model.mightContainNonBasicASCII());
const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, model.mightContainRTL());
const r = renderViewLine(new RenderLineInput(
(fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations) && !options.get(EditorOption.fontLigatures)),
(fontInfo.isMonospace && !options.get(EditorOption.disableMonospaceOptimizations)),
fontInfo.canUseHalfwidthRightwardsArrow,
lineContent,
false,
......@@ -784,7 +784,7 @@ export class DiffReview extends Disposable {
options.get(EditorOption.stopRenderingLineAfter),
options.get(EditorOption.renderWhitespace),
options.get(EditorOption.renderControlCharacters),
options.get(EditorOption.fontLigatures),
options.get(EditorOption.fontLigatures) !== EditorFontLigatures.OFF,
null
));
......
......@@ -21,12 +21,6 @@
position: relative;
overflow: visible;
-webkit-text-size-adjust: 100%;
-webkit-font-feature-settings: "liga" off, "calt" off;
font-feature-settings: "liga" off, "calt" off;
}
.monaco-editor.enable-ligatures {
-webkit-font-feature-settings: "liga" on, "calt" on;
font-feature-settings: "liga" on, "calt" on;
}
/* -------------------- Misc -------------------- */
......
......@@ -178,7 +178,7 @@ export interface IEditorOptions {
* Enable font ligatures.
* Defaults to false.
*/
fontLigatures?: boolean;
fontLigatures?: boolean | string;
/**
* Disable the use of `will-change` for the editor margin and lines layers.
* The usage of `will-change` acts as a hint for browsers to create an extra layer.
......@@ -641,6 +641,9 @@ export interface IEditorOption<K1 extends EditorOption, V> {
type PossibleKeyName0<V> = { [K in keyof IEditorOptions]: IEditorOptions[K] extends V | undefined ? K : never }[keyof IEditorOptions];
type PossibleKeyName<V> = NonNullable<PossibleKeyName0<V>>;
/**
* @internal
*/
abstract class BaseEditorOption<K1 extends EditorOption, V> implements IEditorOption<K1, V> {
public readonly id: K1;
......@@ -1044,7 +1047,7 @@ function _cursorStyleFromString(cursorStyle: 'line' | 'block' | 'underline' | 'l
class EditorClassName extends ComputedEditorOption<EditorOption.editorClassName, string> {
constructor() {
super(EditorOption.editorClassName, [EditorOption.mouseStyle, EditorOption.fontLigatures, EditorOption.extraEditorClassName]);
super(EditorOption.editorClassName, [EditorOption.mouseStyle, EditorOption.extraEditorClassName]);
}
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: string): string {
......@@ -1055,9 +1058,6 @@ class EditorClassName extends ComputedEditorOption<EditorOption.editorClassName,
if (env.extraEditorClassName) {
className += ' ' + env.extraEditorClassName;
}
if (options.get(EditorOption.fontLigatures)) {
className += ' enable-ligatures';
}
if (options.get(EditorOption.mouseStyle) === 'default') {
className += ' mouse-default';
} else if (options.get(EditorOption.mouseStyle) === 'copy') {
......@@ -1167,6 +1167,57 @@ class EditorFind extends BaseEditorOption<EditorOption.find, EditorFindOptions>
//#endregion
//#region fontLigatures
/**
* @internal
*/
export class EditorFontLigatures extends BaseEditorOption<EditorOption.fontLigatures, string> {
public static OFF = '"liga" off, "calt" off';
public static ON = '"liga" on, "calt" on';
constructor() {
super(
EditorOption.fontLigatures, 'fontLigatures', EditorFontLigatures.OFF,
{
anyOf: [
{
type: 'boolean',
description: nls.localize('fontLigatures', "Enables/Disables font ligatures."),
},
{
type: 'string',
description: nls.localize('fontFeatureSettings', "Explicit font-feature-settings.")
}
],
default: false
}
);
}
public validate(input: any): string {
if (typeof input === 'undefined') {
return this.defaultValue;
}
if (typeof input === 'string') {
if (input === 'false') {
return EditorFontLigatures.OFF;
}
if (input === 'true') {
return EditorFontLigatures.ON;
}
return input;
}
if (Boolean(input)) {
return EditorFontLigatures.ON;
}
return EditorFontLigatures.OFF;
}
}
//#endregion
//#region fontInfo
class EditorFontInfo extends ComputedEditorOption<EditorOption.fontInfo, FontInfo> {
......@@ -2910,10 +2961,7 @@ export const EditorOptions = {
{ description: nls.localize('fontFamily', "Controls the font family.") }
)),
fontInfo: register(new EditorFontInfo()),
fontLigatures: register(new EditorBooleanOption(
EditorOption.fontLigatures, 'fontLigatures', false,
{ description: nls.localize('fontLigatures', "Enables/Disables font ligatures.") }
)),
fontLigatures2: register(new EditorFontLigatures()),
fontSize: register(new EditorFontSize()),
fontWeight: register(new EditorStringOption(
EditorOption.fontWeight, 'fontWeight', EDITOR_FONT_DEFAULTS.fontWeight,
......
......@@ -28,27 +28,29 @@ export class BareFontInfo {
const fontFamily = options.get(EditorOption.fontFamily);
const fontWeight = options.get(EditorOption.fontWeight);
const fontSize = options.get(EditorOption.fontSize);
const fontFeatureSettings = options.get(EditorOption.fontLigatures);
const lineHeight = options.get(EditorOption.lineHeight);
const letterSpacing = options.get(EditorOption.letterSpacing);
return BareFontInfo._create(fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, zoomLevel, ignoreEditorZoom);
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, zoomLevel, ignoreEditorZoom);
}
/**
* @internal
*/
public static createFromRawSettings(opts: { fontFamily?: string; fontWeight?: string; fontSize?: number; lineHeight?: number; letterSpacing?: number; }, zoomLevel: number, ignoreEditorZoom: boolean = false): BareFontInfo {
public static createFromRawSettings(opts: { fontFamily?: string; fontWeight?: string; fontSize?: number; fontLigatures?: boolean | string; lineHeight?: number; letterSpacing?: number; }, zoomLevel: number, ignoreEditorZoom: boolean = false): BareFontInfo {
const fontFamily = EditorOptions.fontFamily.validate(opts.fontFamily);
const fontWeight = EditorOptions.fontWeight.validate(opts.fontWeight);
const fontSize = EditorOptions.fontSize.validate(opts.fontSize);
const fontFeatureSettings = EditorOptions.fontLigatures2.validate(opts.fontLigatures);
const lineHeight = EditorOptions.lineHeight.validate(opts.lineHeight);
const letterSpacing = EditorOptions.letterSpacing.validate(opts.letterSpacing);
return BareFontInfo._create(fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, zoomLevel, ignoreEditorZoom);
return BareFontInfo._create(fontFamily, fontWeight, fontSize, fontFeatureSettings, lineHeight, letterSpacing, zoomLevel, ignoreEditorZoom);
}
/**
* @internal
*/
private static _create(fontFamily: string, fontWeight: string, fontSize: number, lineHeight: number, letterSpacing: number, zoomLevel: number, ignoreEditorZoom: boolean): BareFontInfo {
private static _create(fontFamily: string, fontWeight: string, fontSize: number, fontFeatureSettings: string, lineHeight: number, letterSpacing: number, zoomLevel: number, ignoreEditorZoom: boolean): BareFontInfo {
if (lineHeight === 0) {
lineHeight = Math.round(GOLDEN_LINE_HEIGHT_RATIO * fontSize);
} else if (lineHeight < MINIMUM_LINE_HEIGHT) {
......@@ -64,6 +66,7 @@ export class BareFontInfo {
fontFamily: fontFamily,
fontWeight: fontWeight,
fontSize: fontSize,
fontFeatureSettings: fontFeatureSettings,
lineHeight: lineHeight,
letterSpacing: letterSpacing
});
......@@ -73,6 +76,7 @@ export class BareFontInfo {
readonly fontFamily: string;
readonly fontWeight: string;
readonly fontSize: number;
readonly fontFeatureSettings: string;
readonly lineHeight: number;
readonly letterSpacing: number;
......@@ -84,6 +88,7 @@ export class BareFontInfo {
fontFamily: string;
fontWeight: string;
fontSize: number;
fontFeatureSettings: string;
lineHeight: number;
letterSpacing: number;
}) {
......@@ -91,6 +96,7 @@ export class BareFontInfo {
this.fontFamily = String(opts.fontFamily);
this.fontWeight = String(opts.fontWeight);
this.fontSize = opts.fontSize;
this.fontFeatureSettings = opts.fontFeatureSettings;
this.lineHeight = opts.lineHeight | 0;
this.letterSpacing = opts.letterSpacing;
}
......@@ -99,7 +105,7 @@ export class BareFontInfo {
* @internal
*/
public getId(): string {
return this.zoomLevel + '-' + this.fontFamily + '-' + this.fontWeight + '-' + this.fontSize + '-' + this.lineHeight + '-' + this.letterSpacing;
return this.zoomLevel + '-' + this.fontFamily + '-' + this.fontWeight + '-' + this.fontSize + '-' + this.fontFeatureSettings + '-' + this.lineHeight + '-' + this.letterSpacing;
}
/**
......@@ -138,6 +144,7 @@ export class FontInfo extends BareFontInfo {
fontFamily: string;
fontWeight: string;
fontSize: number;
fontFeatureSettings: string;
lineHeight: number;
letterSpacing: number;
isMonospace: boolean;
......@@ -165,6 +172,7 @@ export class FontInfo extends BareFontInfo {
this.fontFamily === other.fontFamily
&& this.fontWeight === other.fontWeight
&& this.fontSize === other.fontSize
&& this.fontFeatureSettings === other.fontFeatureSettings
&& this.lineHeight === other.lineHeight
&& this.letterSpacing === other.letterSpacing
&& this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IEditorOptions, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
......@@ -33,6 +33,7 @@ export class TestConfiguration extends CommonEditorConfiguration {
fontFamily: 'mockFont',
fontWeight: 'normal',
fontSize: 14,
fontFeatureSettings: EditorFontLigatures.OFF,
lineHeight: 19,
letterSpacing: 1.5,
isMonospace: true,
......
......@@ -2581,7 +2581,7 @@ declare namespace monaco.editor {
* Enable font ligatures.
* Defaults to false.
*/
fontLigatures?: boolean;
fontLigatures?: boolean | string;
/**
* Disable the use of `will-change` for the editor margin and lines layers.
* The usage of `will-change` acts as a hint for browsers to create an extra layer.
......@@ -4124,6 +4124,7 @@ declare namespace monaco.editor {
readonly fontFamily: string;
readonly fontWeight: string;
readonly fontSize: number;
readonly fontFeatureSettings: string;
readonly lineHeight: number;
readonly letterSpacing: number;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册