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: 0 additions & 1 deletion src/vs/editor/browser/view/dynamicViewOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { RenderingContext } from 'vs/editor/browser/view/renderingContext';
import { ViewEventHandler } from 'vs/editor/common/viewEventHandler';

export abstract class DynamicViewOverlay extends ViewEventHandler {

public abstract prepareRender(ctx: RenderingContext): void;

public abstract render(startLineNumber: number, lineNumber: number): string;
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
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
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;
}
18 changes: 9 additions & 9 deletions src/vs/editor/browser/viewParts/selections/selections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,12 @@ export class SelectionsOverlay extends DynamicViewOverlay {
return linesVisibleRanges;
}

private _createSelectionPiece(top: number, height: string, className: string, left: number, width: number): string {
private _createSelectionPiece(bottom: number, height: string, className: string, left: number, width: number): string {
return (
'<div class="cslr '
+ className
+ '" style="top:'
+ top.toString()
+ '" style="bottom:'
+ bottom.toString()
+ 'px;left:'
+ left.toString()
+ 'px;width:'
Expand Down Expand Up @@ -289,7 +289,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
const lineIndex = lineNumber - visibleStartLineNumber;

const lineHeight = hasMultipleSelections ? (lineNumber === lastLineNumber || lineNumber === firstLineNumber ? reducedLineHeight : fullLineHeight) : fullLineHeight;
const top = hasMultipleSelections ? (lineNumber === firstLineNumber ? 1 : 0) : 0;
const bottom = hasMultipleSelections ? (lineNumber === firstLineNumber ? -1 : 0) : 0;

let innerCornerOutput = '';
let restOfSelectionOutput = '';
Expand All @@ -304,7 +304,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
// Reverse rounded corner to the left

// First comes the selection (blue layer)
innerCornerOutput += this._createSelectionPiece(top, lineHeight, SelectionsOverlay.SELECTION_CLASS_NAME, visibleRange.left - SelectionsOverlay.ROUNDED_PIECE_WIDTH, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
innerCornerOutput += this._createSelectionPiece(bottom, lineHeight, SelectionsOverlay.SELECTION_CLASS_NAME, visibleRange.left - SelectionsOverlay.ROUNDED_PIECE_WIDTH, SelectionsOverlay.ROUNDED_PIECE_WIDTH);

// Second comes the background (white layer) with inverse border radius
let className = SelectionsOverlay.EDITOR_BACKGROUND_CLASS_NAME;
Expand All @@ -314,13 +314,13 @@ export class SelectionsOverlay extends DynamicViewOverlay {
if (startStyle.bottom === CornerStyle.INTERN) {
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_RIGHT;
}
innerCornerOutput += this._createSelectionPiece(top, lineHeight, className, visibleRange.left - SelectionsOverlay.ROUNDED_PIECE_WIDTH, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
innerCornerOutput += this._createSelectionPiece(bottom, lineHeight, className, visibleRange.left - SelectionsOverlay.ROUNDED_PIECE_WIDTH, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
}
if (endStyle.top === CornerStyle.INTERN || endStyle.bottom === CornerStyle.INTERN) {
// Reverse rounded corner to the right

// First comes the selection (blue layer)
innerCornerOutput += this._createSelectionPiece(top, lineHeight, SelectionsOverlay.SELECTION_CLASS_NAME, visibleRange.left + visibleRange.width, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
innerCornerOutput += this._createSelectionPiece(bottom, lineHeight, SelectionsOverlay.SELECTION_CLASS_NAME, visibleRange.left + visibleRange.width, SelectionsOverlay.ROUNDED_PIECE_WIDTH);

// Second comes the background (white layer) with inverse border radius
let className = SelectionsOverlay.EDITOR_BACKGROUND_CLASS_NAME;
Expand All @@ -330,7 +330,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
if (endStyle.bottom === CornerStyle.INTERN) {
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_LEFT;
}
innerCornerOutput += this._createSelectionPiece(top, lineHeight, className, visibleRange.left + visibleRange.width, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
innerCornerOutput += this._createSelectionPiece(bottom, lineHeight, className, visibleRange.left + visibleRange.width, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
}
}

Expand All @@ -351,7 +351,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_RIGHT;
}
}
restOfSelectionOutput += this._createSelectionPiece(top, lineHeight, className, visibleRange.left, visibleRange.width);
restOfSelectionOutput += this._createSelectionPiece(bottom, lineHeight, className, visibleRange.left, visibleRange.width);
}

output2[lineIndex][0] += innerCornerOutput;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/browser/viewParts/whitespace/whitespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export class WhitespaceOverlay extends DynamicViewOverlay {
if (USE_SVG) {
maxLeft = Math.round(maxLeft + spaceWidth);
return (
`<svg style="position:absolute;width:${maxLeft}px;height:${lineHeight}px" viewBox="0 0 ${maxLeft} ${lineHeight}" xmlns="http://www.w3.org/2000/svg" fill="${color}">`
`<svg style="bottom:0;position:absolute;width:${maxLeft}px;height:${lineHeight}px" viewBox="0 0 ${maxLeft} ${lineHeight}" xmlns="http://www.w3.org/2000/svg" fill="${color}">`
+ result
+ `</svg>`
);
Expand Down
3 changes: 2 additions & 1 deletion src/vs/editor/browser/widget/codeEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE

private static readonly dropIntoEditorDecorationOptions = ModelDecorationOptions.register({
description: 'workbench-dnd-target',
className: 'dnd-target'
className: 'dnd-target',
lineHeight: 0
});

//#region Eventing
Expand Down
Loading