@utsp/render 0.1.1

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,1058 @@
1
+ import { IRenderer, RGBColor, RenderState } from '@utsp/types';
2
+ export { IColorPalette, IRenderer, RenderState } from '@utsp/types';
3
+
4
+ /**
5
+ * Default color palette (VGA colors + extended)
6
+ * Maps palette index to CSS color string
7
+ */
8
+ declare const DEFAULT_PALETTE: readonly string[];
9
+ /**
10
+ * Convert a color palette index to CSS color string
11
+ */
12
+ declare function paletteIndexToColor(index: number, palette?: readonly string[]): string;
13
+ /**
14
+ * Convert CSS color string to palette index (finds closest match)
15
+ */
16
+ declare function colorToPaletteIndex(color: string, palette?: readonly string[]): number;
17
+
18
+ /**
19
+ * Représente une cellule du terminal
20
+ */
21
+ interface TerminalCell {
22
+ /** Le caractère à afficher */
23
+ char: string;
24
+ /** Couleur du caractère (format CSS) */
25
+ fgColor: string;
26
+ /** Couleur de fond de la cellule (format CSS) */
27
+ bgColor: string;
28
+ }
29
+ /**
30
+ * Données brutes pour définir le terminal en une fois
31
+ */
32
+ interface TerminalData {
33
+ /** Largeur en cellules */
34
+ width: number;
35
+ /** Hauteur en cellules */
36
+ height: number;
37
+ /** Tableau de cellules (longueur = width * height) */
38
+ cells: Array<{
39
+ /** Code du caractère ou le caractère lui-même */
40
+ char: string;
41
+ /** Couleur du texte (format CSS) */
42
+ fgColor: string;
43
+ /** Couleur de fond (format CSS) */
44
+ bgColor: string;
45
+ }>;
46
+ }
47
+ /**
48
+ * Police bitmap matricielle
49
+ * Map qui associe un code de caractère (charCode) à une représentation bitmap 8x8
50
+ * Chaque Uint8Array contient 8 octets, un par ligne de pixels
51
+ */
52
+ type BitmapFont$1 = Map<number, Uint8Array>;
53
+ /**
54
+ * Type de police à utiliser
55
+ */
56
+ type FontType = {
57
+ type: 'web';
58
+ fontFamily: string;
59
+ fontSize: number;
60
+ } | {
61
+ type: 'bitmap';
62
+ font: BitmapFont$1;
63
+ charWidth: number;
64
+ charHeight: number;
65
+ };
66
+ /**
67
+ * Options pour la configuration du terminal
68
+ */
69
+ interface RenderOptions {
70
+ /** Largeur d'une cellule en pixels (défaut: 10) - ignoré en mode fixedGrid */
71
+ cellWidth?: number;
72
+ /** Hauteur d'une cellule en pixels (défaut: 14) - ignoré en mode fixedGrid */
73
+ cellHeight?: number;
74
+ /** Taille de la police en pixels (défaut: 12) */
75
+ fontSize?: number;
76
+ /** Famille de police (défaut: "monospace") */
77
+ fontFamily?: string;
78
+ /** Couleur de texte par défaut (défaut: "#ffffff") */
79
+ defaultFgColor?: string;
80
+ /** Couleur de fond par défaut (défaut: "#000000") */
81
+ defaultBgColor?: string;
82
+ /** Couleur de fond du canvas lui-même (défaut: transparent). Si null ou undefined, le canvas sera transparent */
83
+ canvasBgColor?: string | null;
84
+ /** Afficher une grille de débogage (défaut: false) */
85
+ showDebugGrid?: boolean;
86
+ /** Couleur de la grille de débogage (défaut: "rgba(255, 0, 0, 0.3)") */
87
+ debugGridColor?: string;
88
+ /** Classes CSS additionnelles pour le canvas */
89
+ className?: string;
90
+ /** Style inline pour le canvas */
91
+ style?: Partial<CSSStyleDeclaration>;
92
+ /** Nombre de colonnes fixe (active le mode fixedGrid) */
93
+ fixedCols?: number;
94
+ /** Nombre de lignes fixe (active le mode fixedGrid) */
95
+ fixedRows?: number;
96
+ /** Ratio largeur/hauteur de cellule pour mode fixedGrid (défaut: 10/14 ≈ 0.714) */
97
+ cellAspectRatio?: number;
98
+ }
99
+ /**
100
+ * UTSP Render - Gère une grille de caractères avec couleurs
101
+ * Similaire à un terminal mais avec contrôle total de chaque cellule
102
+ *
103
+ * Implements IRenderer interface for compatibility with TerminalGL and dependency injection.
104
+ */
105
+ declare class Terminal2D implements IRenderer {
106
+ private canvas;
107
+ private ctx;
108
+ private parentElement;
109
+ private cells;
110
+ private cols;
111
+ private rows;
112
+ private fontSize;
113
+ private fontFamily;
114
+ private defaultFgColor;
115
+ private defaultBgColor;
116
+ private canvasBgColor;
117
+ private cellWidth;
118
+ private cellHeight;
119
+ private offsetX;
120
+ private offsetY;
121
+ private fontType;
122
+ private bitmapFont?;
123
+ private bitmapAtlas?;
124
+ private bitmapCharWidth;
125
+ private bitmapCharHeight;
126
+ private showDebugGrid;
127
+ private debugGridColor;
128
+ private gridOverlay?;
129
+ private fixedGridMode;
130
+ private fixedCols?;
131
+ private fixedRows?;
132
+ private cellAspectRatio;
133
+ private resizeObserver?;
134
+ private imageDataBuffer?;
135
+ private useImageDataRendering;
136
+ private paletteCache?;
137
+ /**
138
+ * Crée une instance de UTSPRender
139
+ * @param parentDiv - L'élément HTML parent dans lequel créer le canvas
140
+ * @param options - Options de configuration du terminal
141
+ */
142
+ constructor(parentDiv: HTMLElement, options?: RenderOptions);
143
+ /**
144
+ * Calcule le nombre de colonnes et de lignes en fonction de la taille du parent
145
+ * et centre le terminal dans le canvas
146
+ */
147
+ private calculateGridSize;
148
+ /**
149
+ * Crée une grille vide avec les valeurs par défaut
150
+ */
151
+ private createEmptyGrid;
152
+ /**
153
+ * Active le redimensionnement automatique
154
+ * Recalcule le nombre de colonnes/lignes quand le parent change de taille
155
+ */
156
+ private enableAutoResize;
157
+ /**
158
+ * Définit le contenu d'une cellule
159
+ * @param col - Colonne (0-indexed)
160
+ * @param row - Ligne (0-indexed)
161
+ * @param char - Caractère à afficher
162
+ * @param fgColor - Couleur du texte (optionnel, utilise la valeur par défaut si non fourni)
163
+ * @param bgColor - Couleur de fond (optionnel, utilise la valeur par défaut si non fourni)
164
+ */
165
+ setCell(col: number, row: number, char: string, fgColor?: string, bgColor?: string): void;
166
+ /**
167
+ * Récupère le contenu d'une cellule
168
+ * @param col - Colonne (0-indexed)
169
+ * @param row - Ligne (0-indexed)
170
+ */
171
+ getCell(col: number, row: number): TerminalCell | null;
172
+ /**
173
+ * Écrit une chaîne de caractères à partir d'une position
174
+ * @param col - Colonne de départ
175
+ * @param row - Ligne
176
+ * @param text - Texte à écrire
177
+ * @param fgColor - Couleur du texte (optionnel)
178
+ * @param bgColor - Couleur de fond (optionnel)
179
+ */
180
+ write(col: number, row: number, text: string, fgColor?: string, bgColor?: string): void;
181
+ /**
182
+ * Remplit une zone rectangulaire
183
+ * @param startCol - Colonne de départ
184
+ * @param startRow - Ligne de départ
185
+ * @param width - Largeur en cellules
186
+ * @param height - Hauteur en cellules
187
+ * @param char - Caractère de remplissage
188
+ * @param fgColor - Couleur du texte (optionnel)
189
+ * @param bgColor - Couleur de fond (optionnel)
190
+ */
191
+ fillRect(startCol: number, startRow: number, width: number, height: number, char?: string, fgColor?: string, bgColor?: string): void;
192
+ /**
193
+ * Efface tout le terminal (remplit avec des espaces)
194
+ */
195
+ clear(): void;
196
+ /**
197
+ * Définit tout le contenu du terminal à partir d'un tableau de données
198
+ * Le tableau doit contenir width * height éléments
199
+ * Les cellules sont lues ligne par ligne (row-major order)
200
+ *
201
+ * @param data - Données du terminal avec dimensions et cellules
202
+ * @throws Error si le tableau n'a pas la bonne taille
203
+ *
204
+ * @example
205
+ * terminal.setFromArray({
206
+ * width: 3,
207
+ * height: 2,
208
+ * cells: [
209
+ * { char: 'A', fgColor: '#ff0000', bgColor: '#000000' }, // (0,0)
210
+ * { char: 'B', fgColor: '#00ff00', bgColor: '#000000' }, // (1,0)
211
+ * { char: 'C', fgColor: '#0000ff', bgColor: '#000000' }, // (2,0)
212
+ * { char: 'D', fgColor: '#ffff00', bgColor: '#000000' }, // (0,1)
213
+ * { char: 'E', fgColor: '#ff00ff', bgColor: '#000000' }, // (1,1)
214
+ * { char: 'F', fgColor: '#00ffff', bgColor: '#000000' }, // (2,1)
215
+ * ]
216
+ * });
217
+ */
218
+ setFromArray(data: TerminalData): void;
219
+ /**
220
+ * Rend la grille sur le canvas
221
+ */
222
+ render(): void;
223
+ /**
224
+ * Rendu ultra-rapide avec ImageData (bitmap)
225
+ * ~10-20× plus rapide que fillRect en boucle
226
+ * Fonctionne avec scaling : buffer natif 8×8 puis drawImage() pour upscale
227
+ */
228
+ private renderWithImageData;
229
+ /**
230
+ * Parse une couleur CSS en composantes RGBA
231
+ */
232
+ private parseColorToRGB;
233
+ /**
234
+ * Rendu classique avec fillRect/fillText (compatible scaling, web fonts, etc.)
235
+ */
236
+ private renderClassic;
237
+ /**
238
+ * Dessine un caractère en utilisant une police bitmap
239
+ */
240
+ private drawBitmapChar;
241
+ /**
242
+ * Dessine une grille de débogage pour visualiser les cellules
243
+ */
244
+ private drawDebugGrid;
245
+ /**
246
+ * Obtient le canvas HTML
247
+ */
248
+ getCanvas(): HTMLCanvasElement;
249
+ /**
250
+ * Obtient le contexte 2D
251
+ */
252
+ getContext(): CanvasRenderingContext2D;
253
+ /**
254
+ * Obtient les dimensions de la grille
255
+ */
256
+ getDimensions(): {
257
+ cols: number;
258
+ rows: number;
259
+ };
260
+ /**
261
+ * Obtient les dimensions des cellules
262
+ */
263
+ getCellDimensions(): {
264
+ cellWidth: number;
265
+ cellHeight: number;
266
+ };
267
+ /**
268
+ * Obtient la largeur d'une cellule
269
+ */
270
+ getCellWidth(): number;
271
+ /**
272
+ * Obtient la hauteur d'une cellule
273
+ */
274
+ getCellHeight(): number;
275
+ /**
276
+ * Obtient les décalages de centrage du terminal
277
+ */
278
+ getOffsets(): {
279
+ offsetX: number;
280
+ offsetY: number;
281
+ };
282
+ /**
283
+ * Active ou désactive la grille de débogage
284
+ * @param show - true pour afficher la grille, false pour la masquer
285
+ */
286
+ setDebugGrid(show: boolean): void;
287
+ /**
288
+ * Change la couleur de fond du canvas
289
+ * @param color - Couleur CSS (ex: "#000000", "rgba(0,0,0,0.5)") ou null pour transparent
290
+ */
291
+ setCanvasBackgroundColor(color: string | null): void;
292
+ /**
293
+ * Obtient la couleur de fond actuelle du canvas
294
+ * @returns La couleur de fond ou null si transparent
295
+ */
296
+ getCanvasBackgroundColor(): string | null;
297
+ /**
298
+ * Active le mode grille fixe avec le nombre de colonnes/lignes spécifié
299
+ * Les cellules s'adapteront en taille pour maintenir les dimensions demandées
300
+ * @param cols - Nombre de colonnes fixe
301
+ * @param rows - Nombre de lignes fixe
302
+ * @param aspectRatio - Ratio largeur/hauteur de cellule (optionnel, défaut: 10/14)
303
+ */
304
+ setFixedGrid(cols: number, rows: number, aspectRatio?: number): void;
305
+ /**
306
+ * Désactive le mode grille fixe et revient au mode adaptatif
307
+ * @param cellWidth - Largeur de cellule en pixels (optionnel)
308
+ * @param cellHeight - Hauteur de cellule en pixels (optionnel)
309
+ */
310
+ setAdaptiveGrid(cellWidth?: number, cellHeight?: number): void;
311
+ /**
312
+ * Vérifie si le terminal est en mode grille fixe
313
+ */
314
+ isFixedGridMode(): boolean;
315
+ /**
316
+ * Définit la couleur de la grille de débogage
317
+ * @param color - Couleur CSS (ex: "rgba(255, 0, 0, 0.3)" ou "#ff0000")
318
+ */
319
+ setDebugGridColor(color: string): void;
320
+ /**
321
+ * Vérifie si la grille de débogage est activée
322
+ */
323
+ isDebugGridEnabled(): boolean;
324
+ /**
325
+ * Active ou désactive le rendu optimisé avec ImageData
326
+ * Uniquement disponible pour les polices bitmap à taille native (pas de scaling)
327
+ * Environ 10-20× plus rapide que le rendu classique, idéal pour les benchmarks
328
+ *
329
+ * @param enable - true pour activer, false pour désactiver
330
+ */
331
+ setImageDataRendering(enable: boolean): void;
332
+ /**
333
+ * Vérifie si le rendu ImageData est activé
334
+ */
335
+ isImageDataRenderingEnabled(): boolean;
336
+ /**
337
+ * Configure une police web (CSS)
338
+ * @param fontFamily - Nom de la police CSS (ex: "Courier New", "monospace")
339
+ * @param fontSize - Taille de la police en pixels (optionnel, garde la taille actuelle si non spécifié)
340
+ */
341
+ setWebFont(fontFamily: string, fontSize?: number): void;
342
+ /**
343
+ * Configure une police bitmap matricielle
344
+ * @param font - Map contenant les définitions bitmap des caractères (charCode -> Uint8Array)
345
+ * @param charWidth - Largeur du glyphe en pixels (bitmap source)
346
+ * @param charHeight - Hauteur du glyphe en pixels (bitmap source)
347
+ * @param cellWidth - Largeur de la cellule de rendu en pixels
348
+ * @param cellHeight - Hauteur de la cellule de rendu en pixels
349
+ */
350
+ setBitmapFont(font: BitmapFont$1, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void;
351
+ /**
352
+ * Retourne le type de police actuellement utilisé
353
+ */
354
+ getFontType(): 'web' | 'bitmap';
355
+ /**
356
+ * Retourne la police bitmap actuelle (si applicable)
357
+ */
358
+ getBitmapFont(): BitmapFont$1 | undefined;
359
+ /**
360
+ * Retourne les dimensions de caractère bitmap (si applicable)
361
+ */
362
+ getBitmapCharDimensions(): {
363
+ width: number;
364
+ height: number;
365
+ } | null;
366
+ /**
367
+ * Set color palette (IRenderer contract).
368
+ * Called by ClientRuntime when Core palette changes.
369
+ *
370
+ * @param palette - Array of 256 RGBA colors
371
+ */
372
+ setPalette(palette: RGBColor[]): void;
373
+ /**
374
+ * Render display data (IRenderer contract).
375
+ * Converts RenderState from Core to cell-based rendering.
376
+ *
377
+ * @param display - Display data with palette indices
378
+ */
379
+ renderDisplayData(display: RenderState): void;
380
+ /**
381
+ * Check if renderer is ready to render (IRenderer contract).
382
+ * Canvas 2D is always ready immediately (no async initialization).
383
+ *
384
+ * @returns Always true for Canvas 2D
385
+ */
386
+ isReady(): boolean;
387
+ /**
388
+ * Get width in columns (IRenderer contract).
389
+ */
390
+ getCols(): number;
391
+ /**
392
+ * Get height in rows (IRenderer contract).
393
+ */
394
+ getRows(): number;
395
+ /**
396
+ * Resize renderer dimensions (IRenderer contract).
397
+ *
398
+ * @param cols - New width in columns
399
+ * @param rows - New height in rows
400
+ */
401
+ resize(cols: number, rows: number): void;
402
+ /**
403
+ * Détruit le terminal et nettoie les ressources
404
+ */
405
+ destroy(): void;
406
+ }
407
+
408
+ /**
409
+ * WebGL compatibility report
410
+ */
411
+ interface WebGLCompatibilityReport {
412
+ /** WebGL 1.0 support */
413
+ webgl1: boolean;
414
+ /** OES_element_index_uint extension (Uint32 indices) */
415
+ uint32Indices: boolean;
416
+ /** Maximum texture size */
417
+ maxTextureSize: number;
418
+ /** Maximum viewport dimensions */
419
+ maxViewportDims: [number, number];
420
+ /** Maximum terminal size with Uint16 indices (cols × rows) */
421
+ maxCellsUint16: number;
422
+ /** Maximum terminal size with Uint32 indices (cols × rows) */
423
+ maxCellsUint32: number;
424
+ /** Recommended maximum terminal size for this device */
425
+ recommendedMaxCells: number;
426
+ /** Warnings (empty if fully compatible) */
427
+ warnings: string[];
428
+ /** Errors (empty if compatible) */
429
+ errors: string[];
430
+ }
431
+ /**
432
+ * Options for WebGL terminal configuration
433
+ */
434
+ interface TerminalGLOptions {
435
+ /** Number of columns (required) */
436
+ cols: number;
437
+ /** Number of rows (required) */
438
+ rows: number;
439
+ /** Character width in pixels */
440
+ charWidth?: number;
441
+ /** Character height in pixels */
442
+ charHeight?: number;
443
+ /** Canvas background color (CSS format, for gl.clearColor) */
444
+ canvasBgColor?: string | null;
445
+ /** Show cell delimitation grid (debug) */
446
+ showGrid?: boolean;
447
+ /** Force Uint16 indices (for compatibility testing, auto-detected by default) */
448
+ forceUint16?: boolean;
449
+ }
450
+ /**
451
+ * Simplified terminal using WebGL for basic rendering
452
+ * Only supports bitmap fonts with atlas
453
+ * Implements IRenderer interface for dependency injection with core
454
+ *
455
+ * ✨ SIMPLIFIED VERSION: Only backgrounds + colored characters
456
+ */
457
+ declare class TerminalGL implements IRenderer {
458
+ /**
459
+ * Check WebGL 1.0 compatibility and device capabilities
460
+ *
461
+ * Tests all required WebGL features and returns a detailed compatibility report.
462
+ * Use this before creating a TerminalGL instance to ensure device support.
463
+ *
464
+ * @returns Detailed compatibility report with warnings and errors
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * const report = TerminalGL.checkCompatibility();
469
+ * if (report.errors.length > 0) {
470
+ * console.error('WebGL not supported:', report.errors);
471
+ * // Fallback to Canvas 2D renderer
472
+ * } else if (report.warnings.length > 0) {
473
+ * console.warn('WebGL limitations:', report.warnings);
474
+ * }
475
+ * console.log(`Max terminal size: ${report.recommendedMaxCells} cells`);
476
+ * ```
477
+ */
478
+ static checkCompatibility(): WebGLCompatibilityReport;
479
+ private canvas;
480
+ private gl;
481
+ private parentElement;
482
+ private containerDiv;
483
+ private cols;
484
+ private rows;
485
+ private charWidth;
486
+ private charHeight;
487
+ private cellWidth;
488
+ private cellHeight;
489
+ private glyphOffsetX;
490
+ private glyphOffsetY;
491
+ private canvasBgColor;
492
+ private showGrid;
493
+ private supportsUint32Indices;
494
+ private useUint16Indices;
495
+ private gridOverlay?;
496
+ private bitmapFont?;
497
+ private atlasTexture;
498
+ private atlasCanvas?;
499
+ private atlasColumns;
500
+ private paletteTexture;
501
+ private program;
502
+ private positionBuffer;
503
+ private texCoordBuffer;
504
+ private colorIndexBuffer;
505
+ private indexBuffer;
506
+ private aPosition?;
507
+ private aTexCoord?;
508
+ private aColorIndex?;
509
+ private uResolution;
510
+ private uTexture;
511
+ private uPalette;
512
+ private resizeObserver?;
513
+ private charCodeToAtlasIndex;
514
+ private atlasUVs;
515
+ private cachedAtlasWidth;
516
+ private cachedAtlasHeight;
517
+ private paletteFloat;
518
+ private maxCells;
519
+ private renderPositions;
520
+ private renderTexCoords;
521
+ private renderColorIndices;
522
+ private renderIndices;
523
+ private cachedResolution;
524
+ private cachedTextureUnit;
525
+ private cachedPaletteUnit;
526
+ private cachedTextureUniform;
527
+ private cachedPaletteUniform;
528
+ private paletteHash;
529
+ private staticPositionsInitialized;
530
+ private vaoExtension;
531
+ private vao;
532
+ private instancedExtension;
533
+ private useInstancing;
534
+ private instanceDataBuffer;
535
+ private instanceData;
536
+ private templateQuadPositions;
537
+ private templateQuadIndices;
538
+ constructor(parentDiv: HTMLDivElement, options: TerminalGLOptions);
539
+ /**
540
+ * 🚀 INSTANCING: Initialize template quad and instance buffers
541
+ * Called once at init if instancing is supported
542
+ */
543
+ private initInstancedBuffers;
544
+ /**
545
+ * 🚀 OPTIMIZATION: Initialize pre-allocated buffers for rendering
546
+ * Avoids allocations each frame
547
+ * Uses Uint16 or Uint32 indices based on device support
548
+ */
549
+ private initRenderBuffers;
550
+ /**
551
+ * 🚀 MEGA OPTIMIZATION: Pre-compute static positions for ALL possible quads
552
+ * Called only once after font load, or after resize
553
+ * Positions never change during rendering - only colors and UVs change!
554
+ */
555
+ private precomputeStaticPositions;
556
+ /**
557
+ * Initialize WebGL (shaders, buffers, etc.)
558
+ */
559
+ private initWebGL;
560
+ /**
561
+ * Compile a shader
562
+ */
563
+ private compileShader;
564
+ /**
565
+ * 🔲 Initialize 2D canvas overlay for debug grid
566
+ * Performance: 2D canvas drawn only once, 0ms per frame
567
+ */
568
+ private initGridOverlay;
569
+ /**
570
+ * 🔲 Draw grid lines on 2D canvas overlay
571
+ * Called only once at init and resize
572
+ */
573
+ private updateGridOverlay;
574
+ /**
575
+ * Configure bitmap font and generate atlas
576
+ *
577
+ * ⚠️ **INTERNAL USE ONLY** - This method is called automatically by ClientRuntime's
578
+ * event system when Core.loadBitmapFontById() is called. Do NOT call this directly
579
+ * unless you're implementing a custom runtime.
580
+ *
581
+ * Event flow: Core.loadBitmapFontById() → Core.onBitmapFontChangedCallback
582
+ * → ClientRuntime.onCoreBitmapFontChanged() → RendererManager.setBitmapFont()
583
+ *
584
+ * @param font - Bitmap font mapping (charCode → byte array)
585
+ * @param charWidth - Width of each character in pixels
586
+ * @param charHeight - Height of each character in pixels
587
+ * @param cellWidth - Width of each cell in pixels
588
+ * @param cellHeight - Height of each cell in pixels
589
+ * @throws {Error} If atlas generation fails
590
+ *
591
+ * @example
592
+ * ```typescript
593
+ * // ❌ DON'T: Call setBitmapFont directly
594
+ * renderer.setBitmapFont(font, 8, 16, 8, 16);
595
+ *
596
+ * // ✅ DO: Use Core's loadBitmapFontById (triggers event automatically)
597
+ * core.loadBitmapFontById(1, {
598
+ * charWidth: 8, charHeight: 16,
599
+ * cellWidth: 8, cellHeight: 16,
600
+ * glyphs: new Map([[65, new Uint8Array([...])]])
601
+ * });
602
+ * ```
603
+ */
604
+ setBitmapFont(font: BitmapFont$1, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void;
605
+ /**
606
+ * Generate texture atlas from bitmap font
607
+ */
608
+ private generateAtlas;
609
+ /**
610
+ * 🚀 OPTIMIZED: Build charCode → atlas index using direct array lookup
611
+ */
612
+ private buildCharCodeMap;
613
+ /**
614
+ * 🚀 MEGA OPTIMIZATION: Pre-compute ALL atlas UVs
615
+ * Called once after atlas generation - UVs never change!
616
+ * Eliminates per-frame division and modulo operations
617
+ */
618
+ private precomputeAtlasUVs;
619
+ /**
620
+ * Create WebGL texture from atlas
621
+ */
622
+ private createAtlasTexture;
623
+ /**
624
+ * Clear entire terminal
625
+ *
626
+ * Clears the WebGL canvas. Note: Actual terminal content clearing is handled
627
+ * by Core's RenderState, not by this renderer.
628
+ *
629
+ * @example
630
+ * ```typescript
631
+ * renderer.clear();
632
+ * ```
633
+ */
634
+ clear(): void;
635
+ /**
636
+ * Parse CSS color to normalized RGBA (0-1)
637
+ */
638
+ private parseColor;
639
+ /**
640
+ * Configure ResizeObserver to adapt canvas
641
+ */
642
+ private setupResizeObserver;
643
+ /**
644
+ * Update canvas display size
645
+ *
646
+ * 🎯 PIXEL PERFECT: Forces display dimensions to be exact multiples of cell size
647
+ * to avoid sub-pixel rendering artifacts (like Terminal2D does).
648
+ *
649
+ * Strategy: Keep canvas internal resolution fixed at base size (cols × cellWidth),
650
+ * and use CSS scaling with image-rendering: pixelated for integer upscaling.
651
+ */
652
+ private updateCanvasSize;
653
+ /**
654
+ * Set color palette and upload to GPU
655
+ *
656
+ * ⚠️ IMPORTANT: This is the ONLY way to update the palette.
657
+ * Typically called automatically by ClientRuntime via Core.onPaletteChanged() event.
658
+ * Do NOT call this directly unless you know what you're doing.
659
+ *
660
+ * @param palette - Array of 256 RGB colors
661
+ *
662
+ * @example
663
+ * ```typescript
664
+ * // ✅ Normal usage: Core handles this automatically
665
+ * core.loadPalette([...]);
666
+ * // → Core emits event
667
+ * // → ClientRuntime receives event
668
+ * // → renderer.setPalette() called automatically
669
+ *
670
+ * // ⚠️ Manual usage (advanced):
671
+ * const myPalette: RGBColor[] = [
672
+ * { r: 0, g: 0, b: 0, a: 255 }, // Color 0: Black
673
+ * { r: 255, g: 0, b: 0, a: 255 }, // Color 1: Red
674
+ * // ... 254 more colors
675
+ * ];
676
+ * renderer.setPalette(myPalette);
677
+ * ```
678
+ */
679
+ setPalette(palette: RGBColor[]): void;
680
+ /**
681
+ * 🚀 GPU OPTIMIZATION: Upload palette to GPU texture (256×1 RGBA)
682
+ */
683
+ private updatePaletteTexture;
684
+ /**
685
+ * Render display data from core engine (ULTRA-OPTIMIZED)
686
+ *
687
+ * Bypasses internal cells and renders directly from RenderState for maximum performance.
688
+ * Uses GPU palette texture lookup to minimize CPU→GPU bandwidth (4× reduction).
689
+ *
690
+ * @param data - Render state containing cells, dimensions, and palette
691
+ *
692
+ * @example
693
+ * ```typescript
694
+ * const renderState: RenderState = {
695
+ * cells: [...],
696
+ * width: 80,
697
+ * height: 25,
698
+ * palette: [...]
699
+ * };
700
+ * renderer.renderDisplayData(renderState);
701
+ * ```
702
+ */
703
+ renderDisplayData(data: RenderState): void;
704
+ /**
705
+ * 🚀 NEW METHOD: Render directly from RenderState
706
+ * Bypass this.cells for maximum performance
707
+ */
708
+ private renderDirect;
709
+ /**
710
+ * 🚀 INSTANCED RENDERING: 1 draw call for entire terminal
711
+ * MASSIVE performance boost - reduces draw calls from cols×rows×2 to just 1!
712
+ */
713
+ private renderInstanced;
714
+ /**
715
+ * 🚀 ULTRA-OPTIMIZED: Update ONLY dynamic data (colors + UVs)
716
+ * Positions are static and pre-computed - only updated on resize!
717
+ * This is a MASSIVE performance win - positions never change during normal rendering
718
+ */
719
+ private renderDirectBuffers;
720
+ /**
721
+ * Resize the terminal dimensions
722
+ *
723
+ * Changes the number of columns and rows. Preserves existing cell content
724
+ * where possible. Reallocates render buffers if needed.
725
+ *
726
+ * @param cols - New number of columns (must be positive integer)
727
+ * @param rows - New number of rows (must be positive integer)
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * renderer.resize(120, 40); // Resize to 120×40
732
+ * ```
733
+ */
734
+ resize(cols: number, rows: number): void;
735
+ /**
736
+ * Get canvas element
737
+ */
738
+ getCanvas(): HTMLCanvasElement;
739
+ /**
740
+ * Get grid dimensions
741
+ */
742
+ getGridSize(): {
743
+ cols: number;
744
+ rows: number;
745
+ };
746
+ /**
747
+ * Get cell width
748
+ */
749
+ getCellWidth(): number;
750
+ /**
751
+ * Get cell height
752
+ */
753
+ getCellHeight(): number;
754
+ /**
755
+ * Get number of columns (IRenderer interface)
756
+ *
757
+ * @returns Current number of columns
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * const cols = renderer.getCols(); // 80
762
+ * ```
763
+ */
764
+ getCols(): number;
765
+ /**
766
+ * Get number of rows (IRenderer interface)
767
+ *
768
+ * @returns Current number of rows
769
+ *
770
+ * @example
771
+ * ```typescript
772
+ * const rows = renderer.getRows(); // 25
773
+ * ```
774
+ */
775
+ getRows(): number;
776
+ /**
777
+ * Check if renderer is ready (IRenderer interface)
778
+ *
779
+ * Returns true when bitmap font, atlas texture, and shader program are initialized.
780
+ *
781
+ * @returns true if ready to render, false otherwise
782
+ *
783
+ * @example
784
+ * ```typescript
785
+ * if (renderer.isReady()) {
786
+ * renderer.renderDisplayData(data);
787
+ * }
788
+ * ```
789
+ */
790
+ isReady(): boolean;
791
+ /**
792
+ * Destroy/cleanup resources (IRenderer interface)
793
+ *
794
+ * Destroys WebGL resources (textures, buffers), disconnects ResizeObserver,
795
+ * and removes canvases from DOM. Call this before removing the renderer.
796
+ *
797
+ * @example
798
+ * ```typescript
799
+ * renderer.destroy();
800
+ * renderer = null;
801
+ * ```
802
+ */
803
+ destroy(): void;
804
+ /**
805
+ * Cleanup resources
806
+ */
807
+ dispose(): void;
808
+ }
809
+
810
+ /**
811
+ * Police bitmap matricielle
812
+ * Map qui associe un code de caractère (charCode) à une représentation bitmap
813
+ */
814
+ type BitmapFont = Map<number, Uint8Array>;
815
+ /**
816
+ * Atlas à une résolution spécifique
817
+ */
818
+ interface AtlasResolution {
819
+ canvas: HTMLCanvasElement;
820
+ ctx: CanvasRenderingContext2D;
821
+ scale: number;
822
+ charWidth: number;
823
+ charHeight: number;
824
+ }
825
+ /**
826
+ * Classe pour générer et gérer un atlas de police bitmap multi-résolution
827
+ * Convertit une police matricielle (bits) en plusieurs textures canvas à différentes échelles
828
+ * pour un rendu ultra-rapide avec qualité optimale quelque soit le zoom
829
+ *
830
+ * Utilise un cache LRU de glyphes colorés pour éviter la re-colorisation
831
+ */
832
+ declare class BitmapFontAtlas {
833
+ private atlases;
834
+ private charMap;
835
+ private baseCharWidth;
836
+ private baseCharHeight;
837
+ private baseCellWidth;
838
+ private baseCellHeight;
839
+ private atlasColumns;
840
+ private font;
841
+ private readonly SCALES;
842
+ private colorCache;
843
+ private readonly MAX_CACHE_SIZE;
844
+ /**
845
+ * Construit un atlas de police bitmap multi-résolution
846
+ * @param font La police bitmap source
847
+ * @param charWidth Largeur de base d'un caractère en pixels (taille du glyphe dans l'atlas)
848
+ * @param charHeight Hauteur de base d'un caractère en pixels (taille du glyphe dans l'atlas)
849
+ * @param cellWidth Largeur de base d'une cellule en pixels (peut être > charWidth pour l'espacement)
850
+ * @param cellHeight Hauteur de base d'une cellule en pixels (peut être > charHeight pour l'espacement)
851
+ */
852
+ constructor(font: BitmapFont, charWidth: number, charHeight: number, cellWidth?: number, cellHeight?: number); /**
853
+ * Génère les 4 atlas à différentes résolutions (1x, 2x, 4x, 8x)
854
+ * Très rapide: ~4-8ms pour 256 caractères × 4 résolutions
855
+ */
856
+ private generateAtlases;
857
+ /**
858
+ * Récupère ou crée un atlas pour une échelle donnée
859
+ */
860
+ private getOrCreateAtlas;
861
+ /**
862
+ * Rend un caractère bitmap dans un atlas à une résolution donnée
863
+ * Utilise fillRect pour un rendu ultra-rapide
864
+ */
865
+ private renderBitmapToAtlas;
866
+ /**
867
+ * Dessine un caractère en utilisant le cache de glyphes colorés
868
+ * Ultra-rapide: 1 seul drawImage() par caractère
869
+ * Utilise ImageData pour coloriser + Canvas cache pour éviter la re-colorisation
870
+ *
871
+ * @param ctx - Contexte de destination
872
+ * @param charCode - Code du caractère à dessiner
873
+ * @param x - Position X de destination (coin de la cellule)
874
+ * @param y - Position Y de destination (coin de la cellule)
875
+ * @param width - Largeur de la cellule de destination
876
+ * @param height - Hauteur de la cellule de destination
877
+ * @param color - Couleur du caractère (format CSS)
878
+ */
879
+ drawChar(ctx: CanvasRenderingContext2D, charCode: number, x: number, y: number, width: number, height: number, color: string): void;
880
+ /**
881
+ * Crée un glyphe colorisé à partir de l'atlas blanc
882
+ * Utilise ImageData pour une colorisation ultra-rapide
883
+ */
884
+ private createColoredGlyph;
885
+ /**
886
+ * Convertit une couleur hex en RGB
887
+ */
888
+ private hexToRgb;
889
+ /**
890
+ * Élimine les entrées les moins récemment utilisées du cache (LRU)
891
+ */
892
+ private evictLRU;
893
+ /**
894
+ * Retourne le canvas d'atlas pour une résolution donnée (pour débogage/visualisation)
895
+ * Par défaut retourne l'atlas 1x
896
+ */
897
+ getAtlasCanvas(scale?: number): HTMLCanvasElement | undefined;
898
+ /**
899
+ * Retourne tous les atlas disponibles
900
+ */
901
+ getAllAtlases(): Map<number, AtlasResolution>;
902
+ /**
903
+ * Retourne les dimensions de base d'un caractère
904
+ */
905
+ getCharDimensions(): {
906
+ width: number;
907
+ height: number;
908
+ };
909
+ /**
910
+ * Retourne le nombre de caractères dans l'atlas
911
+ */
912
+ getCharCount(): number;
913
+ /**
914
+ * Vérifie si un caractère existe dans l'atlas
915
+ */
916
+ hasChar(charCode: number): boolean;
917
+ /**
918
+ * Retourne les dimensions d'un atlas à une résolution donnée
919
+ */
920
+ getAtlasDimensions(scale?: number): {
921
+ width: number;
922
+ height: number;
923
+ } | undefined;
924
+ /**
925
+ * Exporte un atlas en Data URL (pour débogage)
926
+ * Permet de visualiser l'atlas ou de le sauvegarder
927
+ */
928
+ toDataURL(scale?: number, type?: string): string | undefined;
929
+ /**
930
+ * Retourne les statistiques du cache de glyphes colorés
931
+ */
932
+ getCacheStats(): {
933
+ size: number;
934
+ maxSize: number;
935
+ hitRate?: number;
936
+ };
937
+ /**
938
+ * Vide le cache de glyphes colorés
939
+ */
940
+ clearCache(): void;
941
+ /**
942
+ * Libère les ressources
943
+ */
944
+ destroy(): void;
945
+ }
946
+
947
+ /**
948
+ * 🔲 GridOverlay - Classe réutilisable pour gérer le canvas de grille de débogage
949
+ *
950
+ * Gère un canvas 2D superposé qui affiche une grille de cellules.
951
+ * Au lieu de simples lignes, dessine un cadre fin à l'intérieur de chaque cellule
952
+ * pour une meilleure visualisation.
953
+ *
954
+ * @example
955
+ * ```typescript
956
+ * const grid = new GridOverlay(containerElement);
957
+ * grid.setDimensions(80, 24, 10, 16);
958
+ * grid.render();
959
+ * ```
960
+ */
961
+ declare class GridOverlay {
962
+ private canvas;
963
+ private ctx;
964
+ private container;
965
+ private cols;
966
+ private rows;
967
+ private cellWidth;
968
+ private cellHeight;
969
+ private offsetX;
970
+ private offsetY;
971
+ private strokeColor;
972
+ private lineWidth;
973
+ private innerPadding;
974
+ /**
975
+ * Crée une nouvelle overlay de grille
976
+ * @param container - Élément parent qui contiendra le canvas
977
+ * @param options - Options de configuration
978
+ */
979
+ constructor(container: HTMLElement, options?: {
980
+ strokeColor?: string;
981
+ lineWidth?: number;
982
+ innerPadding?: number;
983
+ zIndex?: number;
984
+ });
985
+ /**
986
+ * Configure les dimensions de la grille
987
+ * @param cols - Nombre de colonnes
988
+ * @param rows - Nombre de lignes
989
+ * @param cellWidth - Largeur d'une cellule en pixels
990
+ * @param cellHeight - Hauteur d'une cellule en pixels
991
+ * @param offsetX - Décalage horizontal (optionnel)
992
+ * @param offsetY - Décalage vertical (optionnel)
993
+ */
994
+ setDimensions(cols: number, rows: number, cellWidth: number, cellHeight: number, offsetX?: number, offsetY?: number): void;
995
+ /**
996
+ * Configure la taille physique du canvas
997
+ * Doit correspondre à la taille d'affichage du canvas principal
998
+ * @param displayWidth - Largeur d'affichage en pixels
999
+ * @param displayHeight - Hauteur d'affichage en pixels
1000
+ */
1001
+ setCanvasSize(displayWidth: number, displayHeight: number): void;
1002
+ /**
1003
+ * Configure les options visuelles
1004
+ * @param options - Options de rendu
1005
+ */
1006
+ setStyle(options: {
1007
+ strokeColor?: string;
1008
+ lineWidth?: number;
1009
+ innerPadding?: number;
1010
+ }): void;
1011
+ /**
1012
+ * Dessine la grille avec des lignes fines continues
1013
+ *
1014
+ * Dessine une grille continue sans écarts entre les cellules.
1015
+ * Les lignes sont décalées vers l'intérieur de la cellule (innerPadding)
1016
+ * pour créer un effet visuel élégant tout en gardant la grille continue.
1017
+ */
1018
+ render(): void;
1019
+ /**
1020
+ * Met à jour et redessine la grille avec de nouvelles dimensions
1021
+ * Méthode pratique qui combine setDimensions, setCanvasSize et render
1022
+ *
1023
+ * @param cols - Nombre de colonnes
1024
+ * @param rows - Nombre de lignes
1025
+ * @param cellWidth - Largeur d'une cellule
1026
+ * @param cellHeight - Hauteur d'une cellule
1027
+ * @param displayWidth - Largeur d'affichage du canvas
1028
+ * @param displayHeight - Hauteur d'affichage du canvas
1029
+ * @param offsetX - Décalage horizontal (optionnel)
1030
+ * @param offsetY - Décalage vertical (optionnel)
1031
+ */
1032
+ update(cols: number, rows: number, cellWidth: number, cellHeight: number, displayWidth: number, displayHeight: number, offsetX?: number, offsetY?: number): void;
1033
+ /**
1034
+ * Affiche ou cache la grille
1035
+ * @param visible - true pour afficher, false pour cacher
1036
+ */
1037
+ setVisible(visible: boolean): void;
1038
+ /**
1039
+ * Supprime le canvas de grille du DOM
1040
+ */
1041
+ destroy(): void;
1042
+ /**
1043
+ * Retourne le canvas HTML
1044
+ */
1045
+ getCanvas(): HTMLCanvasElement;
1046
+ }
1047
+
1048
+ /**
1049
+ * UTSP Render - Main entry point
1050
+ *
1051
+ * Terminal de caractères avec rendu WebGL optimisé
1052
+ * TerminalGL est le renderer principal - WebGL 1.0 avec palette GPU
1053
+ */
1054
+
1055
+ declare const version = "0.1.0";
1056
+
1057
+ export { BitmapFontAtlas, DEFAULT_PALETTE, GridOverlay, Terminal2D, TerminalGL, colorToPaletteIndex, paletteIndexToColor, version };
1058
+ export type { BitmapFont$1 as BitmapFont, FontType, RenderOptions, TerminalCell, TerminalData, TerminalGLOptions, WebGLCompatibilityReport };