@utsp/render 0.11.0-nightly.20251213152020.671c815 → 0.11.0-nightly.20251213232121.8b318c1

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.
@@ -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 };