@wendongfly/myhi 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/lib/xterm/LICENSE +21 -0
- package/dist/lib/xterm/README.md +225 -0
- package/dist/lib/xterm/css/xterm.css +190 -0
- package/dist/lib/xterm/lib/xterm.js +2 -0
- package/dist/lib/xterm/lib/xterm.js.map +1 -0
- package/dist/lib/xterm/package.json +90 -0
- package/dist/lib/xterm/src/browser/AccessibilityManager.ts +301 -0
- package/dist/lib/xterm/src/browser/Clipboard.ts +99 -0
- package/dist/lib/xterm/src/browser/ColorContrastCache.ts +39 -0
- package/dist/lib/xterm/src/browser/ColorManager.ts +268 -0
- package/dist/lib/xterm/src/browser/Dom.ts +10 -0
- package/dist/lib/xterm/src/browser/Lifecycle.ts +30 -0
- package/dist/lib/xterm/src/browser/Linkifier.ts +356 -0
- package/dist/lib/xterm/src/browser/Linkifier2.ts +397 -0
- package/dist/lib/xterm/src/browser/LocalizableStrings.ts +10 -0
- package/dist/lib/xterm/src/browser/MouseZoneManager.ts +236 -0
- package/dist/lib/xterm/src/browser/RenderDebouncer.ts +82 -0
- package/dist/lib/xterm/src/browser/ScreenDprMonitor.ts +69 -0
- package/dist/lib/xterm/src/browser/Terminal.ts +1447 -0
- package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +86 -0
- package/dist/lib/xterm/src/browser/Types.d.ts +317 -0
- package/dist/lib/xterm/src/browser/Viewport.ts +276 -0
- package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +131 -0
- package/dist/lib/xterm/src/browser/decorations/ColorZoneStore.ts +117 -0
- package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +228 -0
- package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +237 -0
- package/dist/lib/xterm/src/browser/input/Mouse.ts +64 -0
- package/dist/lib/xterm/src/browser/input/MoveToCell.ts +249 -0
- package/dist/lib/xterm/src/browser/public/Terminal.ts +298 -0
- package/dist/lib/xterm/src/browser/renderer/BaseRenderLayer.ts +582 -0
- package/dist/lib/xterm/src/browser/renderer/CursorRenderLayer.ts +378 -0
- package/dist/lib/xterm/src/browser/renderer/CustomGlyphs.ts +632 -0
- package/dist/lib/xterm/src/browser/renderer/GridCache.ts +33 -0
- package/dist/lib/xterm/src/browser/renderer/LinkRenderLayer.ts +84 -0
- package/dist/lib/xterm/src/browser/renderer/Renderer.ts +219 -0
- package/dist/lib/xterm/src/browser/renderer/RendererUtils.ts +26 -0
- package/dist/lib/xterm/src/browser/renderer/SelectionRenderLayer.ts +131 -0
- package/dist/lib/xterm/src/browser/renderer/TextRenderLayer.ts +344 -0
- package/dist/lib/xterm/src/browser/renderer/Types.d.ts +109 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/BaseCharAtlas.ts +58 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasCache.ts +95 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasUtils.ts +54 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/Constants.ts +15 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/DynamicCharAtlas.ts +404 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/LRUMap.ts +136 -0
- package/dist/lib/xterm/src/browser/renderer/atlas/Types.d.ts +29 -0
- package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +403 -0
- package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +344 -0
- package/dist/lib/xterm/src/browser/selection/SelectionModel.ts +144 -0
- package/dist/lib/xterm/src/browser/selection/Types.d.ts +15 -0
- package/dist/lib/xterm/src/browser/services/CharSizeService.ts +87 -0
- package/dist/lib/xterm/src/browser/services/CharacterJoinerService.ts +339 -0
- package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +20 -0
- package/dist/lib/xterm/src/browser/services/MouseService.ts +36 -0
- package/dist/lib/xterm/src/browser/services/RenderService.ts +237 -0
- package/dist/lib/xterm/src/browser/services/SelectionService.ts +1027 -0
- package/dist/lib/xterm/src/browser/services/Services.ts +123 -0
- package/dist/lib/xterm/src/browser/services/SoundService.ts +63 -0
- package/dist/lib/xterm/src/common/CircularList.ts +239 -0
- package/dist/lib/xterm/src/common/Clone.ts +23 -0
- package/dist/lib/xterm/src/common/Color.ts +285 -0
- package/dist/lib/xterm/src/common/CoreTerminal.ts +300 -0
- package/dist/lib/xterm/src/common/EventEmitter.ts +69 -0
- package/dist/lib/xterm/src/common/InputHandler.ts +3230 -0
- package/dist/lib/xterm/src/common/Lifecycle.ts +68 -0
- package/dist/lib/xterm/src/common/Platform.ts +31 -0
- package/dist/lib/xterm/src/common/SortedList.ts +88 -0
- package/dist/lib/xterm/src/common/TypedArrayUtils.ts +50 -0
- package/dist/lib/xterm/src/common/Types.d.ts +489 -0
- package/dist/lib/xterm/src/common/WindowsMode.ts +27 -0
- package/dist/lib/xterm/src/common/buffer/AttributeData.ts +148 -0
- package/dist/lib/xterm/src/common/buffer/Buffer.ts +711 -0
- package/dist/lib/xterm/src/common/buffer/BufferLine.ts +441 -0
- package/dist/lib/xterm/src/common/buffer/BufferRange.ts +13 -0
- package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +220 -0
- package/dist/lib/xterm/src/common/buffer/BufferSet.ts +131 -0
- package/dist/lib/xterm/src/common/buffer/CellData.ts +94 -0
- package/dist/lib/xterm/src/common/buffer/Constants.ts +139 -0
- package/dist/lib/xterm/src/common/buffer/Marker.ts +37 -0
- package/dist/lib/xterm/src/common/buffer/Types.d.ts +64 -0
- package/dist/lib/xterm/src/common/data/Charsets.ts +256 -0
- package/dist/lib/xterm/src/common/data/EscapeSequences.ts +153 -0
- package/dist/lib/xterm/src/common/input/Keyboard.ts +398 -0
- package/dist/lib/xterm/src/common/input/TextDecoder.ts +346 -0
- package/dist/lib/xterm/src/common/input/UnicodeV6.ts +133 -0
- package/dist/lib/xterm/src/common/input/WriteBuffer.ts +229 -0
- package/dist/lib/xterm/src/common/input/XParseColor.ts +80 -0
- package/dist/lib/xterm/src/common/parser/Constants.ts +58 -0
- package/dist/lib/xterm/src/common/parser/DcsParser.ts +192 -0
- package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +796 -0
- package/dist/lib/xterm/src/common/parser/OscParser.ts +238 -0
- package/dist/lib/xterm/src/common/parser/Params.ts +229 -0
- package/dist/lib/xterm/src/common/parser/Types.d.ts +274 -0
- package/dist/lib/xterm/src/common/public/AddonManager.ts +56 -0
- package/dist/lib/xterm/src/common/public/BufferApiView.ts +35 -0
- package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +29 -0
- package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +33 -0
- package/dist/lib/xterm/src/common/public/ParserApi.ts +37 -0
- package/dist/lib/xterm/src/common/public/UnicodeApi.ts +27 -0
- package/dist/lib/xterm/src/common/services/BufferService.ts +185 -0
- package/dist/lib/xterm/src/common/services/CharsetService.ts +34 -0
- package/dist/lib/xterm/src/common/services/CoreMouseService.ts +309 -0
- package/dist/lib/xterm/src/common/services/CoreService.ts +92 -0
- package/dist/lib/xterm/src/common/services/DecorationService.ts +139 -0
- package/dist/lib/xterm/src/common/services/DirtyRowService.ts +53 -0
- package/dist/lib/xterm/src/common/services/InstantiationService.ts +83 -0
- package/dist/lib/xterm/src/common/services/LogService.ts +88 -0
- package/dist/lib/xterm/src/common/services/OptionsService.ts +178 -0
- package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +49 -0
- package/dist/lib/xterm/src/common/services/Services.ts +323 -0
- package/dist/lib/xterm/src/common/services/UnicodeService.ts +82 -0
- package/dist/lib/xterm/src/headless/Terminal.ts +170 -0
- package/dist/lib/xterm/src/headless/Types.d.ts +31 -0
- package/dist/lib/xterm/src/headless/public/Terminal.ts +216 -0
- package/dist/lib/xterm/typings/xterm.d.ts +1872 -0
- package/dist/lib/xterm-fit/LICENSE +19 -0
- package/dist/lib/xterm-fit/README.md +24 -0
- package/dist/lib/xterm-fit/lib/xterm-addon-fit.js +2 -0
- package/dist/lib/xterm-fit/lib/xterm-addon-fit.js.map +1 -0
- package/dist/lib/xterm-fit/out/FitAddon.js +58 -0
- package/dist/lib/xterm-fit/out/FitAddon.js.map +1 -0
- package/dist/lib/xterm-fit/out-test/FitAddon.api.js.map +1 -0
- package/dist/lib/xterm-fit/package.json +21 -0
- package/dist/lib/xterm-fit/src/FitAddon.ts +86 -0
- package/dist/lib/xterm-fit/typings/xterm-addon-fit.d.ts +55 -0
- package/dist/lib/xterm-links/LICENSE +19 -0
- package/dist/lib/xterm-links/README.md +21 -0
- package/dist/lib/xterm-links/lib/xterm-addon-web-links.js +2 -0
- package/dist/lib/xterm-links/lib/xterm-addon-web-links.js.map +1 -0
- package/dist/lib/xterm-links/package.json +26 -0
- package/dist/lib/xterm-links/src/WebLinkProvider.ts +145 -0
- package/dist/lib/xterm-links/src/WebLinksAddon.ts +77 -0
- package/dist/lib/xterm-links/typings/xterm-addon-web-links.d.ts +58 -0
- package/package.json +1 -1
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IRenderDimensions } from 'browser/renderer/Types';
|
|
7
|
+
import { CharData, ICellData } from 'common/Types';
|
|
8
|
+
import { GridCache } from 'browser/renderer/GridCache';
|
|
9
|
+
import { BaseRenderLayer } from 'browser/renderer/BaseRenderLayer';
|
|
10
|
+
import { AttributeData } from 'common/buffer/AttributeData';
|
|
11
|
+
import { NULL_CELL_CODE, Content } from 'common/buffer/Constants';
|
|
12
|
+
import { IColorSet } from 'browser/Types';
|
|
13
|
+
import { CellData } from 'common/buffer/CellData';
|
|
14
|
+
import { IOptionsService, IBufferService, IDecorationService } from 'common/services/Services';
|
|
15
|
+
import { ICharacterJoinerService } from 'browser/services/Services';
|
|
16
|
+
import { JoinedCellData } from 'browser/services/CharacterJoinerService';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This CharData looks like a null character, which will forc a clear and render
|
|
20
|
+
* when the character changes (a regular space ' ' character may not as it's
|
|
21
|
+
* drawn state is a cleared cell).
|
|
22
|
+
*/
|
|
23
|
+
// const OVERLAP_OWNED_CHAR_DATA: CharData = [null, '', 0, -1];
|
|
24
|
+
|
|
25
|
+
export class TextRenderLayer extends BaseRenderLayer {
|
|
26
|
+
private _state: GridCache<CharData>;
|
|
27
|
+
private _characterWidth: number = 0;
|
|
28
|
+
private _characterFont: string = '';
|
|
29
|
+
private _characterOverlapCache: { [key: string]: boolean } = {};
|
|
30
|
+
private _workCell = new CellData();
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
container: HTMLElement,
|
|
34
|
+
zIndex: number,
|
|
35
|
+
colors: IColorSet,
|
|
36
|
+
alpha: boolean,
|
|
37
|
+
rendererId: number,
|
|
38
|
+
@IBufferService bufferService: IBufferService,
|
|
39
|
+
@IOptionsService optionsService: IOptionsService,
|
|
40
|
+
@ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService,
|
|
41
|
+
@IDecorationService decorationService: IDecorationService
|
|
42
|
+
) {
|
|
43
|
+
super(container, 'text', zIndex, alpha, colors, rendererId, bufferService, optionsService, decorationService);
|
|
44
|
+
this._state = new GridCache<CharData>();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public resize(dim: IRenderDimensions): void {
|
|
48
|
+
super.resize(dim);
|
|
49
|
+
|
|
50
|
+
// Clear the character width cache if the font or width has changed
|
|
51
|
+
const terminalFont = this._getFont(false, false);
|
|
52
|
+
if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) {
|
|
53
|
+
this._characterWidth = dim.scaledCharWidth;
|
|
54
|
+
this._characterFont = terminalFont;
|
|
55
|
+
this._characterOverlapCache = {};
|
|
56
|
+
}
|
|
57
|
+
// Resizing the canvas discards the contents of the canvas so clear state
|
|
58
|
+
this._state.clear();
|
|
59
|
+
this._state.resize(this._bufferService.cols, this._bufferService.rows);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public reset(): void {
|
|
63
|
+
this._state.clear();
|
|
64
|
+
this._clearAll();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private _forEachCell(
|
|
68
|
+
firstRow: number,
|
|
69
|
+
lastRow: number,
|
|
70
|
+
callback: (
|
|
71
|
+
cell: ICellData,
|
|
72
|
+
x: number,
|
|
73
|
+
y: number
|
|
74
|
+
) => void
|
|
75
|
+
): void {
|
|
76
|
+
for (let y = firstRow; y <= lastRow; y++) {
|
|
77
|
+
const row = y + this._bufferService.buffer.ydisp;
|
|
78
|
+
const line = this._bufferService.buffer.lines.get(row);
|
|
79
|
+
const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
|
|
80
|
+
for (let x = 0; x < this._bufferService.cols; x++) {
|
|
81
|
+
line!.loadCell(x, this._workCell);
|
|
82
|
+
let cell = this._workCell;
|
|
83
|
+
|
|
84
|
+
// If true, indicates that the current character(s) to draw were joined.
|
|
85
|
+
let isJoined = false;
|
|
86
|
+
let lastCharX = x;
|
|
87
|
+
|
|
88
|
+
// The character to the left is a wide character, drawing is owned by
|
|
89
|
+
// the char at x-1
|
|
90
|
+
if (cell.getWidth() === 0) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Process any joined character ranges as needed. Because of how the
|
|
95
|
+
// ranges are produced, we know that they are valid for the characters
|
|
96
|
+
// and attributes of our input.
|
|
97
|
+
if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {
|
|
98
|
+
isJoined = true;
|
|
99
|
+
const range = joinedRanges.shift()!;
|
|
100
|
+
|
|
101
|
+
// We already know the exact start and end column of the joined range,
|
|
102
|
+
// so we get the string and width representing it directly
|
|
103
|
+
cell = new JoinedCellData(
|
|
104
|
+
this._workCell,
|
|
105
|
+
line!.translateToString(true, range[0], range[1]),
|
|
106
|
+
range[1] - range[0]
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Skip over the cells occupied by this range in the loop
|
|
110
|
+
lastCharX = range[1] - 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// If the character is an overlapping char and the character to the
|
|
114
|
+
// right is a space, take ownership of the cell to the right. We skip
|
|
115
|
+
// this check for joined characters because their rendering likely won't
|
|
116
|
+
// yield the same result as rendering the last character individually.
|
|
117
|
+
if (!isJoined && this._isOverlapping(cell)) {
|
|
118
|
+
// If the character is overlapping, we want to force a re-render on every
|
|
119
|
+
// frame. This is specifically to work around the case where two
|
|
120
|
+
// overlaping chars `a` and `b` are adjacent, the cursor is moved to b and a
|
|
121
|
+
// space is added. Without this, the first half of `b` would never
|
|
122
|
+
// get removed, and `a` would not re-render because it thinks it's
|
|
123
|
+
// already in the correct state.
|
|
124
|
+
// this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA;
|
|
125
|
+
if (lastCharX < line!.length - 1 && line!.getCodePoint(lastCharX + 1) === NULL_CELL_CODE) {
|
|
126
|
+
// patch width to 2
|
|
127
|
+
cell.content &= ~Content.WIDTH_MASK;
|
|
128
|
+
cell.content |= 2 << Content.WIDTH_SHIFT;
|
|
129
|
+
// this._clearChar(x + 1, y);
|
|
130
|
+
// The overlapping char's char data will force a clear and render when the
|
|
131
|
+
// overlapping char is no longer to the left of the character and also when
|
|
132
|
+
// the space changes to another character.
|
|
133
|
+
// this._state.cache[x + 1][y] = OVERLAP_OWNED_CHAR_DATA;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
callback(
|
|
138
|
+
cell,
|
|
139
|
+
x,
|
|
140
|
+
y
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
x = lastCharX;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Draws the background for a specified range of columns. Tries to batch adjacent cells of the
|
|
150
|
+
* same color together to reduce draw calls.
|
|
151
|
+
*/
|
|
152
|
+
private _drawBackground(firstRow: number, lastRow: number): void {
|
|
153
|
+
const ctx = this._ctx;
|
|
154
|
+
const cols = this._bufferService.cols;
|
|
155
|
+
let startX: number = 0;
|
|
156
|
+
let startY: number = 0;
|
|
157
|
+
let prevFillStyle: string | null = null;
|
|
158
|
+
|
|
159
|
+
ctx.save();
|
|
160
|
+
|
|
161
|
+
this._forEachCell(firstRow, lastRow, (cell, x, y) => {
|
|
162
|
+
// libvte and xterm both draw the background (but not foreground) of invisible characters,
|
|
163
|
+
// so we should too.
|
|
164
|
+
let nextFillStyle = null; // null represents default background color
|
|
165
|
+
|
|
166
|
+
if (cell.isInverse()) {
|
|
167
|
+
if (cell.isFgDefault()) {
|
|
168
|
+
nextFillStyle = this._colors.foreground.css;
|
|
169
|
+
} else if (cell.isFgRGB()) {
|
|
170
|
+
nextFillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
|
171
|
+
} else {
|
|
172
|
+
nextFillStyle = this._colors.ansi[cell.getFgColor()].css;
|
|
173
|
+
}
|
|
174
|
+
} else if (cell.isBgRGB()) {
|
|
175
|
+
nextFillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
|
176
|
+
} else if (cell.isBgPalette()) {
|
|
177
|
+
nextFillStyle = this._colors.ansi[cell.getBgColor()].css;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Get any decoration foreground/background overrides, this must be fetched before the early
|
|
181
|
+
// exist but applied after inverse
|
|
182
|
+
let isTop = false;
|
|
183
|
+
for (const d of this._decorationService.getDecorationsAtCell(x, this._bufferService.buffer.ydisp + y)) {
|
|
184
|
+
if (d.options.layer !== 'top' && isTop) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (d.backgroundColorRGB) {
|
|
188
|
+
nextFillStyle = d.backgroundColorRGB.css;
|
|
189
|
+
}
|
|
190
|
+
isTop = d.options.layer === 'top';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (prevFillStyle === null) {
|
|
194
|
+
// This is either the first iteration, or the default background was set. Either way, we
|
|
195
|
+
// don't need to draw anything.
|
|
196
|
+
startX = x;
|
|
197
|
+
startY = y;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (y !== startY) {
|
|
201
|
+
// our row changed, draw the previous row
|
|
202
|
+
ctx.fillStyle = prevFillStyle || '';
|
|
203
|
+
this._fillCells(startX, startY, cols - startX, 1);
|
|
204
|
+
startX = x;
|
|
205
|
+
startY = y;
|
|
206
|
+
} else if (prevFillStyle !== nextFillStyle) {
|
|
207
|
+
// our color changed, draw the previous characters in this row
|
|
208
|
+
ctx.fillStyle = prevFillStyle || '';
|
|
209
|
+
this._fillCells(startX, startY, x - startX, 1);
|
|
210
|
+
startX = x;
|
|
211
|
+
startY = y;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
prevFillStyle = nextFillStyle;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// flush the last color we encountered
|
|
218
|
+
if (prevFillStyle !== null) {
|
|
219
|
+
ctx.fillStyle = prevFillStyle;
|
|
220
|
+
this._fillCells(startX, startY, cols - startX, 1);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
ctx.restore();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private _drawForeground(firstRow: number, lastRow: number): void {
|
|
227
|
+
this._forEachCell(firstRow, lastRow, (cell, x, y) => {
|
|
228
|
+
if (cell.isInvisible()) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this._drawChars(cell, x, y);
|
|
232
|
+
if (cell.isUnderline() || cell.isStrikethrough()) {
|
|
233
|
+
this._ctx.save();
|
|
234
|
+
|
|
235
|
+
if (cell.isInverse()) {
|
|
236
|
+
if (cell.isBgDefault()) {
|
|
237
|
+
this._ctx.fillStyle = this._colors.background.css;
|
|
238
|
+
} else if (cell.isBgRGB()) {
|
|
239
|
+
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
|
240
|
+
} else {
|
|
241
|
+
let bg = cell.getBgColor();
|
|
242
|
+
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
|
|
243
|
+
bg += 8;
|
|
244
|
+
}
|
|
245
|
+
this._ctx.fillStyle = this._colors.ansi[bg].css;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
if (cell.isFgDefault()) {
|
|
249
|
+
this._ctx.fillStyle = this._colors.foreground.css;
|
|
250
|
+
} else if (cell.isFgRGB()) {
|
|
251
|
+
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
|
252
|
+
} else {
|
|
253
|
+
let fg = cell.getFgColor();
|
|
254
|
+
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
|
|
255
|
+
fg += 8;
|
|
256
|
+
}
|
|
257
|
+
this._ctx.fillStyle = this._colors.ansi[fg].css;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (cell.isStrikethrough()) {
|
|
262
|
+
this._fillMiddleLineAtCells(x, y, cell.getWidth());
|
|
263
|
+
}
|
|
264
|
+
if (cell.isUnderline()) {
|
|
265
|
+
this._fillBottomLineAtCells(x, y, cell.getWidth());
|
|
266
|
+
}
|
|
267
|
+
this._ctx.restore();
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public onGridChanged(firstRow: number, lastRow: number): void {
|
|
273
|
+
// Resize has not been called yet
|
|
274
|
+
if (this._state.cache.length === 0) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (this._charAtlas) {
|
|
279
|
+
this._charAtlas.beginFrame();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this._clearCells(0, firstRow, this._bufferService.cols, lastRow - firstRow + 1);
|
|
283
|
+
this._drawBackground(firstRow, lastRow);
|
|
284
|
+
this._drawForeground(firstRow, lastRow);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public onOptionsChanged(): void {
|
|
288
|
+
this._setTransparency(this._optionsService.rawOptions.allowTransparency);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Whether a character is overlapping to the next cell.
|
|
293
|
+
*/
|
|
294
|
+
private _isOverlapping(cell: ICellData): boolean {
|
|
295
|
+
// Only single cell characters can be overlapping, rendering issues can
|
|
296
|
+
// occur without this check
|
|
297
|
+
if (cell.getWidth() !== 1) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// We assume that any ascii character will not overlap
|
|
302
|
+
if (cell.getCode() < 256) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const chars = cell.getChars();
|
|
307
|
+
|
|
308
|
+
// Deliver from cache if available
|
|
309
|
+
if (this._characterOverlapCache.hasOwnProperty(chars)) {
|
|
310
|
+
return this._characterOverlapCache[chars];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Setup the font
|
|
314
|
+
this._ctx.save();
|
|
315
|
+
this._ctx.font = this._characterFont;
|
|
316
|
+
|
|
317
|
+
// Measure the width of the character, but Math.floor it
|
|
318
|
+
// because that is what the renderer does when it calculates
|
|
319
|
+
// the character dimensions we are comparing against
|
|
320
|
+
const overlaps = Math.floor(this._ctx.measureText(chars).width) > this._characterWidth;
|
|
321
|
+
|
|
322
|
+
// Restore the original context
|
|
323
|
+
this._ctx.restore();
|
|
324
|
+
|
|
325
|
+
// Cache and return
|
|
326
|
+
this._characterOverlapCache[chars] = overlaps;
|
|
327
|
+
return overlaps;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Clear the charcater at the cell specified.
|
|
332
|
+
* @param x The column of the char.
|
|
333
|
+
* @param y The row of the char.
|
|
334
|
+
*/
|
|
335
|
+
// private _clearChar(x: number, y: number): void {
|
|
336
|
+
// let colsToClear = 1;
|
|
337
|
+
// // Clear the adjacent character if it was wide
|
|
338
|
+
// const state = this._state.cache[x][y];
|
|
339
|
+
// if (state && state[CHAR_DATA_WIDTH_INDEX] === 2) {
|
|
340
|
+
// colsToClear = 2;
|
|
341
|
+
// }
|
|
342
|
+
// this.clearCells(x, y, colsToClear, 1);
|
|
343
|
+
// }
|
|
344
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IDisposable } from 'common/Types';
|
|
7
|
+
import { IColorSet } from 'browser/Types';
|
|
8
|
+
import { IEvent } from 'common/EventEmitter';
|
|
9
|
+
|
|
10
|
+
export interface IRenderDimensions {
|
|
11
|
+
scaledCharWidth: number;
|
|
12
|
+
scaledCharHeight: number;
|
|
13
|
+
scaledCellWidth: number;
|
|
14
|
+
scaledCellHeight: number;
|
|
15
|
+
scaledCharLeft: number;
|
|
16
|
+
scaledCharTop: number;
|
|
17
|
+
scaledCanvasWidth: number;
|
|
18
|
+
scaledCanvasHeight: number;
|
|
19
|
+
canvasWidth: number;
|
|
20
|
+
canvasHeight: number;
|
|
21
|
+
actualCellWidth: number;
|
|
22
|
+
actualCellHeight: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IRequestRedrawEvent {
|
|
26
|
+
start: number;
|
|
27
|
+
end: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Note that IRenderer implementations should emit the refresh event after
|
|
32
|
+
* rendering rows to the screen.
|
|
33
|
+
*/
|
|
34
|
+
export interface IRenderer extends IDisposable {
|
|
35
|
+
readonly dimensions: IRenderDimensions;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fires when the renderer is requesting to be redrawn on the next animation
|
|
39
|
+
* frame but is _not_ a result of content changing (eg. selection changes).
|
|
40
|
+
*/
|
|
41
|
+
readonly onRequestRedraw: IEvent<IRequestRedrawEvent>;
|
|
42
|
+
|
|
43
|
+
dispose(): void;
|
|
44
|
+
setColors(colors: IColorSet): void;
|
|
45
|
+
onDevicePixelRatioChange(): void;
|
|
46
|
+
onResize(cols: number, rows: number): void;
|
|
47
|
+
onCharSizeChanged(): void;
|
|
48
|
+
onBlur(): void;
|
|
49
|
+
onFocus(): void;
|
|
50
|
+
onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;
|
|
51
|
+
onCursorMove(): void;
|
|
52
|
+
onOptionsChanged(): void;
|
|
53
|
+
clear(): void;
|
|
54
|
+
renderRows(start: number, end: number): void;
|
|
55
|
+
clearTextureAtlas?(): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface IRenderLayer extends IDisposable {
|
|
59
|
+
/**
|
|
60
|
+
* Called when the terminal loses focus.
|
|
61
|
+
*/
|
|
62
|
+
onBlur(): void;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* * Called when the terminal gets focus.
|
|
66
|
+
*/
|
|
67
|
+
onFocus(): void;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Called when the cursor is moved.
|
|
71
|
+
*/
|
|
72
|
+
onCursorMove(): void;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Called when options change.
|
|
76
|
+
*/
|
|
77
|
+
onOptionsChanged(): void;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Called when the theme changes.
|
|
81
|
+
*/
|
|
82
|
+
setColors(colorSet: IColorSet): void;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Called when the data in the grid has changed (or needs to be rendered
|
|
86
|
+
* again).
|
|
87
|
+
*/
|
|
88
|
+
onGridChanged(startRow: number, endRow: number): void;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Calls when the selection changes.
|
|
92
|
+
*/
|
|
93
|
+
onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Resize the render layer.
|
|
97
|
+
*/
|
|
98
|
+
resize(dim: IRenderDimensions): void;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Clear the state of the render layer.
|
|
102
|
+
*/
|
|
103
|
+
reset(): void;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Clears the texture atlas.
|
|
107
|
+
*/
|
|
108
|
+
clearTextureAtlas(): void;
|
|
109
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IGlyphIdentifier } from 'browser/renderer/atlas/Types';
|
|
7
|
+
import { IDisposable } from 'common/Types';
|
|
8
|
+
|
|
9
|
+
export abstract class BaseCharAtlas implements IDisposable {
|
|
10
|
+
private _didWarmUp: boolean = false;
|
|
11
|
+
|
|
12
|
+
public dispose(): void { }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Perform any work needed to warm the cache before it can be used. May be called multiple times.
|
|
16
|
+
* Implement _doWarmUp instead if you only want to get called once.
|
|
17
|
+
*/
|
|
18
|
+
public warmUp(): void {
|
|
19
|
+
if (!this._didWarmUp) {
|
|
20
|
+
this._doWarmUp();
|
|
21
|
+
this._didWarmUp = true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Perform any work needed to warm the cache before it can be used. Used by the default
|
|
27
|
+
* implementation of warmUp(), and will only be called once.
|
|
28
|
+
*/
|
|
29
|
+
private _doWarmUp(): void { }
|
|
30
|
+
|
|
31
|
+
public clear(): void { }
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Called when we start drawing a new frame.
|
|
35
|
+
*
|
|
36
|
+
* TODO: We rely on this getting called by TextRenderLayer. This should really be called by
|
|
37
|
+
* Renderer instead, but we need to make Renderer the source-of-truth for the char atlas, instead
|
|
38
|
+
* of BaseRenderLayer.
|
|
39
|
+
*/
|
|
40
|
+
public beginFrame(): void { }
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* May be called before warmUp finishes, however it is okay for the implementation to
|
|
44
|
+
* do nothing and return false in that case.
|
|
45
|
+
*
|
|
46
|
+
* @param ctx Where to draw the character onto.
|
|
47
|
+
* @param glyph Information about what to draw
|
|
48
|
+
* @param x The position on the context to start drawing at
|
|
49
|
+
* @param y The position on the context to start drawing at
|
|
50
|
+
* @returns The success state. True if we drew the character.
|
|
51
|
+
*/
|
|
52
|
+
public abstract draw(
|
|
53
|
+
ctx: CanvasRenderingContext2D,
|
|
54
|
+
glyph: IGlyphIdentifier,
|
|
55
|
+
x: number,
|
|
56
|
+
y: number
|
|
57
|
+
): boolean;
|
|
58
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { generateConfig, configEquals } from 'browser/renderer/atlas/CharAtlasUtils';
|
|
7
|
+
import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas';
|
|
8
|
+
import { DynamicCharAtlas } from 'browser/renderer/atlas/DynamicCharAtlas';
|
|
9
|
+
import { ICharAtlasConfig } from 'browser/renderer/atlas/Types';
|
|
10
|
+
import { IColorSet } from 'browser/Types';
|
|
11
|
+
import { ITerminalOptions } from 'common/services/Services';
|
|
12
|
+
|
|
13
|
+
interface ICharAtlasCacheEntry {
|
|
14
|
+
atlas: BaseCharAtlas;
|
|
15
|
+
config: ICharAtlasConfig;
|
|
16
|
+
// N.B. This implementation potentially holds onto copies of the terminal forever, so
|
|
17
|
+
// this may cause memory leaks.
|
|
18
|
+
ownedBy: number[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const charAtlasCache: ICharAtlasCacheEntry[] = [];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Acquires a char atlas, either generating a new one or returning an existing
|
|
25
|
+
* one that is in use by another terminal.
|
|
26
|
+
*/
|
|
27
|
+
export function acquireCharAtlas(
|
|
28
|
+
options: ITerminalOptions,
|
|
29
|
+
rendererId: number,
|
|
30
|
+
colors: IColorSet,
|
|
31
|
+
scaledCharWidth: number,
|
|
32
|
+
scaledCharHeight: number
|
|
33
|
+
): BaseCharAtlas {
|
|
34
|
+
const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, options, colors);
|
|
35
|
+
|
|
36
|
+
// Check to see if the renderer already owns this config
|
|
37
|
+
for (let i = 0; i < charAtlasCache.length; i++) {
|
|
38
|
+
const entry = charAtlasCache[i];
|
|
39
|
+
const ownedByIndex = entry.ownedBy.indexOf(rendererId);
|
|
40
|
+
if (ownedByIndex >= 0) {
|
|
41
|
+
if (configEquals(entry.config, newConfig)) {
|
|
42
|
+
return entry.atlas;
|
|
43
|
+
}
|
|
44
|
+
// The configs differ, release the renderer from the entry
|
|
45
|
+
if (entry.ownedBy.length === 1) {
|
|
46
|
+
entry.atlas.dispose();
|
|
47
|
+
charAtlasCache.splice(i, 1);
|
|
48
|
+
} else {
|
|
49
|
+
entry.ownedBy.splice(ownedByIndex, 1);
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Try match a char atlas from the cache
|
|
56
|
+
for (let i = 0; i < charAtlasCache.length; i++) {
|
|
57
|
+
const entry = charAtlasCache[i];
|
|
58
|
+
if (configEquals(entry.config, newConfig)) {
|
|
59
|
+
// Add the renderer to the cache entry and return
|
|
60
|
+
entry.ownedBy.push(rendererId);
|
|
61
|
+
return entry.atlas;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const newEntry: ICharAtlasCacheEntry = {
|
|
66
|
+
atlas: new DynamicCharAtlas(
|
|
67
|
+
document,
|
|
68
|
+
newConfig
|
|
69
|
+
),
|
|
70
|
+
config: newConfig,
|
|
71
|
+
ownedBy: [rendererId]
|
|
72
|
+
};
|
|
73
|
+
charAtlasCache.push(newEntry);
|
|
74
|
+
return newEntry.atlas;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Removes a terminal reference from the cache, allowing its memory to be freed.
|
|
79
|
+
*/
|
|
80
|
+
export function removeTerminalFromCache(rendererId: number): void {
|
|
81
|
+
for (let i = 0; i < charAtlasCache.length; i++) {
|
|
82
|
+
const index = charAtlasCache[i].ownedBy.indexOf(rendererId);
|
|
83
|
+
if (index !== -1) {
|
|
84
|
+
if (charAtlasCache[i].ownedBy.length === 1) {
|
|
85
|
+
// Remove the cache entry if it's the only renderer
|
|
86
|
+
charAtlasCache[i].atlas.dispose();
|
|
87
|
+
charAtlasCache.splice(i, 1);
|
|
88
|
+
} else {
|
|
89
|
+
// Remove the reference from the cache entry
|
|
90
|
+
charAtlasCache[i].ownedBy.splice(index, 1);
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ICharAtlasConfig } from 'browser/renderer/atlas/Types';
|
|
7
|
+
import { DEFAULT_COLOR } from 'common/buffer/Constants';
|
|
8
|
+
import { IColorSet, IPartialColorSet } from 'browser/Types';
|
|
9
|
+
import { ITerminalOptions } from 'common/services/Services';
|
|
10
|
+
|
|
11
|
+
export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, options: ITerminalOptions, colors: IColorSet): ICharAtlasConfig {
|
|
12
|
+
// null out some fields that don't matter
|
|
13
|
+
const clonedColors: IPartialColorSet = {
|
|
14
|
+
foreground: colors.foreground,
|
|
15
|
+
background: colors.background,
|
|
16
|
+
cursor: undefined,
|
|
17
|
+
cursorAccent: undefined,
|
|
18
|
+
selection: undefined,
|
|
19
|
+
ansi: colors.ansi.slice()
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
devicePixelRatio: window.devicePixelRatio,
|
|
23
|
+
scaledCharWidth,
|
|
24
|
+
scaledCharHeight,
|
|
25
|
+
fontFamily: options.fontFamily,
|
|
26
|
+
fontSize: options.fontSize,
|
|
27
|
+
fontWeight: options.fontWeight,
|
|
28
|
+
fontWeightBold: options.fontWeightBold,
|
|
29
|
+
allowTransparency: options.allowTransparency,
|
|
30
|
+
colors: clonedColors
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean {
|
|
35
|
+
for (let i = 0; i < a.colors.ansi.length; i++) {
|
|
36
|
+
if (a.colors.ansi[i].rgba !== b.colors.ansi[i].rgba) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return a.devicePixelRatio === b.devicePixelRatio &&
|
|
41
|
+
a.fontFamily === b.fontFamily &&
|
|
42
|
+
a.fontSize === b.fontSize &&
|
|
43
|
+
a.fontWeight === b.fontWeight &&
|
|
44
|
+
a.fontWeightBold === b.fontWeightBold &&
|
|
45
|
+
a.allowTransparency === b.allowTransparency &&
|
|
46
|
+
a.scaledCharWidth === b.scaledCharWidth &&
|
|
47
|
+
a.scaledCharHeight === b.scaledCharHeight &&
|
|
48
|
+
a.colors.foreground === b.colors.foreground &&
|
|
49
|
+
a.colors.background === b.colors.background;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function is256Color(colorCode: number): boolean {
|
|
53
|
+
return colorCode < DEFAULT_COLOR;
|
|
54
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { isFirefox, isLegacyEdge } from 'common/Platform';
|
|
7
|
+
|
|
8
|
+
export const INVERTED_DEFAULT_COLOR = 257;
|
|
9
|
+
export const DIM_OPACITY = 0.5;
|
|
10
|
+
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox or Legacy Edge would
|
|
11
|
+
// result in truncated text (Issue 3353). Using 'bottom' for Chrome would result in slightly
|
|
12
|
+
// unaligned Powerline fonts (PR 3356#issuecomment-850928179).
|
|
13
|
+
export const TEXT_BASELINE: CanvasTextBaseline = isFirefox || isLegacyEdge ? 'bottom' : 'ideographic';
|
|
14
|
+
|
|
15
|
+
export const CHAR_ATLAS_CELL_SPACING = 1;
|