UNPKG

@utsp/render

Version:

UTSP Render - Browser-based rendering engine for terminal graphics

1,142 lines (1,132 loc) 37.3 kB
import { IRenderer, RGBColor, RenderState } from '@utsp/types'; export { IColorPalette, IRenderer, RenderState } from '@utsp/types'; /** * Default color palette (VGA colors + extended) * Maps palette index to CSS color string */ declare const DEFAULT_PALETTE: readonly string[]; /** * Convert a color palette index to CSS color string */ declare function paletteIndexToColor(index: number, palette?: readonly string[]): string; /** * Convert CSS color string to palette index (finds closest match) */ declare function colorToPaletteIndex(color: string, palette?: readonly string[]): number; /** * Représente une cellule du terminal */ interface TerminalCell { /** Le caractère à afficher */ char: string; /** Couleur du caractère (format CSS) */ fgColor: string; /** Couleur de fond de la cellule (format CSS) */ bgColor: string; } /** * Données brutes pour définir le terminal en une fois */ interface TerminalData { /** Largeur en cellules */ width: number; /** Hauteur en cellules */ height: number; /** Tableau de cellules (longueur = width * height) */ cells: Array<{ /** Code du caractère ou le caractère lui-même */ char: string; /** Couleur du texte (format CSS) */ fgColor: string; /** Couleur de fond (format CSS) */ bgColor: string; }>; } /** * Police bitmap matricielle * Map qui associe un code de caractère (charCode) à une représentation bitmap 8x8 * Chaque Uint8Array contient 8 octets, un par ligne de pixels */ type BitmapFont$1 = Map<number, Uint8Array>; /** * Type de police à utiliser */ type FontType = { type: 'web'; fontFamily: string; fontSize: number; } | { type: 'bitmap'; font: BitmapFont$1; charWidth: number; charHeight: number; }; /** * Options pour la configuration du terminal */ interface RenderOptions { /** Largeur d'une cellule en pixels (défaut: 10) - ignoré en mode fixedGrid */ cellWidth?: number; /** Hauteur d'une cellule en pixels (défaut: 14) - ignoré en mode fixedGrid */ cellHeight?: number; /** Taille de la police en pixels (défaut: 12) */ fontSize?: number; /** Famille de police (défaut: "monospace") */ fontFamily?: string; /** Couleur de texte par défaut (défaut: "#ffffff") */ defaultFgColor?: string; /** Couleur de fond par défaut (défaut: "#000000") */ defaultBgColor?: string; /** Couleur de fond du canvas lui-même (défaut: transparent). Si null ou undefined, le canvas sera transparent */ canvasBgColor?: string | null; /** Afficher une grille de débogage (défaut: false) */ showDebugGrid?: boolean; /** Couleur de la grille de débogage (défaut: "rgba(255, 0, 0, 0.3)") */ debugGridColor?: string; /** Classes CSS additionnelles pour le canvas */ className?: string; /** Style inline pour le canvas */ style?: Partial<CSSStyleDeclaration>; /** Nombre de colonnes fixe (active le mode fixedGrid) */ fixedCols?: number; /** Nombre de lignes fixe (active le mode fixedGrid) */ fixedRows?: number; /** Ratio largeur/hauteur de cellule pour mode fixedGrid (défaut: 10/14 ≈ 0.714) */ cellAspectRatio?: number; } /** * UTSP Render - Gère une grille de caractères avec couleurs * Similaire à un terminal mais avec contrôle total de chaque cellule * * Implements IRenderer interface for compatibility with TerminalGL and dependency injection. */ declare class Terminal2D implements IRenderer { private canvas; private ctx; private parentElement; private cells; private cols; private rows; private fontSize; private fontFamily; private defaultFgColor; private defaultBgColor; private canvasBgColor; private cellWidth; private cellHeight; private offsetX; private offsetY; private fontType; private bitmapFont?; private bitmapAtlas?; private bitmapCharWidth; private bitmapCharHeight; private showDebugGrid; private debugGridColor; private gridOverlay?; private fixedGridMode; private fixedCols?; private fixedRows?; private cellAspectRatio; private resizeObserver?; private imageDataBuffer?; private useImageDataRendering; private paletteCache?; /** * Crée une instance de UTSPRender * @param parentDiv - L'élément HTML parent dans lequel créer le canvas * @param options - Options de configuration du terminal */ constructor(parentDiv: HTMLElement, options?: RenderOptions); /** * Calcule le nombre de colonnes et de lignes en fonction de la taille du parent * et centre le terminal dans le canvas */ private calculateGridSize; /** * Crée une grille vide avec les valeurs par défaut */ private createEmptyGrid; /** * Active le redimensionnement automatique * Recalcule le nombre de colonnes/lignes quand le parent change de taille */ private enableAutoResize; /** * Définit le contenu d'une cellule * @param col - Colonne (0-indexed) * @param row - Ligne (0-indexed) * @param char - Caractère à afficher * @param fgColor - Couleur du texte (optionnel, utilise la valeur par défaut si non fourni) * @param bgColor - Couleur de fond (optionnel, utilise la valeur par défaut si non fourni) */ setCell(col: number, row: number, char: string, fgColor?: string, bgColor?: string): void; /** * Récupère le contenu d'une cellule * @param col - Colonne (0-indexed) * @param row - Ligne (0-indexed) */ getCell(col: number, row: number): TerminalCell | null; /** * Écrit une chaîne de caractères à partir d'une position * @param col - Colonne de départ * @param row - Ligne * @param text - Texte à écrire * @param fgColor - Couleur du texte (optionnel) * @param bgColor - Couleur de fond (optionnel) */ write(col: number, row: number, text: string, fgColor?: string, bgColor?: string): void; /** * Remplit une zone rectangulaire * @param startCol - Colonne de départ * @param startRow - Ligne de départ * @param width - Largeur en cellules * @param height - Hauteur en cellules * @param char - Caractère de remplissage * @param fgColor - Couleur du texte (optionnel) * @param bgColor - Couleur de fond (optionnel) */ fillRect(startCol: number, startRow: number, width: number, height: number, char?: string, fgColor?: string, bgColor?: string): void; /** * Efface tout le terminal (remplit avec des espaces) */ clear(): void; /** * Définit tout le contenu du terminal à partir d'un tableau de données * Le tableau doit contenir width * height éléments * Les cellules sont lues ligne par ligne (row-major order) * * @param data - Données du terminal avec dimensions et cellules * @throws Error si le tableau n'a pas la bonne taille * * @example * terminal.setFromArray({ * width: 3, * height: 2, * cells: [ * { char: 'A', fgColor: '#ff0000', bgColor: '#000000' }, // (0,0) * { char: 'B', fgColor: '#00ff00', bgColor: '#000000' }, // (1,0) * { char: 'C', fgColor: '#0000ff', bgColor: '#000000' }, // (2,0) * { char: 'D', fgColor: '#ffff00', bgColor: '#000000' }, // (0,1) * { char: 'E', fgColor: '#ff00ff', bgColor: '#000000' }, // (1,1) * { char: 'F', fgColor: '#00ffff', bgColor: '#000000' }, // (2,1) * ] * }); */ setFromArray(data: TerminalData): void; /** * Rend la grille sur le canvas */ render(): void; /** * Rendu ultra-rapide avec ImageData (bitmap) * ~10-20× plus rapide que fillRect en boucle * Fonctionne avec scaling : buffer natif 8×8 puis drawImage() pour upscale */ private renderWithImageData; /** * Parse une couleur CSS en composantes RGBA */ private parseColorToRGB; /** * Rendu classique avec fillRect/fillText (compatible scaling, web fonts, etc.) */ private renderClassic; /** * Dessine un caractère en utilisant une police bitmap */ private drawBitmapChar; /** * Dessine une grille de débogage pour visualiser les cellules */ private drawDebugGrid; /** * Obtient le canvas HTML */ getCanvas(): HTMLCanvasElement; /** * Obtient le contexte 2D */ getContext(): CanvasRenderingContext2D; /** * Obtient les dimensions de la grille */ getDimensions(): { cols: number; rows: number; }; /** * Obtient les dimensions des cellules */ getCellDimensions(): { cellWidth: number; cellHeight: number; }; /** * Obtient la largeur d'une cellule */ getCellWidth(): number; /** * Obtient la hauteur d'une cellule */ getCellHeight(): number; /** * Obtient les décalages de centrage du terminal */ getOffsets(): { offsetX: number; offsetY: number; }; /** * Active ou désactive la grille de débogage * @param show - true pour afficher la grille, false pour la masquer */ setDebugGrid(show: boolean): void; /** * Change la couleur de fond du canvas * @param color - Couleur CSS (ex: "#000000", "rgba(0,0,0,0.5)") ou null pour transparent */ setCanvasBackgroundColor(color: string | null): void; /** * Obtient la couleur de fond actuelle du canvas * @returns La couleur de fond ou null si transparent */ getCanvasBackgroundColor(): string | null; /** * Active le mode grille fixe avec le nombre de colonnes/lignes spécifié * Les cellules s'adapteront en taille pour maintenir les dimensions demandées * @param cols - Nombre de colonnes fixe * @param rows - Nombre de lignes fixe * @param aspectRatio - Ratio largeur/hauteur de cellule (optionnel, défaut: 10/14) */ setFixedGrid(cols: number, rows: number, aspectRatio?: number): void; /** * Désactive le mode grille fixe et revient au mode adaptatif * @param cellWidth - Largeur de cellule en pixels (optionnel) * @param cellHeight - Hauteur de cellule en pixels (optionnel) */ setAdaptiveGrid(cellWidth?: number, cellHeight?: number): void; /** * Vérifie si le terminal est en mode grille fixe */ isFixedGridMode(): boolean; /** * Définit la couleur de la grille de débogage * @param color - Couleur CSS (ex: "rgba(255, 0, 0, 0.3)" ou "#ff0000") */ setDebugGridColor(color: string): void; /** * Vérifie si la grille de débogage est activée */ isDebugGridEnabled(): boolean; /** * Active ou désactive le rendu optimisé avec ImageData * Uniquement disponible pour les polices bitmap à taille native (pas de scaling) * Environ 10-20× plus rapide que le rendu classique, idéal pour les benchmarks * * @param enable - true pour activer, false pour désactiver */ setImageDataRendering(enable: boolean): void; /** * Vérifie si le rendu ImageData est activé */ isImageDataRenderingEnabled(): boolean; /** * Configure une police web (CSS) * @param fontFamily - Nom de la police CSS (ex: "Courier New", "monospace") * @param fontSize - Taille de la police en pixels (optionnel, garde la taille actuelle si non spécifié) */ setWebFont(fontFamily: string, fontSize?: number): void; /** * Configure une police bitmap matricielle * @param font - Map contenant les définitions bitmap des caractères (charCode -> Uint8Array) * @param charWidth - Largeur du glyphe en pixels (bitmap source) * @param charHeight - Hauteur du glyphe en pixels (bitmap source) * @param cellWidth - Largeur de la cellule de rendu en pixels * @param cellHeight - Hauteur de la cellule de rendu en pixels */ setBitmapFont(font: BitmapFont$1, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void; /** * Retourne le type de police actuellement utilisé */ getFontType(): 'web' | 'bitmap'; /** * Retourne la police bitmap actuelle (si applicable) */ getBitmapFont(): BitmapFont$1 | undefined; /** * Retourne les dimensions de caractère bitmap (si applicable) */ getBitmapCharDimensions(): { width: number; height: number; } | null; /** * Set color palette (IRenderer contract). * Called by ClientRuntime when Core palette changes. * * @param palette - Array of 256 RGBA colors */ setPalette(palette: RGBColor[]): void; /** * Render display data (IRenderer contract). * Converts RenderState from Core to cell-based rendering. * * @param display - Display data with palette indices */ renderDisplayData(display: RenderState): void; /** * Check if renderer is ready to render (IRenderer contract). * Canvas 2D is always ready immediately (no async initialization). * * @returns Always true for Canvas 2D */ isReady(): boolean; /** * Get width in columns (IRenderer contract). */ getCols(): number; /** * Get height in rows (IRenderer contract). */ getRows(): number; /** * Resize renderer dimensions (IRenderer contract). * * @param cols - New width in columns * @param rows - New height in rows */ resize(cols: number, rows: number): void; /** * Détruit le terminal et nettoie les ressources */ destroy(): void; } /** * WebGL compatibility report */ interface WebGLCompatibilityReport { /** WebGL 1.0 support */ webgl1: boolean; /** OES_element_index_uint extension (Uint32 indices) */ uint32Indices: boolean; /** Maximum texture size */ maxTextureSize: number; /** Maximum viewport dimensions */ maxViewportDims: [number, number]; /** Maximum terminal size with Uint16 indices (cols × rows) */ maxCellsUint16: number; /** Maximum terminal size with Uint32 indices (cols × rows) */ maxCellsUint32: number; /** Recommended maximum terminal size for this device */ recommendedMaxCells: number; /** Warnings (empty if fully compatible) */ warnings: string[]; /** Errors (empty if compatible) */ errors: string[]; } /** * Options for WebGL terminal configuration */ interface TerminalGLOptions { /** Number of columns (required) */ cols: number; /** Number of rows (required) */ rows: number; /** Character width in pixels */ charWidth?: number; /** Character height in pixels */ charHeight?: number; /** Canvas background color (CSS format, for gl.clearColor) */ canvasBgColor?: string | null; /** Show cell delimitation grid (debug) */ showGrid?: boolean; /** Force Uint16 indices (for compatibility testing, auto-detected by default) */ forceUint16?: boolean; } /** * Simplified terminal using WebGL for basic rendering * Only supports bitmap fonts with atlas * Implements IRenderer interface for dependency injection with core * * ✨ SIMPLIFIED VERSION: Only backgrounds + colored characters */ declare class TerminalGL implements IRenderer { /** * Check WebGL 1.0 compatibility and device capabilities * * Tests all required WebGL features and returns a detailed compatibility report. * Use this before creating a TerminalGL instance to ensure device support. * * @returns Detailed compatibility report with warnings and errors * * @example * ```typescript * const report = TerminalGL.checkCompatibility(); * if (report.errors.length > 0) { * console.error('WebGL not supported:', report.errors); * // Fallback to Canvas 2D renderer * } else if (report.warnings.length > 0) { * console.warn('WebGL limitations:', report.warnings); * } * console.log(`Max terminal size: ${report.recommendedMaxCells} cells`); * ``` */ static checkCompatibility(): WebGLCompatibilityReport; private canvas; private gl; private parentElement; private containerDiv; private cols; private rows; private charWidth; private charHeight; private cellWidth; private cellHeight; private glyphOffsetX; private glyphOffsetY; private canvasBgColor; private showGrid; private supportsUint32Indices; private useUint16Indices; private gridOverlay?; private bitmapFont?; private atlasTexture; private atlasCanvas?; private atlasColumns; private paletteTexture; private program; private positionBuffer; private texCoordBuffer; private colorIndexBuffer; private indexBuffer; private aPosition?; private aTexCoord?; private aColorIndex?; private uResolution; private uTexture; private uPalette; private resizeObserver?; private charCodeToAtlasIndex; private atlasUVs; private cachedAtlasWidth; private cachedAtlasHeight; private paletteFloat; private maxCells; private renderPositions; private renderTexCoords; private renderColorIndices; private renderIndices; private cachedResolution; private cachedTextureUnit; private cachedPaletteUnit; private cachedTextureUniform; private cachedPaletteUniform; private paletteHash; private staticPositionsInitialized; private vaoExtension; private vao; private instancedExtension; private useInstancing; private instanceDataBuffer; private instanceData; private templateQuadPositions; private templateQuadIndices; constructor(parentDiv: HTMLDivElement, options: TerminalGLOptions); /** * 🚀 INSTANCING: Initialize template quad and instance buffers * Called once at init if instancing is supported */ private initInstancedBuffers; /** * 🚀 OPTIMIZATION: Initialize pre-allocated buffers for rendering * Avoids allocations each frame * Uses Uint16 or Uint32 indices based on device support */ private initRenderBuffers; /** * 🚀 MEGA OPTIMIZATION: Pre-compute static positions for ALL possible quads * Called only once after font load, or after resize * Positions never change during rendering - only colors and UVs change! */ private precomputeStaticPositions; /** * Initialize WebGL (shaders, buffers, etc.) */ private initWebGL; /** * Compile a shader */ private compileShader; /** * 🔲 Initialize 2D canvas overlay for debug grid * Performance: 2D canvas drawn only once, 0ms per frame */ private initGridOverlay; /** * 🔲 Draw grid lines on 2D canvas overlay * Called only once at init and resize */ private updateGridOverlay; /** * Configure bitmap font and generate atlas * * ⚠️ **INTERNAL USE ONLY** - This method is called automatically by ClientRuntime's * event system when Core.loadBitmapFontById() is called. Do NOT call this directly * unless you're implementing a custom runtime. * * Event flow: Core.loadBitmapFontById() → Core.onBitmapFontChangedCallback * → ClientRuntime.onCoreBitmapFontChanged() → RendererManager.setBitmapFont() * * @param font - Bitmap font mapping (charCode → byte array) * @param charWidth - Width of each character in pixels * @param charHeight - Height of each character in pixels * @param cellWidth - Width of each cell in pixels * @param cellHeight - Height of each cell in pixels * @throws {Error} If atlas generation fails * * @example * ```typescript * // ❌ DON'T: Call setBitmapFont directly * renderer.setBitmapFont(font, 8, 16, 8, 16); * * // ✅ DO: Use Core's loadBitmapFontById (triggers event automatically) * core.loadBitmapFontById(1, { * charWidth: 8, charHeight: 16, * cellWidth: 8, cellHeight: 16, * glyphs: new Map([[65, new Uint8Array([...])]]) * }); * ``` */ setBitmapFont(font: BitmapFont$1, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void; /** * Generate texture atlas from bitmap font */ private generateAtlas; /** * 🚀 OPTIMIZED: Build charCode → atlas index using direct array lookup */ private buildCharCodeMap; /** * 🚀 MEGA OPTIMIZATION: Pre-compute ALL atlas UVs * Called once after atlas generation - UVs never change! * Eliminates per-frame division and modulo operations */ private precomputeAtlasUVs; /** * Create WebGL texture from atlas */ private createAtlasTexture; /** * Clear entire terminal * * Clears the WebGL canvas. Note: Actual terminal content clearing is handled * by Core's RenderState, not by this renderer. * * @example * ```typescript * renderer.clear(); * ``` */ clear(): void; /** * Parse CSS color to normalized RGBA (0-1) */ private parseColor; /** * Configure ResizeObserver to adapt canvas */ private setupResizeObserver; /** * Update canvas display size * * 🎯 PIXEL PERFECT: Forces display dimensions to be exact multiples of cell size * to avoid sub-pixel rendering artifacts (like Terminal2D does). * * Strategy: Keep canvas internal resolution fixed at base size (cols × cellWidth), * and use CSS scaling with image-rendering: pixelated for integer upscaling. */ private updateCanvasSize; /** * Set color palette and upload to GPU * * ⚠️ IMPORTANT: This is the ONLY way to update the palette. * Typically called automatically by ClientRuntime via Core.onPaletteChanged() event. * Do NOT call this directly unless you know what you're doing. * * @param palette - Array of 256 RGB colors * * @example * ```typescript * // ✅ Normal usage: Core handles this automatically * core.loadPalette([...]); * // → Core emits event * // → ClientRuntime receives event * // → renderer.setPalette() called automatically * * // ⚠️ Manual usage (advanced): * const myPalette: RGBColor[] = [ * { r: 0, g: 0, b: 0, a: 255 }, // Color 0: Black * { r: 255, g: 0, b: 0, a: 255 }, // Color 1: Red * // ... 254 more colors * ]; * renderer.setPalette(myPalette); * ``` */ setPalette(palette: RGBColor[]): void; /** * 🚀 GPU OPTIMIZATION: Upload palette to GPU texture (256×1 RGBA) */ private updatePaletteTexture; /** * Render display data from core engine (ULTRA-OPTIMIZED) * * Bypasses internal cells and renders directly from RenderState for maximum performance. * Uses GPU palette texture lookup to minimize CPU→GPU bandwidth (4× reduction). * * @param data - Render state containing cells, dimensions, and palette * * @example * ```typescript * const renderState: RenderState = { * cells: [...], * width: 80, * height: 25, * palette: [...] * }; * renderer.renderDisplayData(renderState); * ``` */ renderDisplayData(data: RenderState): void; /** * 🚀 NEW METHOD: Render directly from RenderState * Bypass this.cells for maximum performance */ private renderDirect; /** * 🚀 INSTANCED RENDERING: 1 draw call for entire terminal * MASSIVE performance boost - reduces draw calls from cols×rows×2 to just 1! */ private renderInstanced; /** * 🚀 ULTRA-OPTIMIZED: Update ONLY dynamic data (colors + UVs) * Positions are static and pre-computed - only updated on resize! * This is a MASSIVE performance win - positions never change during normal rendering */ private renderDirectBuffers; /** * Resize the terminal dimensions * * Changes the number of columns and rows. Preserves existing cell content * where possible. Reallocates render buffers if needed. * * @param cols - New number of columns (must be positive integer) * @param rows - New number of rows (must be positive integer) * * @example * ```typescript * renderer.resize(120, 40); // Resize to 120×40 * ``` */ resize(cols: number, rows: number): void; /** * Get canvas element */ getCanvas(): HTMLCanvasElement; /** * Get grid dimensions */ getGridSize(): { cols: number; rows: number; }; /** * Get cell width */ getCellWidth(): number; /** * Get cell height */ getCellHeight(): number; /** * Get number of columns (IRenderer interface) * * @returns Current number of columns * * @example * ```typescript * const cols = renderer.getCols(); // 80 * ``` */ getCols(): number; /** * Get number of rows (IRenderer interface) * * @returns Current number of rows * * @example * ```typescript * const rows = renderer.getRows(); // 25 * ``` */ getRows(): number; /** * Check if renderer is ready (IRenderer interface) * * Returns true when bitmap font, atlas texture, and shader program are initialized. * * @returns true if ready to render, false otherwise * * @example * ```typescript * if (renderer.isReady()) { * renderer.renderDisplayData(data); * } * ``` */ isReady(): boolean; /** * Destroy/cleanup resources (IRenderer interface) * * Destroys WebGL resources (textures, buffers), disconnects ResizeObserver, * and removes canvases from DOM. Call this before removing the renderer. * * @example * ```typescript * renderer.destroy(); * renderer = null; * ``` */ destroy(): void; /** * Cleanup resources */ dispose(): void; } /** * Police bitmap matricielle * Map qui associe un code de caractère (charCode) à une représentation bitmap */ type BitmapFont = Map<number, Uint8Array>; /** * Atlas à une résolution spécifique */ interface AtlasResolution { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D; scale: number; charWidth: number; charHeight: number; } /** * Classe pour générer et gérer un atlas de police bitmap multi-résolution * Convertit une police matricielle (bits) en plusieurs textures canvas à différentes échelles * pour un rendu ultra-rapide avec qualité optimale quelque soit le zoom * * Utilise un cache LRU de glyphes colorés pour éviter la re-colorisation */ declare class BitmapFontAtlas { private atlases; private charMap; private baseCharWidth; private baseCharHeight; private baseCellWidth; private baseCellHeight; private atlasColumns; private font; private readonly SCALES; private colorCache; private readonly MAX_CACHE_SIZE; /** * Construit un atlas de police bitmap multi-résolution * @param font La police bitmap source * @param charWidth Largeur de base d'un caractère en pixels (taille du glyphe dans l'atlas) * @param charHeight Hauteur de base d'un caractère en pixels (taille du glyphe dans l'atlas) * @param cellWidth Largeur de base d'une cellule en pixels (peut être > charWidth pour l'espacement) * @param cellHeight Hauteur de base d'une cellule en pixels (peut être > charHeight pour l'espacement) */ constructor(font: BitmapFont, charWidth: number, charHeight: number, cellWidth?: number, cellHeight?: number); /** * Génère les 4 atlas à différentes résolutions (1x, 2x, 4x, 8x) * Très rapide: ~4-8ms pour 256 caractères × 4 résolutions */ private generateAtlases; /** * Récupère ou crée un atlas pour une échelle donnée */ private getOrCreateAtlas; /** * Rend un caractère bitmap dans un atlas à une résolution donnée * Utilise fillRect pour un rendu ultra-rapide */ private renderBitmapToAtlas; /** * Dessine un caractère en utilisant le cache de glyphes colorés * Ultra-rapide: 1 seul drawImage() par caractère * Utilise ImageData pour coloriser + Canvas cache pour éviter la re-colorisation * * @param ctx - Contexte de destination * @param charCode - Code du caractère à dessiner * @param x - Position X de destination (coin de la cellule) * @param y - Position Y de destination (coin de la cellule) * @param width - Largeur de la cellule de destination * @param height - Hauteur de la cellule de destination * @param color - Couleur du caractère (format CSS) */ drawChar(ctx: CanvasRenderingContext2D, charCode: number, x: number, y: number, width: number, height: number, color: string): void; /** * Crée un glyphe colorisé à partir de l'atlas blanc * Utilise ImageData pour une colorisation ultra-rapide */ private createColoredGlyph; /** * Convertit une couleur hex en RGB */ private hexToRgb; /** * Élimine les entrées les moins récemment utilisées du cache (LRU) */ private evictLRU; /** * Retourne le canvas d'atlas pour une résolution donnée (pour débogage/visualisation) * Par défaut retourne l'atlas 1x */ getAtlasCanvas(scale?: number): HTMLCanvasElement | undefined; /** * Retourne tous les atlas disponibles */ getAllAtlases(): Map<number, AtlasResolution>; /** * Retourne les dimensions de base d'un caractère */ getCharDimensions(): { width: number; height: number; }; /** * Retourne le nombre de caractères dans l'atlas */ getCharCount(): number; /** * Vérifie si un caractère existe dans l'atlas */ hasChar(charCode: number): boolean; /** * Retourne les dimensions d'un atlas à une résolution donnée */ getAtlasDimensions(scale?: number): { width: number; height: number; } | undefined; /** * Exporte un atlas en Data URL (pour débogage) * Permet de visualiser l'atlas ou de le sauvegarder */ toDataURL(scale?: number, type?: string): string | undefined; /** * Retourne les statistiques du cache de glyphes colorés */ getCacheStats(): { size: number; maxSize: number; hitRate?: number; }; /** * Vide le cache de glyphes colorés */ clearCache(): void; /** * Libère les ressources */ destroy(): void; } /** * 🔲 GridOverlay - Classe réutilisable pour gérer le canvas de grille de débogage * * Gère un canvas 2D superposé qui affiche une grille de cellules. * Au lieu de simples lignes, dessine un cadre fin à l'intérieur de chaque cellule * pour une meilleure visualisation. * * @example * ```typescript * const grid = new GridOverlay(containerElement); * grid.setDimensions(80, 24, 10, 16); * grid.render(); * ``` */ declare class GridOverlay { private canvas; private ctx; private container; private cols; private rows; private cellWidth; private cellHeight; private offsetX; private offsetY; private strokeColor; private lineWidth; private innerPadding; /** * Crée une nouvelle overlay de grille * @param container - Élément parent qui contiendra le canvas * @param options - Options de configuration */ constructor(container: HTMLElement, options?: { strokeColor?: string; lineWidth?: number; innerPadding?: number; zIndex?: number; }); /** * Configure les dimensions de la grille * @param cols - Nombre de colonnes * @param rows - Nombre de lignes * @param cellWidth - Largeur d'une cellule en pixels * @param cellHeight - Hauteur d'une cellule en pixels * @param offsetX - Décalage horizontal (optionnel) * @param offsetY - Décalage vertical (optionnel) */ setDimensions(cols: number, rows: number, cellWidth: number, cellHeight: number, offsetX?: number, offsetY?: number): void; /** * Configure la taille physique du canvas * Doit correspondre à la taille d'affichage du canvas principal * @param displayWidth - Largeur d'affichage en pixels * @param displayHeight - Hauteur d'affichage en pixels */ setCanvasSize(displayWidth: number, displayHeight: number): void; /** * Configure les options visuelles * @param options - Options de rendu */ setStyle(options: { strokeColor?: string; lineWidth?: number; innerPadding?: number; }): void; /** * Dessine la grille avec des lignes fines continues * * Dessine une grille continue sans écarts entre les cellules. * Les lignes sont décalées vers l'intérieur de la cellule (innerPadding) * pour créer un effet visuel élégant tout en gardant la grille continue. */ render(): void; /** * Met à jour et redessine la grille avec de nouvelles dimensions * Méthode pratique qui combine setDimensions, setCanvasSize et render * * @param cols - Nombre de colonnes * @param rows - Nombre de lignes * @param cellWidth - Largeur d'une cellule * @param cellHeight - Hauteur d'une cellule * @param displayWidth - Largeur d'affichage du canvas * @param displayHeight - Hauteur d'affichage du canvas * @param offsetX - Décalage horizontal (optionnel) * @param offsetY - Décalage vertical (optionnel) */ update(cols: number, rows: number, cellWidth: number, cellHeight: number, displayWidth: number, displayHeight: number, offsetX?: number, offsetY?: number): void; /** * Affiche ou cache la grille * @param visible - true pour afficher, false pour cacher */ setVisible(visible: boolean): void; /** * Supprime le canvas de grille du DOM */ destroy(): void; /** * Retourne le canvas HTML */ getCanvas(): HTMLCanvasElement; } /** * AutoplayOverlay - Displays a play button overlay that must be clicked to start the application * * This is useful for: * - Audio APIs that require user interaction before playing * - Preventing automatic resource consumption * - Better UX on mobile where autoplay may not be desired * * @example * ```typescript * const overlay = new AutoplayOverlay(container, { * buttonText: 'Click to Start', * onStart: () => { * // Application starts here * } * }); * * // To programmatically start (e.g., if autoplay is enabled): * overlay.start(); * * // Cleanup: * overlay.destroy(); * ``` */ interface AutoplayOverlayOptions { /** Text to display on the button (default: 'Click to Start') */ buttonText?: string; /** Callback when user clicks the button */ onStart?: () => void; /** Background color of the overlay (default: 'rgba(0, 0, 0, 0.8)') */ backgroundColor?: string; /** Button background color (default: '#4a90d9') */ buttonColor?: string; /** Button hover color (default: '#357abd') */ buttonHoverColor?: string; /** Button text color (default: '#ffffff') */ buttonTextColor?: string; /** Z-index of the overlay (default: 1000) */ zIndex?: number; } declare class AutoplayOverlay { private container; private overlayDiv; private button; private options; private started; private onStartCallback?; constructor(container: HTMLElement, options?: AutoplayOverlayOptions); /** * Create the overlay DOM elements */ private createOverlay; /** * Start the application (hide overlay and call onStart callback) * Can be called programmatically if autoplay is enabled */ start(): void; /** * Check if the overlay has been started */ isStarted(): boolean; /** * Check if the overlay is currently visible */ isVisible(): boolean; /** * Remove the overlay from DOM */ private removeOverlay; /** * Set the button text */ setButtonText(text: string): void; /** * Update the onStart callback */ setOnStart(callback: () => void): void; /** * Destroy the overlay and cleanup */ destroy(): void; } /** * UTSP Render - Main entry point * * Terminal de caractères avec rendu WebGL optimisé * TerminalGL est le renderer principal - WebGL 1.0 avec palette GPU */ declare const version = "0.1.0"; export { AutoplayOverlay, BitmapFontAtlas, DEFAULT_PALETTE, GridOverlay, Terminal2D, TerminalGL, colorToPaletteIndex, paletteIndexToColor, version }; export type { AutoplayOverlayOptions, BitmapFont$1 as BitmapFont, FontType, RenderOptions, TerminalCell, TerminalData, TerminalGLOptions, WebGLCompatibilityReport };