Path: blob/main/src/vs/editor/browser/view/renderingContext.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Position } from '../../common/core/position.js';6import { Range } from '../../common/core/range.js';7import { ViewportData } from '../../common/viewLayout/viewLinesViewportData.js';8import { IViewLayout } from '../../common/viewModel.js';9import { ViewModelDecoration } from '../../common/viewModel/viewModelDecoration.js';1011export interface IViewLines {12linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] | null;13visibleRangeForPosition(position: Position): HorizontalPosition | null;14}1516export abstract class RestrictedRenderingContext {17_restrictedRenderingContextBrand: void = undefined;1819public readonly viewportData: ViewportData;2021public readonly scrollWidth: number;22public readonly scrollHeight: number;2324public readonly visibleRange: Range;25public readonly bigNumbersDelta: number;2627public readonly scrollTop: number;28public readonly scrollLeft: number;2930public readonly viewportWidth: number;31public readonly viewportHeight: number;3233private readonly _viewLayout: IViewLayout;3435constructor(viewLayout: IViewLayout, viewportData: ViewportData) {36this._viewLayout = viewLayout;37this.viewportData = viewportData;3839this.scrollWidth = this._viewLayout.getScrollWidth();40this.scrollHeight = this._viewLayout.getScrollHeight();4142this.visibleRange = this.viewportData.visibleRange;43this.bigNumbersDelta = this.viewportData.bigNumbersDelta;4445const vInfo = this._viewLayout.getCurrentViewport();46this.scrollTop = vInfo.top;47this.scrollLeft = vInfo.left;48this.viewportWidth = vInfo.width;49this.viewportHeight = vInfo.height;50}5152public getScrolledTopFromAbsoluteTop(absoluteTop: number): number {53return absoluteTop - this.scrollTop;54}5556public getVerticalOffsetForLineNumber(lineNumber: number, includeViewZones?: boolean): number {57return this._viewLayout.getVerticalOffsetForLineNumber(lineNumber, includeViewZones);58}5960public getVerticalOffsetAfterLineNumber(lineNumber: number, includeViewZones?: boolean): number {61return this._viewLayout.getVerticalOffsetAfterLineNumber(lineNumber, includeViewZones);62}6364public getLineHeightForLineNumber(lineNumber: number): number {65return this._viewLayout.getLineHeightForLineNumber(lineNumber);66}6768public getDecorationsInViewport(): ViewModelDecoration[] {69return this.viewportData.getDecorationsInViewport();70}7172}7374export class RenderingContext extends RestrictedRenderingContext {75_renderingContextBrand: void = undefined;7677private readonly _viewLines: IViewLines;78private readonly _viewLinesGpu?: IViewLines;7980constructor(viewLayout: IViewLayout, viewportData: ViewportData, viewLines: IViewLines, viewLinesGpu?: IViewLines) {81super(viewLayout, viewportData);82this._viewLines = viewLines;83this._viewLinesGpu = viewLinesGpu;84}8586public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] | null {87const domRanges = this._viewLines.linesVisibleRangesForRange(range, includeNewLines);88if (!this._viewLinesGpu) {89return domRanges ?? null;90}91const gpuRanges = this._viewLinesGpu.linesVisibleRangesForRange(range, includeNewLines);92if (!domRanges) {93return gpuRanges;94}95if (!gpuRanges) {96return domRanges;97}98return domRanges.concat(gpuRanges).sort((a, b) => a.lineNumber - b.lineNumber);99}100101public visibleRangeForPosition(position: Position): HorizontalPosition | null {102return this._viewLines.visibleRangeForPosition(position) ?? this._viewLinesGpu?.visibleRangeForPosition(position) ?? null;103}104}105106export class LineVisibleRanges {107/**108* Returns the element with the smallest `lineNumber`.109*/110public static firstLine(ranges: LineVisibleRanges[] | null): LineVisibleRanges | null {111if (!ranges) {112return null;113}114let result: LineVisibleRanges | null = null;115for (const range of ranges) {116if (!result || range.lineNumber < result.lineNumber) {117result = range;118}119}120return result;121}122123/**124* Returns the element with the largest `lineNumber`.125*/126public static lastLine(ranges: LineVisibleRanges[] | null): LineVisibleRanges | null {127if (!ranges) {128return null;129}130let result: LineVisibleRanges | null = null;131for (const range of ranges) {132if (!result || range.lineNumber > result.lineNumber) {133result = range;134}135}136return result;137}138139constructor(140public readonly outsideRenderedLine: boolean,141public readonly lineNumber: number,142public readonly ranges: HorizontalRange[],143/**144* Indicates if the requested range does not end in this line, but continues on the next line.145*/146public readonly continuesOnNextLine: boolean,147) { }148}149150export class HorizontalRange {151_horizontalRangeBrand: void = undefined;152153public left: number;154public width: number;155156public static from(ranges: FloatHorizontalRange[]): HorizontalRange[] {157const result = new Array(ranges.length);158for (let i = 0, len = ranges.length; i < len; i++) {159const range = ranges[i];160result[i] = new HorizontalRange(range.left, range.width);161}162return result;163}164165constructor(left: number, width: number) {166this.left = Math.round(left);167this.width = Math.round(width);168}169170public toString(): string {171return `[${this.left},${this.width}]`;172}173}174175export class FloatHorizontalRange {176_floatHorizontalRangeBrand: void = undefined;177178public left: number;179public width: number;180181constructor(left: number, width: number) {182this.left = left;183this.width = width;184}185186public toString(): string {187return `[${this.left},${this.width}]`;188}189190public static compare(a: FloatHorizontalRange, b: FloatHorizontalRange): number {191return a.left - b.left;192}193}194195export class HorizontalPosition {196public outsideRenderedLine: boolean;197/**198* Math.round(this.originalLeft)199*/200public left: number;201public originalLeft: number;202203constructor(outsideRenderedLine: boolean, left: number) {204this.outsideRenderedLine = outsideRenderedLine;205this.originalLeft = left;206this.left = Math.round(this.originalLeft);207}208}209210export class VisibleRanges {211constructor(212public readonly outsideRenderedLine: boolean,213public readonly ranges: FloatHorizontalRange[]214) {215}216}217218219