Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dynamic line heights using decorations #194609

Closed
3 changes: 3 additions & 0 deletions src/vs/editor/browser/services/abstractCodeEditorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
public afterContentClassName: string | undefined;
public glyphMarginClassName: string | undefined;
public isWholeLine: boolean;
public lineHeight?: number;
public overviewRuler: IModelDecorationOverviewRulerOptions | undefined;
public stickiness: TrackedRangeStickiness | undefined;
public beforeInjectedText: InjectedTextOptions | undefined;
Expand Down Expand Up @@ -518,6 +519,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {

const options = providerArgs.options;
this.isWholeLine = Boolean(options.isWholeLine);
this.lineHeight = options.lineHeight;
this.stickiness = options.rangeBehavior;

const lightOverviewRulerColor = options.light && options.light.overviewRulerColor || options.overviewRulerColor;
Expand Down Expand Up @@ -547,6 +549,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
className: this.className,
glyphMarginClassName: this.glyphMarginClassName,
isWholeLine: this.isWholeLine,
lineHeight: this.lineHeight,
overviewRuler: this.overviewRuler,
stickiness: this.stickiness,
before: this.beforeInjectedText,
Expand Down
1 change: 1 addition & 0 deletions src/vs/editor/browser/view/dynamicViewOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RenderingContext } from 'vs/editor/browser/view/renderingContext';
import { ViewEventHandler } from 'vs/editor/common/viewEventHandler';

export abstract class DynamicViewOverlay extends ViewEventHandler {
public lineHeight?: number | undefined;
remcohaszing marked this conversation as resolved.
Show resolved Hide resolved

public abstract prepareRender(ctx: RenderingContext): void;

Expand Down
25 changes: 16 additions & 9 deletions src/vs/editor/browser/view/viewLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface IVisibleLine extends ILine {
* Return null if the HTML should not be touched.
* Return the new HTML otherwise.
*/
renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData, sb: StringBuilder): boolean;
renderLine(lineNumber: number, deltaTop: number, lineHeight: number, viewportData: ViewportData, sb: StringBuilder): boolean;

/**
* Layout the line.
Expand Down Expand Up @@ -460,13 +460,14 @@ class ViewLayerRenderer<T extends IVisibleLine> {
}

private _renderUntouchedLines(ctx: IRendererContext<T>, startIndex: number, endIndex: number, deltaTop: number[], deltaLN: number): void {
const rendLineNumberStart = ctx.rendLineNumberStart;
const lines = ctx.lines;
// XXX This needs to be restored and adjusted.
// const rendLineNumberStart = ctx.rendLineNumberStart;
// const lines = ctx.lines;

for (let i = startIndex; i <= endIndex; i++) {
const lineNumber = rendLineNumberStart + i;
lines[i].layoutLine(lineNumber, deltaTop[lineNumber - deltaLN]);
}
// for (let i = startIndex; i <= endIndex; i++) {
// const lineNumber = rendLineNumberStart + i;
// lines[i].layoutLine(lineNumber, deltaTop[lineNumber - deltaLN]);
// }
}

private _insertLinesBefore(ctx: IRendererContext<T>, fromLineNumber: number, toLineNumber: number, deltaTop: number[], deltaLN: number): void {
Expand Down Expand Up @@ -562,6 +563,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
{
sb.reset();
let hadNewLine = false;
const safeDeltaTOp = deltaTop.length - 1;

for (let i = 0; i < linesLength; i++) {
const line = lines[i];
Expand All @@ -573,7 +575,9 @@ class ViewLayerRenderer<T extends IVisibleLine> {
continue;
}

const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);
// XXX Get rid of the hardcoded 19
const lineHeight = i < safeDeltaTOp ? deltaTop[i + 1] - deltaTop[i] : 19;
const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], lineHeight, this.viewportData, sb);
if (!renderResult) {
// line does not need rendering
continue;
Expand All @@ -593,6 +597,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {

let hadInvalidLine = false;
const wasInvalid: boolean[] = [];
const safeDeltaTOp = deltaTop.length - 1;

for (let i = 0; i < linesLength; i++) {
const line = lines[i];
Expand All @@ -603,7 +608,9 @@ class ViewLayerRenderer<T extends IVisibleLine> {
continue;
}

const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);
// XXX Get rid of the hardcoded 19
const lineHeight = i < safeDeltaTOp ? deltaTop[i + 1] - deltaTop[i] : 19;
const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], lineHeight, this.viewportData, sb);
if (!renderResult) {
// line does not need rendering
continue;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/browser/view/viewOverlays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export class ViewOverlayLine implements IVisibleLine {
this._lineHeight = this._configuration.options.get(EditorOption.lineHeight);
}

public renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData, sb: StringBuilder): boolean {
public renderLine(lineNumber: number, deltaTop: number, lineHeight: number, viewportData: ViewportData, sb: StringBuilder): boolean {
let result = '';
for (let i = 0, len = this._dynamicOverlays.length; i < len; i++) {
const dynamicOverlay = this._dynamicOverlays[i];
Expand All @@ -201,7 +201,7 @@ export class ViewOverlayLine implements IVisibleLine {
sb.appendString('<div style="position:absolute;top:');
sb.appendString(String(deltaTop));
sb.appendString('px;width:100%;height:');
sb.appendString(String(this._lineHeight));
sb.appendString(String(lineHeight));
sb.appendString('px;">');
sb.appendString(result);
sb.appendString('</div>');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
left: 0;
top: 0;
box-sizing: border-box;
height: 100%;
}

.monaco-editor .margin-view-overlays .current-line {
Expand All @@ -17,8 +18,11 @@
left: 0;
top: 0;
box-sizing: border-box;
height: 100%;
}

.monaco-editor .margin-view-overlays .current-line.current-line-margin.current-line-margin-both {
.monaco-editor
.margin-view-overlays
.current-line.current-line-margin.current-line-margin-both {
border-right: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export class CurrentLineHighlightOverlay extends AbstractLineHighlightOverlay {

protected _renderOne(ctx: RenderingContext): string {
const className = 'current-line' + (this._shouldRenderOther() ? ' current-line-both' : '');
return `<div class="${className}" style="width:${Math.max(ctx.scrollWidth, this._contentWidth)}px; height:${this._lineHeight}px;"></div>`;
return `<div class="${className}" style="width:${Math.max(ctx.scrollWidth, this._contentWidth)}px;"></div>`;
}
protected _shouldRenderThis(): boolean {
return this._shouldRenderInContent();
Expand Down
8 changes: 6 additions & 2 deletions src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ export class DecorationToRender {
public endLineNumber: number;
public className: string;
public readonly zIndex: number;
public lineHeight?: number;

constructor(startLineNumber: number, endLineNumber: number, className: string, zIndex: number | undefined) {
constructor(startLineNumber: number, endLineNumber: number, className: string, zIndex: number | undefined, lineHeight: number | undefined) {
this.startLineNumber = +startLineNumber;
this.endLineNumber = +endLineNumber;
this.className = String(className);
this.zIndex = zIndex ?? 0;
this.lineHeight = lineHeight;
}
}

Expand All @@ -42,6 +44,7 @@ export class LineDecorationToRender {
constructor(
public readonly className: string,
public readonly zIndex: number,
public readonly lineHeight: number | undefined
) { }
}

Expand Down Expand Up @@ -95,6 +98,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay {
const d = decorations[i];
const className = d.className;
const zIndex = d.zIndex;
const lineHeight = d.lineHeight;
let startLineIndex = Math.max(d.startLineNumber, visibleStartLineNumber) - visibleStartLineNumber;
const endLineIndex = Math.min(d.endLineNumber, visibleEndLineNumber) - visibleStartLineNumber;

Expand All @@ -108,7 +112,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay {
}

for (let i = startLineIndex; i <= prevEndLineIndex; i++) {
output[i].add(new LineDecorationToRender(className, zIndex));
output[i].add(new LineDecorationToRender(className, zIndex, lineHeight));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
.monaco-editor .lines-content .core-guide {
position: absolute;
box-sizing: border-box;
height: 100%;
}
6 changes: 1 addition & 5 deletions src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {

private readonly _context: ViewContext;
private _primaryPosition: Position | null;
private _lineHeight: number;
private _spaceWidth: number;
private _renderResult: string[] | null;
private _maxIndentLeft: number;
Expand All @@ -37,7 +36,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
const wrappingInfo = options.get(EditorOption.wrappingInfo);
const fontInfo = options.get(EditorOption.fontInfo);

this._lineHeight = options.get(EditorOption.lineHeight);
this._spaceWidth = fontInfo.spaceWidth;
this._maxIndentLeft = wrappingInfo.wrappingColumn === -1 ? -1 : (wrappingInfo.wrappingColumn * fontInfo.typicalHalfwidthCharacterWidth);
this._bracketPairGuideOptions = options.get(EditorOption.guides);
Expand All @@ -60,7 +58,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
const wrappingInfo = options.get(EditorOption.wrappingInfo);
const fontInfo = options.get(EditorOption.fontInfo);

this._lineHeight = options.get(EditorOption.lineHeight);
this._spaceWidth = fontInfo.spaceWidth;
this._maxIndentLeft = wrappingInfo.wrappingColumn === -1 ? -1 : (wrappingInfo.wrappingColumn * fontInfo.typicalHalfwidthCharacterWidth);
this._bracketPairGuideOptions = options.get(EditorOption.guides);
Expand Down Expand Up @@ -114,7 +111,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
const scrollWidth = ctx.scrollWidth;
const lineHeight = this._lineHeight;

const activeCursorPosition = this._primaryPosition;

Expand Down Expand Up @@ -150,7 +146,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
)?.left ?? (left + this._spaceWidth)) - left
: this._spaceWidth;

result += `<div class="core-guide ${guide.className} ${className}" style="left:${left}px;height:${lineHeight}px;width:${width}px"></div>`;
result += `<div class="core-guide ${guide.className} ${className}" style="left:${left}px;width:${width}px"></div>`;
}
output[lineIndex] = result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/

.monaco-editor .margin-view-overlays .line-numbers {
bottom: 0;
font-variant-numeric: tabular-nums;
position: absolute;
text-align: right;
display: inline-block;
vertical-align: middle;
box-sizing: border-box;
cursor: default;
height: 100%;
}

.monaco-editor .relative-current-line-number {
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/browser/viewParts/lines/viewLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export class ViewLine implements IVisibleLine {
return false;
}

public renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData, sb: StringBuilder): boolean {
public renderLine(lineNumber: number, deltaTop: number, lineHeight: number, viewportData: ViewportData, sb: StringBuilder): boolean {
if (this._isMaybeInvalid === false) {
// it appears that nothing relevant has changed
return false;
Expand Down Expand Up @@ -222,7 +222,7 @@ export class ViewLine implements IVisibleLine {
sb.appendString('<div style="top:');
sb.appendString(String(deltaTop));
sb.appendString('px;height:');
sb.appendString(String(this._options.lineHeight));
sb.appendString(String(lineHeight));
sb.appendString('px;" class="');
sb.appendString(ViewLine.CLASS_NAME);
sb.appendString('">');
Expand Down
10 changes: 9 additions & 1 deletion src/vs/editor/browser/viewParts/lines/viewLines.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
}

.mtkoverflow {
background-color: var(--vscode-button-background, var(--vscode-editor-background));
background-color: var(
--vscode-button-background,
var(--vscode-editor-background)
);
color: var(--vscode-button-foreground, var(--vscode-editor-foreground));
border-width: 1px;
border-style: solid;
Expand Down Expand Up @@ -63,6 +66,11 @@
width: 100%;
}

.monaco-editor .view-line > span {
bottom: 0;
position: absolute;
}

.monaco-editor .mtkw {
color: var(--vscode-editorWhitespace-foreground) !important;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,13 @@ export class LinesDecorationsOverlay extends DedupOverlay {
const d = decorations[i];
const linesDecorationsClassName = d.options.linesDecorationsClassName;
const zIndex = d.options.zIndex;
const lineHeight = d.options.lineHeight;
if (linesDecorationsClassName) {
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, linesDecorationsClassName, zIndex);
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, linesDecorationsClassName, zIndex, lineHeight);
}
const firstLineDecorationClassName = d.options.firstLineDecorationClassName;
if (firstLineDecorationClassName) {
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.startLineNumber, firstLineDecorationClassName, zIndex);
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.startLineNumber, firstLineDecorationClassName, zIndex, lineHeight);
}
}
return r;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,16 @@ export class MarginViewLineDecorationsOverlay extends DedupOverlay {
const d = decorations[i];
const marginClassName = d.options.marginClassName;
const zIndex = d.options.zIndex;
const lineHeight = d.options.lineHeight;
if (lineHeight) {
if (this.lineHeight) {
this.lineHeight = Math.max(this.lineHeight, lineHeight);
} else {
this.lineHeight = lineHeight;
}
}
if (marginClassName) {
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, marginClassName, zIndex);
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, marginClassName, zIndex, lineHeight);
}
}
return r;
Expand Down
49 changes: 37 additions & 12 deletions src/vs/editor/browser/viewParts/selections/selections.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,44 @@

.monaco-editor .selected-text {
background-color: var(--vscode-editor-inactiveSelectionBackground);
bottom: 0;
remcohaszing marked this conversation as resolved.
Show resolved Hide resolved
}

.monaco-editor .top-left-radius { border-top-left-radius: 3px; }
.monaco-editor .bottom-left-radius { border-bottom-left-radius: 3px; }
.monaco-editor .top-right-radius { border-top-right-radius: 3px; }
.monaco-editor .bottom-right-radius { border-bottom-right-radius: 3px; }
.monaco-editor .top-left-radius {
border-top-left-radius: 3px;
}
.monaco-editor .bottom-left-radius {
border-bottom-left-radius: 3px;
}
.monaco-editor .top-right-radius {
border-top-right-radius: 3px;
}
.monaco-editor .bottom-right-radius {
border-bottom-right-radius: 3px;
}
remcohaszing marked this conversation as resolved.
Show resolved Hide resolved

.monaco-editor.hc-black .top-left-radius { border-top-left-radius: 0; }
.monaco-editor.hc-black .bottom-left-radius { border-bottom-left-radius: 0; }
.monaco-editor.hc-black .top-right-radius { border-top-right-radius: 0; }
.monaco-editor.hc-black .bottom-right-radius { border-bottom-right-radius: 0; }
.monaco-editor.hc-black .top-left-radius {
border-top-left-radius: 0;
}
.monaco-editor.hc-black .bottom-left-radius {
border-bottom-left-radius: 0;
}
.monaco-editor.hc-black .top-right-radius {
border-top-right-radius: 0;
}
.monaco-editor.hc-black .bottom-right-radius {
border-bottom-right-radius: 0;
}

.monaco-editor.hc-light .top-left-radius { border-top-left-radius: 0; }
.monaco-editor.hc-light .bottom-left-radius { border-bottom-left-radius: 0; }
.monaco-editor.hc-light .top-right-radius { border-top-right-radius: 0; }
.monaco-editor.hc-light .bottom-right-radius { border-bottom-right-radius: 0; }
.monaco-editor.hc-light .top-left-radius {
border-top-left-radius: 0;
}
.monaco-editor.hc-light .bottom-left-radius {
border-bottom-left-radius: 0;
}
.monaco-editor.hc-light .top-right-radius {
border-top-right-radius: 0;
}
.monaco-editor.hc-light .bottom-right-radius {
border-bottom-right-radius: 0;
}
Loading