UNPKG

@21epub/epub-thirdparty

Version:
293 lines (292 loc) 11.8 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as strings from '../../../base/common/strings.js'; import { Position } from '../core/position.js'; import { Range } from '../core/range.js'; export class Viewport { constructor(top, left, width, height) { this._viewportBrand = undefined; this.top = top | 0; this.left = left | 0; this.width = width | 0; this.height = height | 0; } } export class OutputPosition { constructor(outputLineIndex, outputOffset) { this.outputLineIndex = outputLineIndex; this.outputOffset = outputOffset; } toString() { return `${this.outputLineIndex}:${this.outputOffset}`; } toPosition(baseLineNumber, wrappedTextIndentLength) { const delta = (this.outputLineIndex > 0 ? wrappedTextIndentLength : 0); return new Position(baseLineNumber + this.outputLineIndex, delta + this.outputOffset + 1); } } export class LineBreakData { constructor(breakOffsets, breakOffsetsVisibleColumn, wrappedTextIndentLength, injectionOffsets, injectionOptions) { this.breakOffsets = breakOffsets; this.breakOffsetsVisibleColumn = breakOffsetsVisibleColumn; this.wrappedTextIndentLength = wrappedTextIndentLength; this.injectionOffsets = injectionOffsets; this.injectionOptions = injectionOptions; } getInputOffsetOfOutputPosition(outputLineIndex, outputOffset) { let inputOffset = 0; if (outputLineIndex === 0) { inputOffset = outputOffset; } else { inputOffset = this.breakOffsets[outputLineIndex - 1] + outputOffset; } if (this.injectionOffsets !== null) { for (let i = 0; i < this.injectionOffsets.length; i++) { if (inputOffset > this.injectionOffsets[i]) { if (inputOffset < this.injectionOffsets[i] + this.injectionOptions[i].content.length) { // `inputOffset` is within injected text inputOffset = this.injectionOffsets[i]; } else { inputOffset -= this.injectionOptions[i].content.length; } } else { break; } } } return inputOffset; } getOutputPositionOfInputOffset(inputOffset, affinity = 2 /* None */) { let delta = 0; if (this.injectionOffsets !== null) { for (let i = 0; i < this.injectionOffsets.length; i++) { if (inputOffset < this.injectionOffsets[i]) { break; } if (affinity !== 1 /* Right */ && inputOffset === this.injectionOffsets[i]) { break; } delta += this.injectionOptions[i].content.length; } } inputOffset += delta; return this.getOutputPositionOfOffsetInUnwrappedLine(inputOffset, affinity); } getOutputPositionOfOffsetInUnwrappedLine(inputOffset, affinity = 2 /* None */) { let low = 0; let high = this.breakOffsets.length - 1; let mid = 0; let midStart = 0; while (low <= high) { mid = low + ((high - low) / 2) | 0; const midStop = this.breakOffsets[mid]; midStart = mid > 0 ? this.breakOffsets[mid - 1] : 0; if (affinity === 0 /* Left */) { if (inputOffset <= midStart) { high = mid - 1; } else if (inputOffset > midStop) { low = mid + 1; } else { break; } } else { if (inputOffset < midStart) { high = mid - 1; } else if (inputOffset >= midStop) { low = mid + 1; } else { break; } } } return new OutputPosition(mid, inputOffset - midStart); } outputPositionToOffsetInUnwrappedLine(outputLineIndex, outputOffset) { let result = (outputLineIndex > 0 ? this.breakOffsets[outputLineIndex - 1] : 0) + outputOffset; if (outputLineIndex > 0) { result -= this.wrappedTextIndentLength; } return result; } normalizeOffsetAroundInjections(offsetInUnwrappedLine, affinity) { const injectedText = this.getInjectedTextAtOffset(offsetInUnwrappedLine); if (!injectedText) { return offsetInUnwrappedLine; } if (affinity === 2 /* None */) { if (offsetInUnwrappedLine === injectedText.offsetInUnwrappedLine + injectedText.length) { // go to the end of this injected text return injectedText.offsetInUnwrappedLine + injectedText.length; } else { // go to the start of this injected text return injectedText.offsetInUnwrappedLine; } } if (affinity === 1 /* Right */) { let result = injectedText.offsetInUnwrappedLine + injectedText.length; let index = injectedText.injectedTextIndex; // traverse all injected text that touch eachother while (index + 1 < this.injectionOffsets.length && this.injectionOffsets[index + 1] === this.injectionOffsets[index]) { result += this.injectionOptions[index + 1].content.length; index++; } return result; } // affinity is left let result = injectedText.offsetInUnwrappedLine; let index = injectedText.injectedTextIndex; // traverse all injected text that touch eachother while (index - 1 >= 0 && this.injectionOffsets[index - 1] === this.injectionOffsets[index]) { result -= this.injectionOptions[index - 1].content.length; index++; } return result; } getInjectedText(outputLineIndex, outputOffset) { const offset = this.outputPositionToOffsetInUnwrappedLine(outputLineIndex, outputOffset); const injectedText = this.getInjectedTextAtOffset(offset); if (!injectedText) { return null; } return { options: this.injectionOptions[injectedText.injectedTextIndex] }; } getInjectedTextAtOffset(offsetInUnwrappedLine) { const injectionOffsets = this.injectionOffsets; const injectionOptions = this.injectionOptions; if (injectionOffsets !== null) { let totalInjectedTextLengthBefore = 0; for (let i = 0; i < injectionOffsets.length; i++) { const length = injectionOptions[i].content.length; const injectedTextStartOffsetInUnwrappedLine = injectionOffsets[i] + totalInjectedTextLengthBefore; const injectedTextEndOffsetInUnwrappedLine = injectionOffsets[i] + totalInjectedTextLengthBefore + length; if (injectedTextStartOffsetInUnwrappedLine > offsetInUnwrappedLine) { // Injected text starts later. break; // All later injected texts have an even larger offset. } if (offsetInUnwrappedLine <= injectedTextEndOffsetInUnwrappedLine) { // Injected text ends after or with the given position (but also starts with or before it). return { injectedTextIndex: i, offsetInUnwrappedLine: injectedTextStartOffsetInUnwrappedLine, length }; } totalInjectedTextLengthBefore += length; } } return undefined; } } export class InjectedText { constructor(options) { this.options = options; } } export class MinimapLinesRenderingData { constructor(tabSize, data) { this.tabSize = tabSize; this.data = data; } } export class ViewLineData { constructor(content, continuesWithWrappedLine, minColumn, maxColumn, startVisibleColumn, tokens, inlineDecorations) { this._viewLineDataBrand = undefined; this.content = content; this.continuesWithWrappedLine = continuesWithWrappedLine; this.minColumn = minColumn; this.maxColumn = maxColumn; this.startVisibleColumn = startVisibleColumn; this.tokens = tokens; this.inlineDecorations = inlineDecorations; } } export class ViewLineRenderingData { constructor(minColumn, maxColumn, content, continuesWithWrappedLine, mightContainRTL, mightContainNonBasicASCII, tokens, inlineDecorations, tabSize, startVisibleColumn) { this.minColumn = minColumn; this.maxColumn = maxColumn; this.content = content; this.continuesWithWrappedLine = continuesWithWrappedLine; this.isBasicASCII = ViewLineRenderingData.isBasicASCII(content, mightContainNonBasicASCII); this.containsRTL = ViewLineRenderingData.containsRTL(content, this.isBasicASCII, mightContainRTL); this.tokens = tokens; this.inlineDecorations = inlineDecorations; this.tabSize = tabSize; this.startVisibleColumn = startVisibleColumn; } static isBasicASCII(lineContent, mightContainNonBasicASCII) { if (mightContainNonBasicASCII) { return strings.isBasicASCII(lineContent); } return true; } static containsRTL(lineContent, isBasicASCII, mightContainRTL) { if (!isBasicASCII && mightContainRTL) { return strings.containsRTL(lineContent); } return false; } } export class InlineDecoration { constructor(range, inlineClassName, type) { this.range = range; this.inlineClassName = inlineClassName; this.type = type; } } export class SingleLineInlineDecoration { constructor(startOffset, endOffset, inlineClassName, inlineClassNameAffectsLetterSpacing) { this.startOffset = startOffset; this.endOffset = endOffset; this.inlineClassName = inlineClassName; this.inlineClassNameAffectsLetterSpacing = inlineClassNameAffectsLetterSpacing; } toInlineDecoration(lineNumber) { return new InlineDecoration(new Range(lineNumber, this.startOffset + 1, lineNumber, this.endOffset + 1), this.inlineClassName, this.inlineClassNameAffectsLetterSpacing ? 3 /* RegularAffectingLetterSpacing */ : 0 /* Regular */); } } export class ViewModelDecoration { constructor(range, options) { this._viewModelDecorationBrand = undefined; this.range = range; this.options = options; } } export class OverviewRulerDecorationsGroup { constructor(color, zIndex, /** * Decorations are encoded in a number array using the following scheme: * - 3*i = lane * - 3*i+1 = startLineNumber * - 3*i+2 = endLineNumber */ data) { this.color = color; this.zIndex = zIndex; this.data = data; } static cmp(a, b) { if (a.zIndex === b.zIndex) { if (a.color < b.color) { return -1; } if (a.color > b.color) { return 1; } return 0; } return a.zIndex - b.zIndex; } }