Skip to content

Commit

Permalink
Refactors: Reduces assumptions about line height.
Browse files Browse the repository at this point in the history
This contains the parts of #194609 that we can already merge.
While it does not implement dynamic line heights, it is a first step in that direction.

Co-authored-by: Remco Haszing <[email protected]>
  • Loading branch information
hediet and remcohaszing committed Mar 8, 2024
1 parent 308c48e commit 86aef2f
Show file tree
Hide file tree
Showing 17 changed files with 75 additions and 82 deletions.
10 changes: 5 additions & 5 deletions src/vs/editor/browser/view/viewLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ 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.
*/
layoutLine(lineNumber: number, deltaTop: number): void;
layoutLine(lineNumber: number, deltaTop: number, lineHeight: number): void;
}

export interface ILine {
Expand Down Expand Up @@ -465,7 +465,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {

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

Expand Down Expand Up @@ -573,7 +573,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
continue;
}

const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);
const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData.lineHeight, this.viewportData, sb);
if (!renderResult) {
// line does not need rendering
continue;
Expand Down Expand Up @@ -603,7 +603,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
continue;
}

const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData, sb);
const renderResult = line.renderLine(i + rendLineNumberStart, deltaTop[i], this.viewportData.lineHeight, this.viewportData, sb);
if (!renderResult) {
// line does not need rendering
continue;
Expand Down
30 changes: 8 additions & 22 deletions src/vs/editor/browser/view/viewOverlays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
import { IVisibleLine, IVisibleLinesHost, VisibleLinesCollection } from 'vs/editor/browser/view/viewLayer';
import { ViewPart } from 'vs/editor/browser/view/viewPart';
import { StringBuilder } from 'vs/editor/common/core/stringBuilder';
import { IEditorConfiguration } from 'vs/editor/common/config/editorConfiguration';
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/browser/view/renderingContext';
import { ViewContext } from 'vs/editor/common/viewModel/viewContext';
import * as viewEvents from 'vs/editor/common/viewEvents';
Expand Down Expand Up @@ -71,7 +70,7 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
// ---- begin IVisibleLinesHost

public createVisibleLine(): ViewOverlayLine {
return new ViewOverlayLine(this._context.configuration, this._dynamicOverlays);
return new ViewOverlayLine(this._dynamicOverlays);
}

// ---- end IVisibleLinesHost
Expand All @@ -84,12 +83,6 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver

public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
this._visibleLines.onConfigurationChanged(e);
const startLineNumber = this._visibleLines.getStartLineNumber();
const endLineNumber = this._visibleLines.getEndLineNumber();
for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
const line = this._visibleLines.getVisibleLine(lineNumber);
line.onConfigurationChanged(e);
}

const options = this._context.configuration.options;
const fontInfo = options.get(EditorOption.fontInfo);
Expand Down Expand Up @@ -149,15 +142,11 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver

export class ViewOverlayLine implements IVisibleLine {

private readonly _configuration: IEditorConfiguration;
private readonly _dynamicOverlays: DynamicViewOverlay[];
private _domNode: FastDomNode<HTMLElement> | null;
private _renderedContent: string | null;
private _lineHeight: number;

constructor(configuration: IEditorConfiguration, dynamicOverlays: DynamicViewOverlay[]) {
this._configuration = configuration;
this._lineHeight = this._configuration.options.get(EditorOption.lineHeight);
constructor(dynamicOverlays: DynamicViewOverlay[]) {
this._dynamicOverlays = dynamicOverlays;

this._domNode = null;
Expand All @@ -180,11 +169,8 @@ export class ViewOverlayLine implements IVisibleLine {
public onTokensChanged(): void {
// Nothing
}
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): void {
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 @@ -198,21 +184,21 @@ export class ViewOverlayLine implements IVisibleLine {

this._renderedContent = result;

sb.appendString('<div style="position:absolute;top:');
sb.appendString('<div style="top:');
sb.appendString(String(deltaTop));
sb.appendString('px;width:100%;height:');
sb.appendString(String(this._lineHeight));
sb.appendString('px;height:');
sb.appendString(String(lineHeight));
sb.appendString('px;">');
sb.appendString(result);
sb.appendString('</div>');

return true;
}

public layoutLine(lineNumber: number, deltaTop: number): void {
public layoutLine(lineNumber: number, deltaTop: number, lineHeight: number): void {
if (this._domNode) {
this._domNode.setTop(deltaTop);
this._domNode.setHeight(this._lineHeight);
this._domNode.setHeight(lineHeight);
}
}
}
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 @@ -18,7 +18,6 @@ import { Position } from 'vs/editor/common/core/position';

export abstract class AbstractLineHighlightOverlay extends DynamicViewOverlay {
private readonly _context: ViewContext;
protected _lineHeight: number;
protected _renderLineHighlight: 'none' | 'gutter' | 'line' | 'all';
protected _wordWrap: boolean;
protected _contentLeft: number;
Expand All @@ -39,7 +38,6 @@ export abstract class AbstractLineHighlightOverlay extends DynamicViewOverlay {

const options = this._context.configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
this._lineHeight = options.get(EditorOption.lineHeight);
this._renderLineHighlight = options.get(EditorOption.renderLineHighlight);
this._renderLineHighlightOnlyWhenFocus = options.get(EditorOption.renderLineHighlightOnlyWhenFocus);
this._wordWrap = layoutInfo.isViewportWrapping;
Expand Down Expand Up @@ -89,7 +87,6 @@ export abstract class AbstractLineHighlightOverlay extends DynamicViewOverlay {
public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
const options = this._context.configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
this._lineHeight = options.get(EditorOption.lineHeight);
this._renderLineHighlight = options.get(EditorOption.renderLineHighlight);
this._renderLineHighlightOnlyWhenFocus = options.get(EditorOption.renderLineHighlightOnlyWhenFocus);
this._wordWrap = layoutInfo.isViewportWrapping;
Expand Down Expand Up @@ -208,7 +205,7 @@ export class CurrentLineHighlightOverlay extends AbstractLineHighlightOverlay {

protected _renderOne(ctx: RenderingContext, exact: boolean): string {
const className = 'current-line' + (this._shouldRenderInMargin() ? ' current-line-both' : '') + (exact ? ' current-line-exact' : '');
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 All @@ -221,7 +218,7 @@ export class CurrentLineHighlightOverlay extends AbstractLineHighlightOverlay {
export class CurrentLineMarginHighlightOverlay extends AbstractLineHighlightOverlay {
protected _renderOne(ctx: RenderingContext, exact: boolean): string {
const className = 'current-line' + (this._shouldRenderInMargin() ? ' current-line-margin' : '') + (this._shouldRenderOther() ? ' current-line-margin-both' : '') + (this._shouldRenderInMargin() && exact ? ' current-line-exact-margin' : '');
return `<div class="${className}" style="width:${this._contentLeft}px; height:${this._lineHeight}px;"></div>`;
return `<div class="${className}" style="width:${this._contentLeft}px"></div>`;
}
protected _shouldRenderThis(): boolean {
return true;
Expand Down
3 changes: 2 additions & 1 deletion src/vs/editor/browser/viewParts/decorations/decorations.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
*/
.monaco-editor .lines-content .cdr {
position: absolute;
}
height: 100%;
}
23 changes: 8 additions & 15 deletions src/vs/editor/browser/viewParts/decorations/decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ import { ViewContext } from 'vs/editor/common/viewModel/viewContext';
export class DecorationsOverlay extends DynamicViewOverlay {

private readonly _context: ViewContext;
private _lineHeight: number;
private _typicalHalfwidthCharacterWidth: number;
private _renderResult: string[] | null;

constructor(context: ViewContext) {
super();
this._context = context;
const options = this._context.configuration.options;
this._lineHeight = options.get(EditorOption.lineHeight);
this._typicalHalfwidthCharacterWidth = options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth;
this._renderResult = null;

Expand All @@ -40,7 +38,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {

public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
const options = this._context.configuration.options;
this._lineHeight = options.get(EditorOption.lineHeight);
this._typicalHalfwidthCharacterWidth = options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth;
return true;
}
Expand Down Expand Up @@ -116,7 +113,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {
}

private _renderWholeLineDecorations(ctx: RenderingContext, decorations: ViewModelDecoration[], output: string[]): void {
const lineHeight = String(this._lineHeight);
const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
const visibleEndLineNumber = ctx.visibleRange.endLineNumber;

Expand All @@ -130,9 +126,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
const decorationOutput = (
'<div class="cdr '
+ d.options.className
+ '" style="left:0;width:100%;height:'
+ lineHeight
+ 'px;"></div>'
+ '" style="left:0;width:100%;"></div>'
);

const startLineNumber = Math.max(d.range.startLineNumber, visibleStartLineNumber);
Expand All @@ -145,7 +139,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {
}

private _renderNormalDecorations(ctx: RenderingContext, decorations: ViewModelDecoration[], output: string[]): void {
const lineHeight = String(this._lineHeight);
const visibleStartLineNumber = ctx.visibleRange.startLineNumber;

let prevClassName: string | null = null;
Expand Down Expand Up @@ -176,7 +169,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {

// flush previous decoration
if (prevClassName !== null) {
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShouldFillLineOnLineBreak, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShouldFillLineOnLineBreak, prevShowIfCollapsed, visibleStartLineNumber, output);
}

prevClassName = className;
Expand All @@ -186,11 +179,11 @@ export class DecorationsOverlay extends DynamicViewOverlay {
}

if (prevClassName !== null) {
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShouldFillLineOnLineBreak, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShouldFillLineOnLineBreak, prevShowIfCollapsed, visibleStartLineNumber, output);
}
}

private _renderNormalDecoration(ctx: RenderingContext, range: Range, className: string, shouldFillLineOnLineBreak: boolean, showIfCollapsed: boolean, lineHeight: string, visibleStartLineNumber: number, output: string[]): void {
private _renderNormalDecoration(ctx: RenderingContext, range: Range, className: string, shouldFillLineOnLineBreak: boolean, showIfCollapsed: boolean, visibleStartLineNumber: number, output: string[]): void {
const linesVisibleRanges = ctx.linesVisibleRangesForRange(range, /*TODO@Alex*/className === 'findMatch');
if (!linesVisibleRanges) {
return;
Expand Down Expand Up @@ -222,12 +215,12 @@ export class DecorationsOverlay extends DynamicViewOverlay {
+ className
+ '" style="left:'
+ String(visibleRange.left)
+ 'px;width:'
+ (expandToLeft ?
'px;width:100%;height:' :
('px;width:' + String(visibleRange.width) + 'px;height:')
'100%;' :
(String(visibleRange.width) + 'px;')
)
+ lineHeight
+ 'px;"></div>'
+ '"></div>'
);
output[lineIndex] += decorationOutput;
}
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
8 changes: 4 additions & 4 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 Expand Up @@ -255,10 +255,10 @@ export class ViewLine implements IVisibleLine {
return true;
}

public layoutLine(lineNumber: number, deltaTop: number): void {
public layoutLine(lineNumber: number, deltaTop: number, lineHeight: number): void {
if (this._renderedViewLine && this._renderedViewLine.domNode) {
this._renderedViewLine.domNode.setTop(deltaTop);
this._renderedViewLine.domNode.setHeight(this._options.lineHeight);
this._renderedViewLine.domNode.setHeight(lineHeight);
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/vs/editor/browser/viewParts/lines/viewLines.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
width: 100%;
}

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

.monaco-editor .mtkw {
color: var(--vscode-editorWhitespace-foreground) !important;
}
Expand Down
Loading

0 comments on commit 86aef2f

Please sign in to comment.