@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.
Files changed (135) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/lib/xterm/LICENSE +21 -0
  3. package/dist/lib/xterm/README.md +225 -0
  4. package/dist/lib/xterm/css/xterm.css +190 -0
  5. package/dist/lib/xterm/lib/xterm.js +2 -0
  6. package/dist/lib/xterm/lib/xterm.js.map +1 -0
  7. package/dist/lib/xterm/package.json +90 -0
  8. package/dist/lib/xterm/src/browser/AccessibilityManager.ts +301 -0
  9. package/dist/lib/xterm/src/browser/Clipboard.ts +99 -0
  10. package/dist/lib/xterm/src/browser/ColorContrastCache.ts +39 -0
  11. package/dist/lib/xterm/src/browser/ColorManager.ts +268 -0
  12. package/dist/lib/xterm/src/browser/Dom.ts +10 -0
  13. package/dist/lib/xterm/src/browser/Lifecycle.ts +30 -0
  14. package/dist/lib/xterm/src/browser/Linkifier.ts +356 -0
  15. package/dist/lib/xterm/src/browser/Linkifier2.ts +397 -0
  16. package/dist/lib/xterm/src/browser/LocalizableStrings.ts +10 -0
  17. package/dist/lib/xterm/src/browser/MouseZoneManager.ts +236 -0
  18. package/dist/lib/xterm/src/browser/RenderDebouncer.ts +82 -0
  19. package/dist/lib/xterm/src/browser/ScreenDprMonitor.ts +69 -0
  20. package/dist/lib/xterm/src/browser/Terminal.ts +1447 -0
  21. package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +86 -0
  22. package/dist/lib/xterm/src/browser/Types.d.ts +317 -0
  23. package/dist/lib/xterm/src/browser/Viewport.ts +276 -0
  24. package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +131 -0
  25. package/dist/lib/xterm/src/browser/decorations/ColorZoneStore.ts +117 -0
  26. package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +228 -0
  27. package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +237 -0
  28. package/dist/lib/xterm/src/browser/input/Mouse.ts +64 -0
  29. package/dist/lib/xterm/src/browser/input/MoveToCell.ts +249 -0
  30. package/dist/lib/xterm/src/browser/public/Terminal.ts +298 -0
  31. package/dist/lib/xterm/src/browser/renderer/BaseRenderLayer.ts +582 -0
  32. package/dist/lib/xterm/src/browser/renderer/CursorRenderLayer.ts +378 -0
  33. package/dist/lib/xterm/src/browser/renderer/CustomGlyphs.ts +632 -0
  34. package/dist/lib/xterm/src/browser/renderer/GridCache.ts +33 -0
  35. package/dist/lib/xterm/src/browser/renderer/LinkRenderLayer.ts +84 -0
  36. package/dist/lib/xterm/src/browser/renderer/Renderer.ts +219 -0
  37. package/dist/lib/xterm/src/browser/renderer/RendererUtils.ts +26 -0
  38. package/dist/lib/xterm/src/browser/renderer/SelectionRenderLayer.ts +131 -0
  39. package/dist/lib/xterm/src/browser/renderer/TextRenderLayer.ts +344 -0
  40. package/dist/lib/xterm/src/browser/renderer/Types.d.ts +109 -0
  41. package/dist/lib/xterm/src/browser/renderer/atlas/BaseCharAtlas.ts +58 -0
  42. package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasCache.ts +95 -0
  43. package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasUtils.ts +54 -0
  44. package/dist/lib/xterm/src/browser/renderer/atlas/Constants.ts +15 -0
  45. package/dist/lib/xterm/src/browser/renderer/atlas/DynamicCharAtlas.ts +404 -0
  46. package/dist/lib/xterm/src/browser/renderer/atlas/LRUMap.ts +136 -0
  47. package/dist/lib/xterm/src/browser/renderer/atlas/Types.d.ts +29 -0
  48. package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +403 -0
  49. package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +344 -0
  50. package/dist/lib/xterm/src/browser/selection/SelectionModel.ts +144 -0
  51. package/dist/lib/xterm/src/browser/selection/Types.d.ts +15 -0
  52. package/dist/lib/xterm/src/browser/services/CharSizeService.ts +87 -0
  53. package/dist/lib/xterm/src/browser/services/CharacterJoinerService.ts +339 -0
  54. package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +20 -0
  55. package/dist/lib/xterm/src/browser/services/MouseService.ts +36 -0
  56. package/dist/lib/xterm/src/browser/services/RenderService.ts +237 -0
  57. package/dist/lib/xterm/src/browser/services/SelectionService.ts +1027 -0
  58. package/dist/lib/xterm/src/browser/services/Services.ts +123 -0
  59. package/dist/lib/xterm/src/browser/services/SoundService.ts +63 -0
  60. package/dist/lib/xterm/src/common/CircularList.ts +239 -0
  61. package/dist/lib/xterm/src/common/Clone.ts +23 -0
  62. package/dist/lib/xterm/src/common/Color.ts +285 -0
  63. package/dist/lib/xterm/src/common/CoreTerminal.ts +300 -0
  64. package/dist/lib/xterm/src/common/EventEmitter.ts +69 -0
  65. package/dist/lib/xterm/src/common/InputHandler.ts +3230 -0
  66. package/dist/lib/xterm/src/common/Lifecycle.ts +68 -0
  67. package/dist/lib/xterm/src/common/Platform.ts +31 -0
  68. package/dist/lib/xterm/src/common/SortedList.ts +88 -0
  69. package/dist/lib/xterm/src/common/TypedArrayUtils.ts +50 -0
  70. package/dist/lib/xterm/src/common/Types.d.ts +489 -0
  71. package/dist/lib/xterm/src/common/WindowsMode.ts +27 -0
  72. package/dist/lib/xterm/src/common/buffer/AttributeData.ts +148 -0
  73. package/dist/lib/xterm/src/common/buffer/Buffer.ts +711 -0
  74. package/dist/lib/xterm/src/common/buffer/BufferLine.ts +441 -0
  75. package/dist/lib/xterm/src/common/buffer/BufferRange.ts +13 -0
  76. package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +220 -0
  77. package/dist/lib/xterm/src/common/buffer/BufferSet.ts +131 -0
  78. package/dist/lib/xterm/src/common/buffer/CellData.ts +94 -0
  79. package/dist/lib/xterm/src/common/buffer/Constants.ts +139 -0
  80. package/dist/lib/xterm/src/common/buffer/Marker.ts +37 -0
  81. package/dist/lib/xterm/src/common/buffer/Types.d.ts +64 -0
  82. package/dist/lib/xterm/src/common/data/Charsets.ts +256 -0
  83. package/dist/lib/xterm/src/common/data/EscapeSequences.ts +153 -0
  84. package/dist/lib/xterm/src/common/input/Keyboard.ts +398 -0
  85. package/dist/lib/xterm/src/common/input/TextDecoder.ts +346 -0
  86. package/dist/lib/xterm/src/common/input/UnicodeV6.ts +133 -0
  87. package/dist/lib/xterm/src/common/input/WriteBuffer.ts +229 -0
  88. package/dist/lib/xterm/src/common/input/XParseColor.ts +80 -0
  89. package/dist/lib/xterm/src/common/parser/Constants.ts +58 -0
  90. package/dist/lib/xterm/src/common/parser/DcsParser.ts +192 -0
  91. package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +796 -0
  92. package/dist/lib/xterm/src/common/parser/OscParser.ts +238 -0
  93. package/dist/lib/xterm/src/common/parser/Params.ts +229 -0
  94. package/dist/lib/xterm/src/common/parser/Types.d.ts +274 -0
  95. package/dist/lib/xterm/src/common/public/AddonManager.ts +56 -0
  96. package/dist/lib/xterm/src/common/public/BufferApiView.ts +35 -0
  97. package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +29 -0
  98. package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +33 -0
  99. package/dist/lib/xterm/src/common/public/ParserApi.ts +37 -0
  100. package/dist/lib/xterm/src/common/public/UnicodeApi.ts +27 -0
  101. package/dist/lib/xterm/src/common/services/BufferService.ts +185 -0
  102. package/dist/lib/xterm/src/common/services/CharsetService.ts +34 -0
  103. package/dist/lib/xterm/src/common/services/CoreMouseService.ts +309 -0
  104. package/dist/lib/xterm/src/common/services/CoreService.ts +92 -0
  105. package/dist/lib/xterm/src/common/services/DecorationService.ts +139 -0
  106. package/dist/lib/xterm/src/common/services/DirtyRowService.ts +53 -0
  107. package/dist/lib/xterm/src/common/services/InstantiationService.ts +83 -0
  108. package/dist/lib/xterm/src/common/services/LogService.ts +88 -0
  109. package/dist/lib/xterm/src/common/services/OptionsService.ts +178 -0
  110. package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +49 -0
  111. package/dist/lib/xterm/src/common/services/Services.ts +323 -0
  112. package/dist/lib/xterm/src/common/services/UnicodeService.ts +82 -0
  113. package/dist/lib/xterm/src/headless/Terminal.ts +170 -0
  114. package/dist/lib/xterm/src/headless/Types.d.ts +31 -0
  115. package/dist/lib/xterm/src/headless/public/Terminal.ts +216 -0
  116. package/dist/lib/xterm/typings/xterm.d.ts +1872 -0
  117. package/dist/lib/xterm-fit/LICENSE +19 -0
  118. package/dist/lib/xterm-fit/README.md +24 -0
  119. package/dist/lib/xterm-fit/lib/xterm-addon-fit.js +2 -0
  120. package/dist/lib/xterm-fit/lib/xterm-addon-fit.js.map +1 -0
  121. package/dist/lib/xterm-fit/out/FitAddon.js +58 -0
  122. package/dist/lib/xterm-fit/out/FitAddon.js.map +1 -0
  123. package/dist/lib/xterm-fit/out-test/FitAddon.api.js.map +1 -0
  124. package/dist/lib/xterm-fit/package.json +21 -0
  125. package/dist/lib/xterm-fit/src/FitAddon.ts +86 -0
  126. package/dist/lib/xterm-fit/typings/xterm-addon-fit.d.ts +55 -0
  127. package/dist/lib/xterm-links/LICENSE +19 -0
  128. package/dist/lib/xterm-links/README.md +21 -0
  129. package/dist/lib/xterm-links/lib/xterm-addon-web-links.js +2 -0
  130. package/dist/lib/xterm-links/lib/xterm-addon-web-links.js.map +1 -0
  131. package/dist/lib/xterm-links/package.json +26 -0
  132. package/dist/lib/xterm-links/src/WebLinkProvider.ts +145 -0
  133. package/dist/lib/xterm-links/src/WebLinksAddon.ts +77 -0
  134. package/dist/lib/xterm-links/typings/xterm-addon-web-links.d.ts +58 -0
  135. package/package.json +1 -1
@@ -0,0 +1,582 @@
1
+ /**
2
+ * Copyright (c) 2017 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { IRenderDimensions, IRenderLayer } from 'browser/renderer/Types';
7
+ import { ICellData, IColor } from 'common/Types';
8
+ import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, Attributes } from 'common/buffer/Constants';
9
+ import { IGlyphIdentifier } from 'browser/renderer/atlas/Types';
10
+ import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, TEXT_BASELINE } from 'browser/renderer/atlas/Constants';
11
+ import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas';
12
+ import { acquireCharAtlas } from 'browser/renderer/atlas/CharAtlasCache';
13
+ import { AttributeData } from 'common/buffer/AttributeData';
14
+ import { IColorSet } from 'browser/Types';
15
+ import { CellData } from 'common/buffer/CellData';
16
+ import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
17
+ import { excludeFromContrastRatioDemands, throwIfFalsy } from 'browser/renderer/RendererUtils';
18
+ import { channels, color, rgba } from 'common/Color';
19
+ import { removeElementFromParent } from 'browser/Dom';
20
+ import { tryDrawCustomChar } from 'browser/renderer/CustomGlyphs';
21
+
22
+ export abstract class BaseRenderLayer implements IRenderLayer {
23
+ private _canvas: HTMLCanvasElement;
24
+ protected _ctx!: CanvasRenderingContext2D;
25
+ private _scaledCharWidth: number = 0;
26
+ private _scaledCharHeight: number = 0;
27
+ private _scaledCellWidth: number = 0;
28
+ private _scaledCellHeight: number = 0;
29
+ private _scaledCharLeft: number = 0;
30
+ private _scaledCharTop: number = 0;
31
+
32
+ private _selectionStart: [number, number] | undefined;
33
+ private _selectionEnd: [number, number] | undefined;
34
+ private _columnSelectMode: boolean = false;
35
+
36
+ protected _charAtlas: BaseCharAtlas | undefined;
37
+
38
+ /**
39
+ * An object that's reused when drawing glyphs in order to reduce GC.
40
+ */
41
+ private _currentGlyphIdentifier: IGlyphIdentifier = {
42
+ chars: '',
43
+ code: 0,
44
+ bg: 0,
45
+ fg: 0,
46
+ bold: false,
47
+ dim: false,
48
+ italic: false
49
+ };
50
+
51
+ constructor(
52
+ private _container: HTMLElement,
53
+ id: string,
54
+ zIndex: number,
55
+ private _alpha: boolean,
56
+ protected _colors: IColorSet,
57
+ private _rendererId: number,
58
+ protected readonly _bufferService: IBufferService,
59
+ protected readonly _optionsService: IOptionsService,
60
+ protected readonly _decorationService: IDecorationService
61
+ ) {
62
+ this._canvas = document.createElement('canvas');
63
+ this._canvas.classList.add(`xterm-${id}-layer`);
64
+ this._canvas.style.zIndex = zIndex.toString();
65
+ this._initCanvas();
66
+ this._container.appendChild(this._canvas);
67
+ }
68
+
69
+ public dispose(): void {
70
+ removeElementFromParent(this._canvas);
71
+ this._charAtlas?.dispose();
72
+ }
73
+
74
+ private _initCanvas(): void {
75
+ this._ctx = throwIfFalsy(this._canvas.getContext('2d', { alpha: this._alpha }));
76
+ // Draw the background if this is an opaque layer
77
+ if (!this._alpha) {
78
+ this._clearAll();
79
+ }
80
+ }
81
+
82
+ public onOptionsChanged(): void {}
83
+ public onBlur(): void {}
84
+ public onFocus(): void {}
85
+ public onCursorMove(): void {}
86
+ public onGridChanged(startRow: number, endRow: number): void {}
87
+
88
+ public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {
89
+ this._selectionStart = start;
90
+ this._selectionEnd = end;
91
+ this._columnSelectMode = columnSelectMode;
92
+ }
93
+
94
+ public setColors(colorSet: IColorSet): void {
95
+ this._refreshCharAtlas(colorSet);
96
+ }
97
+
98
+ protected _setTransparency(alpha: boolean): void {
99
+ // Do nothing when alpha doesn't change
100
+ if (alpha === this._alpha) {
101
+ return;
102
+ }
103
+
104
+ // Create new canvas and replace old one
105
+ const oldCanvas = this._canvas;
106
+ this._alpha = alpha;
107
+ // Cloning preserves properties
108
+ this._canvas = this._canvas.cloneNode() as HTMLCanvasElement;
109
+ this._initCanvas();
110
+ this._container.replaceChild(this._canvas, oldCanvas);
111
+
112
+ // Regenerate char atlas and force a full redraw
113
+ this._refreshCharAtlas(this._colors);
114
+ this.onGridChanged(0, this._bufferService.rows - 1);
115
+ }
116
+
117
+ /**
118
+ * Refreshes the char atlas, aquiring a new one if necessary.
119
+ * @param colorSet The color set to use for the char atlas.
120
+ */
121
+ private _refreshCharAtlas(colorSet: IColorSet): void {
122
+ if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {
123
+ return;
124
+ }
125
+ this._charAtlas = acquireCharAtlas(this._optionsService.rawOptions, this._rendererId, colorSet, this._scaledCharWidth, this._scaledCharHeight);
126
+ this._charAtlas.warmUp();
127
+ }
128
+
129
+ public resize(dim: IRenderDimensions): void {
130
+ this._scaledCellWidth = dim.scaledCellWidth;
131
+ this._scaledCellHeight = dim.scaledCellHeight;
132
+ this._scaledCharWidth = dim.scaledCharWidth;
133
+ this._scaledCharHeight = dim.scaledCharHeight;
134
+ this._scaledCharLeft = dim.scaledCharLeft;
135
+ this._scaledCharTop = dim.scaledCharTop;
136
+ this._canvas.width = dim.scaledCanvasWidth;
137
+ this._canvas.height = dim.scaledCanvasHeight;
138
+ this._canvas.style.width = `${dim.canvasWidth}px`;
139
+ this._canvas.style.height = `${dim.canvasHeight}px`;
140
+
141
+ // Draw the background if this is an opaque layer
142
+ if (!this._alpha) {
143
+ this._clearAll();
144
+ }
145
+
146
+ this._refreshCharAtlas(this._colors);
147
+ }
148
+
149
+ public abstract reset(): void;
150
+
151
+ public clearTextureAtlas(): void {
152
+ this._charAtlas?.clear();
153
+ }
154
+
155
+ /**
156
+ * Fills 1+ cells completely. This uses the existing fillStyle on the context.
157
+ * @param x The column to start at.
158
+ * @param y The row to start at
159
+ * @param width The number of columns to fill.
160
+ * @param height The number of rows to fill.
161
+ */
162
+ protected _fillCells(x: number, y: number, width: number, height: number): void {
163
+ this._ctx.fillRect(
164
+ x * this._scaledCellWidth,
165
+ y * this._scaledCellHeight,
166
+ width * this._scaledCellWidth,
167
+ height * this._scaledCellHeight);
168
+ }
169
+
170
+ /**
171
+ * Fills a 1px line (2px on HDPI) at the middle of the cell. This uses the
172
+ * existing fillStyle on the context.
173
+ * @param x The column to fill.
174
+ * @param y The row to fill.
175
+ */
176
+ protected _fillMiddleLineAtCells(x: number, y: number, width: number = 1): void {
177
+ const cellOffset = Math.ceil(this._scaledCellHeight * 0.5);
178
+ this._ctx.fillRect(
179
+ x * this._scaledCellWidth,
180
+ (y + 1) * this._scaledCellHeight - cellOffset - window.devicePixelRatio,
181
+ width * this._scaledCellWidth,
182
+ window.devicePixelRatio);
183
+ }
184
+
185
+ /**
186
+ * Fills a 1px line (2px on HDPI) at the bottom of the cell. This uses the
187
+ * existing fillStyle on the context.
188
+ * @param x The column to fill.
189
+ * @param y The row to fill.
190
+ */
191
+ protected _fillBottomLineAtCells(x: number, y: number, width: number = 1): void {
192
+ this._ctx.fillRect(
193
+ x * this._scaledCellWidth,
194
+ (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */,
195
+ width * this._scaledCellWidth,
196
+ window.devicePixelRatio);
197
+ }
198
+
199
+ /**
200
+ * Fills a 1px line (2px on HDPI) at the left of the cell. This uses the
201
+ * existing fillStyle on the context.
202
+ * @param x The column to fill.
203
+ * @param y The row to fill.
204
+ */
205
+ protected _fillLeftLineAtCell(x: number, y: number, width: number): void {
206
+ this._ctx.fillRect(
207
+ x * this._scaledCellWidth,
208
+ y * this._scaledCellHeight,
209
+ window.devicePixelRatio * width,
210
+ this._scaledCellHeight);
211
+ }
212
+
213
+ /**
214
+ * Strokes a 1px rectangle (2px on HDPI) around a cell. This uses the existing
215
+ * strokeStyle on the context.
216
+ * @param x The column to fill.
217
+ * @param y The row to fill.
218
+ */
219
+ protected _strokeRectAtCell(x: number, y: number, width: number, height: number): void {
220
+ this._ctx.lineWidth = window.devicePixelRatio;
221
+ this._ctx.strokeRect(
222
+ x * this._scaledCellWidth + window.devicePixelRatio / 2,
223
+ y * this._scaledCellHeight + (window.devicePixelRatio / 2),
224
+ width * this._scaledCellWidth - window.devicePixelRatio,
225
+ (height * this._scaledCellHeight) - window.devicePixelRatio);
226
+ }
227
+
228
+ /**
229
+ * Clears the entire canvas.
230
+ */
231
+ protected _clearAll(): void {
232
+ if (this._alpha) {
233
+ this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
234
+ } else {
235
+ this._ctx.fillStyle = this._colors.background.css;
236
+ this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Clears 1+ cells completely.
242
+ * @param x The column to start at.
243
+ * @param y The row to start at.
244
+ * @param width The number of columns to clear.
245
+ * @param height The number of rows to clear.
246
+ */
247
+ protected _clearCells(x: number, y: number, width: number, height: number): void {
248
+ if (this._alpha) {
249
+ this._ctx.clearRect(
250
+ x * this._scaledCellWidth,
251
+ y * this._scaledCellHeight,
252
+ width * this._scaledCellWidth,
253
+ height * this._scaledCellHeight);
254
+ } else {
255
+ this._ctx.fillStyle = this._colors.background.css;
256
+ this._ctx.fillRect(
257
+ x * this._scaledCellWidth,
258
+ y * this._scaledCellHeight,
259
+ width * this._scaledCellWidth,
260
+ height * this._scaledCellHeight);
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Draws a truecolor character at the cell. The character will be clipped to
266
+ * ensure that it fits with the cell, including the cell to the right if it's
267
+ * a wide character. This uses the existing fillStyle on the context.
268
+ * @param cell The cell data for the character to draw.
269
+ * @param x The column to draw at.
270
+ * @param y The row to draw at.
271
+ * @param color The color of the character.
272
+ */
273
+ protected _fillCharTrueColor(cell: CellData, x: number, y: number): void {
274
+ this._ctx.font = this._getFont(false, false);
275
+ this._ctx.textBaseline = TEXT_BASELINE;
276
+ this._clipRow(y);
277
+
278
+ // Draw custom characters if applicable
279
+ let drawSuccess = false;
280
+ if (this._optionsService.rawOptions.customGlyphs !== false) {
281
+ drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
282
+ }
283
+
284
+ // Draw the character
285
+ if (!drawSuccess) {
286
+ this._ctx.fillText(
287
+ cell.getChars(),
288
+ x * this._scaledCellWidth + this._scaledCharLeft,
289
+ y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight);
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Draws one or more characters at a cell. If possible this will draw using
295
+ * the character atlas to reduce draw time.
296
+ * @param chars The character or characters.
297
+ * @param code The character code.
298
+ * @param width The width of the characters.
299
+ * @param x The column to draw at.
300
+ * @param y The row to draw at.
301
+ * @param fg The foreground color, in the format stored within the attributes.
302
+ * @param bg The background color, in the format stored within the attributes.
303
+ * This is used to validate whether a cached image can be used.
304
+ * @param bold Whether the text is bold.
305
+ */
306
+ protected _drawChars(cell: ICellData, x: number, y: number): void {
307
+ const contrastColor = this._getContrastColor(cell, x, y);
308
+
309
+ // skip cache right away if we draw in RGB
310
+ // Note: to avoid bad runtime JoinedCellData will be skipped
311
+ // in the cache handler itself (atlasDidDraw == false) and
312
+ // fall through to uncached later down below
313
+ if (contrastColor || cell.isFgRGB() || cell.isBgRGB()) {
314
+ this._drawUncachedChars(cell, x, y, contrastColor);
315
+ return;
316
+ }
317
+
318
+ let fg;
319
+ let bg;
320
+ if (cell.isInverse()) {
321
+ fg = (cell.isBgDefault()) ? INVERTED_DEFAULT_COLOR : cell.getBgColor();
322
+ bg = (cell.isFgDefault()) ? INVERTED_DEFAULT_COLOR : cell.getFgColor();
323
+ } else {
324
+ bg = (cell.isBgDefault()) ? DEFAULT_COLOR : cell.getBgColor();
325
+ fg = (cell.isFgDefault()) ? DEFAULT_COLOR : cell.getFgColor();
326
+ }
327
+
328
+ const drawInBrightColor = this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8;
329
+
330
+ fg += drawInBrightColor ? 8 : 0;
331
+ this._currentGlyphIdentifier.chars = cell.getChars() || WHITESPACE_CELL_CHAR;
332
+ this._currentGlyphIdentifier.code = cell.getCode() || WHITESPACE_CELL_CODE;
333
+ this._currentGlyphIdentifier.bg = bg;
334
+ this._currentGlyphIdentifier.fg = fg;
335
+ this._currentGlyphIdentifier.bold = !!cell.isBold();
336
+ this._currentGlyphIdentifier.dim = !!cell.isDim();
337
+ this._currentGlyphIdentifier.italic = !!cell.isItalic();
338
+
339
+ // Don't try cache the glyph if it uses any decoration foreground/background override.
340
+ let hasOverrides = false;
341
+ for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
342
+ if (d.backgroundColorRGB || d.foregroundColorRGB) {
343
+ hasOverrides = true;
344
+ break;
345
+ }
346
+ }
347
+
348
+ const atlasDidDraw = hasOverrides ? false : this._charAtlas?.draw(this._ctx, this._currentGlyphIdentifier, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop);
349
+
350
+ if (!atlasDidDraw) {
351
+ this._drawUncachedChars(cell, x, y);
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Draws one or more characters at one or more cells. The character(s) will be
357
+ * clipped to ensure that they fit with the cell(s), including the cell to the
358
+ * right if the last character is a wide character.
359
+ * @param chars The character.
360
+ * @param width The width of the character.
361
+ * @param fg The foreground color, in the format stored within the attributes.
362
+ * @param x The column to draw at.
363
+ * @param y The row to draw at.
364
+ */
365
+ private _drawUncachedChars(cell: ICellData, x: number, y: number, fgOverride?: IColor): void {
366
+ this._ctx.save();
367
+ this._ctx.font = this._getFont(!!cell.isBold(), !!cell.isItalic());
368
+ this._ctx.textBaseline = TEXT_BASELINE;
369
+
370
+ if (cell.isInverse()) {
371
+ if (fgOverride) {
372
+ this._ctx.fillStyle = fgOverride.css;
373
+ } else if (cell.isBgDefault()) {
374
+ this._ctx.fillStyle = color.opaque(this._colors.background).css;
375
+ } else if (cell.isBgRGB()) {
376
+ this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
377
+ } else {
378
+ let bg = cell.getBgColor();
379
+ if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
380
+ bg += 8;
381
+ }
382
+ this._ctx.fillStyle = this._colors.ansi[bg].css;
383
+ }
384
+ } else {
385
+ if (fgOverride) {
386
+ this._ctx.fillStyle = fgOverride.css;
387
+ } else if (cell.isFgDefault()) {
388
+ this._ctx.fillStyle = this._colors.foreground.css;
389
+ } else if (cell.isFgRGB()) {
390
+ this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
391
+ } else {
392
+ let fg = cell.getFgColor();
393
+ if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
394
+ fg += 8;
395
+ }
396
+ this._ctx.fillStyle = this._colors.ansi[fg].css;
397
+ }
398
+ }
399
+
400
+ this._clipRow(y);
401
+
402
+ // Apply alpha to dim the character
403
+ if (cell.isDim()) {
404
+ this._ctx.globalAlpha = DIM_OPACITY;
405
+ }
406
+
407
+ // Draw custom characters if applicable
408
+ let drawSuccess = false;
409
+ if (this._optionsService.rawOptions.customGlyphs !== false) {
410
+ drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
411
+ }
412
+
413
+ // Draw the character
414
+ if (!drawSuccess) {
415
+ this._ctx.fillText(
416
+ cell.getChars(),
417
+ x * this._scaledCellWidth + this._scaledCharLeft,
418
+ y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight);
419
+ }
420
+
421
+ this._ctx.restore();
422
+ }
423
+
424
+
425
+ /**
426
+ * Clips a row to ensure no pixels will be drawn outside the cells in the row.
427
+ * @param y The row to clip.
428
+ */
429
+ private _clipRow(y: number): void {
430
+ this._ctx.beginPath();
431
+ this._ctx.rect(
432
+ 0,
433
+ y * this._scaledCellHeight,
434
+ this._bufferService.cols * this._scaledCellWidth,
435
+ this._scaledCellHeight);
436
+ this._ctx.clip();
437
+ }
438
+
439
+ /**
440
+ * Gets the current font.
441
+ * @param isBold If we should use the bold fontWeight.
442
+ */
443
+ protected _getFont(isBold: boolean, isItalic: boolean): string {
444
+ const fontWeight = isBold ? this._optionsService.rawOptions.fontWeightBold : this._optionsService.rawOptions.fontWeight;
445
+ const fontStyle = isItalic ? 'italic' : '';
446
+
447
+ return `${fontStyle} ${fontWeight} ${this._optionsService.rawOptions.fontSize * window.devicePixelRatio}px ${this._optionsService.rawOptions.fontFamily}`;
448
+ }
449
+
450
+ private _getContrastColor(cell: CellData, x: number, y: number): IColor | undefined {
451
+ // Get any decoration foreground/background overrides, this must be fetched before the early
452
+ // exist but applied after inverse
453
+ let bgOverride: number | undefined;
454
+ let fgOverride: number | undefined;
455
+ let isTop = false;
456
+ for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
457
+ if (d.options.layer !== 'top' && isTop) {
458
+ continue;
459
+ }
460
+ if (d.backgroundColorRGB) {
461
+ bgOverride = d.backgroundColorRGB.rgba;
462
+ }
463
+ if (d.foregroundColorRGB) {
464
+ fgOverride = d.foregroundColorRGB.rgba;
465
+ }
466
+ isTop = d.options.layer === 'top';
467
+ }
468
+
469
+ // Apply selection foreground if applicable
470
+ if (!isTop) {
471
+ if (this._colors.selectionForeground && this._isCellInSelection(x, y)) {
472
+ fgOverride = this._colors.selectionForeground.rgba;
473
+ }
474
+ }
475
+
476
+ if (!bgOverride && !fgOverride && (this._optionsService.rawOptions.minimumContrastRatio === 1 || excludeFromContrastRatioDemands(cell.getCode()))) {
477
+ return undefined;
478
+ }
479
+
480
+ if (!bgOverride && !fgOverride) {
481
+ // Try get from cache
482
+ const adjustedColor = this._colors.contrastCache.getColor(cell.bg, cell.fg);
483
+ if (adjustedColor !== undefined) {
484
+ return adjustedColor || undefined;
485
+ }
486
+ }
487
+
488
+ let fgColor = cell.getFgColor();
489
+ let fgColorMode = cell.getFgColorMode();
490
+ let bgColor = cell.getBgColor();
491
+ let bgColorMode = cell.getBgColorMode();
492
+ const isInverse = !!cell.isInverse();
493
+ const isBold = !!cell.isInverse();
494
+ if (isInverse) {
495
+ const temp = fgColor;
496
+ fgColor = bgColor;
497
+ bgColor = temp;
498
+ const temp2 = fgColorMode;
499
+ fgColorMode = bgColorMode;
500
+ bgColorMode = temp2;
501
+ }
502
+
503
+ const bgRgba = this._resolveBackgroundRgba(bgOverride !== undefined ? Attributes.CM_RGB : bgColorMode, bgOverride ?? bgColor, isInverse);
504
+ const fgRgba = this._resolveForegroundRgba(fgColorMode, fgColor, isInverse, isBold);
505
+ let result = rgba.ensureContrastRatio(bgOverride ?? bgRgba, fgOverride ?? fgRgba, this._optionsService.rawOptions.minimumContrastRatio);
506
+
507
+ if (!result) {
508
+ if (!fgOverride) {
509
+ this._colors.contrastCache.setColor(cell.bg, cell.fg, null);
510
+ return undefined;
511
+ }
512
+ // If it was an override and there was no contrast change, set as the result
513
+ result = fgOverride;
514
+ }
515
+
516
+ const color: IColor = {
517
+ css: channels.toCss(
518
+ (result >> 24) & 0xFF,
519
+ (result >> 16) & 0xFF,
520
+ (result >> 8) & 0xFF
521
+ ),
522
+ rgba: result
523
+ };
524
+ if (!bgOverride && !fgOverride) {
525
+ this._colors.contrastCache.setColor(cell.bg, cell.fg, color);
526
+ }
527
+
528
+ return color;
529
+ }
530
+
531
+ private _resolveBackgroundRgba(bgColorMode: number, bgColor: number, inverse: boolean): number {
532
+ switch (bgColorMode) {
533
+ case Attributes.CM_P16:
534
+ case Attributes.CM_P256:
535
+ return this._colors.ansi[bgColor].rgba;
536
+ case Attributes.CM_RGB:
537
+ return bgColor << 8;
538
+ case Attributes.CM_DEFAULT:
539
+ default:
540
+ if (inverse) {
541
+ return this._colors.foreground.rgba;
542
+ }
543
+ return this._colors.background.rgba;
544
+ }
545
+ }
546
+
547
+ private _resolveForegroundRgba(fgColorMode: number, fgColor: number, inverse: boolean, bold: boolean): number {
548
+ switch (fgColorMode) {
549
+ case Attributes.CM_P16:
550
+ case Attributes.CM_P256:
551
+ if (this._optionsService.rawOptions.drawBoldTextInBrightColors && bold && fgColor < 8) {
552
+ fgColor += 8;
553
+ }
554
+ return this._colors.ansi[fgColor].rgba;
555
+ case Attributes.CM_RGB:
556
+ return fgColor << 8;
557
+ case Attributes.CM_DEFAULT:
558
+ default:
559
+ if (inverse) {
560
+ return this._colors.background.rgba;
561
+ }
562
+ return this._colors.foreground.rgba;
563
+ }
564
+ }
565
+
566
+ private _isCellInSelection(x: number, y: number): boolean {
567
+ const start = this._selectionStart;
568
+ const end = this._selectionEnd;
569
+ if (!start || !end) {
570
+ return false;
571
+ }
572
+ if (this._columnSelectMode) {
573
+ return x >= start[0] && y >= start[1] &&
574
+ x < end[0] && y < end[1];
575
+ }
576
+ return (y > start[1] && y < end[1]) ||
577
+ (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) ||
578
+ (start[1] < end[1] && y === end[1] && x < end[0]) ||
579
+ (start[1] < end[1] && y === start[1] && x >= start[0]);
580
+ }
581
+ }
582
+