@xterm/addon-image 0.10.0-beta.214 → 0.10.0-beta.216
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xterm/addon-image",
|
|
3
|
-
"version": "0.10.0-beta.
|
|
3
|
+
"version": "0.10.0-beta.216",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "The xterm.js authors",
|
|
6
6
|
"url": "https://xtermjs.org/"
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"sixel": "^0.16.0",
|
|
28
28
|
"xterm-wasm-parts": "^0.4.1"
|
|
29
29
|
},
|
|
30
|
-
"commit": "
|
|
30
|
+
"commit": "6ba731d73bfbe074e84b57abb62080bed2f4db03",
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@xterm/xterm": "^6.1.0-beta.
|
|
32
|
+
"@xterm/xterm": "^6.1.0-beta.216"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/ImageRenderer.ts
CHANGED
|
@@ -8,8 +8,10 @@ import { IDisposable } from '@xterm/xterm';
|
|
|
8
8
|
import { ICellSize, ImageLayer, ITerminalExt, IImageSpec, IRenderDimensions, IRenderService } from './Types';
|
|
9
9
|
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const enum Constants {
|
|
12
|
+
PLACEHOLDER_LENGTH = 4096,
|
|
13
|
+
PLACEHOLDER_HEIGHT = 24
|
|
14
|
+
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* ImageRenderer - terminal frontend extension:
|
|
@@ -110,7 +112,7 @@ export class ImageRenderer extends Disposable implements IDisposable {
|
|
|
110
112
|
public showPlaceholder(value: boolean): void {
|
|
111
113
|
if (value) {
|
|
112
114
|
if (!this._placeholder && this.cellSize.height !== -1) {
|
|
113
|
-
this._createPlaceHolder(Math.max(this.cellSize.height + 1, PLACEHOLDER_HEIGHT));
|
|
115
|
+
this._createPlaceHolder(Math.max(this.cellSize.height + 1, Constants.PLACEHOLDER_HEIGHT));
|
|
114
116
|
}
|
|
115
117
|
} else {
|
|
116
118
|
this._placeholderBitmap?.close();
|
|
@@ -249,7 +251,7 @@ export class ImageRenderer extends Disposable implements IDisposable {
|
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
if (!this._placeholder) {
|
|
252
|
-
this._createPlaceHolder(Math.max(height + 1, PLACEHOLDER_HEIGHT));
|
|
254
|
+
this._createPlaceHolder(Math.max(height + 1, Constants.PLACEHOLDER_HEIGHT));
|
|
253
255
|
} else if (height >= this._placeholder!.height) {
|
|
254
256
|
this._createPlaceHolder(height + 1);
|
|
255
257
|
}
|
|
@@ -379,7 +381,7 @@ export class ImageRenderer extends Disposable implements IDisposable {
|
|
|
379
381
|
return this._layers.has(layer);
|
|
380
382
|
}
|
|
381
383
|
|
|
382
|
-
private _createPlaceHolder(height: number = PLACEHOLDER_HEIGHT): void {
|
|
384
|
+
private _createPlaceHolder(height: number = Constants.PLACEHOLDER_HEIGHT): void {
|
|
383
385
|
this._placeholderBitmap?.close();
|
|
384
386
|
this._placeholderBitmap = undefined;
|
|
385
387
|
|
|
@@ -403,7 +405,7 @@ export class ImageRenderer extends Disposable implements IDisposable {
|
|
|
403
405
|
ctx.putImageData(imgData, 0, 0);
|
|
404
406
|
|
|
405
407
|
// create placeholder line, width aligned to blueprint width
|
|
406
|
-
const width = (screen.width + bWidth - 1) & ~(bWidth - 1) || PLACEHOLDER_LENGTH;
|
|
408
|
+
const width = (screen.width + bWidth - 1) & ~(bWidth - 1) || Constants.PLACEHOLDER_LENGTH;
|
|
407
409
|
this._placeholder = ImageRenderer.createCanvas(this.document, width, height);
|
|
408
410
|
const ctx2 = this._placeholder.getContext('2d', { alpha: false });
|
|
409
411
|
if (!ctx2) {
|
|
@@ -16,24 +16,23 @@ import {
|
|
|
16
16
|
IKittyCommand,
|
|
17
17
|
IPendingTransmission,
|
|
18
18
|
IKittyImageData,
|
|
19
|
-
|
|
20
|
-
BYTES_PER_PIXEL_RGBA,
|
|
21
|
-
ALPHA_OPAQUE,
|
|
19
|
+
KittyPixelConstants,
|
|
22
20
|
parseKittyCommand
|
|
23
21
|
} from './KittyGraphicsTypes';
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// Local mirror of const enum (esbuild can't inline const enums from external packages)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
const enum Constants {
|
|
24
|
+
// Memory limit for base64 decoder (4MB, same as IIPHandler)
|
|
25
|
+
DECODER_KEEP_DATA = 4194304,
|
|
26
|
+
DECODER_INITIAL_DATA = 4194304, // 4MB
|
|
27
|
+
// Local mirror of const enum (esbuild can't inline const enums from external packages)
|
|
28
|
+
DECODER_OK = 0,
|
|
29
|
+
// Maximum control data size
|
|
30
|
+
MAX_CONTROL_DATA_SIZE = 512,
|
|
31
|
+
// Semicolon codepoint
|
|
32
|
+
SEMICOLON = 0x3B
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
const SEMICOLON = 0x3B;
|
|
35
|
+
const DECODER_OK = Constants.DECODER_OK as unknown as DecodeStatus.OK;
|
|
37
36
|
|
|
38
37
|
// Kitty graphics protocol handler with streaming base64 decoding.
|
|
39
38
|
export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDisposable {
|
|
@@ -50,7 +49,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
50
49
|
private _inControlData = true;
|
|
51
50
|
|
|
52
51
|
// Buffer for control data.
|
|
53
|
-
private _controlData = new Uint32Array(MAX_CONTROL_DATA_SIZE);
|
|
52
|
+
private _controlData = new Uint32Array(Constants.MAX_CONTROL_DATA_SIZE);
|
|
54
53
|
private _controlLength = 0;
|
|
55
54
|
|
|
56
55
|
// Pre-calculated encoded size limit
|
|
@@ -77,7 +76,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
77
76
|
// Convert decoded size limit -> max encoded bytes.
|
|
78
77
|
this._maxEncodedBytes = Math.ceil(this._opts.kittySizeLimit * 4 / 3);
|
|
79
78
|
// ensure we preallocate more than configured limit while using 4mb initial size.
|
|
80
|
-
this._initialEncodedBytes = Math.min(DECODER_INITIAL_DATA, this._maxEncodedBytes);
|
|
79
|
+
this._initialEncodedBytes = Math.min(Constants.DECODER_INITIAL_DATA, this._maxEncodedBytes);
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
public reset(): void {
|
|
@@ -129,7 +128,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
129
128
|
// Scan for semicolon
|
|
130
129
|
let controlEnd = end;
|
|
131
130
|
for (let i = start; i < end; i++) {
|
|
132
|
-
if (data[i] === SEMICOLON) {
|
|
131
|
+
if (data[i] === Constants.SEMICOLON) {
|
|
133
132
|
this._inControlData = false;
|
|
134
133
|
controlEnd = i;
|
|
135
134
|
break;
|
|
@@ -138,7 +137,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
138
137
|
|
|
139
138
|
// Copy control data
|
|
140
139
|
const copyLength = controlEnd - start;
|
|
141
|
-
if (this._controlLength + copyLength > MAX_CONTROL_DATA_SIZE) {
|
|
140
|
+
if (this._controlLength + copyLength > Constants.MAX_CONTROL_DATA_SIZE) {
|
|
142
141
|
this._aborted = true;
|
|
143
142
|
return;
|
|
144
143
|
}
|
|
@@ -201,7 +200,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
201
200
|
this._activeDecoder = pending.decoder;
|
|
202
201
|
}
|
|
203
202
|
if (!this._activeDecoder) {
|
|
204
|
-
this._activeDecoder = new Base64Decoder(DECODER_KEEP_DATA, this._maxEncodedBytes, this._initialEncodedBytes);
|
|
203
|
+
this._activeDecoder = new Base64Decoder(Constants.DECODER_KEEP_DATA, this._maxEncodedBytes, this._initialEncodedBytes);
|
|
205
204
|
this._activeDecoder.init();
|
|
206
205
|
}
|
|
207
206
|
|
|
@@ -484,7 +483,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
484
483
|
return true;
|
|
485
484
|
}
|
|
486
485
|
|
|
487
|
-
const bytesPerPixel = format === KittyFormat.RGBA ? BYTES_PER_PIXEL_RGBA : BYTES_PER_PIXEL_RGB;
|
|
486
|
+
const bytesPerPixel = format === KittyFormat.RGBA ? KittyPixelConstants.BYTES_PER_PIXEL_RGBA : KittyPixelConstants.BYTES_PER_PIXEL_RGB;
|
|
488
487
|
const expectedBytes = width * height * bytesPerPixel;
|
|
489
488
|
|
|
490
489
|
if (bytes.length < expectedBytes) {
|
|
@@ -723,7 +722,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
723
722
|
throw new Error('Width and height required for raw pixel data');
|
|
724
723
|
}
|
|
725
724
|
|
|
726
|
-
const bytesPerPixel = image.format === KittyFormat.RGBA ? BYTES_PER_PIXEL_RGBA : BYTES_PER_PIXEL_RGB;
|
|
725
|
+
const bytesPerPixel = image.format === KittyFormat.RGBA ? KittyPixelConstants.BYTES_PER_PIXEL_RGBA : KittyPixelConstants.BYTES_PER_PIXEL_RGB;
|
|
727
726
|
const expectedBytes = width * height * bytesPerPixel;
|
|
728
727
|
|
|
729
728
|
if (bytes.length < expectedBytes) {
|
|
@@ -734,13 +733,13 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
734
733
|
|
|
735
734
|
if (image.format === KittyFormat.RGBA) {
|
|
736
735
|
// RGBA: use bytes directly — no copy needed
|
|
737
|
-
return createImageBitmap(new ImageData(new Uint8ClampedArray(bytes.buffer as ArrayBuffer, bytes.byteOffset, pixelCount * BYTES_PER_PIXEL_RGBA), width, height));
|
|
736
|
+
return createImageBitmap(new ImageData(new Uint8ClampedArray(bytes.buffer as ArrayBuffer, bytes.byteOffset, pixelCount * KittyPixelConstants.BYTES_PER_PIXEL_RGBA), width, height));
|
|
738
737
|
}
|
|
739
738
|
|
|
740
739
|
// RGB→RGBA: interleave alpha using uint32 block processing (4 pixels per iteration).
|
|
741
740
|
// 3 uint32 reads + 4 uint32 writes per 4 pixels vs 28 byte reads/writes — ~6x faster.
|
|
742
741
|
// Assumes little-endian (all modern browsers/Node.js).
|
|
743
|
-
const data = new Uint8ClampedArray(pixelCount * BYTES_PER_PIXEL_RGBA);
|
|
742
|
+
const data = new Uint8ClampedArray(pixelCount * KittyPixelConstants.BYTES_PER_PIXEL_RGBA);
|
|
744
743
|
const src32 = new Uint32Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 4));
|
|
745
744
|
const dst32 = new Uint32Array(data.buffer);
|
|
746
745
|
const alignedPixels = pixelCount & ~3; // round down to multiple of 4
|
|
@@ -759,15 +758,15 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
|
|
759
758
|
}
|
|
760
759
|
|
|
761
760
|
// Handle remaining 1–3 pixels
|
|
762
|
-
let srcByte = alignedPixels * BYTES_PER_PIXEL_RGB;
|
|
763
|
-
let dstByte = alignedPixels * BYTES_PER_PIXEL_RGBA;
|
|
761
|
+
let srcByte = alignedPixels * KittyPixelConstants.BYTES_PER_PIXEL_RGB;
|
|
762
|
+
let dstByte = alignedPixels * KittyPixelConstants.BYTES_PER_PIXEL_RGBA;
|
|
764
763
|
for (let i = alignedPixels; i < pixelCount; i++) {
|
|
765
764
|
data[dstByte] = bytes[srcByte];
|
|
766
765
|
data[dstByte + 1] = bytes[srcByte + 1];
|
|
767
766
|
data[dstByte + 2] = bytes[srcByte + 2];
|
|
768
|
-
data[dstByte + 3] = ALPHA_OPAQUE;
|
|
769
|
-
srcByte += BYTES_PER_PIXEL_RGB;
|
|
770
|
-
dstByte += BYTES_PER_PIXEL_RGBA;
|
|
767
|
+
data[dstByte + 3] = KittyPixelConstants.ALPHA_OPAQUE;
|
|
768
|
+
srcByte += KittyPixelConstants.BYTES_PER_PIXEL_RGB;
|
|
769
|
+
dstByte += KittyPixelConstants.BYTES_PER_PIXEL_RGBA;
|
|
771
770
|
}
|
|
772
771
|
|
|
773
772
|
return createImageBitmap(new ImageData(data, width, height));
|
|
@@ -82,9 +82,11 @@ export const enum KittyKey {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// Pixel format constants
|
|
85
|
-
export const
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
export const enum KittyPixelConstants {
|
|
86
|
+
BYTES_PER_PIXEL_RGB = 3,
|
|
87
|
+
BYTES_PER_PIXEL_RGBA = 4,
|
|
88
|
+
ALPHA_OPAQUE = 255
|
|
89
|
+
}
|
|
88
90
|
|
|
89
91
|
// Parsed Kitty graphics command.
|
|
90
92
|
export interface IKittyCommand {
|