Skip to content

Commit

Permalink
Fixes #82153: Allow editor.fontLigatures to contain font-feature-se…
Browse files Browse the repository at this point in the history
…ttings
  • Loading branch information
alexdima committed Oct 9, 2019
1 parent e1f09b5 commit ab0eb6d
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 38 deletions.
10 changes: 10 additions & 0 deletions src/vs/base/browser/fastDomNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 = '';
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/vs/editor/browser/config/charWidthReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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';
Expand Down
20 changes: 14 additions & 6 deletions src/vs/editor/browser/config/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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';
}
Expand All @@ -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);
}
Expand Down
7 changes: 3 additions & 4 deletions src/vs/editor/browser/viewParts/lines/viewLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -218,7 +217,7 @@ export class ViewLine implements IVisibleLine {
options.stopRenderingLineAfter,
options.renderWhitespace,
options.renderControlCharacters,
options.fontLigatures,
options.fontLigatures !== EditorFontLigatures.OFF,
selectionsOnLine
);

Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/browser/widget/diffEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/browser/widget/diffReview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -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
));

Expand Down
6 changes: 0 additions & 6 deletions src/vs/editor/browser/widget/media/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 -------------------- */
Expand Down
66 changes: 57 additions & 9 deletions src/vs/editor/common/config/editorOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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') {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit ab0eb6d

Please sign in to comment.