@utsp/render 0.11.0-nightly.20251213152020.671c815 → 0.11.0
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/README.md +102 -8
- package/dist/2d/index.cjs +34 -0
- package/dist/2d/index.d.ts +907 -0
- package/dist/2d/index.mjs +34 -0
- package/dist/ansi/index.cjs +2 -0
- package/dist/ansi/index.d.ts +132 -0
- package/dist/ansi/index.mjs +2 -0
- package/dist/common/index.cjs +50 -0
- package/dist/common/index.d.ts +390 -0
- package/dist/common/index.mjs +50 -0
- package/dist/gl/index.cjs +127 -0
- package/dist/gl/index.d.ts +802 -0
- package/dist/gl/index.mjs +127 -0
- package/dist/index.cjs +10 -9
- package/dist/index.d.ts +154 -4
- package/dist/index.mjs +10 -9
- package/package.json +40 -3
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
import { IRenderer, ScalingMode, RGBColor, RenderState } from '@utsp/types';
|
|
2
|
+
export { IRenderer, RenderState, ScalingMode } from '@utsp/types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Atlas Utilities
|
|
6
|
+
*
|
|
7
|
+
* Shared utilities for block-based font atlas calculations.
|
|
8
|
+
* Used by both TerminalGL (WebGL) and ImageFontAtlas (Canvas2D).
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Number of 256-char blocks in an atlas
|
|
12
|
+
* - 1 block = 16×16 grid = 256 chars (8-bit)
|
|
13
|
+
* - 4 blocks = 32×32 grid = 1024 chars (10-bit)
|
|
14
|
+
* - 16 blocks = 64×64 grid = 4096 chars (12-bit)
|
|
15
|
+
*/
|
|
16
|
+
type AtlasBlocks = 1 | 4 | 16;
|
|
17
|
+
/**
|
|
18
|
+
* Get the number of columns in the atlas grid
|
|
19
|
+
* @param blocks - Number of 256-char blocks (1, 4, or 16)
|
|
20
|
+
* @returns Number of character columns (16, 32, or 64)
|
|
21
|
+
*/
|
|
22
|
+
declare function getAtlasColumns(blocks: AtlasBlocks): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get the maximum valid charCode for a given atlas size
|
|
25
|
+
* @param blocks - Number of 256-char blocks (1, 4, or 16)
|
|
26
|
+
* @returns Maximum charCode (255, 1023, or 4095)
|
|
27
|
+
*/
|
|
28
|
+
declare function getMaxCharCode(blocks: AtlasBlocks): number;
|
|
29
|
+
/**
|
|
30
|
+
* Get character grid position in a block-based atlas
|
|
31
|
+
*
|
|
32
|
+
* Atlas layout for multi-block fonts:
|
|
33
|
+
* - Each block contains 256 chars in a 16×16 grid
|
|
34
|
+
* - Blocks are arranged in a square:
|
|
35
|
+
* - 1 block: 1×1 (16×16 chars total)
|
|
36
|
+
* - 4 blocks: 2×2 (32×32 chars total)
|
|
37
|
+
* - 16 blocks: 4×4 (64×64 chars total)
|
|
38
|
+
*
|
|
39
|
+
* CharCode mapping:
|
|
40
|
+
* charCode 0-255 → Block 0 (top-left)
|
|
41
|
+
* charCode 256-511 → Block 1 (top-right for 4+ blocks)
|
|
42
|
+
* charCode 512-767 → Block 2 (bottom-left for 4 blocks)
|
|
43
|
+
* etc.
|
|
44
|
+
*
|
|
45
|
+
* @param charCode - Character code (0 to maxCharCode)
|
|
46
|
+
* @param blocks - Number of 256-char blocks (1, 4, or 16)
|
|
47
|
+
* @returns Grid position { col, row } in the atlas
|
|
48
|
+
*/
|
|
49
|
+
declare function getCharGridPosition(charCode: number, blocks: AtlasBlocks): {
|
|
50
|
+
col: number;
|
|
51
|
+
row: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Police bitmap matricielle
|
|
56
|
+
* Map qui associe un code de caractère (charCode) à une représentation bitmap 8x8
|
|
57
|
+
* Chaque Uint8Array contient 8 octets, un par ligne de pixels
|
|
58
|
+
*/
|
|
59
|
+
type BitmapFont = Map<number, Uint8Array>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* WebGL compatibility report
|
|
63
|
+
*/
|
|
64
|
+
interface WebGLCompatibilityReport {
|
|
65
|
+
/** WebGL 1.0 support */
|
|
66
|
+
webgl1: boolean;
|
|
67
|
+
/** OES_element_index_uint extension (Uint32 indices) */
|
|
68
|
+
uint32Indices: boolean;
|
|
69
|
+
/** Maximum texture size */
|
|
70
|
+
maxTextureSize: number;
|
|
71
|
+
/** Maximum viewport dimensions */
|
|
72
|
+
maxViewportDims: [number, number];
|
|
73
|
+
/** Maximum terminal size with Uint16 indices (cols × rows) */
|
|
74
|
+
maxCellsUint16: number;
|
|
75
|
+
/** Maximum terminal size with Uint32 indices (cols × rows) */
|
|
76
|
+
maxCellsUint32: number;
|
|
77
|
+
/** Recommended maximum terminal size for this device */
|
|
78
|
+
recommendedMaxCells: number;
|
|
79
|
+
/** Warnings (empty if fully compatible) */
|
|
80
|
+
warnings: string[];
|
|
81
|
+
/** Errors (empty if compatible) */
|
|
82
|
+
errors: string[];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Options for WebGL terminal configuration
|
|
86
|
+
*/
|
|
87
|
+
interface TerminalGLOptions {
|
|
88
|
+
/** Number of columns (required) */
|
|
89
|
+
cols: number;
|
|
90
|
+
/** Number of rows (required) */
|
|
91
|
+
rows: number;
|
|
92
|
+
/** Character width in pixels */
|
|
93
|
+
charWidth?: number;
|
|
94
|
+
/** Character height in pixels */
|
|
95
|
+
charHeight?: number;
|
|
96
|
+
/** Canvas background color (CSS format, for gl.clearColor) */
|
|
97
|
+
canvasBgColor?: string | null;
|
|
98
|
+
/** Show cell delimitation grid (debug) */
|
|
99
|
+
showGrid?: boolean;
|
|
100
|
+
/** Force Uint16 indices (for compatibility testing, auto-detected by default) */
|
|
101
|
+
forceUint16?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Scaling mode for pixel-perfect rendering (default: ScalingMode.None)
|
|
104
|
+
*
|
|
105
|
+
* Controls how the canvas is scaled to fit the container:
|
|
106
|
+
* - ScalingMode.None: Fills available space, may have sub-pixel artifacts (default)
|
|
107
|
+
* - ScalingMode.Eighth: Snaps to 0.125 increments (1.0, 1.125, 1.25...)
|
|
108
|
+
* - ScalingMode.Quarter: Snaps to 0.25 increments (1.0, 1.25, 1.5...)
|
|
109
|
+
* - ScalingMode.Half: Snaps to 0.5 increments (1.0, 1.5, 2.0...)
|
|
110
|
+
* - ScalingMode.Integer: Integer scaling only (1x, 2x, 3x...), crispest pixels
|
|
111
|
+
*/
|
|
112
|
+
scalingMode?: ScalingMode;
|
|
113
|
+
/**
|
|
114
|
+
* Ambient effect configuration
|
|
115
|
+
*
|
|
116
|
+
* Creates a blurred glow effect around the terminal when using pixel-perfect
|
|
117
|
+
* scaling modes that leave empty space around the canvas.
|
|
118
|
+
*
|
|
119
|
+
* - false or undefined: Disabled (default)
|
|
120
|
+
* - true: Enabled with default settings (blur: 30px, scale: 1.15, opacity: 0.7)
|
|
121
|
+
* - object: Custom configuration
|
|
122
|
+
*/
|
|
123
|
+
ambientEffect?: boolean | {
|
|
124
|
+
/** Blur radius in pixels (default: 30) */
|
|
125
|
+
blur?: number;
|
|
126
|
+
/** Scale factor for the background canvas (default: 1.15) */
|
|
127
|
+
scale?: number;
|
|
128
|
+
/** Opacity of the ambient effect (0-1, default: 0.7) */
|
|
129
|
+
opacity?: number;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Simplified terminal using WebGL for basic rendering
|
|
134
|
+
* Only supports bitmap fonts with atlas
|
|
135
|
+
* Implements IRenderer interface for dependency injection with core
|
|
136
|
+
*
|
|
137
|
+
* ✨ SIMPLIFIED VERSION: Only backgrounds + colored characters
|
|
138
|
+
*/
|
|
139
|
+
declare class TerminalGL implements IRenderer {
|
|
140
|
+
/**
|
|
141
|
+
* Check WebGL 1.0 compatibility and device capabilities
|
|
142
|
+
*
|
|
143
|
+
* Tests all required WebGL features and returns a detailed compatibility report.
|
|
144
|
+
* Use this before creating a TerminalGL instance to ensure device support.
|
|
145
|
+
*
|
|
146
|
+
* @returns Detailed compatibility report with warnings and errors
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const report = TerminalGL.checkCompatibility();
|
|
151
|
+
* if (report.errors.length > 0) {
|
|
152
|
+
* console.error('WebGL not supported:', report.errors);
|
|
153
|
+
* // Fallback to Canvas 2D renderer
|
|
154
|
+
* } else if (report.warnings.length > 0) {
|
|
155
|
+
* console.warn('WebGL limitations:', report.warnings);
|
|
156
|
+
* }
|
|
157
|
+
* console.log(`Max terminal size: ${report.recommendedMaxCells} cells`);
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
static checkCompatibility(): WebGLCompatibilityReport;
|
|
161
|
+
private canvas;
|
|
162
|
+
private gl;
|
|
163
|
+
private parentElement;
|
|
164
|
+
private containerDiv;
|
|
165
|
+
private cols;
|
|
166
|
+
private rows;
|
|
167
|
+
private charWidth;
|
|
168
|
+
private charHeight;
|
|
169
|
+
private cellWidth;
|
|
170
|
+
private cellHeight;
|
|
171
|
+
private glyphOffsetX;
|
|
172
|
+
private glyphOffsetY;
|
|
173
|
+
private canvasBgColor;
|
|
174
|
+
private showGrid;
|
|
175
|
+
private supportsUint32Indices;
|
|
176
|
+
private useUint16Indices;
|
|
177
|
+
private gridOverlay?;
|
|
178
|
+
private bitmapFont?;
|
|
179
|
+
private atlasTexture;
|
|
180
|
+
private atlasCanvas?;
|
|
181
|
+
private atlasColumns;
|
|
182
|
+
private fontLoaded;
|
|
183
|
+
private paletteTexture;
|
|
184
|
+
private program;
|
|
185
|
+
private positionBuffer;
|
|
186
|
+
private texCoordBuffer;
|
|
187
|
+
private colorIndexBuffer;
|
|
188
|
+
private indexBuffer;
|
|
189
|
+
private aPosition?;
|
|
190
|
+
private aTexCoord?;
|
|
191
|
+
private aColorIndex?;
|
|
192
|
+
private uResolution;
|
|
193
|
+
private uTexture;
|
|
194
|
+
private uPalette;
|
|
195
|
+
private resizeObserver?;
|
|
196
|
+
private charCodeToAtlasIndex;
|
|
197
|
+
private atlasUVs;
|
|
198
|
+
private cachedAtlasWidth;
|
|
199
|
+
private cachedAtlasHeight;
|
|
200
|
+
private paletteFloat;
|
|
201
|
+
private maxCells;
|
|
202
|
+
private renderPositions;
|
|
203
|
+
private renderTexCoords;
|
|
204
|
+
private renderColorIndices;
|
|
205
|
+
private renderIndices;
|
|
206
|
+
private cachedResolution;
|
|
207
|
+
private cachedTextureUnit;
|
|
208
|
+
private cachedPaletteUnit;
|
|
209
|
+
private cachedTextureUniform;
|
|
210
|
+
private cachedPaletteUniform;
|
|
211
|
+
private paletteHash;
|
|
212
|
+
private currentScale;
|
|
213
|
+
private scalingMode;
|
|
214
|
+
private ambientEffectEnabled;
|
|
215
|
+
private ambientEffectCanvas;
|
|
216
|
+
private ambientEffectCtx;
|
|
217
|
+
private ambientEffectBlur;
|
|
218
|
+
private ambientEffectScale;
|
|
219
|
+
private ambientEffectOpacity;
|
|
220
|
+
private onResizeCallback?;
|
|
221
|
+
private staticPositionsInitialized;
|
|
222
|
+
private vaoExtension;
|
|
223
|
+
private vao;
|
|
224
|
+
private instancedExtension;
|
|
225
|
+
private useInstancing;
|
|
226
|
+
private instanceDataBuffer;
|
|
227
|
+
private instanceData;
|
|
228
|
+
private templateQuadPositions;
|
|
229
|
+
private templateQuadIndices;
|
|
230
|
+
constructor(parentDiv: HTMLDivElement, options: TerminalGLOptions);
|
|
231
|
+
/**
|
|
232
|
+
* 🚀 INSTANCING: Initialize template quad and instance buffers
|
|
233
|
+
* Called once at init if instancing is supported
|
|
234
|
+
*/
|
|
235
|
+
private initInstancedBuffers;
|
|
236
|
+
/**
|
|
237
|
+
* 🚀 OPTIMIZATION: Initialize pre-allocated buffers for rendering
|
|
238
|
+
* Avoids allocations each frame
|
|
239
|
+
* Uses Uint16 or Uint32 indices based on device support
|
|
240
|
+
*/
|
|
241
|
+
private initRenderBuffers;
|
|
242
|
+
/**
|
|
243
|
+
* 🚀 MEGA OPTIMIZATION: Pre-compute static positions for ALL possible quads
|
|
244
|
+
* Called only once after font load, or after resize
|
|
245
|
+
* Positions never change during rendering - only colors and UVs change!
|
|
246
|
+
*/
|
|
247
|
+
private precomputeStaticPositions;
|
|
248
|
+
/**
|
|
249
|
+
* Initialize WebGL (shaders, buffers, etc.)
|
|
250
|
+
*/
|
|
251
|
+
private initWebGL;
|
|
252
|
+
/**
|
|
253
|
+
* Compile a shader
|
|
254
|
+
*/
|
|
255
|
+
private compileShader;
|
|
256
|
+
/**
|
|
257
|
+
* 🔲 Initialize 2D canvas overlay for debug grid
|
|
258
|
+
* Performance: 2D canvas drawn only once, 0ms per frame
|
|
259
|
+
*/
|
|
260
|
+
private initGridOverlay;
|
|
261
|
+
/**
|
|
262
|
+
* 🔲 Draw grid lines on 2D canvas overlay
|
|
263
|
+
* Called only once at init and resize
|
|
264
|
+
*
|
|
265
|
+
* The grid must match the terminal's pixel-perfect scaling:
|
|
266
|
+
* - Same base size as the main canvas
|
|
267
|
+
* - Same transform: scale() factor
|
|
268
|
+
* - Centered in the container like the main canvas (via flexbox or calculated position)
|
|
269
|
+
*/
|
|
270
|
+
private updateGridOverlay;
|
|
271
|
+
/**
|
|
272
|
+
* Configure bitmap font and generate atlas
|
|
273
|
+
*
|
|
274
|
+
* ⚠️ **INTERNAL USE ONLY** - This method is called automatically by ClientRuntime's
|
|
275
|
+
* event system when Core.loadBitmapFontById() is called. Do NOT call this directly
|
|
276
|
+
* unless you're implementing a custom runtime.
|
|
277
|
+
*
|
|
278
|
+
* Event flow: Core.loadBitmapFontById() → Core.onBitmapFontChangedCallback
|
|
279
|
+
* → ClientRuntime.onCoreBitmapFontChanged() → RendererManager.setBitmapFont()
|
|
280
|
+
*
|
|
281
|
+
* @param font - Bitmap font mapping (charCode → byte array)
|
|
282
|
+
* @param charWidth - Width of each character in pixels
|
|
283
|
+
* @param charHeight - Height of each character in pixels
|
|
284
|
+
* @param cellWidth - Width of each cell in pixels
|
|
285
|
+
* @param cellHeight - Height of each cell in pixels
|
|
286
|
+
* @throws {Error} If atlas generation fails
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* // ❌ DON'T: Call setBitmapFont directly
|
|
291
|
+
* renderer.setBitmapFont(font, 8, 16, 8, 16);
|
|
292
|
+
*
|
|
293
|
+
* // ✅ DO: Use Core's loadBitmapFontById (triggers event automatically)
|
|
294
|
+
* core.loadBitmapFontById(1, {
|
|
295
|
+
* charWidth: 8, charHeight: 16,
|
|
296
|
+
* cellWidth: 8, cellHeight: 16,
|
|
297
|
+
* glyphs: new Map([[65, new Uint8Array([...])]])
|
|
298
|
+
* });
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
setBitmapFont(font: BitmapFont, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void;
|
|
302
|
+
/**
|
|
303
|
+
* Set image font (PNG atlas) for extended character rendering
|
|
304
|
+
* Supports 1, 4, or 16 blocks (256, 1024, or 4096 characters)
|
|
305
|
+
*
|
|
306
|
+
* @param imageData - PNG image data as Uint8Array
|
|
307
|
+
* @param glyphWidth - Glyph width in pixels
|
|
308
|
+
* @param glyphHeight - Glyph height in pixels
|
|
309
|
+
* @param cellWidth - Cell width in pixels
|
|
310
|
+
* @param cellHeight - Cell height in pixels
|
|
311
|
+
* @param atlasBlocks - Number of 256-char blocks (1, 4, or 16)
|
|
312
|
+
*/
|
|
313
|
+
setImageFont(imageData: Uint8Array, glyphWidth: number, glyphHeight: number, cellWidth: number, cellHeight: number, atlasBlocks: AtlasBlocks): Promise<void>;
|
|
314
|
+
/**
|
|
315
|
+
* Load PNG image and create WebGL texture
|
|
316
|
+
*/
|
|
317
|
+
private loadImageFontAtlas;
|
|
318
|
+
/**
|
|
319
|
+
* Pre-compute UVs for ImageFont (block-based grid layout)
|
|
320
|
+
*
|
|
321
|
+
* Atlas layout for multi-block fonts:
|
|
322
|
+
* - Each block contains 256 chars in a 16×16 grid
|
|
323
|
+
* - Blocks are arranged visually:
|
|
324
|
+
* - 1 block: 1×1 (16×16 chars)
|
|
325
|
+
* - 4 blocks: 2×2 (32×32 chars total)
|
|
326
|
+
* - 16 blocks: 4×4 (64×64 chars total)
|
|
327
|
+
*
|
|
328
|
+
* CharCode mapping:
|
|
329
|
+
* charCode 0-255 → Block 0 (top-left)
|
|
330
|
+
* charCode 256-511 → Block 1 (top-right for 4 blocks)
|
|
331
|
+
* charCode 512-767 → Block 2 (bottom-left for 4 blocks)
|
|
332
|
+
* etc.
|
|
333
|
+
*/
|
|
334
|
+
private precomputeImageFontUVs;
|
|
335
|
+
/**
|
|
336
|
+
* Generate texture atlas from bitmap font
|
|
337
|
+
*/
|
|
338
|
+
private generateAtlas;
|
|
339
|
+
/**
|
|
340
|
+
* 🚀 OPTIMIZED: Build charCode → atlas index using direct array lookup
|
|
341
|
+
*/
|
|
342
|
+
private buildCharCodeMap;
|
|
343
|
+
/**
|
|
344
|
+
* 🚀 MEGA OPTIMIZATION: Pre-compute ALL atlas UVs
|
|
345
|
+
* Called once after atlas generation - UVs never change!
|
|
346
|
+
* Eliminates per-frame division and modulo operations
|
|
347
|
+
*/
|
|
348
|
+
private precomputeAtlasUVs;
|
|
349
|
+
/**
|
|
350
|
+
* Create WebGL texture from atlas
|
|
351
|
+
*/
|
|
352
|
+
private createAtlasTexture;
|
|
353
|
+
/**
|
|
354
|
+
* Clear entire terminal
|
|
355
|
+
*
|
|
356
|
+
* Clears the WebGL canvas. Note: Actual terminal content clearing is handled
|
|
357
|
+
* by Core's RenderState, not by this renderer.
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```typescript
|
|
361
|
+
* renderer.clear();
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
clear(): void;
|
|
365
|
+
/**
|
|
366
|
+
* Parse CSS color to normalized RGBA (0-1)
|
|
367
|
+
*/
|
|
368
|
+
private parseColor;
|
|
369
|
+
/**
|
|
370
|
+
* Configure ResizeObserver to adapt canvas
|
|
371
|
+
*/
|
|
372
|
+
private setupResizeObserver;
|
|
373
|
+
/**
|
|
374
|
+
* Update canvas display size
|
|
375
|
+
*
|
|
376
|
+
* Supports multiple scaling modes:
|
|
377
|
+
*
|
|
378
|
+
* 🎯 INTEGER MODE (ScalingMode.Integer):
|
|
379
|
+
* Uses integer scaling (1x, 2x, 3x...) for crisp pixels without artifacts.
|
|
380
|
+
* The canvas is centered in the container via flexbox.
|
|
381
|
+
* May leave empty space around the canvas.
|
|
382
|
+
*
|
|
383
|
+
* 📐 HALF MODE (ScalingMode.Half):
|
|
384
|
+
* Snaps to half increments (1.0, 1.5, 2.0...).
|
|
385
|
+
* Good balance between space usage and visual quality.
|
|
386
|
+
*
|
|
387
|
+
* 📏 QUARTER MODE (ScalingMode.Quarter):
|
|
388
|
+
* Snaps to quarter increments (1.0, 1.25, 1.5, 1.75, 2.0...).
|
|
389
|
+
* Finer control over scaling with minimal artifacts.
|
|
390
|
+
*
|
|
391
|
+
* 🔲 NONE MODE (ScalingMode.None):
|
|
392
|
+
* Scales to fill as much space as possible while maintaining aspect ratio.
|
|
393
|
+
* May cause some lines to appear thicker due to sub-pixel rendering.
|
|
394
|
+
* Useful when maximizing screen usage is more important than pixel purity.
|
|
395
|
+
*/
|
|
396
|
+
private updateCanvasSize;
|
|
397
|
+
/**
|
|
398
|
+
* 🌈 AMBIENT EFFECT: Copy main canvas to ambient effect background
|
|
399
|
+
*
|
|
400
|
+
* This creates a glow effect around the terminal by copying the main
|
|
401
|
+
* WebGL canvas to a 2D canvas behind it, which has CSS blur applied.
|
|
402
|
+
*/
|
|
403
|
+
private updateAmbientEffect;
|
|
404
|
+
/**
|
|
405
|
+
* Set color palette and upload to GPU
|
|
406
|
+
*
|
|
407
|
+
* ⚠️ IMPORTANT: This is the ONLY way to update the palette.
|
|
408
|
+
* Typically called automatically by ClientRuntime via Core.onPaletteChanged() event.
|
|
409
|
+
* Do NOT call this directly unless you know what you're doing.
|
|
410
|
+
*
|
|
411
|
+
* @param palette - Array of 256 RGB colors
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* // ✅ Normal usage: Core handles this automatically
|
|
416
|
+
* core.loadPalette([...]);
|
|
417
|
+
* // → Core emits event
|
|
418
|
+
* // → ClientRuntime receives event
|
|
419
|
+
* // → renderer.setPalette() called automatically
|
|
420
|
+
*
|
|
421
|
+
* // ⚠️ Manual usage (advanced):
|
|
422
|
+
* const myPalette: RGBColor[] = [
|
|
423
|
+
* { r: 0, g: 0, b: 0, a: 255 }, // Color 0: Black
|
|
424
|
+
* { r: 255, g: 0, b: 0, a: 255 }, // Color 1: Red
|
|
425
|
+
* // ... 254 more colors
|
|
426
|
+
* ];
|
|
427
|
+
* renderer.setPalette(myPalette);
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
setPalette(palette: RGBColor[]): void;
|
|
431
|
+
/**
|
|
432
|
+
* 🚀 GPU OPTIMIZATION: Upload palette to GPU texture (256×1 RGBA)
|
|
433
|
+
*/
|
|
434
|
+
private updatePaletteTexture;
|
|
435
|
+
/**
|
|
436
|
+
* Render display data from core engine (ULTRA-OPTIMIZED)
|
|
437
|
+
*
|
|
438
|
+
* Bypasses internal cells and renders directly from RenderState for maximum performance.
|
|
439
|
+
* Uses GPU palette texture lookup to minimize CPU→GPU bandwidth (4× reduction).
|
|
440
|
+
*
|
|
441
|
+
* @param data - Render state containing cells, dimensions, and palette
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const renderState: RenderState = {
|
|
446
|
+
* cells: [...],
|
|
447
|
+
* width: 80,
|
|
448
|
+
* height: 25,
|
|
449
|
+
* palette: [...]
|
|
450
|
+
* };
|
|
451
|
+
* renderer.renderDisplayData(renderState);
|
|
452
|
+
* ```
|
|
453
|
+
*/
|
|
454
|
+
renderDisplayData(data: RenderState): void;
|
|
455
|
+
/**
|
|
456
|
+
* 🚀 NEW METHOD: Render directly from RenderState
|
|
457
|
+
* Bypass this.cells for maximum performance
|
|
458
|
+
*/
|
|
459
|
+
private renderDirect;
|
|
460
|
+
/**
|
|
461
|
+
* 🚀 INSTANCED RENDERING: 1 draw call for entire terminal
|
|
462
|
+
* MASSIVE performance boost - reduces draw calls from cols×rows×2 to just 1!
|
|
463
|
+
*/
|
|
464
|
+
private renderInstanced;
|
|
465
|
+
/**
|
|
466
|
+
* 🚀 ULTRA-OPTIMIZED: Update ONLY dynamic data (colors + UVs)
|
|
467
|
+
* Positions are static and pre-computed - only updated on resize!
|
|
468
|
+
* This is a MASSIVE performance win - positions never change during normal rendering
|
|
469
|
+
*/
|
|
470
|
+
private renderDirectBuffers;
|
|
471
|
+
/**
|
|
472
|
+
* Resize the terminal dimensions
|
|
473
|
+
*
|
|
474
|
+
* Changes the number of columns and rows. Preserves existing cell content
|
|
475
|
+
* where possible. Reallocates render buffers if needed.
|
|
476
|
+
*
|
|
477
|
+
* @param cols - New number of columns (must be positive integer)
|
|
478
|
+
* @param rows - New number of rows (must be positive integer)
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```typescript
|
|
482
|
+
* renderer.resize(120, 40); // Resize to 120×40
|
|
483
|
+
* ```
|
|
484
|
+
*/
|
|
485
|
+
resize(cols: number, rows: number): void;
|
|
486
|
+
/**
|
|
487
|
+
* Get canvas element
|
|
488
|
+
*/
|
|
489
|
+
getCanvas(): HTMLCanvasElement;
|
|
490
|
+
/**
|
|
491
|
+
* Get grid dimensions
|
|
492
|
+
*/
|
|
493
|
+
getGridSize(): {
|
|
494
|
+
cols: number;
|
|
495
|
+
rows: number;
|
|
496
|
+
};
|
|
497
|
+
/**
|
|
498
|
+
* Get cell width
|
|
499
|
+
*/
|
|
500
|
+
getCellWidth(): number;
|
|
501
|
+
/**
|
|
502
|
+
* Get cell height
|
|
503
|
+
*/
|
|
504
|
+
getCellHeight(): number;
|
|
505
|
+
/**
|
|
506
|
+
* Get current integer scale factor
|
|
507
|
+
* Used by PostProcessOverlay to sync dimensions
|
|
508
|
+
*/
|
|
509
|
+
getCurrentScale(): number;
|
|
510
|
+
/**
|
|
511
|
+
* Get base canvas dimensions (before scaling)
|
|
512
|
+
* Used by PostProcessOverlay to sync dimensions
|
|
513
|
+
*/
|
|
514
|
+
getBaseDimensions(): {
|
|
515
|
+
width: number;
|
|
516
|
+
height: number;
|
|
517
|
+
};
|
|
518
|
+
/**
|
|
519
|
+
* Set callback to be called after every resize
|
|
520
|
+
* Used by ClientRuntime to sync PostProcessOverlay
|
|
521
|
+
*/
|
|
522
|
+
setOnResizeCallback(callback: () => void): void;
|
|
523
|
+
/**
|
|
524
|
+
* Clear the resize callback
|
|
525
|
+
*/
|
|
526
|
+
clearOnResizeCallback(): void;
|
|
527
|
+
/**
|
|
528
|
+
* Set scaling mode
|
|
529
|
+
*
|
|
530
|
+
* @param mode - ScalingMode enum value:
|
|
531
|
+
* - ScalingMode.None: Fill space, may have sub-pixel artifacts
|
|
532
|
+
* - ScalingMode.Eighth: Snap to 0.125 increments (1.0, 1.125, 1.25...)
|
|
533
|
+
* - ScalingMode.Quarter: Snap to 0.25 increments (1.0, 1.25, 1.5...)
|
|
534
|
+
* - ScalingMode.Half: Snap to 0.5 increments (1.0, 1.5, 2.0...)
|
|
535
|
+
* - ScalingMode.Integer: Crisp pixels, may waste space (1x, 2x, 3x...)
|
|
536
|
+
*/
|
|
537
|
+
setScalingMode(mode: ScalingMode): void;
|
|
538
|
+
/**
|
|
539
|
+
* Get current scaling mode
|
|
540
|
+
*/
|
|
541
|
+
getScalingMode(): ScalingMode;
|
|
542
|
+
/**
|
|
543
|
+
* Enable or configure debug grid overlay
|
|
544
|
+
*
|
|
545
|
+
* The grid shows cell boundaries aligned with the terminal grid.
|
|
546
|
+
* Useful for debugging layout and alignment issues.
|
|
547
|
+
*
|
|
548
|
+
* @param config - Configuration options:
|
|
549
|
+
* - enabled: Whether to show the grid
|
|
550
|
+
* - color: CSS color string (e.g., 'rgba(255,0,0,0.5)', '#ff0000')
|
|
551
|
+
* - lineWidth: Line width in pixels (1-10)
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```typescript
|
|
555
|
+
* // Enable with default red color
|
|
556
|
+
* renderer.setGrid({ enabled: true });
|
|
557
|
+
*
|
|
558
|
+
* // Custom green grid
|
|
559
|
+
* renderer.setGrid({ enabled: true, color: 'rgba(0, 255, 0, 0.5)' });
|
|
560
|
+
*
|
|
561
|
+
* // Disable grid
|
|
562
|
+
* renderer.setGrid({ enabled: false });
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
setGrid(config: {
|
|
566
|
+
enabled: boolean;
|
|
567
|
+
color?: string;
|
|
568
|
+
lineWidth?: number;
|
|
569
|
+
}): void;
|
|
570
|
+
/**
|
|
571
|
+
* Check if grid is currently enabled
|
|
572
|
+
*/
|
|
573
|
+
isGridEnabled(): boolean;
|
|
574
|
+
/**
|
|
575
|
+
* Enable or configure ambient effect
|
|
576
|
+
*
|
|
577
|
+
* Ambient effect creates a blurred glow around the terminal canvas,
|
|
578
|
+
* filling the unused space with colors from the terminal content.
|
|
579
|
+
*
|
|
580
|
+
* @param config - true to enable with defaults, false to disable,
|
|
581
|
+
* or object with blur and scale settings
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```typescript
|
|
585
|
+
* // Enable with defaults (blur: 30px, scale: 1.3)
|
|
586
|
+
* renderer.setAmbientEffect(true);
|
|
587
|
+
*
|
|
588
|
+
* // Disable
|
|
589
|
+
* renderer.setAmbientEffect(false);
|
|
590
|
+
*
|
|
591
|
+
* // Custom settings
|
|
592
|
+
* renderer.setAmbientEffect({ blur: 50, scale: 1.5 });
|
|
593
|
+
* ```
|
|
594
|
+
*/
|
|
595
|
+
setAmbientEffect(config: boolean | {
|
|
596
|
+
blur?: number;
|
|
597
|
+
scale?: number;
|
|
598
|
+
}): void;
|
|
599
|
+
/**
|
|
600
|
+
* Create the ambient effect canvas element (called lazily if needed)
|
|
601
|
+
*/
|
|
602
|
+
private createAmbientEffectCanvas;
|
|
603
|
+
/**
|
|
604
|
+
* Check if ambient effect is enabled
|
|
605
|
+
*/
|
|
606
|
+
isAmbientEffectEnabled(): boolean;
|
|
607
|
+
/**
|
|
608
|
+
* Get current ambient effect configuration
|
|
609
|
+
*/
|
|
610
|
+
getAmbientEffectConfig(): {
|
|
611
|
+
enabled: boolean;
|
|
612
|
+
blur: number;
|
|
613
|
+
scale: number;
|
|
614
|
+
};
|
|
615
|
+
/**
|
|
616
|
+
* Get number of columns (IRenderer interface)
|
|
617
|
+
*
|
|
618
|
+
* @returns Current number of columns
|
|
619
|
+
*
|
|
620
|
+
* @example
|
|
621
|
+
* ```typescript
|
|
622
|
+
* const cols = renderer.getCols(); // 80
|
|
623
|
+
* ```
|
|
624
|
+
*/
|
|
625
|
+
getCols(): number;
|
|
626
|
+
/**
|
|
627
|
+
* Get number of rows (IRenderer interface)
|
|
628
|
+
*
|
|
629
|
+
* @returns Current number of rows
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```typescript
|
|
633
|
+
* const rows = renderer.getRows(); // 25
|
|
634
|
+
* ```
|
|
635
|
+
*/
|
|
636
|
+
getRows(): number;
|
|
637
|
+
/**
|
|
638
|
+
* Check if renderer is ready (IRenderer interface)
|
|
639
|
+
*
|
|
640
|
+
* Returns true when bitmap font, atlas texture, and shader program are initialized.
|
|
641
|
+
*
|
|
642
|
+
* @returns true if ready to render, false otherwise
|
|
643
|
+
*
|
|
644
|
+
* @example
|
|
645
|
+
* ```typescript
|
|
646
|
+
* if (renderer.isReady()) {
|
|
647
|
+
* renderer.renderDisplayData(data);
|
|
648
|
+
* }
|
|
649
|
+
* ```
|
|
650
|
+
*/
|
|
651
|
+
isReady(): boolean;
|
|
652
|
+
/**
|
|
653
|
+
* Destroy/cleanup resources (IRenderer interface)
|
|
654
|
+
*
|
|
655
|
+
* Destroys WebGL resources (textures, buffers), disconnects ResizeObserver,
|
|
656
|
+
* and removes canvases from DOM. Call this before removing the renderer.
|
|
657
|
+
*
|
|
658
|
+
* @example
|
|
659
|
+
* ```typescript
|
|
660
|
+
* renderer.destroy();
|
|
661
|
+
* renderer = null;
|
|
662
|
+
* ```
|
|
663
|
+
*/
|
|
664
|
+
destroy(): void;
|
|
665
|
+
/**
|
|
666
|
+
* Cleanup resources
|
|
667
|
+
*/
|
|
668
|
+
dispose(): void;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* 🔲 GridOverlay - Classe réutilisable pour gérer le canvas de grille de débogage
|
|
673
|
+
*
|
|
674
|
+
* Gère un canvas 2D superposé qui affiche une grille de cellules.
|
|
675
|
+
* Au lieu de simples lignes, dessine un cadre fin à l'intérieur de chaque cellule
|
|
676
|
+
* pour une meilleure visualisation.
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* const grid = new GridOverlay(containerElement);
|
|
681
|
+
* grid.setDimensions(80, 24, 10, 16);
|
|
682
|
+
* grid.render();
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
declare class GridOverlay {
|
|
686
|
+
private canvas;
|
|
687
|
+
private ctx;
|
|
688
|
+
private container;
|
|
689
|
+
private cols;
|
|
690
|
+
private rows;
|
|
691
|
+
private cellWidth;
|
|
692
|
+
private cellHeight;
|
|
693
|
+
private offsetX;
|
|
694
|
+
private offsetY;
|
|
695
|
+
private strokeColor;
|
|
696
|
+
private lineWidth;
|
|
697
|
+
/**
|
|
698
|
+
* Crée une nouvelle overlay de grille
|
|
699
|
+
* @param container - Élément parent qui contiendra le canvas
|
|
700
|
+
* @param options - Options de configuration
|
|
701
|
+
*/
|
|
702
|
+
constructor(container: HTMLElement, options?: {
|
|
703
|
+
strokeColor?: string;
|
|
704
|
+
lineWidth?: number;
|
|
705
|
+
zIndex?: number;
|
|
706
|
+
});
|
|
707
|
+
/**
|
|
708
|
+
* Configure les dimensions de la grille
|
|
709
|
+
* @param cols - Nombre de colonnes
|
|
710
|
+
* @param rows - Nombre de lignes
|
|
711
|
+
* @param cellWidth - Largeur d'une cellule en pixels
|
|
712
|
+
* @param cellHeight - Hauteur d'une cellule en pixels
|
|
713
|
+
* @param offsetX - Décalage horizontal (optionnel)
|
|
714
|
+
* @param offsetY - Décalage vertical (optionnel)
|
|
715
|
+
*/
|
|
716
|
+
setDimensions(cols: number, rows: number, cellWidth: number, cellHeight: number, offsetX?: number, offsetY?: number): void;
|
|
717
|
+
/**
|
|
718
|
+
* Configure la taille physique du canvas
|
|
719
|
+
* Le canvas doit avoir la MÊME approche que le canvas principal WebGL :
|
|
720
|
+
* - Résolution physique = dimensions de base (SANS DPR)
|
|
721
|
+
* - Taille CSS = dimensions de base
|
|
722
|
+
* - Le scaling visuel est fait via transform: scale()
|
|
723
|
+
*
|
|
724
|
+
* @param baseWidth - Largeur de base en pixels
|
|
725
|
+
* @param baseHeight - Hauteur de base en pixels
|
|
726
|
+
*/
|
|
727
|
+
setCanvasSize(baseWidth: number, baseHeight: number): void;
|
|
728
|
+
/**
|
|
729
|
+
* Configure les options visuelles
|
|
730
|
+
* @param options - Options de rendu
|
|
731
|
+
*/
|
|
732
|
+
setStyle(options: {
|
|
733
|
+
strokeColor?: string;
|
|
734
|
+
lineWidth?: number;
|
|
735
|
+
}): void;
|
|
736
|
+
/**
|
|
737
|
+
* Configure la transformation et le positionnement du canvas de grille
|
|
738
|
+
* pour qu'il corresponde exactement au canvas principal (pixel-perfect scaling)
|
|
739
|
+
*
|
|
740
|
+
* APPROCHE SIMPLE : On ne fait PAS de transform: scale().
|
|
741
|
+
* On définit le canvas à la taille finale (scalée) directement,
|
|
742
|
+
* et on le positionne exactement où est le canvas principal.
|
|
743
|
+
*
|
|
744
|
+
* Le dessin de la grille doit alors être fait à l'échelle scalée.
|
|
745
|
+
*
|
|
746
|
+
* @param scale - Facteur de scale (même valeur que le canvas principal)
|
|
747
|
+
* @param baseWidth - Largeur de base du canvas (avant scale)
|
|
748
|
+
* @param baseHeight - Hauteur de base du canvas (avant scale)
|
|
749
|
+
* @param mainCanvasRect - Le getBoundingClientRect() du canvas principal
|
|
750
|
+
* @param containerRect - Le getBoundingClientRect() du container
|
|
751
|
+
*/
|
|
752
|
+
setTransform(_scale: number, _baseWidth: number, _baseHeight: number, mainCanvasRect: DOMRect, containerRect: DOMRect): void;
|
|
753
|
+
/**
|
|
754
|
+
* Dessine la grille avec des lignes fines continues
|
|
755
|
+
* Les lignes sont dessinées aux bords exacts des cellules.
|
|
756
|
+
*/
|
|
757
|
+
render(): void;
|
|
758
|
+
/**
|
|
759
|
+
* Met à jour et redessine la grille avec de nouvelles dimensions
|
|
760
|
+
* Méthode pratique qui combine setDimensions, setCanvasSize et render
|
|
761
|
+
*
|
|
762
|
+
* @param cols - Nombre de colonnes
|
|
763
|
+
* @param rows - Nombre de lignes
|
|
764
|
+
* @param cellWidth - Largeur d'une cellule
|
|
765
|
+
* @param cellHeight - Hauteur d'une cellule
|
|
766
|
+
* @param displayWidth - Largeur d'affichage du canvas
|
|
767
|
+
* @param displayHeight - Hauteur d'affichage du canvas
|
|
768
|
+
* @param offsetX - Décalage horizontal (optionnel)
|
|
769
|
+
* @param offsetY - Décalage vertical (optionnel)
|
|
770
|
+
*/
|
|
771
|
+
update(cols: number, rows: number, cellWidth: number, cellHeight: number, displayWidth: number, displayHeight: number, offsetX?: number, offsetY?: number): void;
|
|
772
|
+
/**
|
|
773
|
+
* Affiche ou cache la grille
|
|
774
|
+
* @param visible - true pour afficher, false pour cacher
|
|
775
|
+
*/
|
|
776
|
+
setVisible(visible: boolean): void;
|
|
777
|
+
/**
|
|
778
|
+
* Supprime le canvas de grille du DOM
|
|
779
|
+
*/
|
|
780
|
+
destroy(): void;
|
|
781
|
+
/**
|
|
782
|
+
* Retourne le canvas HTML
|
|
783
|
+
*/
|
|
784
|
+
getCanvas(): HTMLCanvasElement;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Default color palette (VGA colors + extended)
|
|
789
|
+
* Maps palette index to CSS color string
|
|
790
|
+
*/
|
|
791
|
+
declare const DEFAULT_PALETTE: readonly string[];
|
|
792
|
+
/**
|
|
793
|
+
* Convert a color palette index to CSS color string
|
|
794
|
+
*/
|
|
795
|
+
declare function paletteIndexToColor(index: number, palette?: readonly string[]): string;
|
|
796
|
+
/**
|
|
797
|
+
* Convert CSS color string to palette index (finds closest match)
|
|
798
|
+
*/
|
|
799
|
+
declare function colorToPaletteIndex(color: string, palette?: readonly string[]): number;
|
|
800
|
+
|
|
801
|
+
export { DEFAULT_PALETTE, GridOverlay, TerminalGL, colorToPaletteIndex, getAtlasColumns, getCharGridPosition, getMaxCharCode, paletteIndexToColor };
|
|
802
|
+
export type { AtlasBlocks, BitmapFont, TerminalGLOptions, WebGLCompatibilityReport };
|