Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/browser/view/renderingContext.ts
3294 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Position } from '../../common/core/position.js';
7
import { Range } from '../../common/core/range.js';
8
import { ViewportData } from '../../common/viewLayout/viewLinesViewportData.js';
9
import { IViewLayout } from '../../common/viewModel.js';
10
import { ViewModelDecoration } from '../../common/viewModel/viewModelDecoration.js';
11
12
export interface IViewLines {
13
linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] | null;
14
visibleRangeForPosition(position: Position): HorizontalPosition | null;
15
}
16
17
export abstract class RestrictedRenderingContext {
18
_restrictedRenderingContextBrand: void = undefined;
19
20
public readonly viewportData: ViewportData;
21
22
public readonly scrollWidth: number;
23
public readonly scrollHeight: number;
24
25
public readonly visibleRange: Range;
26
public readonly bigNumbersDelta: number;
27
28
public readonly scrollTop: number;
29
public readonly scrollLeft: number;
30
31
public readonly viewportWidth: number;
32
public readonly viewportHeight: number;
33
34
private readonly _viewLayout: IViewLayout;
35
36
constructor(viewLayout: IViewLayout, viewportData: ViewportData) {
37
this._viewLayout = viewLayout;
38
this.viewportData = viewportData;
39
40
this.scrollWidth = this._viewLayout.getScrollWidth();
41
this.scrollHeight = this._viewLayout.getScrollHeight();
42
43
this.visibleRange = this.viewportData.visibleRange;
44
this.bigNumbersDelta = this.viewportData.bigNumbersDelta;
45
46
const vInfo = this._viewLayout.getCurrentViewport();
47
this.scrollTop = vInfo.top;
48
this.scrollLeft = vInfo.left;
49
this.viewportWidth = vInfo.width;
50
this.viewportHeight = vInfo.height;
51
}
52
53
public getScrolledTopFromAbsoluteTop(absoluteTop: number): number {
54
return absoluteTop - this.scrollTop;
55
}
56
57
public getVerticalOffsetForLineNumber(lineNumber: number, includeViewZones?: boolean): number {
58
return this._viewLayout.getVerticalOffsetForLineNumber(lineNumber, includeViewZones);
59
}
60
61
public getVerticalOffsetAfterLineNumber(lineNumber: number, includeViewZones?: boolean): number {
62
return this._viewLayout.getVerticalOffsetAfterLineNumber(lineNumber, includeViewZones);
63
}
64
65
public getLineHeightForLineNumber(lineNumber: number): number {
66
return this._viewLayout.getLineHeightForLineNumber(lineNumber);
67
}
68
69
public getDecorationsInViewport(): ViewModelDecoration[] {
70
return this.viewportData.getDecorationsInViewport();
71
}
72
73
}
74
75
export class RenderingContext extends RestrictedRenderingContext {
76
_renderingContextBrand: void = undefined;
77
78
private readonly _viewLines: IViewLines;
79
private readonly _viewLinesGpu?: IViewLines;
80
81
constructor(viewLayout: IViewLayout, viewportData: ViewportData, viewLines: IViewLines, viewLinesGpu?: IViewLines) {
82
super(viewLayout, viewportData);
83
this._viewLines = viewLines;
84
this._viewLinesGpu = viewLinesGpu;
85
}
86
87
public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] | null {
88
const domRanges = this._viewLines.linesVisibleRangesForRange(range, includeNewLines);
89
if (!this._viewLinesGpu) {
90
return domRanges ?? null;
91
}
92
const gpuRanges = this._viewLinesGpu.linesVisibleRangesForRange(range, includeNewLines);
93
if (!domRanges) {
94
return gpuRanges;
95
}
96
if (!gpuRanges) {
97
return domRanges;
98
}
99
return domRanges.concat(gpuRanges).sort((a, b) => a.lineNumber - b.lineNumber);
100
}
101
102
public visibleRangeForPosition(position: Position): HorizontalPosition | null {
103
return this._viewLines.visibleRangeForPosition(position) ?? this._viewLinesGpu?.visibleRangeForPosition(position) ?? null;
104
}
105
}
106
107
export class LineVisibleRanges {
108
/**
109
* Returns the element with the smallest `lineNumber`.
110
*/
111
public static firstLine(ranges: LineVisibleRanges[] | null): LineVisibleRanges | null {
112
if (!ranges) {
113
return null;
114
}
115
let result: LineVisibleRanges | null = null;
116
for (const range of ranges) {
117
if (!result || range.lineNumber < result.lineNumber) {
118
result = range;
119
}
120
}
121
return result;
122
}
123
124
/**
125
* Returns the element with the largest `lineNumber`.
126
*/
127
public static lastLine(ranges: LineVisibleRanges[] | null): LineVisibleRanges | null {
128
if (!ranges) {
129
return null;
130
}
131
let result: LineVisibleRanges | null = null;
132
for (const range of ranges) {
133
if (!result || range.lineNumber > result.lineNumber) {
134
result = range;
135
}
136
}
137
return result;
138
}
139
140
constructor(
141
public readonly outsideRenderedLine: boolean,
142
public readonly lineNumber: number,
143
public readonly ranges: HorizontalRange[],
144
/**
145
* Indicates if the requested range does not end in this line, but continues on the next line.
146
*/
147
public readonly continuesOnNextLine: boolean,
148
) { }
149
}
150
151
export class HorizontalRange {
152
_horizontalRangeBrand: void = undefined;
153
154
public left: number;
155
public width: number;
156
157
public static from(ranges: FloatHorizontalRange[]): HorizontalRange[] {
158
const result = new Array(ranges.length);
159
for (let i = 0, len = ranges.length; i < len; i++) {
160
const range = ranges[i];
161
result[i] = new HorizontalRange(range.left, range.width);
162
}
163
return result;
164
}
165
166
constructor(left: number, width: number) {
167
this.left = Math.round(left);
168
this.width = Math.round(width);
169
}
170
171
public toString(): string {
172
return `[${this.left},${this.width}]`;
173
}
174
}
175
176
export class FloatHorizontalRange {
177
_floatHorizontalRangeBrand: void = undefined;
178
179
public left: number;
180
public width: number;
181
182
constructor(left: number, width: number) {
183
this.left = left;
184
this.width = width;
185
}
186
187
public toString(): string {
188
return `[${this.left},${this.width}]`;
189
}
190
191
public static compare(a: FloatHorizontalRange, b: FloatHorizontalRange): number {
192
return a.left - b.left;
193
}
194
}
195
196
export class HorizontalPosition {
197
public outsideRenderedLine: boolean;
198
/**
199
* Math.round(this.originalLeft)
200
*/
201
public left: number;
202
public originalLeft: number;
203
204
constructor(outsideRenderedLine: boolean, left: number) {
205
this.outsideRenderedLine = outsideRenderedLine;
206
this.originalLeft = left;
207
this.left = Math.round(this.originalLeft);
208
}
209
}
210
211
export class VisibleRanges {
212
constructor(
213
public readonly outsideRenderedLine: boolean,
214
public readonly ranges: FloatHorizontalRange[]
215
) {
216
}
217
}
218
219